Repository navigation
Planning
CodingDude treats planning as data, not prose. Four kinds of object, four lifecycles, three storage locations — and the states carry meaning, so a shipped document does not get mislabelled as retired.
| Kind | What it is | Ladder |
|---|---|---|
| PRD | the what and why of a product or epic: problem, users, numbered requirements, success metrics |
draft → active → delivered → sunset
|
| Tech design | how a system meets PRD requirements: traceability, contracts, alternatives, risks |
draft → approved → delivered → superseded
|
| Roadmap item | the umbrella every ticket lives under (R<n>) |
open → in_progress → done
|
| Ticket | a tracer bullet: one slice of work with a contract and blocking edges |
todo → in_progress → done
|
| Design decision | ADR-style record of a choice and its consequences | no status — a record, not a task |
Read the document states precisely:
-
PRD —
activeis in flight ·deliveredis shipped and still in force ·sunsetis shipped but retired. A delivered PRD is not sunset: sunset says the product direction ended. -
Tech design —
approvedmeans agreed but not built ·deliveredmeans built ·supersededmeans replaced. Closing out a design that landed asapprovedclaims it was never built; assupersededit claims something replaced it. Neither is true of a document that simply shipped.
The allowed values live in exactly one place — roadmap.py
(ROADMAP_STATUSES, TICKET_STATUSES, PRD_STATUSES, DESIGN_STATUSES) — and
an unknown stored value still renders and keeps its own entry in the select
rather than blanking the control.
| Object | Store |
|---|---|
| Roadmap items | the repository's ROADMAP.md — canonical when present; the DB is the fallback, and both adding an item and changing status write back to the file |
| Tickets, PRDs, tech designs, decisions | the project database |
| Plan steps, evidence, attempts | the project database (plans, ticket_execution) |
The Planning panel writes the same store as the agent's planning tools, so you and the agent cannot diverge.
A ticket is claimed with an ordered plan, and each step is recorded as done only with structured evidence: the verification command, its exit code, and the output line that proves it. Free text is not evidence — the store refuses it.
That gives you, per ticket:
- who claimed it and when (with a heartbeat while work is live),
- per-step progress and the command that proved each step,
- drift flags for steps marked done without evidence or run out of order (waivable, explicitly and visibly),
- evaluator passes and their findings.
A ticket cannot be released as done while steps lack evidence or ran out of
order; the waiver is the only bypass, and it stays on the attempt.
claim_ticket(ticket_id, plan_steps=[...]) # claim + ordered plan
update_execution_step(index, "done", command=..., exit_code=0, key_output_line="3 passed")
heartbeat_claim() # keep the claim alive during long work
evaluate_work(ticket_id) # fresh read-only grading pass (cap 3)
release_ticket("done") # closes the ticket, records the closing commit
A good ticket is one vertical slice that can be demonstrated end to end, with its blocking edges declared. Splitting a plan into tickets exists so that each one can be verified independently — not so that the plan looks organised.
- Non-trivial work gets a roadmap item before tickets exist; a ticket may not exist without one.
- One ticket, one review. Wide briefs get split, because a reviewer given a whole branch reads none of it properly.
- Closing a ticket records the commit that closed it — and after a squash-merge, that reference must be repointed at the squash commit, or it dangles.
- Roadmap items are closed only when their tickets are, and the closure names the evidence.
It is human-readable markdown, editable by hand, and canonical. Regenerating it
through the planning tools normalises the formatting — expected, but it means a
ROADMAP.md touched by the agent will show up as a diff. Commit it as you would
any other document.
Start
How it works
Using it
Project