task-pipeline-skill 1.41.0 → 1.43.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 +173 -0
- package/SKILL-CARD.md +1 -1
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +8 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +52 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +96 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +6 -1
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,178 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.43.0 — the rail said where, and nothing said what happened
|
|
4
|
+
|
|
5
|
+
A fourteen-iteration session on this repository ended each return with the same question
|
|
6
|
+
from the operator: *what did you actually do?* The rail answered **where** the run was —
|
|
7
|
+
one line, computed, correct — and nothing answered the rest. Everything else was
|
|
8
|
+
recoverable from artefacts; what a run learned by accident was recoverable from nothing.
|
|
9
|
+
|
|
10
|
+
### The hand-back
|
|
11
|
+
|
|
12
|
+
At both boundaries — an iteration's close and stage 10's — the run now writes four
|
|
13
|
+
sections and two lists:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
TASK the request as it was GIVEN, quoted from the brief
|
|
17
|
+
PROGRESS where the run stands against that request
|
|
18
|
+
DONE what was solved, each with its evidence
|
|
19
|
+
SURFACED what came up that nobody asked for
|
|
20
|
+
|
|
21
|
+
DECISIONS WAITING <n> each as a question with options, asked HERE
|
|
22
|
+
AMBIGUITIES <n> computed from four registers, with ids
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**TASK is quoted, never paraphrased** — a run that restates the request in its own words
|
|
26
|
+
after eight iterations has rewritten it, and the operator cannot see that happen.
|
|
27
|
+
**DECISIONS WAITING are asked, not parked**: a question in a report is answered days
|
|
28
|
+
later, if at all. And **AMBIGUITIES are computed**, from four registers an earlier stage
|
|
29
|
+
already wrote — open `OQ-####` rows, carry-over rows with no home, REQ rows whose check is
|
|
30
|
+
`review` rather than a command, and source-ledger rows reading *none found*. An unbounded
|
|
31
|
+
*"is anything unclear?"* becomes a ritual sentence within three runs.
|
|
32
|
+
|
|
33
|
+
**It is a gate criterion, not a good intention.** `progress.md` already carried one
|
|
34
|
+
instruction with no gate behind it — *"copy it, tick it"* — and the v1.37.0 audit found
|
|
35
|
+
that no run had ever obeyed it.
|
|
36
|
+
|
|
37
|
+
### The reader found that this release built what it had just condemned
|
|
38
|
+
|
|
39
|
+
A gate criterion with **no artefact**. Every guard read the doctrine files, so all any of
|
|
40
|
+
them could establish was that the instruction was still written down — none could
|
|
41
|
+
establish that a run obeyed it. The reader then constructed a conforming hand-back
|
|
42
|
+
concealing a weakened test and showed that **nothing in the repository would notice**,
|
|
43
|
+
and that an audit a year later could reach no verdict either way, because there would be
|
|
44
|
+
no run records to check. This file's own diagnosis of *"copy it, tick it"* — a rung-1
|
|
45
|
+
rule read as rung 3 — reproduced one level up.
|
|
46
|
+
|
|
47
|
+
**The hand-back now has an address:** a `hand:` line in the run ledger, declared as its
|
|
48
|
+
fourth shape. `grep -c '^hand:'` against `grep -c '^iter:'` is what makes a missing one
|
|
49
|
+
readable.
|
|
50
|
+
|
|
51
|
+
Six more, all verified by planting and watching `PASS`:
|
|
52
|
+
|
|
53
|
+
- **`"hand-back"` as a bare substring could not tell a requirement from a mention** — a
|
|
54
|
+
gate reading *"the hand-back is OPTIONAL and may be skipped"* passed, in the release
|
|
55
|
+
whose entire argument is that it must be a criterion. Both gate guards now require the
|
|
56
|
+
normative phrase;
|
|
57
|
+
- **the gate span was unbounded below** — the GATE is the last bullet, so a paragraph
|
|
58
|
+
after it answered for it;
|
|
59
|
+
- **the template was every fence joined**, so a worked example — the likeliest next edit
|
|
60
|
+
to that section — would have answered for the template;
|
|
61
|
+
- **the two lists were left to prose** while the four sections were read from the fence,
|
|
62
|
+
which is the split this release wrote a guard to forbid;
|
|
63
|
+
- **the AMBIGUITIES subsection could be replaced by explicit judgement** and pass, keeping
|
|
64
|
+
the four words as *examples*;
|
|
65
|
+
- and a relocated section was reported as a deletion.
|
|
66
|
+
|
|
67
|
+
**Four doctrinal defects, not guard defects:**
|
|
68
|
+
|
|
69
|
+
- *"at both boundaries"* named a pair this file defines as something else three sections
|
|
70
|
+
above — a reader resolving it there writes a hand-back at task start, where TASK is the
|
|
71
|
+
only field with content;
|
|
72
|
+
- **the four ambiguity sources had no commands**, though the section claimed *"each read
|
|
73
|
+
by a command"* — and one of them would have grepped for a string the source ledger's own
|
|
74
|
+
doctrine never writes, returning a false zero;
|
|
75
|
+
- **one register is structurally zero at the gated boundary**: stage 10's own gate already
|
|
76
|
+
forbids an unresolved carry-over row, so that count is zero because a sibling clause
|
|
77
|
+
compelled it. The section now says to print *why*;
|
|
78
|
+
- and **`acceptance.md` — the file stage 10 actually opens — never mentioned the
|
|
79
|
+
hand-back**, while carrying every other criterion. Two surfaces were updated where four
|
|
80
|
+
state this gate.
|
|
81
|
+
|
|
82
|
+
**Still true and stated rather than fixed:** `SURFACED` has no register behind it, and the
|
|
83
|
+
doctrine calls it the section that earns the hand-back. *"Nothing surfaced"* remains a
|
|
84
|
+
quiet decision. The `hand:` line records that a hand-back happened, never that it was
|
|
85
|
+
complete.
|
|
86
|
+
|
|
87
|
+
### Six predicates answered by their neighbours, all caught by their own probes
|
|
88
|
+
|
|
89
|
+
- the four section names were read from the whole section, and `SURFACED` appears in the
|
|
90
|
+
sentence explaining why SURFACED matters — so renaming the template row left the guard
|
|
91
|
+
green. It now reads the **fenced template**;
|
|
92
|
+
- `asked` appears in `SURFACED`'s own description (*"nobody **asked** for"*), so the
|
|
93
|
+
decisions check was answered by a neighbour;
|
|
94
|
+
- and the section span was narrowed to `#{2,3}` by reflex, which cut the guard off from
|
|
95
|
+
the `###` subsection holding four of the things it checks. **The span follows the
|
|
96
|
+
subject, not a house style** — v1.42.0 narrowed a different span for the opposite
|
|
97
|
+
reason.
|
|
98
|
+
|
|
99
|
+
Not one of these needed a reader. The neighbour-probe habit shipped one release earlier
|
|
100
|
+
caught all three, which is the first evidence it does what it was written for.
|
|
101
|
+
|
|
102
|
+
- Guards: 253 → **261**.
|
|
103
|
+
|
|
104
|
+
## v1.42.0 — a probe proves the phrasing its author had in mind
|
|
105
|
+
|
|
106
|
+
Six times in one session a guard was defeated by **text that was not its subject**, and
|
|
107
|
+
every one of those guards had a probe, and every probe fired. The probes and the guards
|
|
108
|
+
were written in the same hour from the same reading of the same file, so they shared the
|
|
109
|
+
blind spot rather than covering it.
|
|
110
|
+
|
|
111
|
+
| The check's subject | What answered it instead |
|
|
112
|
+
|---|---|
|
|
113
|
+
| stage 2 names the loop's arming | *"it **arms** the UX track"*, present since v1.7.0 |
|
|
114
|
+
| the section states the authorization floor | the same phrase in a Rationalizations row, and in a section from v1.11.0 |
|
|
115
|
+
| the run stamps have a cap | the **standing instructions'** `max 10` in the same cell — and, once narrowed past it, the same cap on the other side of the `·` |
|
|
116
|
+
| a section read in full stays capped | rows under one heading, while a second heading held forty more |
|
|
117
|
+
|
|
118
|
+
### The doctrine failed its own first use, and a reader caught that too
|
|
119
|
+
|
|
120
|
+
R-005's fourth consecutive reader read the three new probes against the section that
|
|
121
|
+
defines them. **`nb03` was not a neighbour probe.** It planted the needles of two
|
|
122
|
+
*retired* predicates — proving the guards that used to exist were neighbour-answerable
|
|
123
|
+
and saying nothing about the one that does. The instruction *"plant the guard's own
|
|
124
|
+
evidence"* reads as *"plant something that used to satisfy it"* unless it says **which
|
|
125
|
+
literal**, and now it does: the one the predicate matches today, read out of the guard.
|
|
126
|
+
|
|
127
|
+
Seven more, each planted and watched passing, each now replayed and failing:
|
|
128
|
+
|
|
129
|
+
- **Part 1a's precondition could be replaced by its opposite** and a housekeeping aside in
|
|
130
|
+
a `###` subsection answered for it — the reading `Default off` exists to forbid, shipping
|
|
131
|
+
behind a parenthesis;
|
|
132
|
+
- **the stage-2 guard's declared span was false.** Its comment said *"the GATE bullet and
|
|
133
|
+
nothing else"*; the GATE is the last bullet, so the split handed it everything to the
|
|
134
|
+
section end and a trailing note satisfied it;
|
|
135
|
+
- `- **GATEways to stage 3:**` was taken as the gate — no word boundary;
|
|
136
|
+
- **a decoy row about the archive answered for the live file**, because the retrospective
|
|
137
|
+
check scanned every `|` line rather than the row it names;
|
|
138
|
+
- **the scope depended on a `·`** no doctrine requires: replacing it with `, and` restored
|
|
139
|
+
the v1.41.0 defeat by punctuation;
|
|
140
|
+
- **one disjunct was dead and the live one was a literal** — the source line-wraps, so the
|
|
141
|
+
check was a false positive on any reword and a false negative on inversion;
|
|
142
|
+
- and **rekeying the stage-2 guard silently lost coverage**: deleting the whole queue
|
|
143
|
+
bullet began to pass, while its probe kept firing only because it *also* deleted the
|
|
144
|
+
gate clause. A probe whose stated claim has quietly become another probe's claim.
|
|
145
|
+
|
|
146
|
+
**A probe that only deletes is not a neighbour probe** — it may be correct, but if it
|
|
147
|
+
leans on copies already next door it must assert they are there, or a later edit demotes
|
|
148
|
+
it to a delete-only test that still passes.
|
|
149
|
+
|
|
150
|
+
### The neighbour probe
|
|
151
|
+
|
|
152
|
+
`gates.md` now asks a guard that reads a scoped span for a **second** probe, planting in
|
|
153
|
+
two places at once: break the subject, plant the guard's own evidence **next door**, and
|
|
154
|
+
require it to still fail. A guard that goes green is reading the neighbourhood, and the
|
|
155
|
+
ordinary probe cannot tell the difference — which is why it is a separate probe rather
|
|
156
|
+
than a stricter one.
|
|
157
|
+
|
|
158
|
+
Three shipped with it, one per guard that fell this way. **The third failed on its first
|
|
159
|
+
run and was right to:** a planted sentence saying *"after-decomposition remains a word in
|
|
160
|
+
the schema"* satisfied the stage-2 guard, proving it neighbour-answerable. The guard is
|
|
161
|
+
now keyed on the stage's **gate** — what it must DO — rather than on prose around it,
|
|
162
|
+
because prose above a gate can say anything.
|
|
163
|
+
|
|
164
|
+
**Positional narrowing is not scoping**, and three of the six were "fixed" that way
|
|
165
|
+
before falling again to text still inside the cut.
|
|
166
|
+
|
|
167
|
+
### Half of B-057 was already mechanised, and the row overstated it
|
|
168
|
+
|
|
169
|
+
`test/negatives.py` runs `differs_from_repo` on every planted copy, so a probe whose
|
|
170
|
+
needle no longer matches fails **loudly** rather than silently — which is what every
|
|
171
|
+
stale literal in this session actually did. The remaining half is the silent one, and it
|
|
172
|
+
is what the neighbour probe is for.
|
|
173
|
+
|
|
174
|
+
- Guards: 250 → **253**.
|
|
175
|
+
|
|
3
176
|
## v1.41.0 — one line per run is a slope, not a bound
|
|
4
177
|
|
|
5
178
|
`retro.md` is read **in full** at stage 0, and its own doctrine called both read sections
|
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.43.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` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.43.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 closes with evidence, a work board and a verification ledger that outlive a run, an exposure line naming what shipped unconfirmed, a progress rail computed from the project's own config, a loop guard whose review ceiling measures rather than stops, and stage-3 tracks for what a product does, how it sounds and how it looks. Two modes need no task: `checkup` (what is unverified) and `setup` (audit existing docs). Retro insights can publish upstream as issues, opt-in and redacted.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.43.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -273,7 +273,7 @@ capable available — see `references/model-tiering.md`).
|
|
|
273
273
|
| 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 |
|
|
274
274
|
| 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and says nothing about a 404'd bundle or a console full of errors on load (`chrome-devtools`; absent → call it an HTTP response, which is its honest name) | auto |
|
|
275
275
|
| 9 | Docs + wiki | host module docs/runbook rules → `wiki-update` ([obsidian-wiki](https://github.com/ar9av/obsidian-wiki), recommended) → `/graphify . --update` ([`references/knowledge-graph.md`](references/knowledge-graph.md), recommended) | every stale row of the stage-0 source ledger updated; **the propagation matrix walked for every change type this run produced** — the ledger names what you read, the matrix names what you owe — every settled thing recorded with an id, every answered question resolved, and **the documentation gate green with its ratchet counts printed**; docs synced; wiki synced; **the code graph refreshed where one exists** and checked against the docs (a hub no doc names, a doc naming a node the graph lost); **every number computed rather than restated, every named command or file resolvable** ([`references/learned.md`](references/learned.md)); the carry-over count printed beside the verdict | auto |
|
|
276
|
-
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) → [`references/retrospective.md`](references/retrospective.md) (retro: stamp, prune, entry) | 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; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **both disclosures printed beside the verdict** — `abstained` (what the run declined to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither with a floor, neither ever a target ([`references/gates.md`](references/gates.md) → *Disclosures*) | manual |
|
|
276
|
+
| 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) → [`references/retrospective.md`](references/retrospective.md) (retro: stamp, prune, entry) | 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; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); **the hand-back is written** — the request quoted as given, progress against it, what was solved, what surfaced unasked, waiting decisions asked here, and the ambiguity count computed ([`references/progress.md`](references/progress.md)); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **both disclosures printed beside the verdict** — `abstained` (what the run declined to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither with a floor, neither ever a target ([`references/gates.md`](references/gates.md) → *Disclosures*) | manual |
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
### Stage 10 in a project of several repositories
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
],
|
|
167
167
|
"gate": {
|
|
168
168
|
"type": "manual",
|
|
169
|
-
"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'; EVERY REPOSITORY IS CLOSED, THE PARENT INCLUDED — a submodule is finished only when its parent points at it, so 'git submodule status' shows no line starting with '+' and every repo is clean and pushed ('git -C <repo> status --porcelain' and 'git -C <repo> log @{u}..HEAD' both empty), because a parent records a submodule as a pointer to one commit and moving the submodule does not move the pointer: neither repo looks wrong alone and the disagreement survives every check that runs inside one; 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. LAST ACT, THE RETROSPECTIVE (references/retrospective.md, written to docs/superpowers/retro.md — one file per project, not per run, because every gate in this flow is good at THIS run and blind across runs): PRUNE BEFORE YOU ADD — every standing instruction checked against its three retirement triggers (it became a check; every path/command/stage it names is gone; it has not fired in the last five run stamps), the list held to its hard cap of ten (at eleven the oldest never-fired row goes — 'they all matter' is the state in which the list stopped being read), and EVERY DELETION LOGGED as one line, never silent; THEN stamp the run (date, topic, verdict, counts); 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 agent was careless' is not one), the fix by grade (mechanical check > standing instruction with its retire-when written at birth > a note that expires in two runs), and the check that catches it the first time from now on. A retro left empty after a messy run is the failure this file exists to stop, and the retro counts are printed beside this gate's verdict like the carry-over ledger's, so a list that quietly grew back is visible where it happened. EVERY LESSON CARRIES ITS COMMIT: each standing instruction has the SHA that introduced it and the SHA of the run in which it last fired, each log entry and each retirement carries one, the run stamp carries the run's own — a file:line rots at the next edit while 'git show <sha>' reconstructs the whole incident two months later — and every SHA must resolve, which the documentation gate checks with 'git rev-parse --verify'. ROTATION: entries older than the last five run stamps MOVE into docs/superpowers/retro/YYYY-QN.md, which is append-only and QUERIED rather than read, so the in-force file stays short enough to be read in full and pruning costs no knowledge. AND THE GATE ITSELF IS PROVEN: every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, with the probe recorded, and its ratchet counts are printed beside this verdict (references/gates.md)."
|
|
169
|
+
"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'; EVERY REPOSITORY IS CLOSED, THE PARENT INCLUDED — a submodule is finished only when its parent points at it, so 'git submodule status' shows no line starting with '+' and every repo is clean and pushed ('git -C <repo> status --porcelain' and 'git -C <repo> log @{u}..HEAD' both empty), because a parent records a submodule as a pointer to one commit and moving the submodule does not move the pointer: neither repo looks wrong alone and the disagreement survives every check that runs inside one; 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. LAST ACT, THE RETROSPECTIVE (references/retrospective.md, written to docs/superpowers/retro.md — one file per project, not per run, because every gate in this flow is good at THIS run and blind across runs): PRUNE BEFORE YOU ADD — every standing instruction checked against its three retirement triggers (it became a check; every path/command/stage it names is gone; it has not fired in the last five run stamps), the list held to its hard cap of ten (at eleven the oldest never-fired row goes — 'they all matter' is the state in which the list stopped being read), and EVERY DELETION LOGGED as one line, never silent; THEN stamp the run (date, topic, verdict, counts); 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 agent was careless' is not one), the fix by grade (mechanical check > standing instruction with its retire-when written at birth > a note that expires in two runs), and the check that catches it the first time from now on. A retro left empty after a messy run is the failure this file exists to stop, and the retro counts are printed beside this gate's verdict like the carry-over ledger's, so a list that quietly grew back is visible where it happened. EVERY LESSON CARRIES ITS COMMIT: each standing instruction has the SHA that introduced it and the SHA of the run in which it last fired, each log entry and each retirement carries one, the run stamp carries the run's own — a file:line rots at the next edit while 'git show <sha>' reconstructs the whole incident two months later — and every SHA must resolve, which the documentation gate checks with 'git rev-parse --verify'. ROTATION: entries older than the last five run stamps MOVE into docs/superpowers/retro/YYYY-QN.md, which is append-only and QUERIED rather than read, so the in-force file stays short enough to be read in full and pruning costs no knowledge. AND THE GATE ITSELF IS PROVEN: every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, with the probe recorded, and its ratchet counts are printed beside this verdict (references/gates.md). THE HAND-BACK IS WRITTEN — the request quoted as GIVEN, progress against it, what was solved with evidence, what surfaced unasked, every waiting decision ASKED here with options, and the ambiguity count computed from the four registers; zero prints as zero."
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
],
|
|
@@ -251,6 +251,14 @@ All of:
|
|
|
251
251
|
Manual by design. An automated check can prove the table is *well-formed*; only
|
|
252
252
|
the person who asked can confirm it is *what they asked for*. Do not let a green
|
|
253
253
|
table substitute for that answer.
|
|
254
|
+
12. **The hand-back is written** ([`progress.md`](progress.md) → *The hand-back*) —
|
|
255
|
+
the request quoted as it was GIVEN, where the run stands against it, what was solved
|
|
256
|
+
with its evidence, what surfaced that nobody asked for, every decision still waiting
|
|
257
|
+
**asked here with options rather than listed**, and the ambiguity count computed from
|
|
258
|
+
its four registers with their ids. A run that cannot say what happened has not
|
|
259
|
+
finished; it has stopped. This file is the one stage 10 opens, and it carried every
|
|
260
|
+
other criterion while omitting this one for a release.
|
|
261
|
+
|
|
254
262
|
|
|
255
263
|
## When the answer is "something's missing"
|
|
256
264
|
|
|
@@ -30,6 +30,7 @@ elsewhere and is not restated here:
|
|
|
30
30
|
- Anatomy of a project gate
|
|
31
31
|
- Writing the check itself
|
|
32
32
|
- Probing — plant, run, restore
|
|
33
|
+
- The neighbour probe — plant the evidence outside the subject
|
|
33
34
|
- The false-positive budget
|
|
34
35
|
- Ratchets
|
|
35
36
|
- Disclosures — counted like a ratchet, and deliberately not monotone
|
|
@@ -295,6 +296,57 @@ Otherwise the next reader has to redo it to know whether it was ever done.
|
|
|
295
296
|
|
|
296
297
|
---
|
|
297
298
|
|
|
299
|
+
## The neighbour probe — plant the evidence outside the subject
|
|
300
|
+
|
|
301
|
+
A probe proves a guard rejects **the phrasing its author had in mind**. That is less than
|
|
302
|
+
it looks, and the gap has one shape: **a check answered by text that is not its subject.**
|
|
303
|
+
|
|
304
|
+
Measured on one project in one session, six times, each found by a reader planting a
|
|
305
|
+
defect and watching `PASS`:
|
|
306
|
+
|
|
307
|
+
| The check's subject | The text that answered it instead |
|
|
308
|
+
|---|---|
|
|
309
|
+
| stage 2 names the loop's arming | *"it **arms** the UX track"*, present since an earlier release |
|
|
310
|
+
| the section states the authorization floor | the same phrase in a Rationalizations row, and in a section written twenty-nine releases before |
|
|
311
|
+
| the run stamps have a cap | the **standing instructions'** `max 10`, in the same table cell — and, once the check was narrowed past it, the same cap moved to the other side of the `·` |
|
|
312
|
+
| a section read in full stays capped | rows under **one** heading, while a second heading in the same file held forty more |
|
|
313
|
+
|
|
314
|
+
Every one of those guards had a probe. Every probe fired. The probes and the guards were
|
|
315
|
+
written in the same hour from the same reading, so they shared the same blind spot.
|
|
316
|
+
|
|
317
|
+
**So a guard that reads a scoped span owes a second probe, and it plants in two places at
|
|
318
|
+
once:**
|
|
319
|
+
|
|
320
|
+
1. **break the subject** — remove the thing the guard is about;
|
|
321
|
+
2. **plant the guard's own evidence next door** — in a sibling section, an adjacent table
|
|
322
|
+
cell, a rationalizations row, the other side of a separator;
|
|
323
|
+
3. require the guard to **still fail**.
|
|
324
|
+
|
|
325
|
+
A guard that passes step 3 is reading its subject. A guard that goes green is reading the
|
|
326
|
+
neighbourhood, and the ordinary probe cannot tell the difference — which is why this one
|
|
327
|
+
is separate rather than a stricter version of it.
|
|
328
|
+
|
|
329
|
+
**Step 2 means the literal the predicate matches *today*, read out of the guard.** The
|
|
330
|
+
first three neighbour probes written against this section got that wrong on their first
|
|
331
|
+
run: one planted the needles of two **retired** predicates, which proves the guards that
|
|
332
|
+
used to exist were neighbour-answerable and says nothing about the one that does. A
|
|
333
|
+
neighbour probe keyed to a needle the guard no longer reads is the same defect it was
|
|
334
|
+
written to catch, one level up.
|
|
335
|
+
|
|
336
|
+
**A probe that only deletes is not a neighbour probe.** It may still be a correct probe —
|
|
337
|
+
but if it relies on copies that already sit next door, it must **assert they are there**.
|
|
338
|
+
Otherwise a later edit removes them and the probe quietly becomes a delete-only test that
|
|
339
|
+
still passes, having stopped testing the thing it is named for.
|
|
340
|
+
|
|
341
|
+
**Positional narrowing is not scoping.** Three of the six were "fixed" by cutting the
|
|
342
|
+
search down to a row, then to everything after a phrase, and fell each time to text that
|
|
343
|
+
was still inside the cut. Scope by *what the span is about*: split to the cell, then to
|
|
344
|
+
the item, then match on flattened text so an emphasis marker cannot hide the boundary.
|
|
345
|
+
|
|
346
|
+
**And state the span in the guard.** One line above the predicate — *what it reads, and
|
|
347
|
+
where that ends*. It costs nothing and it is the only part of a check a later reader can
|
|
348
|
+
disagree with before the defect arrives.
|
|
349
|
+
|
|
298
350
|
## The false-positive budget
|
|
299
351
|
|
|
300
352
|
Run a new heuristic over the **real corpus** before shipping it and count the false
|
|
@@ -25,6 +25,7 @@ maintains them and the next run reads them as current.
|
|
|
25
25
|
- The iteration line
|
|
26
26
|
- The rail is computed, never eleven
|
|
27
27
|
- What each glyph means
|
|
28
|
+
- The hand-back — what the operator reads when you stop
|
|
28
29
|
- Every number is borrowed
|
|
29
30
|
- Absent is a word, never a zero
|
|
30
31
|
- The run ledger this reads from
|
|
@@ -119,6 +120,101 @@ the verdict the gate wrote, in the run ledger, and from nothing else.
|
|
|
119
120
|
**`⊘` may never be silent.** A skipped stage with no recorded reason is exactly what a
|
|
120
121
|
`·` looks like from outside, and the two mean opposite things.
|
|
121
122
|
|
|
123
|
+
## The hand-back — what the operator reads when you stop
|
|
124
|
+
|
|
125
|
+
The rail says **where** the run is. It does not say what happened, and a reader who was
|
|
126
|
+
away cannot reconstruct that from a glyph. Measured on this project: a fourteen-iteration
|
|
127
|
+
session where the operator returned to a one-line rail each time and had to ask.
|
|
128
|
+
|
|
129
|
+
**At the close of an iteration, and again at stage 10.** This is *not* the pair named
|
|
130
|
+
three sections above: *The two boundaries, and only those two* governs the **rail**, and
|
|
131
|
+
its pair is task start and iteration close. The hand-back shares one and adds the run's
|
|
132
|
+
end — a rail at task start has nothing to report, and a run that ends without a hand-back
|
|
133
|
+
is the case this section exists for. A reader resolving *"both boundaries"* against the
|
|
134
|
+
other section wrote one at task start, where TASK is the only field with content. The run
|
|
135
|
+
writes a hand-back with **four sections and two lists**. It is a gate criterion **at stage
|
|
136
|
+
10**, not a good intention: this file already carried one instruction with no gate behind
|
|
137
|
+
it (*"copy it, tick it"*), and the v1.37.0 audit found no run had ever obeyed it.
|
|
138
|
+
|
|
139
|
+
**The iteration-close instance has no gate, and that is a weakness rather than an
|
|
140
|
+
oversight** — an iteration boundary has no verdict to hang a criterion on. It is
|
|
141
|
+
therefore the very shape the sentence above indicts, written inside it. What keeps it
|
|
142
|
+
from being *"copy it, tick it"* is the run ledger: the iteration line already lands there,
|
|
143
|
+
and the hand-back lands beside it, so a later audit has something to read. Where a project
|
|
144
|
+
keeps no ledger, the iteration hand-back is prose discipline, and the run says which of
|
|
145
|
+
the two it is running.
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
── hand-back · <topic> · iteration <n> ───────────────────────────
|
|
149
|
+
TASK the request as it was GIVEN, quoted from the brief — not
|
|
150
|
+
as it looks now that you understand it
|
|
151
|
+
PROGRESS where the run stands against that request: gates passed,
|
|
152
|
+
what remains, and the board id it is heading for
|
|
153
|
+
DONE what was solved this iteration, each with its evidence
|
|
154
|
+
SURFACED what came up that nobody asked for — findings, corrections,
|
|
155
|
+
things that turned out to be other than assumed
|
|
156
|
+
|
|
157
|
+
DECISIONS WAITING <n> each as a question with options, asked HERE
|
|
158
|
+
AMBIGUITIES <n> computed, below
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Where there is no brief** — `checkup`, `setup`, a short path — TASK quotes the
|
|
162
|
+
operator's own sentence instead, marked as such. An unquotable TASK is a run that cannot
|
|
163
|
+
say what it was asked, which is worth its own line.
|
|
164
|
+
|
|
165
|
+
**Where it lands.** The narrative goes to the operator; the trace goes to the run
|
|
166
|
+
ledger as a `hand:` line ([`../templates/run.md`](../templates/run.md)). Without it the
|
|
167
|
+
hand-back is a gate criterion with no artefact — a reader proved that of v1.43.0's
|
|
168
|
+
first draft: every guard could check the instruction was still written, none could
|
|
169
|
+
check a run obeyed it, and an audit a year later could reach no verdict either way.
|
|
170
|
+
`grep -c '^hand:'` against `grep -c '^iter:'` is what makes the difference readable.
|
|
171
|
+
|
|
172
|
+
**TASK is quoted, never paraphrased.** A run that restates the request in its own words
|
|
173
|
+
after eight iterations has rewritten it, and the operator cannot see that happen. The
|
|
174
|
+
quote is the one line the drift shows against.
|
|
175
|
+
|
|
176
|
+
**SURFACED is the section that earns the hand-back.** Everything else is recoverable from
|
|
177
|
+
the artefacts; what a run *learned by accident* is recoverable from nothing. A run that
|
|
178
|
+
found a stale claim, corrected a number, or discovered a rule was never enforced puts it
|
|
179
|
+
here even when it was fixed in passing — especially then.
|
|
180
|
+
|
|
181
|
+
**DECISIONS WAITING are asked, not listed.** A question parked in a report is a question
|
|
182
|
+
the operator answers days later, if at all. Ask it at the boundary, with options and a
|
|
183
|
+
recommendation, in the same breath as the report. If there are none, the field prints
|
|
184
|
+
`0` — [`gates.md`](gates.md)'s rule about absence applies here too.
|
|
185
|
+
|
|
186
|
+
### AMBIGUITIES are computed from four registers the run already keeps
|
|
187
|
+
|
|
188
|
+
Not judgement, and not a prompt to think harder — an unbounded *"is anything unclear?"*
|
|
189
|
+
becomes a ritual sentence within three runs. Four sources, each read by a command:
|
|
190
|
+
|
|
191
|
+
| Source | What it means | Read by |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| open `OQ-####` rows ([`documentation.md`](documentation.md)) | a question raised and never answered | `grep -cE '^\| OQ-[0-9]+' docs/OPEN_QUESTIONS.md` — **no file prints `— no register`, never `0`** |
|
|
194
|
+
| carry-over rows whose home is unsettled | deferred into nothing ([`../templates/carryover.md`](../templates/carryover.md): `open`, `unresolved`, or a bare `backlog`) | `grep -cEi '\\|[[:space:]]*(open\\|unresolved\\|backlog)[[:space:]]*\\|' <ledger>` |
|
|
195
|
+
| REQ rows whose check is `review` rather than a command | shipped on judgement, unverifiable by a machine | the brief's REQ table, *Verified by* column. The count `spec.md` prints is **checks**, not REQ rows — different units, and quoting one for the other is a borrowed number that does not fit |
|
|
196
|
+
| source-ledger rows with **no source** | the run built on the absence of a document | the brief's ledger, rows whose *Source* cell is empty or parenthesised. `knowledge-sources.md` writes them `(none for X)` while `templates/brief.md` writes `none found`, so **a grep for either string alone returns a false zero** |
|
|
197
|
+
|
|
198
|
+
The `Read by` column is the point of the table. Without it, *"each read by a command"* is a
|
|
199
|
+
claim the section makes about itself and cannot keep — and one of the four greps would
|
|
200
|
+
have returned zero for searching a string the source ledger's own doctrine never writes.
|
|
201
|
+
|
|
202
|
+
Each prints its count **and its ids**. A count with no ids is a number nobody can act on,
|
|
203
|
+
and **zero prints as zero** — silence and "I looked and found none" are the two states
|
|
204
|
+
this file exists to keep apart.
|
|
205
|
+
|
|
206
|
+
**One of the four is structurally zero at the gated boundary.** Stage 10's own gate
|
|
207
|
+
already requires that no carry-over row is left unresolved, so there that count is zero
|
|
208
|
+
**because a sibling clause compelled it**, not because the run looked. At an iteration
|
|
209
|
+
close it is a real measurement. Print it either way, and at stage 10 print *why* it is
|
|
210
|
+
zero — a number that had no choice is not evidence.
|
|
211
|
+
|
|
212
|
+
**Why these four and not a fifth.** Every one is already written down by an earlier stage,
|
|
213
|
+
so the hand-back reports rather than re-derives, and a run cannot quietly decide that
|
|
214
|
+
nothing was unclear. Where a project keeps no open-questions register, that row prints
|
|
215
|
+
`— no register` rather than `0`: an absent register and an empty one are different facts,
|
|
216
|
+
and the second is the one worth acting on.
|
|
217
|
+
|
|
122
218
|
## Every number is borrowed
|
|
123
219
|
|
|
124
220
|
| Field | Its home |
|
|
@@ -651,7 +651,12 @@ never that the work was skipped quietly.
|
|
|
651
651
|
a messy run is the failure the file exists to stop. Stage 0 reads the standing
|
|
652
652
|
instructions in full next time, which is why the cap is not negotiable.
|
|
653
653
|
- **GATE (manual):** the ladder walk ran and its absences became REQ rows before
|
|
654
|
-
the table was written; **
|
|
654
|
+
the table was written; **the hand-back is written** — the request quoted as it was
|
|
655
|
+
GIVEN, where the run stands against it, what was solved with its evidence, what
|
|
656
|
+
surfaced that nobody asked for, every decision still waiting **asked here with
|
|
657
|
+
options rather than listed**, and the ambiguity count computed from the four
|
|
658
|
+
registers with its ids ([`progress.md`](progress.md) → *The hand-back*) — a run
|
|
659
|
+
that cannot say what happened has not finished, it has stopped; **both disclosures printed beside the verdict** — `abstained` (what the run declined
|
|
655
660
|
to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither
|
|
656
661
|
with a floor, neither ever a target ([`gates.md`](gates.md) → *Disclosures*); **the
|
|
657
662
|
retrospective is written — stamped first, then pruned, then the entry; the
|
|
@@ -13,12 +13,13 @@ Run: `<topic>` · started `<YYYY-MM-DD>` · module map: `<path or "none">`
|
|
|
13
13
|
|
|
14
14
|
## Lines
|
|
15
15
|
|
|
16
|
-
Append-only.
|
|
16
|
+
Append-only. Four shapes, and nothing else belongs here:
|
|
17
17
|
|
|
18
18
|
```
|
|
19
19
|
stage: <id> <name> — gate <auto|manual> — verdict <pass|fail|skip> — <ISO-8601>
|
|
20
20
|
iter: <N> — item <B-NNN or task id> — closed at gate <stage id>
|
|
21
21
|
touch: <file> — pass <N> (<stage|round|module>) — reason: <finding id / gate item>
|
|
22
|
+
hand: <N|10> — task "<quoted>" — done <n> — surfaced <n> — decisions <n> — amb <n> (<ids or "— no register">)
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
- **`stage:`** — written when a gate **returns**, not when the stage is entered. The
|
|
@@ -26,6 +27,14 @@ touch: <file> — pass <N> (<stage|round|module>) — reason: <finding id / gate
|
|
|
26
27
|
is a summary that is confidently wrong exactly when it matters.
|
|
27
28
|
- **`iter:`** — one line per iteration closed. The progress line's counter is
|
|
28
29
|
`grep -c '^iter:'`, never a number anyone remembers.
|
|
30
|
+
- **`hand:`** — one per hand-back, at an iteration's close and at stage 10
|
|
31
|
+
(`references/progress.md` → *The hand-back*, inside the skill). The
|
|
32
|
+
narrative goes to the operator; **this line is the trace it leaves**, and it exists
|
|
33
|
+
because v1.43.0 shipped a gate criterion with no artefact behind it: every guard could
|
|
34
|
+
check that the instruction was still written, and none could check that a run obeyed
|
|
35
|
+
it. A later audit reads `grep -c '^hand:'` against `grep -c '^iter:'` and the two
|
|
36
|
+
should agree, plus one for stage 10.
|
|
37
|
+
**`amb` prints its ids or `— no register`, never a bare `0` with nothing beside it.**
|
|
29
38
|
- **`touch:`** — one line per file per pass, and the reason names **what forced the
|
|
30
39
|
edit**: a finding id, a failed gate item, an operator instruction. *"Cleanup"*,
|
|
31
40
|
*"polish"* and *"while I was there"* are not reasons; they are churn with better
|
|
@@ -43,6 +52,7 @@ stage: 1 Docs study — gate auto — verdict pass — 2026-08-10T11:31Z
|
|
|
43
52
|
touch: src/export.ts — pass 1 (stage 5) — reason: TASK-3
|
|
44
53
|
touch: src/export.ts — pass 2 (stage 5) — reason: F-014
|
|
45
54
|
touch: src/export.ts — pass 3 (stage 5) — reason: F-014
|
|
55
|
+
hand: 3 — task "add CSV export to the orders table" — done 2 — surfaced 1 — decisions 1 — amb 2 (OQ-0007, ledger row 4)
|
|
46
56
|
```
|
|
47
57
|
|
|
48
58
|
The last two lines are a **trip**: the same file, two consecutive passes, the same
|