- Get Started

Contributor Guide

OpenFlows is a serious system for orchestrating code agents. Every contributor - whether they are fixing a typo, adding a skill, or extending the NEXUS reconcile loop - operates under the same engineering contract: the architecture is the product, the runtime belongs to Coder, and the only acceptable failure mode is a clean hand-off to NEXUS. This guide defines the norms, expectations, and mechanics for working in the codebase.

The project is written primarily in Rust, orchestrated by the PocketFlow engine, and backed by Redis. Its extension point is orchestration/agent/registry.json v2. If you can model a task as a flow phase, you can add it without altering core code. If your change requires core changes, it must be justified by a data-model or flow-level improvement.

Project Norms

These norms are not suggestions. They are the guardrails that keep a distributed team of human and agent contributors from producing a fragile, stateful mess. Read them before you open an issue, before you write code, and before you open a pull request.

NormWhat it means
Architecture-firstEvery change starts with a clear data model, flow phase, or SharedStore contract. Implementation details follow structure.
Coder is the runtimeOpenFlows is a thin orchestration layer over a self-hosted Coder deployment. Workspaces, identity, and LLM keys are owned by Coder.
Ephemeral by defaultNo long-lived agent state. Workspaces are provisioned per task and torn down after merge.
Reconcile, don’t assumeNEXUS recovers from ambiguity and failure. Every change must survive reconcile() and at least one crash scenario.
Minimal surface areaPrefer small, reviewable diffs. One logical change per branch, one branch per ticket.
Write the test before the excuseIf a change is hard to test, it is usually hard to operate. Tests are not optional.

OpenFlows = PocketFlow + SharedStore + NEXUS

The system is a flow graph running on a typed Redis SharedStore, with NEXUS responsible for reconcile. Every feature must fit into one of those three buckets: a flow node, a store contract, or a reconcile decision. If it does not, it probably belongs in Coder itself.

Code of Conduct

We expect direct, respectful, evidence-based communication. Disagreement is welcome; personal attacks, sealioning, or ungrounded criticism are not. The maintainers have final say on scope, architecture, and release readiness. If a decision is made, move forward and capture dissent in an ADR rather than relitigating it in the PR thread.

Harassment, discrimination, or sustained hostility toward any contributor will result in immediate removal from the project. Report concerns privately to the maintainers. We do not tolerate behavior that makes competent engineers hesitate to contribute.

Issue Triage

NEXUS only works on issues that have been triaged. Untriaged issues are invisible to the orchestration layer. When you create an issue, you are asking a human or an agent to spend attention on it. Make that request as cheap to evaluate as possible.

LabelMeaning
UntriagedNew issues without a label or owner. NEXUS ignores them.
needs-infoMissing reproduction, logs, or scope. Ask the reporter before any code is written.
good-first-issueSelf-contained, well-scoped, safe for new contributors.
bugUnexpected behavior with a reproducible path. Needs a regression test.
enhancementNew capability. Requires an ADR or a one-pager in the issue description.
blockedCannot proceed without a merge, decision, or external dependency.

A well-formed issue includes:

  1. Goal - one sentence describing the outcome, not the mechanism.
  2. Context - links to the relevant registry, flow, or SharedStore contract.
  3. Reproduction - for bugs, a minimal set of commands or a failing test.
  4. Acceptance criteria - what must be true for the issue to close.
  5. Risk surface - what could break, and what the rollback plan is.

Use the right audience

NEXUS can handle clearly scoped implementation tickets. Ambiguous product or architecture questions should be opened for human discussion first. If an issue reads like a design review, add the needs-info label and request a one-pager or ADR before work begins.

How to Submit Changes

OpenFlows follows a one-ticket, one-branch, one-PR rule. Branch names are prefixed by the worker slot that owns them, and every branch must be pushed to the remote so NEXUS can observe it. Do not open multiple PRs for the same ticket.

  1. Find or create an issue. Untriaged issues will not be picked up.
  2. Create a branch from the latest default branch using the naming convention below.
  3. Make focused, reviewable commits. Keep the diff under 400 lines when possible.
  4. Run the test suite locally: ./orchestration/agent/tooling/run-tests.sh.
  5. Push the branch and open a pull request. Link the issue in the description.
  6. Respond to review comments. Resolve conversations when the fix is committed.
  7. Mark the PR ready for merge only after CI passes and at least one human or SENTINEL review approves.

Branch Naming

KindPatternNotes
Feature workforge-{slot}/{ticket-id}Primary branch for tickets. Example: forge-1/OF-142.
Docs onlydocs/{ticket-id}-{short-topic}Documentation, copy, and website changes that do not touch runtime code.
Hotfixhotfix/{ticket-id}-{description}Urgent fixes against the current release branch.
Release preprelease/{version}Version bumps, changelog assembly, and release notes.

Never touch another worker’s files

Your working directory is your domain. If you see files owned by another worker slot, treat them as locked. Do not check them out, do not commit into them, and do not resolve conflicts in them without explicit coordination. NEXUS enforces this by worker slot scoping.

Commit Conventions

Commit messages tell the story of a change. They must use conventional commits so the changelog, release notes, and rollback tooling can parse them automatically. Write the message for the person debugging a production issue six months from now.

TypeUse when
feat(scope): descriptionNew behavior or capability.
fix(scope): descriptionBug fix with a regression test.
docs(scope): descriptionDocumentation or website changes.
refactor(scope): descriptionInternal restructuring with no observable behavior change.
test(scope): descriptionTest-only changes.
chore(scope): descriptionTooling, dependencies, or housekeeping.
text
feat(nexus): add reconcile hook for completed_without_pr

NEXUS now detects tickets that reached COMPLETED without a corresponding
PR and re-routes them to the PR creation phase. This closes the gap where
FORGE could finish work but fail to call the GitHub MCP before workspace
teardown.

Closes: OF-312

Commit body rules:

Where to Ask Questions

The right channel depends on the kind of question. Before you ask, do your homework: check the docs, search closed issues, and read the relevant ADR. Then choose the appropriate venue.

Escalation protocol

If you are blocked by an ambiguous requirement, a dependency that has not merged, or a file lock conflict, write a STATUS.json with outcome: blocked and a specific, answerable question. A blocked ticket with a precise question is infinitely more valuable than a wrong guess shipped on time.