task-pipeline-skill 1.30.0 → 1.32.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 +190 -0
- package/CONTRIBUTING.md +23 -1
- package/README.md +2 -0
- package/SKILL-CARD.md +1 -1
- package/cursor/rules/task-pipeline.mdc +23 -0
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/commands/task-pipeline.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +15 -10
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +7 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +109 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +23 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/verification.md +89 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/README.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/backlog.md +58 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/carryover.md +10 -5
- package/plugins/task-pipeline/skills/task-pipeline/templates/verification.md +55 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,195 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.32.0 — the column a machine may not fill
|
|
4
|
+
|
|
5
|
+
Stage 8 already performs the verification trio, reads the CI verdict and opens the
|
|
6
|
+
rendered page. All of it **per run**, none of it accumulating — so *"which features has
|
|
7
|
+
nobody confirmed since they shipped?"* had no artifact to be asked of.
|
|
8
|
+
|
|
9
|
+
`docs/superpowers/verification.md` is one row per shipped REQ, and its point is a single
|
|
10
|
+
column: **`Human` — a date, or the literal `never`.** Nothing else. *"soon"*, *"mostly"*
|
|
11
|
+
and *"looks fine"* are how a column stops being answerable, and this is the one thing in
|
|
12
|
+
the pipeline a machine may not write on your behalf.
|
|
13
|
+
|
|
14
|
+
**`never` is a fact, not a failure.** The count has no floor, no direction, and may
|
|
15
|
+
never be given a target — the moment `never` becomes something to avoid writing, the
|
|
16
|
+
column starts lying and the pipeline loses its only signal about the world outside its
|
|
17
|
+
own checks. One of the new checks is a **property check** proving that filling the
|
|
18
|
+
column does not fail the build: a gate that punishes an honest answer guarantees there
|
|
19
|
+
will not be one.
|
|
20
|
+
|
|
21
|
+
**It keys to the brief, not to the coverage table**, and that was a measurement rather
|
|
22
|
+
than a preference. Ten acceptance files here carry their first REQ-bearing table in
|
|
23
|
+
nearly as many shapes, because `acceptance.md` fixes it in prose — the same drift the
|
|
24
|
+
carry-over ledger reached with six header shapes. Eight of nine briefs carry
|
|
25
|
+
machine-readable `| REQ-NNN |` rows; the ninth was this programme's own brief, fixed the
|
|
26
|
+
day it was measured. That the coverage table has no template is a real finding with a
|
|
27
|
+
real cost, and it is on the board rather than fixed here.
|
|
28
|
+
|
|
29
|
+
Both directions, because they are different failures: a shipped REQ that entered no
|
|
30
|
+
ledger, and a ledger row about a requirement no brief carries.
|
|
31
|
+
|
|
32
|
+
**Seeded truthfully: 103 rows, every one `never`.** Thirty-one versions shipped, and not
|
|
33
|
+
one recorded instance of a person confirming a shipped requirement afterwards. That is
|
|
34
|
+
not a new problem — it is the first time it can be stated.
|
|
35
|
+
|
|
36
|
+
**Review round: N1's lesson carried forward by its wrong half.** The Human check
|
|
37
|
+
scanned *every* cell for a date or `never`, so a bare date sitting in the Note column
|
|
38
|
+
satisfied a row whose Human read *"soon"* — precisely the prose the guard exists to
|
|
39
|
+
reject. N1 concluded *"the header names the candidate columns and the match happens
|
|
40
|
+
inside them"*, not *"never look at columns"*; this file is templated and has exactly one
|
|
41
|
+
shape, so the column is located by name and read alone.
|
|
42
|
+
|
|
43
|
+
**A file that states one truth twice, and drifted for two modules.** `artifacts.md`
|
|
44
|
+
carries an ASCII layout tree *and* the tables that name the same files — and the tree
|
|
45
|
+
never gained `backlog.md` (shipped in v1.31.0) or `verification.md` (this release), both
|
|
46
|
+
named in tables a hundred lines above it. A reader found it; nothing compared them. The
|
|
47
|
+
tree is now computed against those tables.
|
|
48
|
+
|
|
49
|
+
The seeded ledger also truncated its `What` column at 72 characters, leaving unterminated
|
|
50
|
+
code spans, while the template it follows says *"copied from the brief, not re-worded"* —
|
|
51
|
+
sixty-seven of a hundred and three rows landing at exactly 72 is a script's fingerprint,
|
|
52
|
+
not an editor's. Reseeded in full: 26 to 246 characters, none at 72.
|
|
53
|
+
|
|
54
|
+
**The ledger recorded unbuilt features as shipped and verified.** The seed took every
|
|
55
|
+
REQ from every brief — including this programme's own, whose REQ-004/008/009/010 belong
|
|
56
|
+
to modules that do not exist yet, and whose N2 rows were stamped with N1's version. In
|
|
57
|
+
the file whose entire purpose is *what actually shipped*. Reseeded: **99 rows**, four
|
|
58
|
+
omitted as not yet built, each module stamped with its own release.
|
|
59
|
+
|
|
60
|
+
**And the count is printed.** It was computed and dropped on the floor for a release — a
|
|
61
|
+
measurement nobody surfaces is the same silence as no measurement:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
verification: 99 shipped REQ · 99 never confirmed by a person (disclosure — no floor, no target)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Ninety-nine shipped requirements, not one confirmed by a person. That is the answer to a
|
|
68
|
+
question this repository could not previously ask.
|
|
69
|
+
|
|
70
|
+
Guards: 175 → **185**, property checks 4 → 8.
|
|
71
|
+
|
|
72
|
+
## v1.31.0 — the board, and the pointer that was never the one dangling
|
|
73
|
+
|
|
74
|
+
The carry-over ledger has always offered `backlog` as a home for a deferred row — a
|
|
75
|
+
place the pipeline **named and did not own**. The obvious fix was to build that
|
|
76
|
+
backlog. Measuring first changed the target: across ten ledgers in this repository,
|
|
77
|
+
**not one row has ever used that value.** The dangling pointer was never `backlog`. It
|
|
78
|
+
was `open` — **sixteen rows across six ledgers** (later re-measured: **24 rows across eight**), deferred out loud and filed nowhere.
|
|
79
|
+
|
|
80
|
+
`docs/superpowers/backlog.md` is the board: one per project, **mutable** where the
|
|
81
|
+
ledger is append-only, because a queue is re-ranked and a history is not. Rows leave
|
|
82
|
+
only into a *Closed* list, with the commit.
|
|
83
|
+
|
|
84
|
+
**Priority is computed, never assigned:** `prio = sev × blast + age_bonus`, inputs in
|
|
85
|
+
the row and the formula in the doctrine, so a ranking can be **checked** rather than
|
|
86
|
+
trusted. Two consequences are the point rather than side effects: an old small thing
|
|
87
|
+
eventually outranks a new medium one, and a row's priority moves without anyone
|
|
88
|
+
touching it — which is what makes the re-derivation at the end of an iteration real
|
|
89
|
+
work instead of ceremony.
|
|
90
|
+
|
|
91
|
+
**Ten ledgers, six different column shapes.** `#` or `id`; the status column named
|
|
92
|
+
*Home*, *Where it lives now*, *Resolution*, *Status* or *State*. So the guard finds
|
|
93
|
+
columns **by name** — a positional read would have silently checked the wrong cell in
|
|
94
|
+
five files out of six, and passed.
|
|
95
|
+
|
|
96
|
+
Both directions, because they are different failures: a ledger row pointing at an id
|
|
97
|
+
nobody issued, and a board row traceable to nothing. Neither is visible from the other
|
|
98
|
+
side.
|
|
99
|
+
|
|
100
|
+
The seam was closed rather than deferred: all sixteen rows carry a board id, so the
|
|
101
|
+
floor is **zero** and the next unhomed row fails the build instead of joining a debt.
|
|
102
|
+
This repo's own board opens seeded from those ledgers, with several rows that were the
|
|
103
|
+
same finding written separately by different runs — collapsed into one each, which is the
|
|
104
|
+
job the board exists for. The count is deliberately not restated here: it moved twice
|
|
105
|
+
while this entry was being written, which is exactly why this repository deletes
|
|
106
|
+
restated numbers rather than chasing them.
|
|
107
|
+
|
|
108
|
+
**The review found the guard reading the wrong cell in half the corpus.** The status
|
|
109
|
+
column was taken by position — and five of ten ledgers here carry *two* status-ish
|
|
110
|
+
columns (`status`+`home`, `resolution`+`state`), so "take the last one" read a different
|
|
111
|
+
cell per file and passed genuinely open rows in silence. Three more rows carry more
|
|
112
|
+
cells than their header and were skipped outright.
|
|
113
|
+
|
|
114
|
+
The test is now **position-free**: a row is open if any of its cells says so, and homed
|
|
115
|
+
if a board id appears anywhere in it. Neither question asks which column it came from,
|
|
116
|
+
so neither can be defeated by a shape nobody anticipated. It immediately found **eight
|
|
117
|
+
more open rows** — the true count was 24, not 16, and my own measurement was a third
|
|
118
|
+
low. Three of the eight were the same *"evals never run"* finding written by three
|
|
119
|
+
different runs; the board collapses them into one, which is the job it exists for.
|
|
120
|
+
|
|
121
|
+
Two more from the same round: the new stage-0 bullet was spliced into the middle of the
|
|
122
|
+
word *"the"* and `npm test` did not see it, and `templates/backlog.md` — the file seeded
|
|
123
|
+
verbatim into every host project — shipped a worked example that **contradicted the
|
|
124
|
+
formula printed two lines below it**. The arithmetic is now a guard, over both boards.
|
|
125
|
+
|
|
126
|
+
**The class the board logs hit the board itself.** A blank line inside its table split
|
|
127
|
+
three rows off into prose — and row **B-004** on that same board reads *"a blank line
|
|
128
|
+
silently splits a markdown table, and the documentation gate does not catch it."* Second
|
|
129
|
+
instance of a class this repository already had written down, so it became a script
|
|
130
|
+
rather than a third ledger row, swept across the whole corpus. B-004 is closed by the
|
|
131
|
+
check it asked for.
|
|
132
|
+
|
|
133
|
+
**A promise is not a check.** Three doctrine passages described stage-10 resolution as
|
|
134
|
+
keyed on a ledger row homed `backlog`, and the seeded template said outright that *the
|
|
135
|
+
gate refuses it* — while the shipped guard only ever looked for `open`. A reader seeded
|
|
136
|
+
a scratch ledger with exactly that row and watched it pass. Both triggers are enforced
|
|
137
|
+
now, and the doctrine describes what runs.
|
|
138
|
+
|
|
139
|
+
The split-table guard, one round old, could not tell *"table split"* from *"table ends,
|
|
140
|
+
table begins"* — it never checked whether the line after the blank opens its own table,
|
|
141
|
+
which its own comment claimed it did. A **property check** now proves it stays quiet on
|
|
142
|
+
the valid pattern, because a checker with false positives is worse than none.
|
|
143
|
+
|
|
144
|
+
**A tightening that turned the guard off.** Fixing the false positive above, the
|
|
145
|
+
separators were hand-listed — and the list omitted the arrow this repo's own annotations
|
|
146
|
+
use (`open → B-001`), so **all twenty-four resolved rows became invisible** and the
|
|
147
|
+
check passed by seeing nothing at all rather than by finding everything homed. The one
|
|
148
|
+
negative test covering that path caught it, which is the entire argument for the suite
|
|
149
|
+
in a sentence. The separator is now *"not a word character"* and the predicate is proven
|
|
150
|
+
against eight concrete cases instead of one.
|
|
151
|
+
|
|
152
|
+
**The detector reversed three times, and the third answer was in between.** Positional
|
|
153
|
+
read the wrong cell wherever a ledger carried two status columns. Pure-text then broke in
|
|
154
|
+
both directions with one regex — too strict for a live row worded *"open as a printed
|
|
155
|
+
exclusion"*, too loose for a description reading *"Open-source …"*, because a hyphen is
|
|
156
|
+
punctuation exactly like the arrow. What ships reads the header for **candidate columns**
|
|
157
|
+
— all of them, never just the last — and matches a status on a word boundary **inside**
|
|
158
|
+
them. A description cannot masquerade as a status because it is never looked at.
|
|
159
|
+
|
|
160
|
+
Every reversal was found by a reader. None by a probe.
|
|
161
|
+
|
|
162
|
+
**Two surfaces did not know the board exists.** `cursor/rules/task-pipeline.mdc` and
|
|
163
|
+
the command restate stage 0 and stage 10 in detail, and neither mentioned it — the same
|
|
164
|
+
one-rule-in-one-file-of-nine class this repository has a guard for on the rotation axes
|
|
165
|
+
and none for a new mechanism. Both carry it now, the Cursor rule by restatement because
|
|
166
|
+
it is self-contained by contract.
|
|
167
|
+
|
|
168
|
+
**The class that ran through six rounds is closed by computation, not by a sixth fix.**
|
|
169
|
+
Every one of those rounds found the same shape: the doctrine promised a resolution
|
|
170
|
+
trigger the check did not enforce — `open` alone while the prose said `backlog`,
|
|
171
|
+
`backlog` added while `unresolved` was still only promised, *"two triggers"* written in
|
|
172
|
+
a file whose code checked three. `audit.md` says a class seen twice becomes a script, so
|
|
173
|
+
the enumeration is now **extracted from the regex** and required to appear wherever the
|
|
174
|
+
doctrine lists it, in both directions. A guard that loses its own source fails rather
|
|
175
|
+
than passing.
|
|
176
|
+
|
|
177
|
+
**And the seam's origin was the template nobody opened.**
|
|
178
|
+
`templates/carryover.md` — the first ledger every host project ever sees — showed a bare
|
|
179
|
+
`backlog` home as a *settled* outcome, with a worked example carrying no board id. Six
|
|
180
|
+
rounds went into the doctrine, the guard, the board and three consuming surfaces before
|
|
181
|
+
anyone read the file the value came from. It names three unsettled values now, its
|
|
182
|
+
example carries a real id, and the guard checks the template beside the live ledgers.
|
|
183
|
+
|
|
184
|
+
**The guard written to close a false-success class had the class.** It verified that a
|
|
185
|
+
trigger word appeared *somewhere on the page* rather than that it was presented as an
|
|
186
|
+
enabled trigger — so prose reading *"those are the only two triggers"* would pass on the
|
|
187
|
+
strength of the third word appearing in a later paragraph. Scoped to the enumerating
|
|
188
|
+
paragraph now, and what it still cannot decide is written into the code rather than
|
|
189
|
+
implied by its silence.
|
|
190
|
+
|
|
191
|
+
Guards: 156 → **175**, property checks 1 → 4.
|
|
192
|
+
|
|
3
193
|
## v1.30.0 — the cap that would have measured the wrong axis
|
|
4
194
|
|
|
5
195
|
The audit's last finding was that `references/learned.md` has no retirement rule while
|
package/CONTRIBUTING.md
CHANGED
|
@@ -374,7 +374,29 @@ Exclusions are allowed and must each carry a reason in the code: a changelog nar
|
|
|
374
374
|
old formats, `docs/superpowers/specs/` are point-in-time records.
|
|
375
375
|
*(guard: `a worked GATE verdict omits ` and `states the cold-retirement condition as` — both now run over corpora walked from disk, so a new surface joins by existing)*
|
|
376
376
|
|
|
377
|
-
**44.
|
|
377
|
+
**44. A carry-over row still `open` names a board id, and the board row names it back.**
|
|
378
|
+
`docs/superpowers/backlog.md` is the project's queue between runs; the ledger's `open`
|
|
379
|
+
was a home that pointed nowhere, and rows across eight ledgers sat in it — sixteen by the first, positional count, twenty-four once the check stopped reading by column. Both
|
|
380
|
+
directions are checked because they are different failures — an id nobody issued, and a
|
|
381
|
+
row traceable to nothing. The test is **position-free**: a row is open if any of its cells
|
|
382
|
+
says so, and homed if a board id appears anywhere in it. Neither question asks which
|
|
383
|
+
column the value came from — ten ledgers here carry six header shapes and **five of them
|
|
384
|
+
have two status-ish columns**, so both a positional read and a by-name read pick a
|
|
385
|
+
different cell per file and pass open rows in silence. Reading by name was the first
|
|
386
|
+
design and it was wrong for the same reason.
|
|
387
|
+
*(guard: `with no board id` and `names no Source`)*
|
|
388
|
+
|
|
389
|
+
**45. Every shipped REQ has a verification row, and `Human` is a date or `never`.**
|
|
390
|
+
`docs/superpowers/verification.md` records the one thing no check can decide — whether a
|
|
391
|
+
person looked after it shipped. Both directions: a shipped REQ with no row, and a row
|
|
392
|
+
whose REQ is in no brief. It keys to the brief because eight of nine briefs carry
|
|
393
|
+
machine-readable REQ rows while ten acceptance files carry their coverage table in nearly
|
|
394
|
+
as many shapes. **The `never` count has no floor and may never be given a target**; a
|
|
395
|
+
property check proves that filling the column does not fail the build, because a gate
|
|
396
|
+
that punishes an honest answer will not receive one.
|
|
397
|
+
*(guard: `either a date or the literal` and `is in no brief's REQ table`)*
|
|
398
|
+
|
|
399
|
+
**46. Every invariant above names the guard that enforces it, and that guard exists.**This list claims to be *what the validator enforces*; it was eight guards behind when
|
|
378
400
|
an audit measured it. A claim of enforcement is now checked like any other claim.
|
|
379
401
|
*(guard: `whose message does not appear in`)* — and a cited literal must lie inside
|
|
380
402
|
a **single** string in `test/validate.py`: the check reads that file as text, so a
|
package/README.md
CHANGED
|
@@ -129,6 +129,8 @@ until it is installed.
|
|
|
129
129
|
| 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 |
|
|
130
130
|
| any loop | [`loop-guard.md`](plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md) — churn detection, caps, the break protocol |
|
|
131
131
|
| run-wide pacing | [`continuity.md`](plugins/task-pipeline/skills/task-pipeline/references/continuity.md) — the loop mode (`run.loop`, default off, never collapses a manual gate) and the context budget (fires on a harness signal, never on an estimate) |
|
|
132
|
+
| the board between runs | [`backlog.md`](plugins/task-pipeline/skills/task-pipeline/references/backlog.md) — the work-list that outlives a run: seeded at stage 0 or picked up, priority **computed** from three stated inputs rather than assigned, and the seam where the carry-over ledger's `backlog` pointer finally resolves |
|
|
133
|
+
| what a human confirmed | [`verification.md`](plugins/task-pipeline/skills/task-pipeline/references/verification.md) — one row per shipped REQ and the one column a machine may not fill: the date somebody **looked**, or `never`. No floor, no target — `never` is a fact, and a count driven down is a column that has started lying |
|
|
132
134
|
| 0 + 9 + any settled decision | [`documentation.md`](plugins/task-pipeline/skills/task-pipeline/references/documentation.md) — the inventory, registers and ids, SSOT, the Doc Loop, supersede semantics, the propagation matrix, intent vs as-built |
|
|
133
135
|
| 3 + 4 · every spec and plan | the self-review reads its rules back — is every named check real, does anything contradict a locked decision or a rejected option, and what does this cost now versus at design time. Answers land as a committed `## Self-review` of computed numbers |
|
|
134
136
|
| 6–10 + any check you write | [`gates.md`](plugins/task-pipeline/skills/task-pipeline/references/gates.md) — the three axes, the promotion ladder, gate anatomy, the probe recipe, ratchet floors |
|
package/SKILL-CARD.md
CHANGED
|
@@ -12,7 +12,7 @@ harmless.
|
|
|
12
12
|
|---|---|
|
|
13
13
|
| **Purpose** | Runs a substantial task through ten gated delivery stages — intake grill, docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs+registers, acceptance — refusing to advance until each gate passes |
|
|
14
14
|
| **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
|
|
15
|
-
| **Version** | 1.
|
|
15
|
+
| **Version** | 1.32.0 |
|
|
16
16
|
| **Surface** | Claude Code (filesystem skill + plugin) and the vercel `skills` CLI. **Not** uploaded to the Skills API; custom Skills do not sync across surfaces |
|
|
17
17
|
| **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
|
|
18
18
|
| **Evaluation status** | Suite authored, 5 categories. One recorded run, **self-observed by the author**; **zero blind runs on zero of three models** — the split, and the numbers, live in [`evals/RESULTS.md`](evals/RESULTS.md) and are computed by `evals/run.py` |
|
|
@@ -174,6 +174,18 @@ Seed a **carry-over ledger** next to the brief, append-only. Anything deferred,
|
|
|
174
174
|
dropped, or left half-done goes in the moment it's said — including implementer
|
|
175
175
|
concerns and non-blocking review findings. **Deferred out loud is forgotten.**
|
|
176
176
|
|
|
177
|
+
Read **the verification ledger** — `docs/superpowers/verification.md` — and quote how
|
|
178
|
+
many rows sit at `never`: that is the project's standing exposure, and stage 0 is where
|
|
179
|
+
it is cheapest to look. `never` is a fact, not a failure; the count has no floor and may
|
|
180
|
+
never be given a target.
|
|
181
|
+
|
|
182
|
+
Read **the board** — `docs/superpowers/backlog.md`, the project's work-list *between*
|
|
183
|
+
runs — and quote its open count in the brief; seed it from the template when absent. Its
|
|
184
|
+
priority is **computed, never assigned**: `prio = sev × blast + age_bonus`, with the
|
|
185
|
+
three inputs in the row so a ranking can be checked rather than trusted, and `age` moving
|
|
186
|
+
on its own is why the re-derivation at an iteration's end is real work. Where the ledger
|
|
187
|
+
records what *this run* deferred, the board is what the project still owes.
|
|
188
|
+
|
|
177
189
|
Stop when shared understanding is reached (every branch answered or explicitly
|
|
178
190
|
deferred) and lock the answers into a short brief the user confirms. Only then
|
|
179
191
|
start. Later stages read that brief instead of asking again.
|
|
@@ -334,6 +346,17 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
|
|
|
334
346
|
per project, not per run**. Every gate above is good at *this* run and blind
|
|
335
347
|
across runs: the same class of failure gets caught, fixed and forgotten five
|
|
336
348
|
times and nothing notices it is the same one. So, in this order —
|
|
349
|
+
**0a. Every REQ this run shipped has a verification row**, and every row names a
|
|
350
|
+
REQ some brief carries — both directions, because a shipped feature that entered no
|
|
351
|
+
ledger and a ledger row about nothing are different failures.
|
|
352
|
+
|
|
353
|
+
**0. Resolve the ledger onto the board first.** Every carry-over row still
|
|
354
|
+
`open`, `unresolved`, or homed `backlog` leaves with a `B-NNN` id on
|
|
355
|
+
`docs/superpowers/backlog.md`, and the ledger row is updated to name it — both
|
|
356
|
+
directions, because a pointer to an id nobody issued and a board row traceable to
|
|
357
|
+
nothing are different failures. Then re-derive the board's priorities: `age` moved
|
|
358
|
+
while the run was happening.
|
|
359
|
+
|
|
337
360
|
**1. Stamp the run first** — date, topic, commit, verdict, counts. It costs one
|
|
338
361
|
line and it is the only thing that makes the next step computable: one retirement
|
|
339
362
|
trigger counts firings across the last five run stamps **or sixty days**, whichever
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.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"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "task-pipeline",
|
|
3
3
|
"displayName": "Task Pipeline",
|
|
4
4
|
"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.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.32.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -30,8 +30,8 @@ grill's **domain awareness** (challenge terms against `CONTEXT.md`, sharpen fuzz
|
|
|
30
30
|
language, ADRs for hard-to-reverse calls) and covering the **autonomy sweep** (what
|
|
31
31
|
would otherwise stop stages 1→10: docs sources incl. doc repos, the wiki and the code graph, branch/tracker
|
|
32
32
|
policy, test and lint commands, deploy target and authorization, log locations, docs/wiki/graph targets, and for UI tasks whether the design is done visually in Figma or text-only, whether the Figma MCP is connected, and — if it isn't — whether to ship text-only or stop and connect it, since the UX chain degrades on its own and never blocks; **and with Figma on, the design destination: which team/org by name and which file** — the recorded one, a URL the operator gives, or creation in that named team explicitly authorized, written into the project's canonical record before the first frame, because a destination decided at drawing time is how a project ends up with three design files and no way to tell which is real. **Never create while a recorded file resolves; if it doesn't resolve, stop and ask — never create a replacement**) —
|
|
33
|
-
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
|
|
34
|
-
**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. **The docs stage closes three artifacts, not two:** module docs, the wiki, **and the code graph** (`/graphify . --update` where `graphify-out/` exists — `references/knowledge-graph.md`), because the graph is what the next run's harvest queries first and a stale one is a false premise carrying the authority of a machine. Then check the graph against the docs: a hub `graphify god-nodes` reports that no document names is an undocumented seam; an edge the docs deny is a leak in the code or a lie in the docs; a doc naming a module the graph no longer has is stale. Doc-side findings are fixed there, absences become REQ rows in the closing stage. **In a project of several repositories, stage 10 closes on the parent too:** a parent records each submodule as a pointer to one commit, and moving the submodule does not move the pointer — so the work can be committed, pushed and green while a clone of the parent still gets the commit before it. Neither repo looks wrong alone, which is why it survives every check that runs inside one. Require `git submodule status` with no line starting `+`, and every repo clean and pushed (`git -C <repo> status --porcelain`, `git -C <repo> log @{u}..HEAD`). The fix is two commands and the second gets forgotten: push the submodule, then `git add <submodule> && git commit`. **The run's last act is the retrospective** (`references/retrospective.md` → `docs/superpowers/retro.md`, one file per project): **stamp the run first** (its commit is what makes the cold-retirement trigger computable), **then prune** — every standing instruction against its three retirement triggers (it became a check; the paths/commands it names are gone; it hasn't fired in five run stamps, or in sixty days — the calendar is the unit that still moves when the stamp counter has stopped), the list held to a hard cap of ten, every deletion logged as one line and never silent — then, only if the run diverged, write the entry: symptom with evidence, the stage it surfaced at, the stage that *owned* it, the root cause, the fix by grade (mechanical check > standing instruction > note that expires in two runs), and the check that catches it next time. Stage 0 reads those standing instructions in full, so the prune is a gate criterion, not a good intention: a rule nobody reads to the end is worse than no rule, because everyone believes it is covered. Honor every stage gate by its type (`auto` = verify yourself;
|
|
33
|
+
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, and **the board** (`docs/superpowers/backlog.md`, `references/backlog.md`) — the work-list between runs — is read at stage 0 with its open count quoted in the brief, or seeded when absent; **the verification ledger** (`docs/superpowers/verification.md`, `references/verification.md`) is read at stage 0 for how many rows sit at `never`, written at stage 8 with one row per shipped REQ, and required at stage 10 in both directions. For any user-facing task, recommend/use
|
|
34
|
+
**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 every ledger row still `open`, `unresolved` or homed `backlog` leaves stage 10 with a board id and the board's priorities are re-derived (`references/backlog.md`); 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. **The docs stage closes three artifacts, not two:** module docs, the wiki, **and the code graph** (`/graphify . --update` where `graphify-out/` exists — `references/knowledge-graph.md`), because the graph is what the next run's harvest queries first and a stale one is a false premise carrying the authority of a machine. Then check the graph against the docs: a hub `graphify god-nodes` reports that no document names is an undocumented seam; an edge the docs deny is a leak in the code or a lie in the docs; a doc naming a module the graph no longer has is stale. Doc-side findings are fixed there, absences become REQ rows in the closing stage. **In a project of several repositories, stage 10 closes on the parent too:** a parent records each submodule as a pointer to one commit, and moving the submodule does not move the pointer — so the work can be committed, pushed and green while a clone of the parent still gets the commit before it. Neither repo looks wrong alone, which is why it survives every check that runs inside one. Require `git submodule status` with no line starting `+`, and every repo clean and pushed (`git -C <repo> status --porcelain`, `git -C <repo> log @{u}..HEAD`). The fix is two commands and the second gets forgotten: push the submodule, then `git add <submodule> && git commit`. **The run's last act is the retrospective** (`references/retrospective.md` → `docs/superpowers/retro.md`, one file per project): **stamp the run first** (its commit is what makes the cold-retirement trigger computable), **then prune** — every standing instruction against its three retirement triggers (it became a check; the paths/commands it names are gone; it hasn't fired in five run stamps, or in sixty days — the calendar is the unit that still moves when the stamp counter has stopped), the list held to a hard cap of ten, every deletion logged as one line and never silent — then, only if the run diverged, write the entry: symptom with evidence, the stage it surfaced at, the stage that *owned* it, the root cause, the fix by grade (mechanical check > standing instruction > note that expires in two runs), and the check that catches it next time. Stage 0 reads those standing instructions in full, so the prune is a gate criterion, not a good intention: a rule nobody reads to the end is worse than no rule, because everyone believes it is covered. Honor every stage gate by its type (`auto` = verify yourself;
|
|
35
35
|
`manual` = wait for explicit go). Confirm the **model once at preflight** —
|
|
36
36
|
recommend the most capable one the environment offers, never a hardcoded id — then
|
|
37
37
|
run the whole pipeline on it without re-asking.
|
|
@@ -68,6 +68,8 @@ gate stops until it is installed.
|
|
|
68
68
|
| **what travels with the bundle vs stays in a project** | [`references/portability.md`](references/portability.md) |
|
|
69
69
|
| any repeating loop | [`references/loop-guard.md`](references/loop-guard.md) |
|
|
70
70
|
| run-wide · how a run keeps going (the loop mode + the context budget) | [`references/continuity.md`](references/continuity.md) |
|
|
71
|
+
| run-wide · the work-list **between** runs, and how its priority is computed | [`references/backlog.md`](references/backlog.md) |
|
|
72
|
+
| run-wide · whether a **human** ever confirmed what shipped, and when | [`references/verification.md`](references/verification.md) |
|
|
71
73
|
|
|
72
74
|
**Optional bridge.** If the operator already runs an equivalent skill set (e.g.
|
|
73
75
|
`superpowers:brainstorming` / `writing-plans` / `subagent-driven-development` /
|
|
@@ -205,10 +205,15 @@ GATE 10 acceptance: PASS — 14/14 REQ verified
|
|
|
205
205
|
|
|
206
206
|
All of:
|
|
207
207
|
|
|
208
|
-
1. **
|
|
208
|
+
1. **Every shipped REQ has a verification row, and every row names a REQ its own run
|
|
209
|
+
carries** ([`verification.md`](verification.md)) — both directions, because a shipped
|
|
210
|
+
feature that entered no ledger and a ledger row about nothing are different failures.
|
|
211
|
+
The row's `Human` is a date or the literal `never`; `never` is a **fact** and its
|
|
212
|
+
count has no floor, no direction and never a target.
|
|
213
|
+
2. **The ladder walk ran** ([`audit.md`](audit.md)) — every REQ's rungs checked
|
|
209
214
|
bottom-up, findings ordered by seam, absences turned into REQ rows **before**
|
|
210
215
|
the table was written, and the two pass counts recorded.
|
|
211
|
-
|
|
216
|
+
3. **Every check this gate leans on has been seen failing** at least once against a
|
|
212
217
|
planted defect (`audit.md` → *Exit criterion*; the procedure, with the commands,
|
|
213
218
|
is [`gates.md`](gates.md) → *Probing*). An unproven check's green is not
|
|
214
219
|
evidence. That includes **the documentation gate** the project's doc map names
|
|
@@ -216,12 +221,12 @@ All of:
|
|
|
216
221
|
is *proven*, and its **ratchet counts are printed beside this verdict**. A
|
|
217
222
|
documentation gate is the easiest one in a run to inherit unproven, because it
|
|
218
223
|
was green the first time anyone looked at it.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
224
|
+
4. **Every REQ has a status** — none `unknown`, none blank.
|
|
225
|
+
5. **Every `verified` carries evidence** of the kind above.
|
|
226
|
+
6. **Every `partial` names what's missing** and where it's tracked.
|
|
227
|
+
7. **Every `deferred` / `dropped` has the operator's agreement** recorded (in the
|
|
223
228
|
ledger or here) and, for `deferred`, a tracker entry.
|
|
224
|
-
|
|
229
|
+
8. **No carry-over row is left `unresolved`** — every one has a home, and the
|
|
225
230
|
ledger's counts are printed with this verdict, not just filed.
|
|
226
231
|
7a. **Both disclosures are printed** ([`gates.md`](gates.md) → *Disclosures*):
|
|
227
232
|
`abstained` — every REQ closing `partial`, every `unknown`, every ⚠️ *cannot verify
|
|
@@ -230,11 +235,11 @@ All of:
|
|
|
230
235
|
a movement either way wants one sentence. A run reporting `abstained: 0` is claiming
|
|
231
236
|
it knew everything, which is a stronger statement than any run this stage has ever
|
|
232
237
|
seen close honestly.
|
|
233
|
-
|
|
238
|
+
9. **Every repository is closed, the parent included** — `git submodule status`
|
|
234
239
|
shows no `+`, and each repo is clean and pushed. A submodule is finished when
|
|
235
240
|
its parent points at it.
|
|
236
|
-
|
|
237
|
-
|
|
241
|
+
10. **The operator answers the closing question** and signs off.
|
|
242
|
+
11. **The retrospective is written** ([`retrospective.md`](retrospective.md)) — **in
|
|
238
243
|
order**: the run is stamped with its commit first, **then** the prune runs before
|
|
239
244
|
anything is added (standing instructions checked against their retirement triggers,
|
|
240
245
|
the list at or under its cap of ten, every deletion logged), **then** a run that
|
|
@@ -25,6 +25,8 @@ docs/
|
|
|
25
25
|
NNNN-<slug>.md # the OTHER permitted decision home — one project uses ONE
|
|
26
26
|
superpowers/
|
|
27
27
|
retro.md # stage 10's last act — ONE per project, not per run
|
|
28
|
+
backlog.md # the work-list BETWEEN runs — read at 0, resolved at 10
|
|
29
|
+
verification.md # one row per shipped REQ; `Human` is a date or `never`
|
|
28
30
|
retro/YYYY-QN.md # the archive: rotated entries + retirements, queried not read
|
|
29
31
|
specs/
|
|
30
32
|
YYYY-MM-DD-<topic>-brief.md # stage 0 — locked intake brief (grill output)
|
|
@@ -76,7 +78,7 @@ whatever the context happens to hold.
|
|
|
76
78
|
|
|
77
79
|
| Stage | Reads | From where |
|
|
78
80
|
|---|---|---|
|
|
79
|
-
| **0 Harvest** | the project's own knowledge about this task | code · the code graph (`graphify-out/`) · `CLAUDE.md`/`AGENTS.md` · `CONTEXT.md`/`docs/adr/` · `docs/` + `docs/ux/` · past briefs and carry-over ledgers · the retro's standing instructions **in full** · the wiki · any doc repo or hosted system the project names |
|
|
81
|
+
| **0 Harvest** | the project's own knowledge about this task | code · the code graph (`graphify-out/`) · `CLAUDE.md`/`AGENTS.md` · `CONTEXT.md`/`docs/adr/` · `docs/` + `docs/ux/` · past briefs and carry-over ledgers · **the board** (`docs/superpowers/backlog.md`, open count quoted in the brief) · **the verification ledger** (`docs/superpowers/verification.md`, how many rows sit at `never`) · the retro's standing instructions **in full** · the wiki · any doc repo or hosted system the project names |
|
|
80
82
|
| **0 Inventory (1b)** | the documentation regime | `docs/DOCMAP.md` — registers, single homes, propagation matrix, gate commands, ratchet floors. Absent ⇒ seeded ([`adoption.md`](adoption.md)) |
|
|
81
83
|
| **0 Reconcile (1c)** | intent vs as-built | git (how it *should* be) against the run record (how it *turned out*) |
|
|
82
84
|
| **0 Grill** | the operator | the interview — every answer checked against the harvest, which is what makes it checkable rather than confident |
|
|
@@ -100,6 +102,8 @@ that has not read them is running the pipeline's defaults, not this project's.
|
|
|
100
102
|
|---|---|---|---|
|
|
101
103
|
| `CLAUDE.md` / `AGENTS.md` | commands, deploy path, house rules, which docs exist and where | 0 | 6–10 |
|
|
102
104
|
| `docs/DOCMAP.md` | the decision home, each fact's single home, the propagation matrix, the gate and its ratchet floors | 0 (1b) | 9 |
|
|
105
|
+
| `docs/superpowers/verification.md` | one row per shipped REQ, and the one column a machine may not fill: the date a **human** confirmed it, or `never` ([`verification.md`](verification.md)) | 0 | written at 8, required at 10 |
|
|
106
|
+
| `docs/superpowers/backlog.md` | the project's work-list **between** runs — ids, the three priority inputs, state. Mutable; rows leave only into its *Closed* list ([`backlog.md`](backlog.md)) | 0 | re-derived at every iteration's end; resolved at 10 |
|
|
103
107
|
| `docs/superpowers/retro.md` | standing instructions — the rules no check can decide. Capped at ten, **read in full**, stamped the moment one fires | 0 | pruned at 10 |
|
|
104
108
|
| `specs/<topic>-brief.md` → *Autonomy* | every pre-resolved decision; stages 1→10 **answer from it instead of asking** | 0 | 1–10 |
|
|
105
109
|
| `specs/<topic>-carryover.md` | everything deferred, parked or half-done; appended the moment it is said | all | read in full at 10 |
|
|
@@ -124,6 +128,8 @@ them is a finding, not a tie-break ([`knowledge-sources.md`](knowledge-sources.m
|
|
|
124
128
|
| 0 Inventory | `docs/DOCMAP.md` + the registers + `scripts/check-docs.sh` — seeded **only when absent**, and the seeding is the register's first entry ([`documentation.md`](documentation.md)) | every later stage; **stage 9** walks the matrix, **stage 10** proves the gate |
|
|
125
129
|
| 0 Grill (domain) | `CONTEXT.md`, `docs/adr/NNNN-<slug>.md` — created **lazily**, only when a term resolves or a decision qualifies. Where `docs/adr/` **is** the register, entries carry the register's field set | stages 2–4 + the repo |
|
|
126
130
|
| any stage | a register entry per settled thing, via the **Doc Loop** — recorded, resolved, propagated, committed with its id | the next run's harvest |
|
|
131
|
+
| 8 Verification row | `docs/superpowers/verification.md` — one row per REQ the run shipped, written right after the deploy verification; `Human` starts at `never` ([`verification.md`](verification.md)) | stage 10 requires it; stage 0 of every later run reads it |
|
|
132
|
+
| 10 Board resolution | `docs/superpowers/backlog.md` — every unresolved ledger row — homed `backlog` or still `open` — arrives with a real id, and the ledger row is updated to name it; priority re-derived ([`backlog.md`](backlog.md)) | the next run's harvest, and every loop iteration |
|
|
127
133
|
| 10 Retro rotation | `docs/superpowers/retro/YYYY-QN.md` — entries older than five stamps, plus every retirement, each with its commit | queried by a later run's harvest |
|
|
128
134
|
| 2 Decompose | `specs/<topic>-modules.md` — module map, build order, contracts, per-module status (platforms only) | stages 3–10, every module's run |
|
|
129
135
|
| 3 Spec | `specs/<topic>-design.md` — module dossier for a decomposed platform (+ links `docs/ux/*` for UI) | stage 4 |
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# The board — the work-list that outlives a run
|
|
2
|
+
|
|
3
|
+
**One job: give the thing every loop already talks about a file to be.**
|
|
4
|
+
[`continuity.md`](continuity.md) says each iteration must re-measure the work-list, and
|
|
5
|
+
that *"next up is X"* at the end of an iteration is a claim about the board that no
|
|
6
|
+
gate reads. Until this file existed, there was no board — the claim had nothing to be
|
|
7
|
+
checked against.
|
|
8
|
+
|
|
9
|
+
**Boundary, so this does not become a second ledger.** The carry-over ledger
|
|
10
|
+
([`templates/carryover.md`](../templates/carryover.md)) records what **one run**
|
|
11
|
+
deferred and closes at that run's stage 10. The board is the **project's queue**: it
|
|
12
|
+
outlives runs, it is re-prioritised, and rows leave it only by closing. They meet at
|
|
13
|
+
exactly one seam, and that seam already existed as a dangling pointer.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Contents
|
|
18
|
+
|
|
19
|
+
- The seam the ledger left open
|
|
20
|
+
- Seeded or picked up
|
|
21
|
+
- Priority is computed, not assigned
|
|
22
|
+
- What a loop iteration does with it
|
|
23
|
+
- Rationalizations
|
|
24
|
+
|
|
25
|
+
## The seam the ledger left open
|
|
26
|
+
|
|
27
|
+
The ledger's last column is *Where it lives now*, and one of its legal values is
|
|
28
|
+
`backlog` — a place the pipeline named and did not own. So the honest reading of a
|
|
29
|
+
finished run was: *"deferred, and filed somewhere nobody here can point at."*
|
|
30
|
+
|
|
31
|
+
**Stage 10 resolves it, on three triggers.** A row is unresolved if its home reads
|
|
32
|
+
`backlog` — the value that pointed nowhere — or `open`, which is what the rows in this
|
|
33
|
+
repository actually said, or `unresolved`, which
|
|
34
|
+
[`templates/carryover.md`](../templates/carryover.md) calls the canonical not-done value
|
|
35
|
+
and says outright blocks this gate. Each of the three was, at some point, described in
|
|
36
|
+
the doctrine and absent from the check; a reader found each by seeding the shape and
|
|
37
|
+
watching it pass. **The trigger list is the one part of this file that must be read
|
|
38
|
+
against the code, not beside it.**
|
|
39
|
+
|
|
40
|
+
- every unresolved ledger row has a board id, and that id exists on the board;
|
|
41
|
+
- every board row sourced from a ledger names the ledger row it came from.
|
|
42
|
+
|
|
43
|
+
One direction alone is not enough, and this repository has a rule about that
|
|
44
|
+
([`learned.md`](learned.md) rule 2): a ledger row pointing at a board id that was never
|
|
45
|
+
created and a board row invented with no source are **different failures**, and only a
|
|
46
|
+
pass in each direction finds both.
|
|
47
|
+
|
|
48
|
+
## Seeded or picked up
|
|
49
|
+
|
|
50
|
+
Stage 0's harvest reads `docs/superpowers/backlog.md` when it exists — it is a source
|
|
51
|
+
in the ledger like any other, and its **open count is quoted in the brief**, because a
|
|
52
|
+
run that begins without knowing what is already queued will cheerfully re-discover it.
|
|
53
|
+
|
|
54
|
+
When the file is absent, stage 0 seeds it from
|
|
55
|
+
[`templates/backlog.md`](../templates/backlog.md) and says so in the brief. Seeding is
|
|
56
|
+
not a decision that needs asking: an empty board and no board are the same thing to
|
|
57
|
+
work on, and only one of them can be appended to.
|
|
58
|
+
|
|
59
|
+
**A picked-up board is re-measured, not recalled.** Its open count comes from a command
|
|
60
|
+
at the top of the run, not from what the last run's report said — the previous run is
|
|
61
|
+
precisely what invalidated that number ([`learned.md`](learned.md) rule 16).
|
|
62
|
+
|
|
63
|
+
## Priority is computed, not assigned
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
prio = sev × blast + age_bonus sev, blast ∈ 1..3
|
|
67
|
+
age_bonus = 1 past 14 days, 2 past 30
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**The inputs live in the row and the formula lives here**, so a ranking can be checked
|
|
71
|
+
rather than trusted. That is the whole reason the number is built this way: a
|
|
72
|
+
hand-assigned priority is an opinion wearing a number's clothes, and the one thing
|
|
73
|
+
nobody can audit is the number that was simply typed.
|
|
74
|
+
|
|
75
|
+
Two consequences worth stating, because both are the point:
|
|
76
|
+
|
|
77
|
+
- **An old small thing eventually outranks a new medium thing.** That is deliberate. A
|
|
78
|
+
row that has sat for a month is a row the queue has been lying about.
|
|
79
|
+
- **A row's priority changes without anyone touching it**, because age moves. The
|
|
80
|
+
re-derivation at the end of an iteration is therefore not busywork — it is the only
|
|
81
|
+
moment the board stops being stale.
|
|
82
|
+
|
|
83
|
+
`sev` and `blast` are judgement, and they are written down *as* judgement: two small
|
|
84
|
+
integers a reader can disagree with, rather than a ranking they can only accept.
|
|
85
|
+
|
|
86
|
+
## What a loop iteration does with it
|
|
87
|
+
|
|
88
|
+
At the **top** of an iteration, one command: count the open rows and read the top few.
|
|
89
|
+
At the **bottom**, re-derive `age` and `prio`, apply anything the iteration itself
|
|
90
|
+
added, and take the highest-priority row.
|
|
91
|
+
|
|
92
|
+
**A row added mid-iteration may outrank the row being worked on.** That is the case the
|
|
93
|
+
board exists for, and it is not a reason to abandon the current item: finish the item at
|
|
94
|
+
hand to its gate — `continuity.md` defines an iteration as *one item taken to its gate*
|
|
95
|
+
— then take the new top. Switching mid-item is how a loop ends with three half-finished
|
|
96
|
+
things and no gate passed on any of them.
|
|
97
|
+
|
|
98
|
+
**The report cites the file.** *"Next up: B-014"* is checkable; *"next up: the export
|
|
99
|
+
fix"* is not, and it is the one sentence in an iteration that no gate reads.
|
|
100
|
+
|
|
101
|
+
## Rationalizations
|
|
102
|
+
|
|
103
|
+
| The excuse | What is actually true |
|
|
104
|
+
|---|---|
|
|
105
|
+
| "The tracker is the backlog, this duplicates it" | Then the `Home` column carries the tracker id and this file is an index with the priority inputs visible. What it replaces is nothing; what it adds is a board an agent can read at 3am without credentials. |
|
|
106
|
+
| "I'll re-prioritise when it matters" | Age moves on its own. A board re-prioritised only when someone remembers is ranked by when they last remembered. |
|
|
107
|
+
| "The row is obvious, it doesn't need a source" | Six weeks later nobody can tell a finding from a passing thought, and the row is either done twice or dropped by whoever trusts it least. |
|
|
108
|
+
| "Priority is a judgement call, a formula can't capture it" | The formula does not replace the judgement — it *exposes* it. `sev` and `blast` are exactly where the judgement lives, and writing them down is what lets somebody argue with it. |
|
|
109
|
+
| "I'll drop the row, it's not worth a line in Closed" | Then the next run re-discovers it, re-decides it, and the decision is made twice by people who never met. A closed row costs one line. |
|
|
@@ -54,6 +54,8 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
54
54
|
| Loop detection and its caps | `references/loop-guard.md` |
|
|
55
55
|
| **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
|
|
56
56
|
| **The context budget** — the evidence rule and what a flush actually updates | `references/continuity.md` |
|
|
57
|
+
| **The board** — the work-list between runs, its computed priority, and the ledger seam it resolves | `references/backlog.md` |
|
|
58
|
+
| **The verification ledger** — what shipped, and whether a human ever confirmed it | `references/verification.md` |
|
|
57
59
|
| The retro: prune, cap, commits, archive | `references/retrospective.md` |
|
|
58
60
|
| Rules earned by failure | `references/learned.md` |
|
|
59
61
|
| **The routing default and its boundary** | `templates/routing-rule.md` |
|
|
@@ -173,6 +173,10 @@ never that the work was skipped quietly.
|
|
|
173
173
|
seeded, the model decision is recorded, and the operator confirms the brief. Stop when a
|
|
174
174
|
re-scan surfaces no new branches (don't grill past diminishing returns;
|
|
175
175
|
reversible calls can be deferred with a note). Only then start stage 1.
|
|
176
|
+
- **The verification ledger is read.** `docs/superpowers/verification.md` — the harvest
|
|
177
|
+
quotes **how many rows sit at `never`**, because that is the project's standing
|
|
178
|
+
exposure and stage 0 is where it is cheapest to look ([`verification.md`](verification.md)).
|
|
179
|
+
- **The board is read, or seeded.** `docs/superpowers/backlog.md` ([`backlog.md`](backlog.md)) — its **open count is quoted in the brief**, measured by a command at the top of the run rather than inherited from the last run's report. Absent ⇒ seeded from the template and said so; an empty board and no board are the same thing to work on, and only one of them can be appended to.
|
|
176
180
|
|
|
177
181
|
## 1 — Docs study
|
|
178
182
|
- **Freedom: medium** — which sources to fetch is judgement; grounding contracts on fetched docs is not ([`gates.md`](gates.md) → *Axis C*).
|
|
@@ -392,6 +396,12 @@ never that the work was skipped quietly.
|
|
|
392
396
|
steps — never silent success. **The CI verdict is one of the reported facts, with
|
|
393
397
|
its run id** — "CI is green" written without a command behind it prints the same
|
|
394
398
|
whether it looked or not ([`gates.md`](gates.md) → *False success*).
|
|
399
|
+
- **Write the verification row.** One line per REQ this run shipped, into
|
|
400
|
+
`docs/superpowers/verification.md` ([`verification.md`](verification.md)) — the run,
|
|
401
|
+
the tag or commit it went out in, what the gate said, and `Human: never` unless the
|
|
402
|
+
operator confirmed during the run. The verification above already happened; this is
|
|
403
|
+
the only step that makes it answerable **later**, and `never` is a fact rather than a
|
|
404
|
+
failure — the count has no floor and may never be given a target.
|
|
395
405
|
|
|
396
406
|
## 9 — Docs + wiki
|
|
397
407
|
- **Freedom: low** — the matrix walk and the gate are mechanical; what a doc says is not this stage's call ([`gates.md`](gates.md) → *Axis C*).
|
|
@@ -453,7 +463,19 @@ never that the work was skipped quietly.
|
|
|
453
463
|
## 10 — Acceptance
|
|
454
464
|
- **Freedom: medium** — the walk and the evidence rule are fixed; whether it is what was asked for is the operator's ([`gates.md`](gates.md) → *Axis C*).
|
|
455
465
|
- **What:** the closing stage — go back to the brief and account for **every**
|
|
456
|
-
requirement. Doctrine: [`acceptance.md`](acceptance.md).
|
|
466
|
+
requirement. Doctrine: [`acceptance.md`](acceptance.md).
|
|
467
|
+
- **Every REQ this run shipped has a verification row, and every row names a REQ some
|
|
468
|
+
brief carries.** Both directions: a shipped feature that entered no ledger and a
|
|
469
|
+
ledger row about nothing are different failures ([`verification.md`](verification.md)).
|
|
470
|
+
- **The ledger's open rows are resolved onto the board.** Every carry-over row still
|
|
471
|
+
`open` leaves with a `B-NNN` id on `docs/superpowers/backlog.md`, and the ledger row
|
|
472
|
+
is updated to name it ([`backlog.md`](backlog.md)). Both directions, because they are
|
|
473
|
+
different failures: a ledger row pointing at an id nobody issued, and a board row
|
|
474
|
+
traceable to nothing. Measured before this was built: across the ledgers in
|
|
475
|
+
this repository, **twenty-four rows sat `open` with no home at all** — deferred out
|
|
476
|
+
loud and filed nowhere. The first count said sixteen across six ledgers; it read the
|
|
477
|
+
status column by position and was wrong wherever a ledger carried two of them. Then the board's priority is re-derived, because `age` moved while the
|
|
478
|
+
run was happening. Every earlier gate asks
|
|
457
479
|
"is this artifact good?"; none asks "does this still contain everything that was
|
|
458
480
|
asked for?" The loss happens on the seams between stages, and this is where it
|
|
459
481
|
surfaces.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# The verification ledger — the column a machine may not fill
|
|
2
|
+
|
|
3
|
+
**One job: record whether a human ever looked at what shipped, and when.**
|
|
4
|
+
|
|
5
|
+
Stage 8 already performs the verification trio, reads the CI verdict and opens the
|
|
6
|
+
rendered page ([`stages.md`](stages.md) → *8 — Post-deploy*). All of it is **per run**,
|
|
7
|
+
and none of it accumulates. Ask a project *"which features has nobody confirmed since
|
|
8
|
+
they shipped?"* and before this file the honest answer was: nobody knows, and no
|
|
9
|
+
artifact could be consulted.
|
|
10
|
+
|
|
11
|
+
**Boundary, so this is not a second coverage table.**
|
|
12
|
+
[`acceptance.md`](acceptance.md)'s table says *an automated check passed at the moment of
|
|
13
|
+
the run*. Three things it does not say, and each is why this file exists:
|
|
14
|
+
|
|
15
|
+
- whether anybody **looked** after it shipped;
|
|
16
|
+
- whether it still works N releases later;
|
|
17
|
+
- anything at all about previous runs — it is per-run and dies with its run.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Contents
|
|
22
|
+
|
|
23
|
+
- Why it keys to the brief, not to the coverage table
|
|
24
|
+
- `never` is a fact
|
|
25
|
+
- What stage 8 writes and what stage 10 refuses
|
|
26
|
+
- Rationalizations
|
|
27
|
+
|
|
28
|
+
## Why it keys to the brief, not to the coverage table
|
|
29
|
+
|
|
30
|
+
The obvious spine is the coverage table — it already carries one row per REQ with a
|
|
31
|
+
verdict. Measured before building on it: **ten acceptance files in this repository, and
|
|
32
|
+
the first REQ-bearing table differs in nearly every one.** Ladder walks and coverage
|
|
33
|
+
tables share a file with different columns, because `acceptance.md` fixes the shape in
|
|
34
|
+
prose and prose does not hold a shape across ten runs.
|
|
35
|
+
|
|
36
|
+
The brief's REQ table does: **eight of nine briefs here carry machine-readable
|
|
37
|
+
`| REQ-NNN |` rows**, and the ninth was fixed the day this was measured. So the ledger
|
|
38
|
+
keys to the brief, and the coverage table remains what it always was — the run's own
|
|
39
|
+
verdict, quoted into the `Auto` column and never re-derived.
|
|
40
|
+
|
|
41
|
+
That the coverage table has no template and has already drifted is a real finding with a
|
|
42
|
+
real cost, and it is on the board rather than fixed here: a run that widens its own scope
|
|
43
|
+
to fix everything it touches finishes nothing.
|
|
44
|
+
|
|
45
|
+
## `never` is a fact
|
|
46
|
+
|
|
47
|
+
A `never` is not a defect, not a debt, and **not a number to drive down**. It is what is
|
|
48
|
+
true about the world, written where somebody can act on it.
|
|
49
|
+
|
|
50
|
+
The moment `never` becomes a thing to avoid writing, the column stops describing
|
|
51
|
+
reality — and this is the pipeline's only signal about the world outside its own checks.
|
|
52
|
+
So the count has **no floor, no direction, and may never be given a target**, exactly
|
|
53
|
+
like the disclosures in [`gates.md`](gates.md). A project with forty `never` rows is not
|
|
54
|
+
failing; it is a project that now knows something it could not previously ask.
|
|
55
|
+
|
|
56
|
+
## What stage 8 writes and what stage 10 refuses
|
|
57
|
+
|
|
58
|
+
**A coverage verdict of `review` becomes `none`.** *No check can decide this* is not
|
|
59
|
+
a pass; `Auto` records what a machine established, and there the honest answer is
|
|
60
|
+
nothing. The first seed wrote `pass` for four such rows — in the file whose whole
|
|
61
|
+
purpose is not to do that.
|
|
62
|
+
|
|
63
|
+
**Stage 8** writes one row per REQ the run shipped, right after the verification it
|
|
64
|
+
already does. `Human` starts at `never` unless the operator confirmed during the run.
|
|
65
|
+
|
|
66
|
+
**A REQ that spans two modules is stamped with the second, not the first.** Its criterion
|
|
67
|
+
is satisfied when the last part of it exists, and stamping the earlier release claims a
|
|
68
|
+
capability the project did not yet have. Caught by a reader on the first ledger this
|
|
69
|
+
skill ever seeded: one row said a file was named in the maps a release before that file
|
|
70
|
+
existed, and the row directly below it said when the file arrived. Two rows of one
|
|
71
|
+
table, disagreeing about the same date.
|
|
72
|
+
|
|
73
|
+
**Stage 10** refuses a REQ that shipped and has no row — and, in the other direction, a
|
|
74
|
+
row whose REQ appears in no brief. They are different failures: a shipped feature that
|
|
75
|
+
entered no ledger, and a ledger row about nothing. One direction alone finds one of them
|
|
76
|
+
([`learned.md`](learned.md) rule 2).
|
|
77
|
+
|
|
78
|
+
**Nothing else writes here.** Not a script, not the release job, and not stage 10 — a
|
|
79
|
+
file that several stages may write is a file whose rows nobody owns.
|
|
80
|
+
|
|
81
|
+
## Rationalizations
|
|
82
|
+
|
|
83
|
+
| The excuse | What is actually true |
|
|
84
|
+
|---|---|
|
|
85
|
+
| "The tests passed, that *is* verification" | The tests passed *at the moment of the run*, against the checks somebody thought to write. This column is about the world, and the world is where the checks were not looking. |
|
|
86
|
+
| "I'll fill `Human` in when I get to it" | Then the row says `never`, which is exactly correct until you do. The file is not asking you to lie faster. |
|
|
87
|
+
| "Forty `never` rows looks terrible" | It looks like what it is. The alternative is forty unverified features and no way to name them, which looked fine right up until it didn't. |
|
|
88
|
+
| "Stage 10 can fill it — it runs after the deploy" | Stage 10 is a machine. The single thing this column means is *a person looked*, and a machine writing it deletes the only information in the file. |
|
|
89
|
+
| "We tag rarely, so `Shipped in` is awkward" | Then it carries the commit, and every row of that run carries the same one. What it may not carry is nothing. |
|
|
@@ -11,6 +11,8 @@ from `super-ux`.
|
|
|
11
11
|
|---|---|---|
|
|
12
12
|
| `brief.md` | `docs/superpowers/specs/YYYY-MM-DD-<topic>-brief.md` | 0 — intake grill |
|
|
13
13
|
| `carryover.md` | `docs/superpowers/specs/YYYY-MM-DD-<topic>-carryover.md` | 0 seeds, all stages append, 10 reads |
|
|
14
|
+
| `verification.md` | `docs/superpowers/verification.md` | 8 writes a row per shipped REQ, 10 requires it, a human fills `Human` |
|
|
15
|
+
| `backlog.md` | `docs/superpowers/backlog.md` | 0 seeds when absent, any stage appends, 10 resolves and re-derives |
|
|
14
16
|
| `context.md` | `CONTEXT.md` at the repo root (or per context) | 0 — grill, domain awareness |
|
|
15
17
|
| `adr.md` | `docs/adr/NNNN-<slug>.md` | 0 — grill, hard-to-reverse decisions |
|
|
16
18
|
| `docmap.md` | `docs/DOCMAP.md` — **one per project** | 0 — the documentation inventory |
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Backlog — <project>
|
|
2
|
+
|
|
3
|
+
> **The board.** One per project, at `docs/superpowers/backlog.md`. Unlike the
|
|
4
|
+
> carry-over ledger, this file is **mutable**: priority is re-derived, state changes,
|
|
5
|
+
> rows close. What may never happen silently is a row *disappearing* — a closed row is
|
|
6
|
+
> marked closed, with the commit that closed it.
|
|
7
|
+
>
|
|
8
|
+
> **This is the file a loop iteration reads at the top and re-prioritises at the
|
|
9
|
+
> bottom.** `continuity.md` requires the work-list to be re-measured every iteration;
|
|
10
|
+
> this is the list.
|
|
11
|
+
|
|
12
|
+
| id | What | Source | Size | Sev | Blast | Age | Prio | State | Home |
|
|
13
|
+
|---|---|---|---|---|---|---|---|---|---|
|
|
14
|
+
| B-001 | `export.ts` has no size guard on the write path | `2026-07-28-export` / 5 Review | S | 2 | 1 | 12 | **2** | open | — |
|
|
15
|
+
| B-002 | XLSX export path | `2026-07-28-export` / 5 Dev | M | 1 | 2 | 12 | 2 | open | LIN-483 |
|
|
16
|
+
| B-003 | REQ-007 bulk export | `2026-07-28-export` / 2 Brainstorm | L | 1 | 1 | 12 | 1 | dropped | operator 2026-07-28 |
|
|
17
|
+
|
|
18
|
+
## Columns
|
|
19
|
+
|
|
20
|
+
- **id** — `B-NNN`, issued in order, **never reused and never closed up**. A gap is
|
|
21
|
+
evidence a row left; the *Closed* section below says which and why.
|
|
22
|
+
- **What** — the concrete thing. *"Error handling"* is not a row; *"`export.ts`
|
|
23
|
+
swallows a failed write instead of surfacing it"* is. Same bar as the ledger.
|
|
24
|
+
- **Source** — the run and stage that surfaced it, so a reader can find the context
|
|
25
|
+
without asking. A row with no source is a wish somebody typed.
|
|
26
|
+
- **Size** — `S` / `M` / `L`. Not hours: an estimate in hours is a number that will be
|
|
27
|
+
quoted back as a commitment.
|
|
28
|
+
- **Sev**, **Blast**, **Age** — the three inputs to priority, each stated so the
|
|
29
|
+
priority can be recomputed by anyone. `Sev` 1–3 (annoyance / wrong behaviour /
|
|
30
|
+
data-or-money). `Blast` 1–3 (one file / one module / crosses a seam). `Age` in days
|
|
31
|
+
since the row was written.
|
|
32
|
+
- **Prio** — **computed, never assigned**: `Sev × Blast + age_bonus`, where
|
|
33
|
+
`age_bonus` is `1` past 14 days and `2` past 30. The formula is repeated here on
|
|
34
|
+
purpose — the inputs are in this table, so a reader checks the arithmetic rather than
|
|
35
|
+
trusting the ranking. Full doctrine: the skill's `references/backlog.md`.
|
|
36
|
+
- **State** — `open` · `in-flight` · `closed` · `dropped`. `dropped` needs the
|
|
37
|
+
operator's agreement and the date they gave it.
|
|
38
|
+
- **Home** — an issue id where a tracker exists, `—` where this file *is* the tracker.
|
|
39
|
+
|
|
40
|
+
## Closed
|
|
41
|
+
|
|
42
|
+
Rows leave the table above only into this list, one line each, with the commit.
|
|
43
|
+
|
|
44
|
+
<!-- - **B-000 · What it was** — closed by `<commit>` on <date> -->
|
|
45
|
+
|
|
46
|
+
*None yet.* Stated rather than omitted: an empty list and a missing list look the same
|
|
47
|
+
from outside, and only one of them means nothing has closed.
|
|
48
|
+
|
|
49
|
+
## How rows arrive
|
|
50
|
+
|
|
51
|
+
1. **Stage 0** seeds this file when it is absent, and reads it when it is present.
|
|
52
|
+
2. **Any stage, mid-run** — the moment something is said aloud and not done. Same rule
|
|
53
|
+
as the carry-over ledger: *deferred out loud, or lost.*
|
|
54
|
+
3. **Stage 10** — every carry-over row that is unresolved arrives here with a real id,
|
|
55
|
+
and the ledger row is updated to name it. Unresolved means either home `backlog` —
|
|
56
|
+
the value that used to point nowhere — or still `open`. A row in either shape with no
|
|
57
|
+
id on this board is the dangling pointer this file exists to resolve, and the gate
|
|
58
|
+
refuses it.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
| # | Stage | What | Why it isn't done | REQ | Where it lives now |
|
|
13
13
|
|---|---|---|---|---|---|
|
|
14
14
|
| 1 | 5 Dev | XLSX export path | scope call — CSV first | REQ-004 | LIN-483 |
|
|
15
|
-
| 2 | 5 Review | `export.ts` lacks a size guard | minor, non-blocking | — |
|
|
15
|
+
| 2 | 5 Review | `export.ts` lacks a size guard | minor, non-blocking | — | `B-014` |
|
|
16
16
|
| 3 | 2 Brainstorm | REQ-007 dropped: bulk export | operator agreed 2026-07-28 | REQ-007 | dropped |
|
|
17
17
|
|
|
18
18
|
## Columns
|
|
@@ -23,10 +23,15 @@
|
|
|
23
23
|
- **Why it isn't done** — scope call, blocked, deliberate deferral, out of budget.
|
|
24
24
|
"Forgot" is a legitimate and useful answer here.
|
|
25
25
|
- **REQ** — the requirement it belongs to, or `—` if it's outside the REQ spine.
|
|
26
|
-
- **Where it lives now** — issue id,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
- **Where it lives now** — an issue id, a **board id** (`B-NNN` on
|
|
27
|
+
`docs/superpowers/backlog.md`), or `dropped` with the operator's agreement. Those are
|
|
28
|
+
the three ways a row is *settled*.
|
|
29
|
+
**Three values are not settled and all three block the stage-10 gate:** `unresolved`,
|
|
30
|
+
`open`, and a bare `backlog` — the last one because it names a place without naming a
|
|
31
|
+
row in it, which is how a deferral reads as filed while being findable by nobody.
|
|
32
|
+
Each leaves stage 10 with a real `B-NNN`, and the board row names this ledger back.
|
|
33
|
+
An item with no home is exactly the thing that gets forgotten, so acceptance refuses
|
|
34
|
+
to close on it.
|
|
30
35
|
|
|
31
36
|
## This ledger is a ratchet, not a TODO list
|
|
32
37
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Verification — <project>
|
|
2
|
+
|
|
3
|
+
> **Append-only.** One row per REQ, written by stage 8 when the change ships. Nobody
|
|
4
|
+
> edits a row except to fill `Human` — and filling it is the one thing in this
|
|
5
|
+
> repository a machine may not do.
|
|
6
|
+
>
|
|
7
|
+
> This is not a second coverage table. The coverage table says *an automated check
|
|
8
|
+
> passed at the moment of the run*. It says nothing about whether anybody **looked**
|
|
9
|
+
> after it shipped, nor whether it still works N releases later, and it dies with its
|
|
10
|
+
> run. This file is the column that outlives it.
|
|
11
|
+
|
|
12
|
+
| REQ | What | Run | Shipped in | Auto | Human | Note |
|
|
13
|
+
|---|---|---|---|---|---|---|
|
|
14
|
+
| REQ-001 | CSV export from a report | `2026-07-28-export` | v1.4.0 | pass | 2026-07-30 | opened the deployed page, exported, opened the file |
|
|
15
|
+
| REQ-004 | XLSX export | `2026-07-28-export` | v1.4.0 | pass | **never** | — |
|
|
16
|
+
| REQ-007 | Export respects active filters | `2026-07-28-export` | v1.4.0 | partial | **never** | CSV path only |
|
|
17
|
+
|
|
18
|
+
## Columns
|
|
19
|
+
|
|
20
|
+
- **REQ** — the id from the run's brief. The brief's REQ table is the spine; a row here
|
|
21
|
+
whose id is in no brief is a row about nothing.
|
|
22
|
+
- **What** — copied from the brief, not re-worded. *"Check REQ-004"* sends a human to
|
|
23
|
+
look something up; *"XLSX export"* sends them to the feature.
|
|
24
|
+
- **Run** — the brief's topic slug, so the context is one file away.
|
|
25
|
+
- **Shipped in** — the tag or commit that carried it. Where a project does not tag,
|
|
26
|
+
the commit, and the same value every row of that run carries.
|
|
27
|
+
- **Auto** — what the run's own gate said: `pass` · `partial` · `none`. Copied from the
|
|
28
|
+
coverage table rather than re-derived; where the two disagree the coverage table wins
|
|
29
|
+
and the disagreement is a finding. A coverage verdict of **`review`** — *no check can
|
|
30
|
+
decide this* — becomes `none`, because this column records what a machine established
|
|
31
|
+
and there the honest answer is *nothing*.
|
|
32
|
+
- **Human** — a date, or the literal **`never`**. Nothing else. *"soon"*, *"mostly"* and
|
|
33
|
+
*"looks fine"* are how a column stops being answerable, and this is the only column in
|
|
34
|
+
the pipeline that a machine may not fill on your behalf.
|
|
35
|
+
- **Note** — what the human actually did. *"opened the deployed page and exported"* is a
|
|
36
|
+
note; *"checked"* is not, and six weeks later nobody can tell those two apart.
|
|
37
|
+
|
|
38
|
+
## `never` is a fact, not a failure
|
|
39
|
+
|
|
40
|
+
A row sitting at `never` is not a defect and not a debt to be paid down before the next
|
|
41
|
+
release. It is **what is true**, printed where somebody can act on it. The moment
|
|
42
|
+
`never` becomes something to avoid writing, this file starts lying and the pipeline
|
|
43
|
+
loses the only signal it has about the world outside its own checks.
|
|
44
|
+
|
|
45
|
+
That is why nothing here has a floor, a target, or a direction. Count them, print them,
|
|
46
|
+
and let the number be what it is.
|
|
47
|
+
|
|
48
|
+
## How rows arrive
|
|
49
|
+
|
|
50
|
+
1. **Stage 8** writes one row per REQ the run shipped, immediately after the deploy
|
|
51
|
+
verification it already performs — `Human` starts at `never` unless the operator
|
|
52
|
+
confirmed during the run, in which case the note says what they did.
|
|
53
|
+
2. **A human, later** — fills `Human` with the date they looked, and the note with what
|
|
54
|
+
they looked at. This is the only edit any row ever receives.
|
|
55
|
+
3. **Nothing else writes here.** Not stage 10, not a script, not a release job.
|