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.
| Norm | What it means |
|---|---|
| Architecture-first | Every change starts with a clear data model, flow phase, or SharedStore contract. Implementation details follow structure. |
| Coder is the runtime | OpenFlows is a thin orchestration layer over a self-hosted Coder deployment. Workspaces, identity, and LLM keys are owned by Coder. |
| Ephemeral by default | No long-lived agent state. Workspaces are provisioned per task and torn down after merge. |
| Reconcile, don’t assume | NEXUS recovers from ambiguity and failure. Every change must survive reconcile() and at least one crash scenario. |
| Minimal surface area | Prefer small, reviewable diffs. One logical change per branch, one branch per ticket. |
| Write the test before the excuse | If a change is hard to test, it is usually hard to operate. Tests are not optional. |
OpenFlows = PocketFlow + SharedStore + NEXUS
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.
- Be precise. Cite files, line numbers, and test results when making claims.
- Assume good intent, but verify. Ask for clarification before assuming incompetence.
- Respect the backlog. Not every good idea is a current priority.
- Document your decisions. If it matters enough to argue about, it matters enough to write down.
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.
| Label | Meaning |
|---|---|
| Untriaged | New issues without a label or owner. NEXUS ignores them. |
| needs-info | Missing reproduction, logs, or scope. Ask the reporter before any code is written. |
| good-first-issue | Self-contained, well-scoped, safe for new contributors. |
| bug | Unexpected behavior with a reproducible path. Needs a regression test. |
| enhancement | New capability. Requires an ADR or a one-pager in the issue description. |
| blocked | Cannot proceed without a merge, decision, or external dependency. |
A well-formed issue includes:
- Goal - one sentence describing the outcome, not the mechanism.
- Context - links to the relevant registry, flow, or SharedStore contract.
- Reproduction - for bugs, a minimal set of commands or a failing test.
- Acceptance criteria - what must be true for the issue to close.
- Risk surface - what could break, and what the rollback plan is.
Use the right audience
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.
- Find or create an issue. Untriaged issues will not be picked up.
- Create a branch from the latest default branch using the naming convention below.
- Make focused, reviewable commits. Keep the diff under 400 lines when possible.
- Run the test suite locally:
./orchestration/agent/tooling/run-tests.sh. - Push the branch and open a pull request. Link the issue in the description.
- Respond to review comments. Resolve conversations when the fix is committed.
- Mark the PR ready for merge only after CI passes and at least one human or SENTINEL review approves.
Branch Naming
| Kind | Pattern | Notes |
|---|---|---|
| Feature work | forge-{slot}/{ticket-id} | Primary branch for tickets. Example: forge-1/OF-142. |
| Docs only | docs/{ticket-id}-{short-topic} | Documentation, copy, and website changes that do not touch runtime code. |
| Hotfix | hotfix/{ticket-id}-{description} | Urgent fixes against the current release branch. |
| Release prep | release/{version} | Version bumps, changelog assembly, and release notes. |
Never touch another worker’s files
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.
| Type | Use when |
|---|---|
feat(scope): description | New behavior or capability. |
fix(scope): description | Bug fix with a regression test. |
docs(scope): description | Documentation or website changes. |
refactor(scope): description | Internal restructuring with no observable behavior change. |
test(scope): description | Test-only changes. |
chore(scope): description | Tooling, dependencies, or housekeeping. |
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:
- Explain what and why, not how. The diff shows the how.
- Reference the issue or ticket with
Closes: OF-XXXorRelates: OF-XXX. - Wrap at 72 characters.
- Separate the summary from the body with a blank line.
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.
- Bug reports and feature requests - GitHub Issues, with the triage template.
- Architecture or design questions - GitHub Discussions, Architecture category, with a one-pager or ADR draft.
- Security concerns - Private maintainer email; do not open a public issue.
- Operational emergencies - The NEXUS runbook and on-call channel, not a GitHub issue.
- Skill or registry questions - This docs section, especially the Adding Skills and Testing pages.
Escalation protocol
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.