Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Contributing to reCode

reCode dogfoods itself: this repo's own backlog runs through the same orchestrator/implementer/reviewer
pipeline it ships to consumers, using a self-hosted adapter (`.claude/self/gates.json`) instead of the
placeholder `.claude/gates.json` that downstream projects fill in. Understanding that loop is most of what
you need to contribute here. See [`docs/USAGE.md`](docs/USAGE.md) for the full mechanics; this file is the
short, contributor-facing version plus the boundaries specific to this repo.

## How work gets approved (two-label workflow)
Every issue starts as **`backlog`** — filed, not yet approved. The loop, and any agent working this repo's
queue, **never** picks up a `backlog` issue.

- **`backlog`** — default state for every new issue, including ones filed by agents/bots. If you file an
issue (or an agent files one on your behalf), it MUST be labelled `backlog`, never `planned`.
- **`planned`** — the repo owner's formal approval: "scoped, reviewed, do it." **Only the repo owner adds
this label** — no contributor, agent, or bot ever assigns it, to their own issue or anyone else's.
Commenting "approved" on an issue does nothing; nothing watches issue text, only the label.
- **`module:<name>`** — routing, not approval. It maps an issue to one of this repo's self-hosted modules
(`docs`, `harness` → `.claude`, `examples`, `ci` → `.github` — see `.claude/self/gates.json`) and therefore
to a worker's non-overlapping boundary. No module label ⇒ nothing safe to hand a worker, `planned` or not.

**If you want to propose work:** open an issue describing it, labelled `backlog` (+ a `module:*` label if you
know which area it touches). The owner reviews and, if it's a good fit, adds `planned` — that's what makes it
loop-eligible.

## How a change actually lands
1. **Scope** — an orchestrator reads the issue and this repo's self-adapter, and splits it into
non-overlapping sub-tasks by module.
2. **Build** — each sub-task goes to an `implementer`, isolated in its own git worktree/branch. Implementers
must stay inside their assigned module's `path` — cross-module work gets re-scoped, never reached across.
3. **Gate** — before anything is called done it must pass this repo's self-hosted gates
(`GATES_FILE=.claude/self/gates.json bash .claude/scripts/gate.sh <build|lint|test>`), enforced by a `Stop`
hook, not by asking the model nicely.
4. **Review** — gated changes go to reviewer lenses (`correctness`, `tests` per `.claude/self/gates.json` →
`review.lenses`), adversarial and one-per-lens. Consensus mode is `all`: every lens must approve.
5. **PR** — opened by a **bot machine account** (`.claude/scripts/bot-gh.sh`), never under the owner's own
`gh` auth — GitHub blocks a PR author from approving their own PR, and the owner's approval is the only
merge gate. Commits/pushes stay on the human contributor's (or the worker's) own git identity; only PR
*creation* goes through the bot.
6. **Merge** — the repo owner reviews and formally Approves on GitHub. Merge happens only once CI is green
and the approval is at/after the PR's last commit (so a later push always requires re-approval).

If you're opening a PR by hand rather than through the loop, the same gates and review expectations apply —
run the self-hosted gates yourself before requesting review (see [Running the gates](#running-the-gates)
below).

## What NOT to touch
- **`.claude/self/`** — this repo's own self-hosting adapter and loop config (module map, gate commands,
review/merge settings for reCode's *own* backlog). It is deliberately kept separate from the shipped
`.claude/gates.json` placeholder so that a downstream project cloning/installing this plugin never inherits
reCode's own configuration (see `.claude/self/README.md`). Treat it as owner-maintained; if a change to the
self-adapter is genuinely part of your task, call it out explicitly rather than editing it incidentally.
- **MANAGED files** — templates under `.claude/skills/setup/templates/` (`feature-fanout.js`,
`pr-loop.service`, `claude-rc.service`, `arm-loop.sh`) each carry an `@orchestrator-managed <name> vN`
marker comment. These are the source of truth that `/orchestrator:setup` scaffolds into consumer repos and
`/orchestrator:sync` re-stamps on plugin updates (see `.claude/skills/sync/SKILL.md`). If you change one,
bump its version marker **and** `.claude/.claude-plugin/plugin.json`'s `version` in the same PR — otherwise
every already-installed consumer's cached copy silently never updates (this bit the project once already,
see `docs/USAGE.md` → "Maintainer note").
- **`LICENSE`** — already MIT (Copyright (c) 2026 Roberto Cano). Don't re-add or modify it.
- **The module-boundary rule** — an implementer (human or agent) assigned one module must not edit files
outside that module's `path`. If a task genuinely spans modules, split it into per-module sub-tasks or flag
it for re-scoping; don't reach across the boundary from inside a single worker/PR.

