Tracker labels
Tracker labels
Section titled “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 one distinction that matters
Section titled “The one distinction that matters”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.
The label set
Section titled “The label set”Work items — what there is to do
Section titled “Work items — what there is to do”| 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 |
Security findings
Section titled “Security findings”| 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. |
Human action items
Section titled “Human action items”| 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.
Execution artifacts — what the loop did
Section titled “Execution artifacts — what the loop did”| 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. |
Pull requests on BoB itself
Section titled “Pull requests on BoB itself”| 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. |
Risk status and rollout phase
Section titled “Risk status and rollout phase”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:
for s in identified assessing monitoring mitigating; do gh label edit "$s" --name "risk-status:$s" --repo OWNER/NAMEdonebash ~/.claude/scripts/bootstrap-labels.sh ensure --repo OWNER/NAMERun 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.
Knowledge records — what we learned
Section titled “Knowledge records — what we learned”| 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:
- A loop note (
.claude/loop-notes.json,bob warploop 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 theloop-notes-inject.shhook. It is not an issue, and it is not meant to be read by a human. - A recurring loop note becomes a
bug. When the same note keeps being re-recorded,/groompromotes it to a fingerprintedbug— at which point it is real work, on the board, farm-eligible. - 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 alessonissue via/journal.
Expiry
Section titled “Expiry”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 warpreportsretired N workaround note(s)on entry toprerequisites, 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-driveare closed as last session’s reporting residue — guarded so that anything carryingcap,req,bug,todoorstatus-reportis 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.
Enforcement
Section titled “Enforcement”| 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.
See also
Section titled “See also”- Todo format contract — what makes a
todoactionable. - Forge health — the availability signal, read cache and write queue behind every
ghcall. - Warp-drive — where chunk and session reports are filed.
- Project orchestration handbook §15.3 — why none of this lives in local PM files.