Skip to content

Tracker labels

BoB has no local PM files. Every requirement, bug, decision, lesson, run report and human action item is a GitHub Issue, and a label is the only thing that says which of those an issue is. That makes the label set a contract, not a convenience: /what-next ranks by it, /groom reconciles by it, /warp-drive discovers by it, /trace-mining counts by it, and bob plan orders by it.

This page is the single definition of that set. The set itself is shipped by scripts/bootstrap-labels.sh — the label-bootstrap path bob init runs, so a fresh repo starts with every label below — and the one rule a machine can check is enforced by scripts/checks/check-report-labels.js in make check.

The tracker holds two kinds of thing that look alike and are not:

Execution artifacts Knowledge records
Labels chunk-report, session-report, ritual-run lesson, decision
Says a commit happened, a session ran, a ritual was held here is what we learned / chose
Filed by the loop automatically; ritual.js open a person or /journal, deliberately
Volume hundreds per month a few dozen, ever
Read rarely, and by number often, and by search

Keeping them apart is the whole point. A chunk report’s body narrates decisions and lessons — that is what a good report does — and for most of this tracker’s life reports were therefore filed with lesson and decision as well. The result was that gh issue list --label lesson returned 49 issues of which 14 were real, and /trace-mining over-counted in the same proportion: the labels that exist to make knowledge findable had been diluted by the artifacts that mention it.

The rule: a report never carries lesson or decision. When a chunk — or a ritual run — genuinely produces one, it is filed as its own issue via /journal and linked from the report — one record, one issue. #2062 relabelled the 1,114 historic reports in one pass and took the knowledge labels out of the report prompts; check-report-labels.js is what keeps it true.

