task-pipeline-skill 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,88 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.1.0 — 2026-07-29
4
+
5
+ **The pipeline could find a requirement that was named and lost. It could not find
6
+ one that was never named.** Every gate compares two things — and a contradiction has
7
+ two sides while **an absence has one**. Nothing in a diff between spec and plan
8
+ reveals the error path nobody specified, the entity nobody gave an owner, the
9
+ failure mode nobody thought of. This release adds the pass that can.
10
+
11
+ ### Added
12
+ - **`references/audit.md` — the audit ladder, cross-cutting.** Eight rungs of one
13
+ deliverable (requirement → decision → spec section → contract **and its failure
14
+ behavior** → plan task → change → **executed** test → surface/docs) and, more
15
+ importantly, the **seam between each pair**, each with its own question: did the
16
+ decision reach the spec; does the section say what happens when the contract
17
+ fails; does every contract have a task (stage 4's set-equality covers REQ→task and
18
+ nothing covers contract→task); did the DoD land in the diff; would this test still
19
+ pass with the production code deleted; can a user reach it and does a doc say so;
20
+ and finally — does what shipped satisfy the requirement's own *statement* rather
21
+ than the task's instructions.
22
+ - **Stage 10 now opens with the ladder walk, before the coverage table.** An absence
23
+ found there becomes a **new REQ row with its check**, and *then* the table is
24
+ written. Appending after the table is exactly how acceptance goes green over a
25
+ gap. Findings that belong to a lower layer go back to that layer (spec → stage 3,
26
+ plan → stage 4) instead of being patched in place at the last stage.
27
+ - **Findings are ordered by seam, never by file.** A file-ordered list reads as
28
+ noise; a seam-ordered one names *which layer of your own process is leaking*,
29
+ which is the part worth knowing.
30
+ - **Bottom-up, and that is not taste.** A missing artefact low on the ladder makes
31
+ everything above it meaningless — top-down you spend the pass polishing a surface
32
+ for a contract that does not exist. Bottom-up, the absence is finding #1 and the
33
+ six findings above it collapse into it.
34
+
35
+ ### Added — three rules that stop the audit becoming another loop
36
+ - **Every pass changes the axis, not the effort.** A searching loop does not
37
+ oscillate the way an editing loop does — it **converges**, because each pass edits
38
+ the corpus the next pass reads, so the newest edits are always the
39
+ least-reviewed text present and are what the next pass finds. Measured over seven
40
+ passes on a production repository: by pass six, ten of thirteen findings were
41
+ caused by pass five's own fixes, while the raw count still looked healthy. So the
42
+ doctrine requires **two counts per pass** — new findings, and self-inflicted ones —
43
+ and names the crossover as the signal to **rotate the axis**: seams down one
44
+ deliverable, then invariants across deliverables, then one class swept end to end.
45
+ - **A class that repeats twice becomes a gate, not a note.** Once is an incident;
46
+ twice is a category, and a category belongs in the host's lint or CI where nobody
47
+ has to remember it. Writing the third instance into the ledger is how a
48
+ mechanical defect class becomes permanent. Wired into the stage-5 fix loop too.
49
+ - **What can't be fixed now becomes a ratchet, never a TODO.** The carry-over ledger
50
+ is now defined as a *named, counted set that may only shrink, printed beside every
51
+ gate verdict* — `carry-over: 4 open (was 6) · unresolved: 0`. A TODO is invisible
52
+ until somebody opens the file; a ratchet sits next to the word `PASS` on every
53
+ run, so **"green" never reads as "verified"** — it reads as *"green, and here is
54
+ exactly what was not looked at"*. A ratchet that grew needs one sentence saying
55
+ why.
56
+
57
+ ### Added — the exit criterion that is usually skipped
58
+ - **A green result from an unproven check is worth nothing.** A deliverable is not
59
+ audited when somebody has read it; it is audited when every rung has its artefact
60
+ **and every check being relied on has fired at least once against a planted
61
+ defect.** This is `tdd.md`'s iron law — *if you didn't watch it fail, you don't
62
+ know it tests the right thing* — raised from one test to every gate, linter and
63
+ script in the run, and it is now part of the stage-10 gate. Checks written under
64
+ pressure lie in ways that read as success: a predicate that inspects the wrong
65
+ shape, a probe that reads its own over-deletion as a pass, a regex that misses the
66
+ word it searches for. All three pass loudly.
67
+
68
+ ### Changed
69
+ - `loop-guard.md` and `audit.md` now state their seam explicitly in both files: the
70
+ loop guard governs loops that **change** things and trips on oscillation; the
71
+ audit governs loops that **look** for things and trips on convergence. Different
72
+ failure, different exit, and an agent reading either one now learns when the other
73
+ applies.
74
+ - `tdd.md` names the generalisation of its own iron law; `build.md`'s fix loop gains
75
+ the repeats-twice rule; `templates/carryover.md` documents the ratchet contract.
76
+
77
+ ### Validator
78
+ - `references/audit.md` joins the built-in-doctrine set (must exist, must not be a
79
+ stub, must be reachable from `SKILL.md`).
80
+ - The shipped acceptance gate must require the ladder walk **and** say that an
81
+ absence becomes a new REQ row — a config where stage 10 only compares the REQ list
82
+ now fails.
83
+ - Both guards ship with CI negative self-tests, and both were proven the way this
84
+ release demands: defect planted, check watched failing, defect removed.
85
+
3
86
  ## v1.0.0 — 2026-07-28
4
87
 
5
88
  **1.0.** Eighteen releases in ten days added a stage, a requirement spine, a
package/README.md CHANGED
@@ -78,7 +78,8 @@ Every gate is **typed**: `auto` — the orchestrator verifies it itself, pass/fa
78
78
  - **Every stage has a gate.** No code before a spec. No deploy before tests. No
79
79
  "done" before the post-deploy logs have been read.
80
80
  - **Nothing falls out the back.** The request becomes a frozen, addressable list of
81
- requirements, and the last stage accounts for every one of them with evidence.
81
+ requirements, and the last stage accounts for every one with evidence then
82
+ walks the ladder for what should have been on the list and never was.
82
83
  - **Team discipline without a team.** ADRs, a written plan, a real test suite, a
83
84
  wiki entry — produced as part of the work, not promised for later.
84
85
  - **It adapts to your repo, not the reverse.** Deploy, docs and wiki conventions
