~/groundwork

The build loop

One card goes through three roles, then stops at your door. This is the whole process.

One cardrunner hands it on · never does the work
  1. Testerwrites tests that fail for the right reason
  2. Implementermakes them pass, nothing more
  3. Reviewerfresh context, reruns everything
  4. Youapprove, or send back with a reason
  5. committed ✓
↺ reviewer finds a problem → back to the implementer↺ you reject, with a reason → back into the loop
Each role is a fresh session that reads the card, its role file and only the code the card touches.

The runner is the main session — the one you type gw-next into. It hands the card to each role in turn and never does their work itself.

The steps

  1. Pick. The lowest-numbered card whose status is todo or rejected and whose depends_on cards are all done.
  2. Test. The tester writes failing tests — one per acceptance criterion — confirms they fail for the right reason, and saves the failing output as evidence.
  3. Implement. The implementer makes the tests pass with the smallest reasonable change, then runs the full suite, lint and build.
  4. Review. The reviewer re-runs everything itself, checks every criterion against the diff, and fills in the Evidence section — or sends the card back with specific problems.
  5. Approve. The runner stops and shows you what changed, how to check it yourself, and the caveats. (In per-phase mode this stop happens at the end of the phase instead.)
  6. Commit. After approval, the runner commits the card and moves on.

The roles

RoleJobMust not
PlannerInterview you for the spec; write phases, cards and decision recordsWrite code; choose your stack
TesterTurn acceptance criteria into failing testsWrite the implementation; weaken tests later
ImplementerMake the tests pass with the smallest reasonable changeEdit tests to make them pass; touch unrelated files
ReviewerCheck the work with fresh eyes, then pass it or send it backFix code itself — it sends the card back

Each role reads only what it needs (its role file, the card, and the files they point to). In tools with subagents, each role runs as a separate agent with fresh context, so the reviewer really is seeing the work for the first time. The planner never picks a stack: options go to you.

What isn't in those files wasn't agreed. A role doesn't go searching chat logs or other folders for a decision; it makes a call and writes it on the card, where you'll see it.

The runner stays light

The runner is one long chat, and every step re-reads its whole history, so every extra step it takes costs more than the last. It keeps its own work small:

  • Short hand-offs. Each role gets the card's path, its role file and facts the runner has checked, nothing else: no retelling what was agreed (it's on the card), no statuses to set (the role file says).
  • No reruns between roles. The reviewer reruns every check; the runner doesn't repeat them.
  • A fresh session each phase. When a phase closes, /gw-approve suggests starting the next phase in a new session. HANDOFF carries everything it needs.

Where these came from: the calculator's measurements →

Statuses

FromToWhoWhen
todotestingrunnerStarts the card
testingimplementingtesterFailing tests are written and saved
implementingreviewimplementerTests, lint and build all pass
implementingtestingimplementerA test looks wrong; the reason is written on the card
reviewimplementingreviewerProblems found; listed under History
reviewawaiting-approvalreviewerPassed, in per-card mode
reviewdonereviewerPassed, in per-phase mode (the runner commits)
awaiting-approvaldonehumanApproved (the runner commits)
awaiting-approvalrejectedhumanRejected, with a reason
donerejectedhumanRejected during a phase review
rejectedimplementingrunnerPicked up again; the reason is on the card

No other changes are allowed, and every change gets one line under History.

After three reviewer send-backs on the same card, the loop stops and asks you rather than going round again.

The checks

The project's test, lint and build commands live in .groundwork/config.json. Normally all must pass before a card reaches you. On a project with a saved baseline, the rule is no new failures instead. Evidence and approval →

Commits

The runner commits — never a role, never before approval (or before review passes, in per-phase mode). After approval it:

  1. marks the card done and adds a History line,
  2. updates HANDOFF.md,
  3. commits the card's changes as [<card-id>] <card title>,
  4. moves to the next card, or stops if you asked it to.

Without subagents

Any tool that can't start separate agents still works: one session plays every role in turn. Before each role it reads that role's file and only the files it lists; it finishes the role completely before switching. As reviewer it re-reads the diff from scratch — and because fresh eyes aren't really possible, it re-runs every check itself.

On this page