Label Means Filed by
business-case Justification for investment: problem, options, cost/benefit, recommendation. Sits above capability. /business-case
cap A capability — a feature spec with user stories and a checkbox list of its requirements. /capability
req A requirement — testable work with acceptance criteria. The unit /warp-drive picks up. /requirement
use-case A concrete scenario, decomposed into a capability or requirements via Realizes #NN. /use-case
bug A defect. Closed with a root cause and a regression test, not just a merged PR. gh issue create --label bug, /report-bug
task Maintenance work — a dependency bump, a CVE fix, a runtime upgrade, a config migration, a cleanup. Its definition of done is a Verification checklist, not acceptance criteria, and it names the trigger that prompted it. A sibling of bug: it needs no parent capability. /task
documentation Work whose deliverable is a doc. /requirement
flight-plan An issue-backed, ordered warp-drive run plan. /flightplan
Label Means Filed by
security A security finding — a vulnerability, an exposure, a dependency advisory. A ritual close links its findings here. security-auditor, bob ritual close, the dependency audit
advisory One dependency advisory — advisory ID + package — filed by the dependency-audit ritual at or above the declared severity, de-duplicated by its bob-advisory/1 body marker, commented on while it persists and closed when the audit no longer reports it (Advisories, #2242). Always alongside security, task (the task shape, #3406) and a priority label. ritual.js prepare, advisories.js run, advisories.js relabel

Workflow signals — what may happen to it

Section titled “Workflow signals — what may happen to it”
Label Means
approved Ready to be worked. A req or bug carrying it is pickup-eligible for /warp-drive.
blocked Waiting on something. Excluded from pickup until cleared.
in-progress On a cap: some of its children are done and some are still open. cap-status.js derives it from the children and sets or clears it; nobody adds it by hand. It is part of the standard set bootstrap-labels.sh creates (#3338).
serial-only A pinch point (config sync, lockfiles, migrations, compiled assets, deploy) — excluded from bob fork --from-issues fan-out.
farm Delegated to the unattended farm tick. Set by a human or /groom, never automatically.
duplicate Asks for the same work as an older open issue. /groom adds it, from its own reading or from the dedupe pass (issue-dedupe.js, #2681), which flags an incoming issue when Jev names the older issue with confidence at or above 0.85. The pass also comments Possible duplicate of #N and never closes anything. A person, or a /groom apply, closes the issue after folding it into the older one.
tracer Greenfield or cross-layer work: its AC-01 is an end-to-end tracer bullet with no mocks for the layers crossed, and its ACs are ordered by slice, not by layer. /requirement applies it exactly when it adds the tracer conditional AC (#2734), and a requirement under a tracer capability inherits it, the way area:<slug> is inherited. /capability applies it to a capability on the same condition, after carving its Requirements by slice rather than by layer, and bob decompose hands it to every child it files, checking it on the read-back (#2739). gh issue list --label tracer therefore lists both the capabilities and the requirements that were meant to be sliced. The operator removes it from a requirement that does not cross layers. The classifier for everything else is tracer-classify.js (#2738). It asks Jev one noul, “does this work cross more than one layer?”, and flags the issue when the probability is at or above 0.85. That threshold is provisional until the live tune in Tracer Classifier Evaluation runs. A probability below the confidence floor asks the operator instead of guessing. The pass is report-only unless --apply is given, which adds the label and one comment with the reasoning. It never removes a label. bob warp status shows a Slice: tracer line for a labelled item. Without the label, warp-drive behaves as it always has; its absence is never an error. (#2738)
p1-critical … p4-low The priority ladder. Discovery orders p1 → p4, bugs before reqs at equal priority.
area:<slug> The workstream an item belongs to. Scopes an --area run and the cap/area seam that triggers re-validation.
Label Means
todo An action only a human can take, handed back by an agent. Must conform to the todo format contract.
completed The canonical done-signal. On a todo, it means the human performed the action, so downstream tooling may resume the work the todo was gating.
needs-clarification An agent-filed todo missing instructions or an issue link — not actionable until clarified, and excluded from “ready to complete”.
ask-waiting An ask (a todo or a brief) beyond the attention budget. It sends no push and raises no banner until it is inside the budget. Added and removed by bob asks --reconcile --apply, and added at filing by ask-gate.js file (bob asks).
stale A todo whose linked issues are all closed. Surfaced for a human to close; never auto-closed.

Closing a todo is not a resume signal. A todo closed without completed was cancelled or became moot, and downstream tooling must leave the gated work gated. Only the completed label resumes it.

Label Means
chunk-report One warp-drive chunk: what was implemented, decisions taken, checks run and skipped, and the iteration trail if the chunk took more than one attempt. One per commit.
session-report One warp-drive session: what was completed, token usage, the decisions digest, and anything skipped. Also carried by an abort report.
session-summary Legacy alias of session-report, kept so the 152 issues filed under it stay findable. New session reports carry both.
warp-drive Filed by the loop. Present on every artifact above, and the label the stale-artifact sweep keys on.
bug-deferred A bug found mid-chunk, logged rather than fixed inline.
risk A risk surfaced during a run, or filed by /risk. An open one carries one risk-status:* label (Risk status and rollout phase).
status-report An on-demand standup requested by a human (/status --file). Never auto-filed — which is why the stale-artifact sweep leaves it alone.
baseline-doc Tracks a missing scaffolding doc (README, runbook, CLAUDE.md) on a greenfield project.
ritual-run One held ritual — a comprehensive review, a dependency audit, a planning session, a drill. Open while it is under way; closed means held, and the newest closed run is the ritual’s last run. Closed as not planned means cancelled and does not count. Filed by ritual.js open.
ritual:<name> Which ritual a ritual-run is — one label per entry in registry/rituals.json (ritual:comprehensive-review … ritual:drill). A drill’s kind lives in the run issue’s body.
Label Means
skill-proposal A pull request the skill proposer opened on BOB_SOURCE (bob wiki propose, #2391): one gated change to one skill, command or agent, citing the wiki pages and traces behind it. A draft one was rejected by the eval gate and is open only so the attempt is on record. A person merges or closes it; the proposer never merges. An open one for an item stops the next proposal for that item. It exists on BOB_SOURCE only: propose.js creates it there, and it is not in the standard set bootstrap-labels.sh gives every repo.

The operator decided both conventions on #3193; #1054 put them in the standard set, so bootstrap-labels.sh ensure creates them in every repo.

Risk status is one namespaced label on an open risk issue. An open risk carries exactly one; changing status swaps the label. Closing the issue ends the lifecycle (retired or realized — say which in the closing comment), so there is no closed or resolved status label.

Label Means
risk-status:identified Logged, not yet assessed. What /risk create applies.
risk-status:assessing Probability and impact are being scored.
risk-status:monitoring Accepted: no mitigation under way, watched for its trigger.
risk-status:mitigating Mitigation work is under way.

Rollout phase is a phase-N label, not a GitHub Milestone. Lower N ships first: a phase-1 issue waits until every phase-0 issue is closed. An issue carries at most one. The standard set declares phase-0 to phase-3; a project that needs a later phase adds phase-4 and up with the same colour (BFDADC) and wording. Phase is sequence only; priority stays on the p1-critical … p4-low ladder.

Label Means
phase-0 First in sequence: prerequisites and blockers.
phase-1 … phase-3 After every issue of the phase before it is closed.

Migrating a project that improvised these. The mapping is one-to-one, so the relabel is mechanical. thefarm is the reference dataset:

Old label New label
identified risk-status:identified
assessing risk-status:assessing
monitoring risk-status:monitoring
mitigating risk-status:mitigating
phase-0, phase-1, phase-2 unchanged — already the standard names; ensure sets the standard colour and description

Rename each old status label in place, which keeps it on every issue, then reconcile the repo to the standard set:

Terminal window
for s in identified assessing monitoring mitigating; do
gh label edit "$s" --name "risk-status:$s" --repo OWNER/NAME
done
bash ~/.claude/scripts/bootstrap-labels.sh ensure --repo OWNER/NAME

Run ensure after the renames, not before: if it has already created risk-status:<s>, the rename fails with a name clash. In that case move the issues instead — gh issue list --label <s> --state all --json number -q '.[].number' | xargs -I{} gh issue edit {} --add-label risk-status:<s> --remove-label <s> --repo OWNER/NAME — then gh label delete <s> --yes --repo OWNER/NAME.

Label Means
lesson A systemic gap and what to change so that class of defect cannot recur. Not a one-off typo; not a chunk narrative.
decision An architectural or process choice, with the options considered and why this one.

Both are filed by /journal, and both are meant to be found later by search. That is the property the report rule protects.

How a note becomes an issue, and how it expires

Section titled “How a note becomes an issue, and how it expires”

Not everything discovered during a run belongs in the tracker. There is a deliberate ladder, and things move up it only when they earn it:

  1. A loop note (.claude/loop-notes.json, bob warp loop memory) — a hidden rule discovered mid-run: a flaky test, a legacy quirk, a constraint, a gotcha. It is agent memory, injected into the next session’s starting context by the loop-notes-inject.sh hook. It is not an issue, and it is not meant to be read by a human.
  2. A recurring loop note becomes a bug. When the same note keeps being re-recorded, /groom promotes it to a fingerprinted bug — at which point it is real work, on the board, farm-eligible.
  3. A systemic loop note becomes a lesson. When the quirk is not “this repo is odd” but “this class of defect can recur anywhere”, it graduates to a lesson issue via /journal.

A record that has outlived its cause is worse than no record — it keeps being applied as a habit. Two mechanisms retire them:

  • Workaround provenance (defect:). A loop note or memory that compensates for a BoB defect is tagged with the issue it works around (--defect <owner>/<repo>#<n>). It renders as provisional ([workaround for open <repo>#<n>]), and once that issue closes it is retired automatically — bob warp reports retired N workaround note(s) on entry to prerequisites, and a workaround the retire line names as fixed must never be re-applied.
  • The stale-artifact sweep. At the start of each session, open issues carrying warp-drive are closed as last session’s reporting residue — guarded so that anything carrying cap, req, bug, todo or status-report is left alone. Those are work items, live human action items, or records a human asked for; only artifacts are swept.

lesson and decision issues are not swept and do not expire. They are the durable end of the ladder, which is precisely why the report rule at the top of this page exists.

What Where Fails on
The set is shipped scripts/bootstrap-labels.sh ensure — (idempotent; bob init runs it)
Reports never wear a knowledge label scripts/checks/check-report-labels.js, in make check an issue carrying chunk-report/session-report/ritual-run and lesson/decision; or a report-shaped issue carrying lesson/decision and no report label
History is corrected scripts/warp-drive/relabel-reports.js [--apply] — (dry run by default; exit 1 on drift)
Every cap/req carries an area scripts/area-labels.sh audit an unlabelled cap or req
A todo is actionable scripts/warp-drive/todo-contract.js check <NN> a body missing a summary, numbered instructions or an #NN link

check-report-labels.js fails open: it grades the tracker, not the checkout, so no gh, no auth or an unreachable API is reported as skipped and exits 0, and it is skipped outright when $CI is set. Its reads go through the bin/gh shim, so they are served from the durable forge cache when the API is degraded. It is also eventually consistent — label-pair queries go through GitHub’s search API, whose index trails writes by a few seconds — so a red run immediately after a relabel is worth repeating before believing.