@@ -117,6 +118,7 @@ stage that can fail because a plugin is missing:
117
118
  | 5 Build | [`build.md`](plugins/task-pipeline/skills/task-pipeline/references/build.md) + [`review.md`](plugins/task-pipeline/skills/task-pipeline/references/review.md) — isolation, ledger, subagent loop, review rubric, fix loop |
118
119
  | 5–6 TDD | [`tdd.md`](plugins/task-pipeline/skills/task-pipeline/references/tdd.md) — the iron law, red/green/refactor, the suite gate |
119
120
  | 10 Acceptance | [`acceptance.md`](plugins/task-pipeline/skills/task-pipeline/references/acceptance.md) — REQ coverage table, evidence rules, the closing question |
121
+ | 10 + any audit | [`audit.md`](plugins/task-pipeline/skills/task-pipeline/references/audit.md) — the L0→L7 ladder and its seams, axis rotation, ratchets, proven checks |
120
122
  | any loop | [`loop-guard.md`](plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md) — churn detection, caps, the break protocol |
121
123
 
122
124
  **Ported, not depended on.** Stage 0 is adapted from
@@ -271,6 +273,57 @@ module map), re-plans the check as an ordered checklist with one verification
271
273
  command per item, and goes through it one at a time. A higher-layer conflict is
272
274
  never settled inside a lower loop.
273
275
 
276
+ ### The audit ladder — finding what was never written
277
+
278
+ The REQ spine catches a requirement that was **named and lost**. It cannot catch
279
+ one that was never named — because **a comparison needs two sides, and an absence
280
+ has one.** Nothing in a diff between spec and plan reveals the error path nobody
281
+ specified, the entity nobody gave an owner, the failure mode nobody thought of.
282
+
283
+ So stage 10 opens with a **ladder walk**
284
+ ([`audit.md`](plugins/task-pipeline/skills/task-pipeline/references/audit.md)), not
285
+ with the coverage table. Each requirement is walked **bottom-up** through its rungs
286
+ — recorded decision → spec section → contract *and its failure behavior* → plan
287
+ task → the change in the tree → an **executed** named assertion → the surface a
288
+ user reaches and its docs — and the work is the **seam between each pair**: did the
289
+ decision reach the spec, does every contract have a task, did the DoD land in the
290
+ diff, would that test still pass with the production code deleted, does what
291
+ shipped satisfy the requirement's own *statement* rather than the task's
292
+ instructions. Findings are ordered **by seam, never by file** — the seam names
293
+ which layer of your process leaks. Every absence becomes a new REQ row with its
294
+ check *before* the table is written.
295
+
296
+ Bottom-up is not taste: a missing artefact low on the ladder makes everything above
297
+ it meaningless, so top-down you spend the pass polishing a surface for a contract
298
+ that does not exist.
299
+
300
+ Three rules keep the audit from becoming another loop:
301
+
302
+ - **Every pass changes the axis, not the effort.** A searching pass doesn't
303
+ oscillate, it *converges*: each pass edits the corpus the next one reads, so the
304
+ newest edits are always the least-reviewed text and are what the next pass finds.
305
+ Measured over seven passes on a production repository, by pass six the audit was
306
+ mostly repairing its own previous pass — while the finding count still looked
307
+ healthy. So count both numbers every pass (new findings vs. self-inflicted ones);
308
+ when the second overtakes the first, **rotate the axis** — seams down one
309
+ deliverable, then invariants across deliverables, then one class swept end to end.
310
+ - **A class that repeats twice becomes a gate, not a note.** Once is an incident;
311
+ twice is a category, and a category belongs in lint or CI where nobody has to
312
+ remember it. The third instance in a ledger is how a mechanical defect becomes
313
+ permanent.
314
+ - **What can't be fixed now becomes a ratchet, never a TODO** — a named, counted
315
+ set that may only shrink, printed *beside every gate verdict*
316
+ (`carry-over: 4 open (was 6) · unresolved: 0`). A TODO is invisible until someone
317
+ opens the file; a ratchet makes **"green" never read as "verified"** — it reads
318
+ as *"green, and here is exactly what was not looked at"*.
319
+
320
+ And the exit criterion that is usually skipped: a deliverable is audited when every
321
+ rung has its artefact **and every check you are relying on has been seen failing
322
+ once against a planted defect.** That is the TDD iron law — *if you didn't watch it
323
+ fail, you don't know it tests the right thing* — raised from one test to every
324
+ gate, linter and script in the run. **A green result from an unproven check is
325
+ worth nothing.**
326
+
274
327
  ### UX track (user-facing tasks) — super-ux recommended
275
328
 
