To Issues
Break a plan into independently-grabbable issues using vertical slices (tracer bullets).
Issues live in issues/ as markdown files. issues/BACKLOG.md is the ordered queue: dependencies, type (AFK/HITL), and status. There is no external issue tracker — issues/ is the tracker, and BACKLOG.md is its entry point.
Artifacts
Paths are defaults — if the repo already names them differently, its names win.
| Role | Default path |
|---|---|
| Live queue | issues/BACKLOG.md — todo and in progress only |
| Completed queue | issues/ARCHIVE.md — rows move here on acceptance |
| Issue files | issues/NNN-kebab-case-title.md |
| Domain glossary | CONTEXT.md |
| Product spec | docs/INTENT-AND-DESIGN.md if present, else docs/REQUIREMENTS-AND-NOTES.md |
Read the glossary for domain vocabulary before drafting. Discover the spec; do not require REQUIREMENTS-AND-NOTES.md in a repo that already has an intent document. If the glossary or spec is missing, say so once and draft from the conversation instead — do not author them here and do not keep searching. They are grill-me output, and a project can run on issues alone. Physical HITL issues must not require a local simulator as proof.
If the tracker does not exist, create it first — both issues/BACKLOG.md and issues/ARCHIVE.md, from backlog-template.md. A fresh project has no tracker, and every later step assumes both files: numbering reads the archive, and the orchestrator moves accepted rows into it. Do this before writing any issue file.
Two modes
Pick the mode before starting — most requests are the second kind.
Breakdown mode — new scope from a plan or spec section that needs several dependent slices. Run the full process below, quiz included.
Straggler mode — one self-contained follow-up: a bug, a doc-sync gap, a small behavior change noticed while doing something else, or a regression in already-delivered behavior. In a maturing project most requests are this shape. Skip steps 3 and 4 entirely: write the single issue file, append one BACKLOG row with Blocked by → —, and report the id. Do not quiz the user about granularity or dependencies — there is one slice and nothing blocks it. Ask only if the "one issue" turns out to need slicing after all, or if it collides with an issue already in progress.
A regression in a done issue is a new issue, not a reopening. Never edit a completed issue file or move its row back out of the archive; cite it in the new issue's description instead.
Process
1. Gather context
Work from whatever is already in the conversation context. If the user passes an issue reference (number, path, or filename), read that file under issues/ and any related entries in issues/BACKLOG.md.
Also read:
- the domain glossary
- the product spec, when breaking down new scope
issues/BACKLOG.md— existing queue; andissues/ARCHIVE.mdfor the highest issue number already used
2. Explore the codebase (optional)
If you have not already explored the codebase, do so to understand the current state of the code. Issue titles and descriptions should use the domain glossary's vocabulary, and respect the spec's architecture decisions for the area you're touching.
3. Draft vertical slices
Break the plan into tracer bullet issues. Each issue is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer.
Slices may be HITL or AFK. HITL slices require human interaction, such as an architectural decision or a design review. AFK slices can be implemented and merged without human interaction. Prefer AFK over HITL where possible.
The one permitted exception — the scaffold slice. On a project with no working test runner, the first slice is scaffold and validate: project skeleton, dependency setup, a working test runner with one trivial passing test, and a way to launch the thing (or an explicit statement that it has no runnable surface). Every other slice is blocked by it. On a fresh tracker that makes it 001; on an existing one it takes the next free id and becomes a blocker for the remaining slices.
This breaks the rules above on purpose, and it is the only slice allowed to. Without it there is nothing to hang a vertical slice from, and the orchestrator's preflight will refuse to dispatch feature work into a project where "tests green" cannot be checked. Do not create it on a project that already has a working harness.
4. Quiz the user
Present the proposed breakdown as a numbered list. For each slice, show:
- Title: short descriptive name
- Type: HITL / AFK
- Blocked by: which other slices (if any) must complete first
- User stories covered: which user stories this addresses (if the source material has them)
Ask the user:
- Does the granularity feel right? (too coarse / too fine)
- Are the dependency relationships correct?
- Should any slices be merged or split further?
- Are the correct slices marked as HITL and AFK?
Iterate until the user approves the breakdown.
5. Write issues to the repo
For each approved slice, create a markdown file under issues/ and add a row to issues/BACKLOG.md.
Numbering: Use the next three-digit id after the highest # found anywhere — check issues/BACKLOG.md, issues/ARCHIVE.md, and the issues/ filenames. Ids are never reused, so the highest completed id usually lives in the archive, not the live queue. Start at 001 on a fresh tracker.
Filename: NNN-kebab-case-title.md (e.g. 015-foo-bar.md).
Write in dependency order (blockers first) so Blocked by can reference real issue ids.
Issue file — use this template:
---
id: "NNN"
title: Short descriptive name
type: AFK
---
## What to build
A concise description of this vertical slice. Describe the end-to-end behavior, not layer-by-layer implementation.
Avoid specific file paths or code snippets — they go stale fast. Exception: if a prototype produced a snippet that encodes a decision more precisely than prose can (state machine, reducer, schema, type shape), inline it here and note briefly that it came from a prototype. Trim to the decision-rich parts — not a working demo, just the important bits.
## Acceptance criteria
- [ ] Criterion 1
- [ ] Criterion 2 `proof: runtime`
- [ ] Criterion 3
## Blocked by
- [NNN](./NNN-blocking-issue.md) — short label
Or "None — can start immediately" if no blockers.
Proof classes. A criterion that changes behavior cannot be closed by reading code or grepping. Tag those criteria with the proof they require — backticked, at the end of the line, exactly `proof: runtime` or `proof: migration` so the gate can find them mechanically:
| Proof | Means | Use for |
|---|---|---|
| (untagged) | A passing test is enough | Pure logic, formatting, internal refactors |
proof: runtime |
The running app was driven and the result observed | Routing, auth, UI, integrations, anything user-visible |
proof: migration |
Verified against real migrated data, not a fixture | Schema and data-shape changes |
Tag sparingly — an issue where every criterion demands runtime proof is usually too thick a slice. Untagged is the default and the common case.
BACKLOG row — append to the Order table in issues/BACKLOG.md:
| NNN | [Title](./NNN-kebab-case-title.md) | AFK | — | todo |
Set Blocked by to issue numbers (e.g. 011, 011, 012) or —. New issues start with Status → todo.
Add dependency notes below the table when parallel or sequential groups matter — a one-line prose note naming the chain, e.g. "Store migration (023 → 024 → 026): schema → verification → stats parity."
Queue hygiene
BACKLOG.md holds only todo and in progress rows. Accepted rows move to issues/ARCHIVE.md — the orchestrator does this at acceptance time — so the live queue stays short no matter how old the project gets — an agent reads the raw markdown every session, so a long table of completed rows is pure context cost. Collapsing them behind <details> does not help; only moving them out does.
If you are filing into a project whose BACKLOG.md still carries done rows, leave them alone unless the user asks for the migration — do not silently restructure their tracker.
Do NOT modify completed issue files unless the user explicitly asks for a rewrite.