Sync to your tracker
Plan, then --apply: scope, ticket, publish, board, sync and bootstrap mirror your planning files and Zurdo's run results onto your tracker.
Carol v0.1.22
Six commands project an initiative onto your tracker, which today is GitHub. You type each one yourself, with your own gh login. Together they mirror the PRD loop: scope and ticket before a PRD exists, publish and board once it's written, and sync after zurdo run.
| What exists on GitHub | Made by | From |
|---|---|---|
| The label vocabulary | carol bootstrap | Carol's built-in list |
| A pinned scope issue, plus a Projects board named after the initiative | carol scope | scope.md |
| One issue per ticket, under the scope issue | carol ticket (and carol scope) | tickets/*.md |
| A milestone, an epic issue, and one task issue per PRD task | carol publish | The PRD |
| The PRD's issues as cards on the board, with a Status | carol board | The PRD and zurdo report |
| Outcome comments, labels, closed tasks, and the epic's status table | carol sync | zurdo report |
Plan, then apply
Every command here computes one plan from a single snapshot of the repository, prints it, and stops:
$ carol sync docs/billing/prds/prd-01-invoices.md
sync: acme/shop (3 ops)
add_issue_labels zurdo:failed [<!-- zurdo-github prd=docs/billing/prds/prd-01-invoices.md task=task-03 -->]
add_comment [<!-- zurdo-github prd=docs/billing/prds/prd-01-invoices.md task=task-03 -->]
set_issue_body [<!-- zurdo-github prd=docs/billing/prds/prd-01-invoices.md epic -->]
Add --apply to run the same plan, not a recomputed one: what you read is what gets written. After each write Carol reads the item back. If a field didn't stick, Carol stops with exit 5 and names the field. Add --format json to get the plan as one envelope ({"schema_version": 1, "command": …, "data": {"repo": …, "ops": […]}}) for scripts and agents. A plan with nothing to do is 0 ops, which exits 0.
carol plan and carol apply do the same for several files at once. Each file's mode comes from its path: scope.md is planned as scope, a file under tickets/ as ticket, and any other .md as publish. An op that two files both plan appears only once. carol apply asks apply N ops? [y/N] when run in a terminal, unless you pass --yes.
carol plan docs/billing/scope.md docs/billing/prds/prd-02-refunds.md
carol apply docs/billing/scope.md docs/billing/prds/prd-02-refunds.md
Re-running is safe
Each item Carol creates carries a hidden marker naming the file, and the task, it came from. The marker is the item's identity, not its number or title, so a re-run finds the item and plans only what changed. Rename a task and its existing issue is renamed. Nothing is ever duplicated.
Warning
Don't copy an issue body that Carol wrote into another issue. Two issues with the same marker make Carol refuse the plan with exit 4, naming the marker. Delete or edit the copy by hand, then re-run.
The marker formats are listed in Labels & markers, and how Carol uses them is in Internals.
carol bootstrap
Creates the base labels. If the repository has no description and no topics, --about "<text>" also sets the description.
| Label | Meaning |
|---|---|
zurdo:scope, zurdo:research, zurdo:grilling | Scope and ticket issues |
zurdo:epic, zurdo:task | A PRD's epic and its tasks |
zurdo:pending-review | The task passed, but zurdo is waiting on a [manual] sign-off |
zurdo:failed | The task failed in its last run |
ready-for-agent | A task with no Depends-on, so an agent can start it now |
needs-triage, needs-info, ready-for-human, wontfix | States for issues people file by hand. See Triage. |
publish adds an effort:<tier> label for each effort tier the PRD uses. The engine loop adds its own carol:* and priority:* labels as it needs them. Every label is listed in Labels & markers.
carol scope
carol scope docs/billing/scope.md [--project "<board title>"] [--apply]
Creates or updates the scope issue and pins it the first time. The issue body carries the destination, notes, decisions, and open questions, plus the Phases table, which gains Epic and Milestone columns linking to what publish created. In the same plan, scope:
- processes every ticket in
tickets/in file-name order, ascarol ticketwould; - projects every contract in
contracts/as one issue under the scope issue; - wires the graph: each published phase's epic becomes a sub-issue of the scope issue, each ticket's
blocked-bybecomes ablocked byedge, and a ticket thatblocksa phase blocks that phase's epic. A phase with no epic yet is skipped with adefer:notice and wired on a later run; - sets up the initiative's Projects board, named after the scope title unless you pass
--project. It links the board to the repository, sets its description to the destination's first paragraph and its README to the scope issue's body, and adds the scope and ticket issues as cards.
carol ticket
carol ticket docs/billing/tickets/tax-rules.md [--apply]
Creates or updates one ticket issue as a sub-issue of the scope issue. Edges between tickets need every ticket's issue number, so carol scope creates them. A resolved ticket gets its findings posted as a comment and is then closed. If the scope issue doesn't exist yet, Carol stops with exit 4 and tells you to run scope first.
carol publish
carol publish docs/billing/prds/prd-01-invoices.md [--scope <issue number>] [--apply]
Publishes a PRD as:
- a milestone named after the PRD's title;
- an epic issue (
zurdo:epic) that links to the scope issue and has a table of tasks with their Status; - one task issue per
## Task:(zurdo:task,effort:<tier>). Each body holds the description and the acceptance criteria as a checklist, with every hint in backticks, so reviewers see exactly what zurdo will check. A task with noDepends-onalso getsready-for-agent.
Tasks become sub-issues of the epic, and each Depends-on becomes a blocked by edge, so GitHub shows the same dependency graph zurdo schedules. For a PRD under docs/<initiative>/prds/, Carol finds the scope issue itself, and you only need --scope for a PRD stored elsewhere. Re-publishing after you edit the PRD updates titles, bodies, and milestones in place, and keeps each task's Status cell in the epic. It also removes what the PRD no longer says: an effort:* label for an old tier, and a blocked by edge between two of the PRD's tasks that Depends-on no longer lists. A PRD whose issues already match plans nothing.
carol board
carol board docs/billing/prds/prd-01-invoices.md [--project "<board title>"] [--apply]
Adds the PRD's task issues to a Projects (v2) board and sets each card's Status from zurdo's run state. The default board is the initiative's (the scope.md title). Use --project to name another one. board adds the Pending Review and Failed Status options if the board doesn't have them. If no run has happened yet, every card is Todo.
This needs the project scope on your gh login. Without it, board exits 3 and tells you to run gh auth refresh -s project. The board is only a view: Carol writes it and never reads your plan back from it.
carol sync
carol sync docs/billing/prds/prd-01-invoices.md [--apply]
Reads zurdo report <prd> --format json, and for each task with a result:
| zurdo task status | Label | Comment | Issue | Epic table / board |
|---|---|---|---|---|
passed | removes zurdo:pending-review, zurdo:failed | Attempts, last model, tokens in and out, estimated cost | Closed | Done |
passed-pending-review | zurdo:pending-review | Same as above | Stays open until you sign off in zurdo review, or under watch with carol:signed | Pending Review |
failed | zurdo:failed | The failing criteria: the report's failed_hints | Stays open | Failed |
in_progress | — | — | — | In Progress |
Each comment carries a marker naming the PRD, the task, and the run's started_at. Syncing the same run twice posts nothing new, and a new run posts once more. sync never removes ready-for-agent and never reopens a closed issue.
If the PRD has never been run, there's no report to read, so sync exits 6. Run carol board after sync to move the cards too.
zurdo run docs/billing/prds/prd-01-invoices.md
carol sync docs/billing/prds/prd-01-invoices.md --apply
carol board docs/billing/prds/prd-01-invoices.md --apply
To have Carol take these steps for you, as a GitHub App, see The engine loop.
Next: The engine loop