276
329
  The moment a task touches any user-facing surface (web / mobile / CLI / TUI — a
@@ -161,14 +161,31 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
161
161
  propose the edit and get an explicit go, or carry it over with the exact change
162
162
  written down. A doc that was worth reading at stage 0 and is wrong now is the
163
163
  next run's false premise.
164
- 10. **Acceptance** (manual) — the closing stage: go back to the brief and account
165
- for **every** REQ. One row each, status `verified` / `partial` / `deferred` /
166
- `dropped`, and every `verified` carries **evidence** a passing test name, a
167
- `file:line`, a command and its output. "Done" without evidence is downgraded to
168
- `partial`, never upgraded. Then ask out loud, list in hand: *here's what you
169
- asked for, here's what shipped, here's what's deferred and where it lives
170
- what's missing?* Ask it even when the table is green. Gate: no REQ `unknown`,
171
- no ledger row without a home, user signs off.
164
+ 10. **Acceptance** (manual) — the closing stage, in two halves.
165
+ **First the ladder walk**, because the REQ table only finds what was named and
166
+ lost: a comparison needs two sides and **an absence has one**. Walk each REQ
167
+ bottom-up through its rungs recorded decision spec section contract *and
168
+ its failure behavior* plan task with a satisfiable DoD the change in the
169
+ tree an **executed** named assertion the surface a user reaches, and its
170
+ docs checking the seam between each pair: does the decision reach the spec;
171
+ does the section say what happens when the contract fails; does every contract
172
+ have a task; did the DoD land in the diff; would that test still pass with the
173
+ production code deleted; can a user reach this and does a doc say so; and
174
+ finally, does what shipped satisfy the requirement's own *statement* rather
175
+ than the task's instructions. Order findings **by seam, not by file** — the
176
+ seam tells you which layer of your process leaks. Every absence becomes a new
177
+ REQ row with its check **before** the table is written; appending afterwards is
178
+ how acceptance goes green over a gap. Findings owned by a lower layer go back
179
+ there (spec → stage 3, plan → stage 4).
180
+ **Then the table:** one row per REQ, status `verified` / `partial` /
181
+ `deferred` / `dropped`, and every `verified` carries **evidence** — a passing
182
+ test name, a `file:line`, a command and its output. "Done" without evidence is
183
+ downgraded to `partial`, never upgraded, and **a green from a check nobody has
184
+ watched fail against a planted defect is not evidence at all**. Then ask out
185
+ loud, list in hand: *here's what you asked for, here's what shipped, here's
186
+ what's deferred and where it lives — what's missing?* Ask it even when the
187
+ table is green. Gate: ladder walk ran, no REQ `unknown`, no ledger row without
188
+ a home, user signs off.
172
189
 
173
190
  Cross-cutting: answer from the brief's autonomy section rather than re-asking, log every deferral in the ledger, never narrow the task silently, track
174
191
  tasks, conventional commits, honest degradation (never claim a failed/skipped step
@@ -193,6 +210,32 @@ no opportunistic edits. Re-check the list once in the same order at the end. If
193
210
  trips again after a re-planned pass, stop and hand back with both shapes, the
194
211
  evidence and your recommendation.
195
212
 
213
+ **Audit rules — for loops that *look* rather than edit.** A searching pass doesn't
214
+ oscillate, it **converges**: each pass edits the corpus the next pass reads, so the
215
+ newest edits are the least-reviewed text and are what the next pass finds. Measured
216
+ over seven passes on a real repository, by pass six the audit was mostly repairing
217
+ its own previous pass while the finding count still looked healthy. So:
218
+ - **Count two numbers every pass** — new findings, and findings caused by the last
219
+ pass's own fixes. When the second overtakes the first, the axis is exhausted:
220
+ **rotate the axis, don't look harder.** The axes are orthogonal by construction —
221
+ seams down one deliverable (the ladder above), then invariants *across*
222
+ deliverables (one name, one enum, one owner everywhere), then one class swept end
223
+ to end (every error path, every count, every status vocabulary).
224
+ - **Audit bottom-up.** A missing artefact at a low rung makes everything above it
225
+ meaningless; top-down you polish a surface for a contract that doesn't exist.
226
+ - **A class that repeats twice becomes a check, not a note.** Once is an incident;
227
+ twice is a category, and a category belongs in lint or CI where nobody has to
228
+ remember it. The third instance in a ledger is how a mechanical defect becomes
229
+ permanent.
230
+ - **What can't be fixed now becomes a ratchet, never a TODO** — a named, counted
231
+ set that may only shrink, **printed beside every gate verdict**
232
+ (`carry-over: 4 open (was 6) · unresolved: 0`). A TODO is invisible until someone
233
+ opens the file; a ratchet makes "green" read as *"green, and here is exactly what
234
+ was not looked at"*. If it grew, one sentence says why.
235
+ - **Never trust an unproven check.** Plant the defect, watch the check fail, remove
236
+ it, then trust the green — same law as the failing test, applied to every gate,
237
+ linter and script the run leans on.
238
+
196
239
  ## super-ux for user-facing tasks (recommended)
197
240
 
198
241
  If the task touches any UI (web/mobile/CLI/TUI), the WHY→UI→scenario chain comes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "task-pipeline": "bin/task-pipeline.js"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "task-pipeline",
3
3
  "description": "Runs a substantial task through a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine is built into the skill — no companion plugin required — with typed auto/manual gates, a frozen requirement spine that must close with evidence, a loop guard that breaks churn, one provider-agnostic model confirmed up front, and an optional super-ux UX track for user-facing work.",
4
- "version": "1.0.0",
4
+ "version": "1.1.0",
5
5
  "author": {
6
6
  "name": "ssheleg"
7
7
  },
@@ -25,7 +25,7 @@ language, ADRs for hard-to-reverse calls) and covering the **autonomy sweep** (w
25
25
  would otherwise stop stages 1→10: docs sources incl. doc repos and the wiki, branch/tracker
26
26
  policy, test and lint commands, deploy target and authorization, log locations, docs/wiki targets) —
27
27
  until the brief is locked — including the **REQ table**, the request as an addressable list where every row names how it is verified — so the rest runs autonomously and the final stage can account for all of it. The list is frozen: adding is free, removing needs the operator's agreement. Anything deferred goes into the carry-over ledger the moment it's said. For any user-facing task, recommend/use
28
- **super-ux**. **If the brief describes a platform rather than a change**, stage 2 also cuts it into modules (`references/decomposition.md`) — module map committed, walking skeleton first, every REQ in exactly one module — and stages 3→10 then run per module, one brick at a time. **If any loop starts undoing an earlier pass** (same file edited twice for the same reason, a closed finding returning, a third entry into one stage), stop and run the loop guard (`references/loop-guard.md`): name both shapes, escalate to the layer that owns the conflict, re-plan the check as an ordered list, then go item by item. Honor every stage gate by its type (`auto` = verify yourself;
28
+ **super-ux**. **If the brief describes a platform rather than a change**, stage 2 also cuts it into modules (`references/decomposition.md`) — module map committed, walking skeleton first, every REQ in exactly one module — and stages 3→10 then run per module, one brick at a time. **If any loop starts undoing an earlier pass** (same file edited twice for the same reason, a closed finding returning, a third entry into one stage), stop and run the loop guard (`references/loop-guard.md`): name both shapes, escalate to the layer that owns the conflict, re-plan the check as an ordered list, then go item by item. **The closing stage opens with the ladder walk** (`references/audit.md`): the REQ table finds what was named and lost, but a comparison needs two sides and an absence has one — so walk each REQ bottom-up through its rungs (decision → spec section → contract *and its failure behavior* → task → change → executed test → surface/docs), check the seam at each step, order findings by seam rather than by file, and turn every absence into a new REQ row **before** the coverage table is written. A green from a check nobody has watched fail against a planted defect is not evidence; a finding class seen twice becomes a script rather than a third ledger row; and the carry-over ledger's counts are printed beside every gate verdict, so "green" never reads as "verified". If a searching pass starts finding mostly what the previous pass's own fixes broke, the axis is exhausted — rotate it, don't look harder. Honor every stage gate by its type (`auto` = verify yourself;
29
29
  `manual` = wait for explicit go). Confirm the **model once at preflight** —
30
30
  recommend the most capable one the environment offers, never a hardcoded id — then
31
31
  run the whole pipeline on it without re-asking.
@@ -50,6 +50,7 @@ and no stage that can fail because a dependency is missing:
50
50
  | 5 Build (worktree, subagents, fix loop) | [`references/build.md`](references/build.md) + [`references/review.md`](references/review.md) |
51
51
  | 5–6 TDD + suite gate | [`references/tdd.md`](references/tdd.md) |
52
52
  | 10 Acceptance (REQ close-out) | [`references/acceptance.md`](references/acceptance.md) |
53
+ | 10 + any audit (what's *missing*) | [`references/audit.md`](references/audit.md) |
53
54
  | any repeating loop | [`references/loop-guard.md`](references/loop-guard.md) |
54
55
 
55
56
  **Optional bridge.** If the operator already runs an equivalent skill set (e.g.
@@ -162,7 +163,10 @@ Three things the grill does beyond clarifying the request:
162
163
  third entry into one stage — stop and run the loop guard**
163
164
  (`references/loop-guard.md`): name the two shapes, escalate to the layer that
164
165
  owns the conflict, re-plan the check as an ordered list, then go through it one
165
- item at a time; task
166
+ item at a time; **when a pass is *searching* rather than editing and starts
167
+ finding mostly what the previous pass's own fixes broke, the axis is exhausted —
168
+ rotate it, don't look harder** (`references/audit.md`), and remember that a
169
+ green from a check nobody has watched fail is not evidence; task
166
170
  tracker + conventional commits per host conventions; worktree isolation for the
167
171
  build, integrated back per the brief's branch policy before stage 7; honest
168
172
  degradation (never claim a failed/skipped step succeeded);
@@ -187,7 +191,7 @@ capable available — see `references/model-tiering.md`).
187
191
  | 7 | Lint + deploy | host lint → deploy per host convention | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
188
192
  | 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report | auto |
189
193
  | 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) | every stale row of the stage-0 source ledger updated; docs synced; wiki synced | auto |
190
- | 10 | **Acceptance** | built in: [`references/acceptance.md`](references/acceptance.md) | every REQ accounted for with evidence; ledger has no unresolved row; operator signs off | manual |
194
+ | 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; operator signs off | manual |
191
195
 
192
196
  ## Model — ask once, at preflight
193
197
 
@@ -223,6 +227,7 @@ automation is on — `pipeline.schema.json` is the only contract.
223
227
  - `references/knowledge-sources.md` — stage-0 phase 1: the source list, the wiki, the ledger, the stage-9 loop-back
224
228
  - `references/grill.md` — the built-in stage-0 grill: loop, domain awareness, autonomy sweep
225
229
  - `references/acceptance.md` — the built-in stage-10 close-out: REQ coverage, evidence, sign-off
230
+ - `references/audit.md` — cross-cutting: the L0→L7 ladder and its seams (what was never written), axis rotation, ratchets, proven checks
226
231
  - `references/brainstorm.md` — stage 2: design dialogue, approaches, UI detection, hard gate
227
232
  - `references/spec.md` — stage 3: UX track order, the spec contract, self-review, review gate
228
233
  - `references/planning.md` — stage 4: zero-context plan format, parallel groups, no placeholders
@@ -152,11 +152,12 @@
152
152
  "name": "Acceptance",
153
153
  "model": "default",
154
154
  "skills": [
155
+ "task-pipeline:audit",
155
156
  "task-pipeline:acceptance"
156
157
  ],
157
158
  "gate": {
158
159
  "type": "manual",
159
- "check": "Close the circle: every REQ in the brief has a status (verified / partial / deferred / dropped) — none unknown; every verified carries evidence (a passing test name, file:line, a command and its output, or a scenario ID) — 'done' without evidence is downgraded to partial, not upgraded; every partial names what is missing and where it is tracked; every deferred/dropped has the operator's agreement and, for deferred, a tracker entry; no carry-over row is left unresolved; and the operator answers the closing question — here is what you asked for, here is what shipped, here is what is deferred, what is missing? — and signs off"
160
+ "check": "Close the circle. FIRST the LADDER WALK (references/audit.md), because the REQ table can only find what was named and lost — a comparison needs two sides and an absence has one: walk each REQ bottom-up through its rungs (decision -> spec section -> contract AND its failure behavior -> plan task -> change -> executed test -> surface/docs), check the seam at each step, order findings BY SEAM not by file, and turn every absence into a new REQ row with its check BEFORE the table is written; findings belonging to a lower layer go back to that layer (spec -> stage 3, plan -> stage 4); record the pass's two counts (new findings vs findings caused by this run's own fixes) so the next pass can tell whether the axis is exhausted. THEN the coverage table: every REQ has a status (verified / partial / deferred / dropped) — none unknown; every verified carries evidence (a passing test name, file:line, a command and its output, or a scenario ID) — 'done' without evidence is downgraded to partial, not upgraded, and a green from a check nobody has watched fail against a planted defect is not evidence at all; every partial names what is missing and where it is tracked; every deferred/dropped has the operator's agreement and, for deferred, a tracker entry; no carry-over row is left unresolved and the ledger's counts are printed beside this verdict, so 'green' never reads as 'verified'; and the operator answers the closing question — here is what you asked for, here is what shipped, here is what is deferred, what is missing? — and signs off"
160
161
  }
161
162
  }