## Running the gates
This repo's own gates run through the self-adapter, not the placeholder `.claude/gates.json`:
```bash
GATES_FILE=.claude/self/gates.json bash .claude/scripts/gate.sh build
GATES_FILE=.claude/self/gates.json bash .claude/scripts/gate.sh lint
GATES_FILE=.claude/self/gates.json bash .claude/scripts/gate.sh test
```
`build`/`lint` are static checks (every adapter JSON is well-shaped; every shell script parses; every
workflow `.js` type-checks with `node --check`). `test` additionally runs a deterministic end-to-end smoke of
the fan-out scaffold against a fixture — no agents, no tokens, no network. All three must be green before a
PR is considered done.

## Hygiene expectations
Don't commit secrets, tokens, or personal machine paths. `.gitignore` already covers the sensitive local-only
paths for this repo (`.claude/state/`, `.claude/settings.local.json`, `.env*` other than `.env.example`,
common editor dirs, `__pycache__/`) — if your change adds a new kind of local-only artifact, extend
`.gitignore` rather than relying on `git status` staying clean by luck.

## Questions
Read [`docs/USAGE.md`](docs/USAGE.md) for the full loop mechanics and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
for the design rationale. If something here and the docs disagree, the docs under `docs/` are the source of
truth — this file is a contributor-facing summary, not a spec.
152 changes: 123 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,141 @@
# reCode

A **GitHub template** (formerly the ai-project-orchestrator template) for running an orchestrated "army" of
Claude Code agents on a codebase: a lead **orchestrator** scopes a task and delegates to worktree-isolated
**implementers**, whose work is gated by adversarial **reviewers** — looping until tests, coverage, and
review all pass.

The design is **two-tier**: a *generic harness* (portable across any stack) plus a thin *project adapter*
(`.claude/gates.json` + `CLAUDE.md`) that you fill in per project. Onboarding a new repo is a ~20-line
config edit, not a rebuild.

> Status: **v0** — a starting point to iterate on. The underlying Claude Code features (subagents, worktree
> isolation, the workflow engine) are evolving; treat your first runs as calibration.

## Use it
1. Click **“Use this template”** on GitHub → create your repo.
2. Open it in Claude Code and follow **[`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md)** (fill `CLAUDE.md`
and `.claude/gates.json` — there are copy-paste prompts in [`docs/PROMPTS.md`](docs/PROMPTS.md) that draft
them for you), then work through the **[new-project configuration
checklist](docs/GETTING_STARTED.md#new-project-configuration-checklist)** to wire it into the autonomous loop.
3. Drive it: see **[`docs/USAGE.md`](docs/USAGE.md)**.
**Orchestrated multi-agent development for [Claude Code](https://claude.com/claude-code).** reCode ships as a
Claude Code plugin that turns a lead agent into a small engineering team: an **orchestrator** scopes a task
into non-overlapping sub-tasks, hands each to a worktree-isolated **implementer**, gates the result against
your project's real build/lint/typecheck/test/coverage commands, and routes it through adversarial
**reviewers** (one per lens — correctness, tests, security, …) before it becomes a PR. Run it conversationally
for one-off work, or arm the **autonomous PR loop** so it drives your GitHub issue backlog hands-off: poll for
work → build → gate → review → open a bot-authored PR → wait for your approval → merge → repeat.

> Status: **v0** — a starting point to iterate on. The underlying Claude Code features (plugins, subagents,
> worktree isolation) are evolving; treat your first runs as calibration.

## What you get
- **The orchestrator pattern.** `orchestrator` (Opus) → `implementer` × N (Sonnet, each in its own git
worktree + branch) → `reviewer` × N (one per lens, adversarial) → `test-runner`. See
[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full topology and the reasoning behind it.
- **Gates as code.** `.claude/gates.json` is a versioned, per-project adapter (module map + real shell
commands for build/lint/typecheck/test/coverage) that every agent must satisfy before it can call anything
"done" — enforced by a `Stop` hook, not by asking the model nicely.
- **Worktree isolation.** Every implementer works in its own `git worktree`, so parallel workers physically
cannot clash on the same files.
- **The autonomous PR loop.** A cron-less `systemd --user` daemon (or a session-scoped cron fallback) polls
your repo, advances one `planned` + `module:*`-labelled issue at a time through the full
scope → implement → gate → review → PR pipeline, and merges once **you** approve — see
[`docs/USAGE.md`](docs/USAGE.md) → "Autonomous loop & the issue queue".
- **The cockpit.** A read-only dashboard — static snapshot or a live, auto-refreshing local server — showing
open issues by module, PR review/CI state, and active worker worktrees in real time. See
[below](#the-cockpit).

## Quickstart (5 minutes)
This is the actual supported path per [`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md) — reCode is added
to an **existing** project as a plugin, not created by cloning/templating a new repo.

