Tracker
July 31, 2026 · View on GitHub
This folder is the single source of truth for what needs doing, what was decided, and what got done.
Documents elsewhere (a docs/ folder) explain and discuss; records in tracker/ have IDs, status, and a lifecycle.
The test for what belongs here: does it have a lifecycle? If it must change state or rot, it's a record and lives here. If it's finished the moment it's written (a guide, an analysis, a transcript), it's a doc and lives in docs/.
Layout
tracker/
readme.md this file — the process
config.json areas + paths (the only repo-specific config)
BACKLOG.md GENERATED index of open items — never hand-edit; run `python tools/track.py index`
DONE.md append-only log of completed/dropped items, newest first (written by `track.py close`)
issues/ one file per tracked item — the frontmatter here is the SOURCE OF TRUTH
decisions/ Architecture Decision Records (ADRs) — dated, immutable, occasionally superseded
Issue frontmatter is the database; BACKLOG.md is a generated view of it (any grouping,
ordering, or filtering is a query — python tools/track.py list --help). DONE.md is an
event log, not a cache: the outcome text lives only there.
Tooling
python tools/track.py new --title "..." --area <area> [--type ...] [--sprint NAME]— allocates the next id, writes the issue file, regenerates BACKLOG.md.python tools/track.py set <id> --status ready --priority p1 ... [--sprint NAME|none]— the ONLY way to change status/priority/effort/risk/sprint (updates frontmatter + regenerates index).python tools/track.py list [--open] [--status S] [--area A] [--type T] [--sprint N] [--sort priority|id|status|sprint|created] [--format table|csv]— query views.python tools/track.py close <id> [--outcome "done (sha)"] [--dropped]— closes the issue, logs to DONE.md, regenerates index.python tools/track.py report [--html PATH] [--md PATH]— renders a shareable point-in-time snapshot (open items grouped by status, plus recent DONE) as a standalone HTML file and/or Markdown; with no path, prints Markdown to stdout. Read-only: never writes into the tracker's own data.python tools/track.py index— regenerate BACKLOG.md (normally automatic).python tools/track.py next-id— peek at the next number./track-idea,/track-issue,/track-backlog— Claude Code skills (.claude/skills/) that drive the script and elaborate: assumptions, design decisions, related-work links, approaches, simplest implementation. See each skill for details.
Issues
One file per item: issues/<id>.md where id = <area>-<number> (e.g. core-015).
Next number = highest existing number across all areas + 1 (numbers are globally unique; the area prefix is just a hint).
Areas are configured in tracker/config.json. In a monorepo, use one area per subproject; add a repo/infra area for cross-cutting process work.
Frontmatter (see issues/_template.md):
---
id: core-015
title: Faster widget codegen
type: feature | debt | bug | idea | problem | retire
status: idea | ready | in-progress | done | dropped
priority: p1 | p2 | p3 | "?"
effort: S | M | L | "?"
risk: low | med | high | "?"
area: core
sprint: # working-set name (e.g. 2026-01-A), empty = not in a sprint
created: 2026-01-01
closed: # date, when done/dropped
links: [] # related docs, plans, discussions, other issues
---
Status semantics: idea = captured, untriaged. ready = triaged (real priority/effort/risk,
plus a ## Done means section — 2–5 verifiable acceptance criteria — required for
feature/debt/bug) — an agent may pick it up. Promotion idea→ready happens
via track.py set during triage. A sprint is a working set, not a time-box: the batch
selected for parallel execution now — big rocks + little rocks, chosen for impact/risk balance
and non-colliding areas (see /track-backlog sprint plan).
Body: motivation, acceptance criteria, pointers to discussion. Terse is fine; a title alone is enough for an idea.
Types:
- feature — new capability
- debt — technical debt to pay down
- bug — defect
- idea — captured thought, not yet triaged (default type for quick capture)
- problem — open design question that needs an answer. Closing a problem usually produces an ADR plus follow-up issues.
- retire — code/doc/feature that should be deleted or deprecated
Lifecycle
- Capture. New idea → new issue file with
status: idea+ one line inBACKLOG.md. Never a new loose doc for trackable work. - Triage. Periodically (weekly, ~10 min) sweep
BACKLOG.md: set priority/effort/risk, promoteidea→ready, drop dead ones. - Plan. Substantial work gets a plan doc; the plan links to the issue and the issue links back. Set
status: in-progresswhen work starts. - Close. When work lands (or is abandoned):
python tools/track.py close <id> --outcome "done (sha)"(sets status + closed date, logs to DONE.md, regenerates the index), and mark any executed plan doc with a banner at the top:> **EXECUTED <date>** — see tracker issue <id>. Historical record; do not execute.then move it to an archive folder.
Decisions (ADRs)
decisions/YYYY-MM-DD-<slug>.md — context, decision, rationale, alternatives rejected, links. See decisions/_template.md.
Write one only when a decision is expensive to reverse or likely to be re-litigated (~1–2/week max). Never edit an ADR's substance after the fact; supersede it with a new one and add superseded-by: to the old.
Rules for agents
-
Check status before executing any plan. A plan doc without a live linked issue in
in-progress/readystate, or carrying an EXECUTED banner, is historical — ask before acting on it. -
File what you find. Out-of-scope debt, bugs, or retire candidates discovered mid-task: create an issue file + BACKLOG line, don't fix inline and don't let it evaporate.
-
Commit tracker changes immediately. Every time you create or update an issue, regenerate
BACKLOG.mdif it changed (new/set/closealready do this), thengit addboth the issue file(s) andBACKLOG.mdand commit them together. Never leave an issue file or a staleBACKLOG.mduncommitted, and never commit one without the other. -
Name the item in the commit. Any commit doing work on a tracked item names that item's id in the Conventional-Commits scope —
fix(studio-149): atomic menu clear+rebuild. This is the join key between git history and tracker state. Tracker bookkeeping commits (docs(tracker):,chore(tracker):) are not work commits and never count as progress on an item. -
Mark progress at the commit that makes it — close what you finish, when you finish it. In the same commit that lands work, tick every
## Done meanscheckbox that commit satisfies. Progress is read from those boxes; there is no stored progress field or percentage.- If every box is now ticked, close immediately:
python tools/track.py close <id> --outcome "done (<work-commit-sha>)", then commit that tracker change. The sha only exists once the work commit is made, so the close is the immediately-following commit — not an end-of-session chore that gets forgotten. - If any box is unticked, the item stays
in-progress, and you say which box is outstanding. A landed fix awaiting verification is not done.
Never infer completion from commit history alone: an unticked box is the item stating it is not finished. At close, banner + archive the executed plan doc. This replaces per-session report docs.
- If every box is now ticked, close immediately:
-
Ideas from the user ("we should someday…") get captured as
type: ideaissues immediately. -
Don't re-litigate ADRs. Check
decisions/before proposing architecture changes; if you disagree with a decision, propose a superseding ADR rather than silently diverging.
This tracker is powered by WorkQuarry. This file is installed from the WorkQuarry source — edit it there, not here.