162
163
  ],
@@ -18,10 +18,34 @@ run itself decided, deferred, or quietly dropped along the way.
18
18
  It runs **last** — after docs and wiki (stage 9), because those are deliverables
19
19
  too and a requirement may name them.
20
20
 
21
+ ## First, the ladder walk — what the list itself is missing
22
+
23
+ The REQ table answers *"did everything on the list ship?"*. It cannot answer
24
+ *"should something else have been on the list?"* — a comparison needs two sides,
25
+ and an absence has one.
26
+
27
+ So **before writing the coverage table**, walk the ladder in
28
+ [`audit.md`](audit.md): each REQ bottom-up through its rungs (decision → spec
29
+ section → contract **and its failure behavior** → task → change → executed test →
30
+ surface and docs), checking the seam at each step. It is one pass, scoped to this
31
+ run's deliverables, and it is the only part of the pipeline that can find a gap
32
+ that was never a row.
33
+
34
+ - **An absence found here becomes a new REQ row with its check**, then the table is
35
+ written. The list is frozen against *narrowing*, never against additions
36
+ ([`grill.md`](grill.md) → *The REQ spine*). Writing the table first and appending
37
+ afterwards is how acceptance goes green over a gap.
38
+ - **A finding that belongs to a lower layer goes back to that layer** — spec gaps to
39
+ stage 3, plan gaps to stage 4 — rather than being patched in place at stage 10.
40
+ - **Report the audit's two counts** (new findings; findings caused by this run's own
41
+ fixes) in the ledger. They are what tells the next pass whether the axis is
42
+ exhausted (`audit.md` → *Every pass changes the axis*).
43
+
21
44
  ## Inputs