**1. Install the `orchestrator` plugin** into your project. Either declare the marketplace straight from
GitHub (no local clone needed) in your project's `.claude/settings.json`:
```json
{
"extraKnownMarketplaces": {
"recode": { "source": { "source": "github", "repo": "robercano/reCode" } }
},
"enabledPlugins": { "orchestrator@recode": true }
}
```
...or clone it locally and add it as a filesystem marketplace:
```bash
git clone https://github.com/robercano/reCode.git ../reCode
```
then, inside **your own project**, in Claude Code:
```
/plugin marketplace add ../reCode/.claude
/plugin install orchestrator@recode
```

**2. Onboard: run `/orchestrator:setup`.** With the plugin enabled, run it in Claude Code. It interviews you
(project basics, module boundaries, gate commands, review/merge config) and scaffolds the files a plugin
can't carry into your repo — `.claude/gates.json`, `CLAUDE.md`, the fan-out workflow, the CI gate workflow —
plus a bot-account check and an offer to arm the loop.

**3. Arm the loop (optional but recommended).** Outside Claude Code, in a real terminal:
```bash
bash .claude/scripts/arm-loop.sh
```
This installs the `systemd --user` daemon that polls your repo and drives approved issues through the
pipeline unattended. See [`docs/USAGE.md`](docs/USAGE.md) → "Cron-less loop (daemon)" for the mechanics, and
[`docs/HARDENING.md`](docs/HARDENING.md) before running it with `bypassPermissions`.

Full walkthrough, prerequisites, and a new-project configuration checklist:
[`docs/GETTING_STARTED.md`](docs/GETTING_STARTED.md).

## The cockpit
`.claude/scripts/cockpit.sh` renders a static local HTML snapshot of your repo's orchestration state: open
issues by module with their blocking graph, PR review/CI status, per-role model routing, and active worker
worktrees. For a live, auto-refreshing view with a **worker inspector drawer** (click a live worker row to see
its timeline, breadcrumbs, worktree diff/forensics, and recent tool activity), run the serve mode:
```bash
pnpm cockpit # http://127.0.0.1:8090
pnpm cockpit -- 9000 # custom port
```
It's a tiny Node HTTP server (no dependencies, node built-ins only, bound to `127.0.0.1`) wrapping the same
renderer used by the static snapshot. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#cockpit-read-only-dashboard)
and [`docs/COCKPIT_EVALUATION.md`](docs/COCKPIT_EVALUATION.md) for the design rationale.

