~/groundwork

Cards and phases

A card is one small piece of work with a checklist for "done". A phase is a group of cards that together leave something working.

The spec describes what you're building. The plan turns it into phases and cards. The build loop takes one card at a time.

What a card looks like

A card is a markdown file in .groundwork/cards/:

---
id: 1.2
title: Voting
phase: 1
status: awaiting-approval
depends_on: [1.1]
---
## Goal
A visitor can vote once for next month's book.

## Acceptance criteria
- [ ] A visitor with the link can cast one vote
- [ ] A second vote isn't possible
- [ ] Results stay hidden until the vote is closed

## How to check
- Run `npm run dev` and open http://localhost:3000/vote

## Evidence
- Tests: `npm test voting` → 12 passed ([output](../evidence/1.2/test-output.txt))
- Reviewer: all criteria met; checked against L-003, L-006

## History
- 2026-09-24 rejected: "results leak before the vote closes" → back to implementer
SectionFilled byPurpose
GoalplannerWhat's true when the card is done, in a sentence or two
Acceptance criteriaplanner (plus gw-ui-spec for UI)Checkable statements; the tester turns each into a test
How to checkreviewerPlain steps for you to see it working, without reading a diff
Evidencetester, implementer, reviewerLinks to proof in .groundwork/evidence/<card-id>/
HistoryeveryoneOne line per event, including rejections and judgment calls

Each role writes its own History and call: lines, in the same step as the work: a report to the runner isn't enough. Keep lines to a sentence or two. Every role rereads the card, so details belong in the evidence files, and npx groundwork-ai doctor flags cards that grow past about 1,500 tokens.

Statuses

The card's status says exactly where it is. Internally the workflow uses one set of names; you always see the plain labels.

StatusYou seeMeaning
todoto doNot started
testingbeing testedThe tester is writing failing tests
implementingbeing builtThe implementer is making them pass
reviewin reviewThe reviewer is checking the evidence
awaiting-approvalwaiting for youYour turn
donedoneApproved and committed
rejectedsent backYou sent it back; it re-enters the loop

Only the transitions in the workflow are allowed, and each one leaves a History line.

Dependencies and picking order

Cards list what they need first:

depends_on: [1.1]

The runner always picks the lowest-numbered card whose status is todo or rejected and whose dependencies are all done. 1.2 comes before 1.10. A card whose dependencies aren't ready is blocked, and /gw will say by what — it never starts work on top of unfinished work.

How the planner shapes a plan

  • Smallest useful version first. Anything else is a later phase, one line each.
  • Each phase leaves something working, or unlocks the next phase.
  • Each card fits one session through tester → implementer → reviewer.
  • Every criterion is checkable, by a test where possible. "Works well" isn't a criterion. Logic that can run without the UI is planned into its own files so it gets real tests.
  • Decisions come first. A stack choice gets a decision record and your answer before cards depend on it.

On an existing project, the planner works one change at a time: only the open change in the spec, never the whole app. Existing projects →

Commits point back to cards

Each approved card is committed as [1.2] Voting — or whatever commitFormat you set. So git log is the project's progress trail, and groundwork retro can find work that was fixed soon after it shipped.

On this page