22
45
 
23
46
  Read all of them before writing anything:
24
47
 
48
+ - the ladder walk's findings (above) — they may have added REQ rows
25
49
  - the brief's **REQ table** (`docs/superpowers/specs/<topic>-brief.md`)
26
50
  - the **carry-over ledger** (`…-carryover.md`) — in full, every row
27
51
  - the plan and its task statuses
@@ -97,13 +121,20 @@ whether the run was finished.
97
121
 
98
122
  All of:
99
123
 
100
- 1. **Every REQ has a status** — none `unknown`, none blank.
101
- 2. **Every `verified` carries evidence** of the kind above.
102
- 3. **Every `partial` names what's missing** and where it's tracked.
103
- 4. **Every `deferred` / `dropped` has the operator's agreement** recorded (in the
124
+ 1. **The ladder walk ran** ([`audit.md`](audit.md)) every REQ's rungs checked
125
+ bottom-up, findings ordered by seam, absences turned into REQ rows **before**
126
+ the table was written, and the two pass counts recorded.
127
+ 2. **Every check this gate leans on has been seen failing** at least once against a
128
+ planted defect (`audit.md` → *Exit criterion*). An unproven check's green is not
129
+ evidence.
130
+ 3. **Every REQ has a status** — none `unknown`, none blank.
131
+ 4. **Every `verified` carries evidence** of the kind above.
132
+ 5. **Every `partial` names what's missing** and where it's tracked.
133
+ 6. **Every `deferred` / `dropped` has the operator's agreement** recorded (in the
104
134
  ledger or here) and, for `deferred`, a tracker entry.
105
- 5. **No carry-over row is left `unresolved`** — every one has a home.
106
- 6. **The operator answers the closing question** and signs off.
135
+ 7. **No carry-over row is left `unresolved`** — every one has a home, and the
136
+ ledger's counts are printed with this verdict, not just filed.
137
+ 8. **The operator answers the closing question** and signs off.
107
138
 
108
139
  Manual by design. An automated check can prove the table is *well-formed*; only
109
140
  the person who asked can confirm it is *what they asked for*. Do not let a green
@@ -82,6 +82,7 @@ plugins/task-pipeline/
82
82
  spec.md planning.md # stages 3-4
83
83
  build.md review.md tdd.md # stages 5-6
84
84
  acceptance.md # stage 10
85
+ audit.md # cross-cutting: the ladder + seams
85
86
  loop-guard.md # cross-cutting: churn detection
86
87
  stages.md model-tiering.md # gates, model policy
87
88
  conventions.md artifacts.md # host conventions, this layout