<!-- TODO(#87): cockpit demo GIF — live workers + inspector drawer; pending screen capture (no agent can record a screen) -->
*(Demo pending: a short capture of the cockpit serve mode showing live worker rows updating in real time, and
the inspector drawer opening to show one worker's timeline/worktree/tool activity.)*

## What's in here
```
.claude/
agents/ orchestrator · implementer (worktree) · reviewer · test-runner ← generic, portable
workflows/ feature-fanout.js — deterministic scope→implement→review→loop
scripts/ gate.sh — runs a gate command from gates.json
settings.json hooks (lint on edit, tests on stop) + permissions ← generic
gates.json ★ PROJECT ADAPTER — module map, gate commands, model routing ← you fill this
CLAUDE.md ★ project context ← you fill this
.github/ PR template (the per-agent "demo artifact")
agents/ orchestrator · implementer (worktree) · reviewer · test-runner ← shipped with the plugin
commands/ /orchestrator:harden · /orchestrator:pr-loop · /orchestrator:test-pr
skills/ setup, sync — onboarding + plugin-update reconciliation
scripts/ gate.sh, cockpit.sh / cockpit-serve.sh, the loop daemon + its helpers
self/ this repo's OWN self-hosted adapter (dogfooding — see docs/USAGE.md → "Self-hosting")
gates.json ★ PROJECT ADAPTER placeholder — module map, gate commands, model routing ← you fill this
CLAUDE.md ★ project context placeholder ← you fill this
CONTRIBUTING.md how contributions to reCode itself work
LICENSE MIT
.github/ CI gate workflow template
docs/
GETTING_STARTED.md setup, step by step
ARCHITECTURE.md the mental model & the three levers
USAGE.md how to drive the orchestrator day to day
USAGE.md how to drive the orchestrator day to day, incl. the autonomous loop
PROMPTS.md copy-paste prompts to populate files & kick off work
TOKEN_BUDGET.md cost control & measurement
TOKEN_BUDGET.md cost control & measurement
HARDENING.md running the loop hands-off safely (bypass + sandbox)
COCKPIT_EVALUATION.md design notes on the cockpit vs. third-party GUIs
```
★ = the only two files you must fill in per project once the plugin is installed.

★ = the only two files you must edit per project.
## Installing / publishing
The supported install path is the **Claude Code plugin marketplace**, either via GitHub source
(`extraKnownMarketplaces`, no clone) or a local clone added as a filesystem marketplace — both shown in
[Quickstart](#quickstart-5-minutes) above, with the full rationale for having two `marketplace.json` files in
[`.claude-plugin/README.md`](.claude-plugin/README.md).

**npm: not published — name is squatted-dead (decision pending).** reCode is not currently published to npm.
The obvious package name is already registered by an unrelated, apparently abandoned/dead package, so an npm
release isn't a plain `npm publish` — the open options are (a) publish under a scope (e.g. `@robercano/recode`)
or (b) file an [npm name dispute](https://docs.npmjs.com/policies/disputes) against the squatted name. Neither
has been decided yet; this note exists so a contributor who wants to pick this up knows where the decision
stands. If you want to drive it, open an issue (`backlog` label — see [`CONTRIBUTING.md`](CONTRIBUTING.md))
proposing one option with the tradeoffs, and the repo owner will label it `planned` if approved.

## Docs
[`GETTING_STARTED.md`](docs/GETTING_STARTED.md) · [`ARCHITECTURE.md`](docs/ARCHITECTURE.md) ·
[`USAGE.md`](docs/USAGE.md) · [`PROMPTS.md`](docs/PROMPTS.md) · [`TOKEN_BUDGET.md`](docs/TOKEN_BUDGET.md) ·
[`HARDENING.md`](docs/HARDENING.md) · [`COCKPIT_EVALUATION.md`](docs/COCKPIT_EVALUATION.md)

## Contributing
See [`CONTRIBUTING.md`](CONTRIBUTING.md) — how issues move from `backlog` to `planned`, what the PR pipeline
enforces, and what's off-limits for external contributors.

## The one thing to remember
The orchestrator-worker pattern is powerful but costs **~15× the tokens of a single chat** (per Anthropic's
own research system). Scale effort to task complexity, route cheap models to cheap work, and measure spend.
See [`docs/TOKEN_BUDGET.md`](docs/TOKEN_BUDGET.md).

## License
[MIT](LICENSE) — Copyright (c) 2026 Roberto Cano.
Loading