@@ -0,0 +1,224 @@
1
+ # Audit — finding what is missing, cross-cutting
2
+
3
+ Every gate in this pipeline asks *"is this artifact good?"*. Stage 10 asks *"is
4
+ anything from the list lost?"* ([`acceptance.md`](acceptance.md)). **Neither asks
5
+ what should have been on the list and never was.**
6
+
7
+ That gap is not an oversight in the gates. It is structural: a gate compares two
8
+ things, and **a contradiction has two sides while an absence has one.** Comparing
9
+ the spec against the plan finds a requirement that was dropped. It cannot find the
10
+ error path nobody specified, the entity nobody gave an owner, the failure mode
11
+ nobody named — because on both sides of every comparison, it simply isn't there.
12
+
13
+ This file is the method that finds those. It is **cross-cutting**: stage 10 runs it
14
+ before writing the coverage table, the program loop runs it per module, and a task
15
+ whose whole job is "audit X" runs nothing else.
16
+
17
+ ## Three things that are easy to confuse
18
+
19
+ | File | Runs when | Answers |
20
+ |---|---|---|
21
+ | [`acceptance.md`](acceptance.md) | stage 10 | did everything **on the list** ship, with evidence? |
22
+ | [`loop-guard.md`](loop-guard.md) | any **editing** loop churns | is this pass undoing the last one? |
23
+ | **this file** | any **audit** pass | what is broken or missing that nobody has compared? |
24
+
25
+ `loop-guard.md` governs loops that *change* things — the fix loop, a re-entered
26
+ stage. Its trip means a decision is being re-litigated at the wrong altitude. This
27
+ file governs loops that *look* for things. Its trip means the axis is exhausted,
28
+ which is a different failure with a different exit. Both can bind one run; they do
29
+ not overlap.
30
+
31
+ ## Why "look again, more carefully" stops working
32
+
33
+ The method most audits use is **horizontal**: compare the documents against each
34
+ other, then do it again. It works, and then it fails in a way that is invisible
35
+ from inside it. Measured over seven passes on a production repository:
36
+
37
+ | Pass | Findings | …of which the previous pass's own fixes caused |
38
+ |---|---|---|
39
+ | 4 | 12 | 5 |
40
+ | 5 | 17 | 9 |
41
+ | 6 | 13 | 10 |
42
+ | 7 | 19 | 4 |
43
+
44
+ By pass six the audit was **mostly repairing itself**. Not fatigue — arithmetic.
45
+ Each pass edits the corpus the next pass reads, so the newest edits are always the
46
+ least-reviewed text present, and they are what the next pass finds. The count stays
47
+ healthy while the yield goes to zero.
48
+
49
+ A single **vertical** pass over the same repository — one capability walked down
50
+ through its layers — found nine defect classes those seven passes had been
51
+ structurally **unable** to see. Not missed: unable. Two of them:
52
+
53
+ - **A component that encrypts every object in the system had no key store
54
+ anywhere.** Its sibling's key table had been modelled for weeks. A comparison
55
+ needs two sides; this had one.
56
+ - **An edit appended a new version while the derived index still pointed at the
57
+ old text.** The archive is correct. The index is correct. The answer is correct —
58
+ *against a version nobody is looking at.* Compare archive to archive and index to
59
+ index: both pass. **The defect lives in the seam.**
60
+
61
+ ## The ladder
62
+
63
+ The rungs are **layers of one deliverable**; the work is the **seams between
64
+ them**. Each rung's artefact either exists or it does not — that is what makes
65
+ absence findable.
66
+
67
+ | Rung | Layer | The artefact that must exist |
68
+ |---|---|---|
69
+ | **L0** | Requirement | a `REQ-###` row in the brief **with a named check** |
70
+ | **L1** | Decision | the locked decision, ADR or `CONTEXT.md` term this REQ rests on |
71
+ | **L2** | Design | a spec section carrying `covers: REQ-…` |
72
+ | **L3** | Contract | an exact signature or schema · **and its failure behavior** |
73
+ | **L4** | Task | a plan task with `Implements:` and a DoD satisfiable **as written** |
74
+ | **L5** | Change | the commits — the thing actually in the tree |
75
+ | **L6** | Test | an **executed** assertion, by name — never "the tests pass" |
76
+ | **L7** | Surface | what a user reaches: scenario, screen state, CLI output, runbook |
77
+
78
+ **Audit the seams, not the artifacts.** Each rung is internally consistent most of
79
+ the time — that is exactly what the horizontal pass is good at, and it has already
80
+ done it. What survives lives between rungs:
81
+
82
+ | Seam | The question | What absence looks like here |
83
+ |---|---|---|
84
+ | L0→L1 | does the requirement rest on a **recorded** decision? | a REQ whose check implies a choice nobody ever made or wrote down |
85
+ | L1→L2 | did the decision reach the spec? | an ADR or glossary term agreed at the grill that no spec section cites |
86
+ | L2→L3 | does the section name its contract **and what happens when it fails**? | "handles errors" — no code, no shape, no caller-visible reason |
87
+ | L3→L4 | does every contract have a task that builds it? | stage 4's set-equality covers REQ→task; **nothing** covers contract→task |
88
+ | L4→L5 | did the DoD land in the tree? | a DoD line nothing in the diff satisfies, marked done anyway |
89
+ | L5→L6 | is there an executed observable? | "tests pass"; a test that still passes with the production code deleted |
90
+ | L6→L7 | can a user reach it, and does a doc say so? | shipped behavior with no scenario, no `--help` line, no runbook entry |
91
+ | L7→L0 | does the shipped surface satisfy the requirement's **statement**? | it does what the task said and not what the requirement meant |
92
+
93
+ The last seam is stage 10's question, expressed as a seam. When it fails, the run
94
+ did every instruction correctly and delivered the wrong thing.
95
+
96
+ ## How one audit pass runs
97
+
98
+ **Scope: one deliverable, all rungs.** One REQ, one module, one capability. Not
99
+ "audit the docs" and not "audit the change" — an unscoped instruction is what
100
+ produces seven converging passes.
101
+
102
+ **Input** is the artifact that already names every rung: the brief's REQ row plus
103
+ the module map row ([`decomposition.md`](decomposition.md)) when there is one. **If
104
+ the input can't supply the rungs, that is the first finding** — do not go looking
105
+ for the layers by hand; record that the spine is missing and fix that first.
106
+
107
+ **Procedure: bottom-up, L0 → L7, running the seam check at each step.**
108
+
109
+ The direction is not taste. A missing artefact at L1 makes everything above it
110
+ meaningless, so top-down you spend the pass polishing a surface for a contract that
111
+ does not exist. Bottom-up, the absence surfaces first and the six findings above it
112
+ collapse into one.
113
+
114
+ **Output: findings ordered by seam, never by file.** A file-ordered list reads as
115
+ noise; a seam-ordered one tells you **which layer of your own process is leaking**,
116
+ which is the thing worth knowing. Each finding carries `file:line`, the artefact
117
+ that is missing, and the minimal fix.
118
+
119
+ **Close through the pipeline, not around it.** A finding that is a genuine gap
120
+ becomes a **new REQ row** (with its check) or a carry-over row — the list is frozen
121
+ against *narrowing*, never against additions ([`grill.md`](grill.md) → *The REQ
122
+ spine*). A finding that contradicts the spec goes back to stage 3; one that
123
+ contradicts the plan goes back to stage 4. Auditing is not a licence to edit
124
+ across layers in place.
125
+
126
+ ## Exit criterion — the part usually skipped
127
+
128
+ A deliverable is **not** audited when somebody has read it. It is audited when:
129
+
130
+ 1. every rung has its artefact, **and**
131
+ 2. **every check you are relying on has fired at least once against a planted
132
+ defect.**
133
+
134
+ **A green result from an unproven check is worth nothing.** This is the iron law of
135
+ [`tdd.md`](tdd.md) — *if you didn't watch it fail, you don't know it tests the
136
+ right thing* — raised from one test to every gate in the run. It applies to the
137
+ stage-4 set-equality check, the host's lint and test commands, the super-ux linter,
138
+ any script the host added, and every check you write during the audit itself.
139
+
140
+ Checks written under time pressure lie in ways that read as success: a predicate
141
+ that inspects the wrong shape and finds nothing; a probe that removes more than it
142
+ adds and reads the shrinkage as a pass; a regex that misses the very word it
143
+ searches for. All three pass loudly. **Plant the defect. Watch the check fail.
144
+ Remove it. Then trust the green.** Record in the ledger that you did.
145
+
146
+ ## The three rules that stop this becoming another loop
147
+
148
+ ### 1. A class that repeats twice becomes a gate, not a note
149
+
150
+ Once is an incident. **Twice is a category, and a category belongs in a script** —
151
+ the host's lint, its CI, its check runner — where nobody has to remember it.
152
+
153
+ Writing the third instance into the carry-over ledger is how a known, mechanical
154
+ defect class becomes permanent. If the class genuinely cannot be checked
155
+ mechanically, say so in one line and *say why*; that sentence is itself a finding
156
+ worth having.
157
+
158
+ ### 2. Every pass changes the axis, not the effort
159
+
160
+ "Look again, more carefully" is what converges. Passes must be **orthogonal by
161
+ construction**:
162
+
163
+ 1. **Seams** — one deliverable walked L0→L7 (this file's ladder).
164
+ 2. **Invariants across deliverables** — one name, one enum, one owner, one spelling,
165
+ everywhere. This is the horizontal pass, and it is where it belongs.
166
+ 3. **One class swept end to end** — every error path, every count, every status
167
+ vocabulary, every timeout, across the whole change at once.
168
+
169
+ **The crossover is measurable, so measure it.** Every pass, count two numbers: new
170
+ findings, and findings caused by the previous pass's own fixes. When the second
171
+ overtakes the first, the axis is exhausted — **rotate it, don't push harder.** Both
172
+ counts go in the ledger; an audit that reports only "found N" cannot see its own
173
+ exhaustion.
174
+
175
+ ### 3. What can't be fixed now becomes a ratchet, never a TODO
176
+
177
+ A **ratchet** is a *named, counted set that may only shrink, printed on every
178
+ run*.
179
+
180
+ The carry-over ledger ([`templates/carryover.md`](../templates/carryover.md)) is
181
+ the pipeline's ratchet, and it only works if its count is **printed at every gate
182
+ beside the verdict**:
183
+
184
+ ```
185
+ GATE 6 tests: PASS — full suite green (247 tests)
186
+ carry-over: 4 open (was 6) · unresolved: 0 · audit findings deferred: 2
187
+ ```
188
+
189
+ The difference from a TODO is not bookkeeping. A TODO is invisible until somebody
190
+ opens the file. A ratchet sits next to the word `PASS` on every single run, so
191
+ **"green" never reads as "verified"** — it reads as *"green, and here is exactly
192
+ what was not looked at."* A ratchet that grew needs a sentence in the run log
193
+ explaining why; a ratchet nobody prints is a TODO with a better name.
194
+
195
+ ## When this runs
196
+
197
+ - **Stage 10, before the coverage table.** Acceptance reads the REQ list; the
198
+ ladder walk is what can add to it. Absences found here become new REQ rows with
199
+ their checks, and *then* the table is written — otherwise acceptance closes green
200
+ over a gap that was never a row.
201
+ - **Per module in the program loop** ([`decomposition.md`](decomposition.md)) — one
202
+ brick's ladder, at that brick's acceptance. Cross-module contracts are audited at
203
+ the seam that owns them, not twice.
204
+ - **As the whole task**, when the operator's request *is* an audit. Then stages 3–5
205
+ produce findings and fixes rather than a feature, and the exit criterion above is
206
+ the stage-10 gate.
207
+ - **Never as an eighth "look again" pass.** If the last two passes found mostly
208
+ self-inflicted findings, the answer is rule 2, not another pass.
209
+
210
+ Once both axes are exhausted, the next finding of a known class should be caught by
211
+ a script — and if it cannot be, **that is the finding: write the check.**
212
+
213
+ ## Rationalizations
214
+
215
+ | Excuse | Reality |
216
+ |---|---|
217
+ | "The gates all passed, so it's complete" | Gates compare. Nothing that was never written appears on either side of a comparison. |
218
+ | "One more careful pass will catch it" | Measured: by pass six the passes were mostly fixing their own last pass. Rotate the axis. |
219
+ | "I'll audit top-down, the surface is where users are" | A surface built on an absent contract wastes the whole pass. Bottom-up, that absence is finding #1. |
220
+ | "The check is green, that's evidence" | Only if you have seen it red. An unproven check is a decoration that reports success. |
221
+ | "It's a small gap, I'll note it in the ledger" | Second occurrence of a class → it goes in a script. The ledger is for what cannot be automated, not what nobody automated. |
222
+ | "Findings grouped by file are easier to fix" | And impossible to learn from. Group by seam; the seam names which layer of your process leaks. |
223
+ | "The ledger has it, we won't forget" | Only if it is printed beside every verdict. Unprinted, it is a TODO, and TODOs are invisible by construction. |
224
+ | "This is out of scope for the audit" | Then it is a carry-over row with a home, right now. An audit that silently declines findings is worse than none. |
@@ -234,6 +234,12 @@ Two routes leave before the loop starts:
234
234
  - **Minor findings** never enter it. Record each in the ledger
235
235
  (`Task <N>: minor (deferred): <one-liner>`) and point the final review at that
236
236
  list. A roll-up nobody reads is a silent discard.
237
+ - **A finding class that shows up a second time stops being a finding and becomes a
238
+ check.** Two tasks flagged for the same mechanical defect — the same missing
239
+ failure path, the same magic value, the same naming slip — means every later task
240
+ will produce it too. Add it to the host's lint or check script now, in its own
241
+ commit, instead of writing the third instance into the ledger
242
+ ([`audit.md`](audit.md) → *A class that repeats twice becomes a gate*).
237
243
  - **A finding that conflicts with what the plan mandates** is the operator's
238
244
  call: present the finding beside the plan text and ask which governs. Don't
239
245
  dismiss the finding because the plan mandated it; don't fix against the plan
@@ -21,6 +21,7 @@ better, plus one that is required only for user-facing work.
21
21
  | 5 Build (isolation, subagents, fix loop) | `references/build.md` + `references/review.md` |
22
22
  | 5–6 TDD + suite gate | `references/tdd.md` |
23
23
  | 10 Acceptance (REQ close-out) | `references/acceptance.md` |
24
+ | 10 + any audit (finding what's missing) | `references/audit.md` |
24
25
  | any repeating loop | `references/loop-guard.md` |
25
26
 
26
27
  ## The matrix
@@ -10,6 +10,14 @@ the pipeline: the stage-5 fix loop, a stage re-entered after a failed gate, the
10
10
  per-module program loop ([`decomposition.md`](decomposition.md)), and any
11
11
  audit → fix → audit cycle.
12
12
 
13
+ **This file governs loops that *change* things.** A loop that *looks* for things —
14
+ pass after pass over one corpus — fails differently: it does not oscillate, it
15
+ **converges**, quietly spending each pass on the previous pass's own edits while the
16
+ finding count stays healthy. That has its own detector and its own exit (rotate the
17
+ axis, don't push harder): [`audit.md`](audit.md) → *Every pass changes the axis*.
18
+ Both can bind one run. Use this file's trips for edits, that file's crossover for
19
+ searches.
20
+
13
21
  ## Bookkeeping — the thing that makes detection mechanical
14
22
 
15
23
  You cannot detect churn from memory, especially after compaction. Every repeating
@@ -262,6 +262,17 @@ stages/agents/types (see SKILL.md → *Bring your own skills*).
262
262
  surfaces.
263
263
  - **Runs last**, after docs and wiki — those are deliverables too, and a REQ may
264
264
  name them.
265
+ - **The ladder walk runs FIRST** ([`audit.md`](audit.md)). The REQ table can only
266
+ find what was named and lost; it cannot find what was never named, because a
267
+ comparison needs two sides and an absence has one. So before the table: walk each
268
+ REQ bottom-up through its rungs (decision → spec section → contract **and its
269
+ failure behavior** → task → change → executed test → surface/docs), check the
270
+ seam at each step, and order the findings **by seam, not by file**. An absence
271
+ becomes a **new REQ row with its check** and *then* the table is written;
272
+ appending after the table is how acceptance goes green over a gap. Findings that
273
+ belong to a lower layer go back to that layer (spec → stage 3, plan → stage 4).
274
+ Record the pass's two counts — new findings, and findings caused by this run's
275
+ own fixes — so the next pass can tell whether the axis is exhausted.
265
276
  - **How it runs:** built in. Read the brief's REQ table, the carry-over ledger in
266
277
  full, the plan's task statuses, git log, the final suite output, stage-8 notes and
267
278
  stage-9 doc changes (plus `docs/ux/scenarios.md` + `/ux-lint` for UI tasks). Write
@@ -274,10 +285,14 @@ stages/agents/types (see SKILL.md → *Bring your own skills*).
274
285
  you asked for, here's what shipped, here's what's deferred and where it lives —
275
286
  what's missing?* Ask it even when the table is green; the operator holds context
276
287
  the brief never captured, and this is the cheapest moment in the run to hear it.
277
- - **GATE (manual):** every REQ has a status (none `unknown`); every `verified`
288
+ - **GATE (manual):** the ladder walk ran and its absences became REQ rows before
289
+ the table was written; **every check this gate leans on has been seen failing
290
+ once against a planted defect** (an unproven check's green is not evidence);
291
+ every REQ has a status (none `unknown`); every `verified`
278
292
  carries evidence; every `partial` names what's missing and where it's tracked;
279
293
  every `deferred`/`dropped` has the operator's agreement and, for `deferred`, a
280
- tracker entry; no carry-over row left `unresolved`; the operator answers the
294
+ tracker entry; no carry-over row left `unresolved`, and the ledger's counts are
295
+ printed with the verdict; the operator answers the
281
296
  closing question and signs off. Manual by design — an automated check can prove
282
297
  the table is well-formed, only the person who asked can confirm it is what they
283
298
  asked for.
@@ -329,3 +344,20 @@ cycle.
329
344
  re-plan the check as an ordered one-item-per-line checklist, then go through it in
330
345
  order, one commit per item. Never settle a higher-layer conflict inside a lower
331
346
  loop, and never adjudicate before the cap.
347
+
348
+ ## Cross-cutting — the audit
349
+
350
+ The loop guard governs loops that **change** things. A loop that **looks** for
351
+ things fails the other way: it converges, spending pass after pass on its own last
352
+ pass's edits while the finding count stays healthy. [`audit.md`](audit.md) is that
353
+ method and that exit — the L0→L7 ladder, the seam questions, the axis-rotation
354
+ crossover, and the rule that a green from a check nobody has watched fail is worth
355
+ nothing.
356
+
357
+ - It runs **at stage 10 before the coverage table** (the only place that can find a
358
+ requirement nobody ever wrote), **per module** in the program loop, and as the
359
+ whole task when the request is itself an audit.
360
+ - **A finding class seen twice becomes a script**, not a third ledger row.
361
+ - **Whatever can't be fixed now becomes a ratchet** — a named, counted set that may
362
+ only shrink, printed beside every gate verdict, so "green" never reads as
363
+ "verified".
@@ -15,6 +15,11 @@ NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
15
15
 
16
16
  **If you didn't watch the test fail, you don't know it tests the right thing.**
17
17
 
18
+ The same law governs every other check in the run — a gate's `check`, a lint rule,
19
+ a host script, a detector written during an audit. A check nobody has seen fail is
20
+ a decoration that reports success. [`audit.md`](audit.md) → *Exit criterion* is
21
+ this rule raised from one test to the whole pipeline.
22
+
18
23
  Wrote code before the test? Delete it and start from the test. Not "keep it as
19
24
  reference", not "adapt it while writing tests", not "look at it once more". Delete
20
25
  means delete — code you kept is code the test was written to fit.
@@ -28,6 +28,29 @@
28
28
  with no home is exactly the thing that gets forgotten, so acceptance refuses to
29
29
  close on it.
30
30
 
31
+ ## This ledger is a ratchet, not a TODO list
32
+
33
+ A TODO is invisible until somebody opens the file. **A ratchet is a named, counted
34
+ set that may only shrink, and it is printed beside every gate verdict:**
35
+
36
+ ```
37
+ GATE 6 tests: PASS — full suite green (247 tests)
38
+ carry-over: 4 open (was 6) · unresolved: 0 · audit findings deferred: 2
39
+ ```
40
+
41
+ That one line is the whole mechanism. Without it, `PASS` reads as *verified*; with
42
+ it, `PASS` reads as *"green, and here is exactly what was not looked at"* — which
43
+ is the true statement.
44
+
45
+ - **Print the counts at every gate**, not only at stage 10. A number nobody sees
46
+ until the end is a number nobody acts on.
47
+ - **The set may only shrink.** If it grew, the run log gets one sentence saying why.
48
+ A ratchet that grows silently is a TODO with a better name.
49
+ - **A finding class that appears twice stops belonging here** and becomes a check in
50
+ the host's lint or CI ([`audit.md`](../references/audit.md) → *A class that
51
+ repeats twice becomes a gate*). This ledger is for what cannot be automated, not
52
+ for what nobody automated.
53
+
31
54
  ## Notes
32
55
 
33
56
  - Adding a row costs one line and never blocks a stage — that is the point. The