task-pipeline-skill 1.23.1 → 1.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,56 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.24.0
4
+
5
+ ### A rule that reached one file, and the guard shape that let it
6
+
7
+ `v1.23.0` added rule 21 — *a step that consumes what a later step produces is a deadlock*
8
+ — and reordered the retrospective's three acts to **stamp → prune → entry**. It changed
9
+ `references/retrospective.md`. It changed nothing else.
10
+
11
+ Every other surface still taught the deadlocked *prune first* — the list is the count,
12
+ and it was written down rather than tallied, because a tally of this fix would be the
13
+ defect the fix is about: `SKILL.md` twice (including
14
+ the stage-10 gate row), `references/acceptance.md` three times, `references/stages.md`
15
+ three times, `references/companion-skills.md`, `references/knowledge-sources.md`,
16
+ `templates/retro.md`, `templates/README.md`, `commands/task-pipeline.md`,
17
+ `cursor/rules/task-pipeline.mdc`, `docs/DOCMAP.md`, `README.md` and this repository's own
18
+ `CLAUDE.md`. **`SKILL.md` is what an agent loads first**, so the most-read surface of the
19
+ shipped skill instructed the exact failure its newest rule defines.
20
+
21
+ **Why every existing guard was green.** Rules 16–21 each have a bespoke check that names
22
+ its consumer files and asserts a needle is present. That answers *"did a consumer drop its
23
+ citation?"* — a real failure, and it catches it. It cannot answer *"does a consumer
24
+ contradict what it cites?"*, because a contradicting consumer **keeps** its citation: the
25
+ link resolves, the section exists, the needle is there. A pointer's validity says nothing
26
+ about whether the two texts agree.
27
+
28
+ **The new guard compares order, not presence** — and derives the expected order from
29
+ `retrospective.md`'s own heading **at check time**, so it cannot drift from the doctrine it
30
+ guards the way a hardcoded literal would.
31
+
32
+ Four deterministic shapes, each arrived at by probing rather than by trusting a green:
33
+
34
+ - an adjacent enumeration (`prune, stamp` / `prune → stamp`);
35
+ - the `first … then` construction, with an aside allowed between;
36
+ - a bare `… then …` sequence with no "first" at all (`prune before you add … then stamp`);
37
+ - an **ordered list** whose items open with the acts — which needs no connector word, and
38
+ which the first two shapes both missed.
39
+
40
+ Each of the four was found by running the check and reading the result, not by writing it
41
+ and shipping. Two of them were blind spots in the guard's *own* first version, and one of
42
+ those was blind to the exact wording this release introduced.
43
+
44
+ **Measured before shipping** (rule 10). The obvious predicate — *both act words in one
45
+ paragraph* — returns 32 hits on this corpus, of which 22 are false, including
46
+ `retrospective.md`'s own correct prose. The shipped predicate returns 8, all true. A
47
+ paragraph narrating the old order as a defect is exempt through an explicit marker list;
48
+ `learned.md`'s rule-21 incident and `retrospective.md`'s own rationale both need it.
49
+
50
+ Swept in the same change, because the class is *a claim that stopped being true*:
51
+ `SKILL-CARD.md` still said the eval suite was **"Never executed"** and counted "the 26
52
+ files under `references/`" against a directory holding 28.
53
+
3
54
  ## v1.23.1
4
55
 
5
56
  ### Four documents that had gone false, and the config this repository never wrote
package/CONTRIBUTING.md CHANGED
@@ -260,7 +260,26 @@ every relative link **from the navigator's directory** — it sits one level ove
260
260
  everything it names, which is canon 4 in the file that publishes canon 4.
261
261
  *(guard: `index that has drifted from its doctrine`)*
262
262
 
263
- **34. 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
263
+ **34. No surface enumerates the retrospective's acts in an order that contradicts
264
+ `references/retrospective.md`.** Rule 21 changed the order to *stamp first* in that one
265
+ file and reached **no other surface that states it** — `SKILL.md` included, which is what
266
+ an agent loads first. (No count here on purpose: whether it is nine, twelve or fifteen
267
+ depends on counting files or occurrences, and this repository produced three different
268
+ answers while writing the fix. The guard is the count.) Every per-rule guard has the same
269
+ blind spot: it
270
+ proves a consumer still **cites** the doctrine, and a contradicting consumer keeps its
271
+ citation. So this one compares the **order** against the order derived from
272
+ `retrospective.md`'s own heading at check time rather than a literal — in the shapes
273
+ listed in the guard's own `SCOPE` comment, which is where they are enumerated so this
274
+ list cannot go stale against them. **What the guard does not cover is written there
275
+ too**: inflected forms, lists whose items are separated by blank lines, and any
276
+ statement of the order that names neither act. Those are stated blind spots, not
277
+ unnoticed ones.
278
+ A paragraph that narrates the old order as the defect is exempt by an explicit marker
279
+ list, not by a heuristic.
280
+ *(guard: `enumerates the retro's acts as`)*
281
+
282
+ **35. 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
264
283
  an audit measured it. A claim of enforcement is now checked like any other claim.
265
284
  *(guard: `whose message does not appear in`)* — and a cited literal must lie inside
266
285
  a **single** string in `test/validate.py`: the check reads that file as text, so a
package/README.md CHANGED
@@ -560,7 +560,9 @@ pipeline notices it is the same one.
560
560
  The last act of stage 10 is therefore a **retrospective**, written to
561
561
  `docs/superpowers/retro.md` — **one file per project, not per run**
562
562
  ([`retrospective.md`](plugins/task-pipeline/skills/task-pipeline/references/retrospective.md)).
563
- Every run **prunes and stamps**; only a run that *diverged* writes an entry:
563
+ Every run **stamps and prunes** in that order, because one retirement trigger
564
+ counts firings across the last five run stamps and a prune ahead of the stamp reads a
565
+ counter its own stage writes afterwards. Only a run that *diverged* writes an entry:
564
566
  symptom with evidence, the stage it surfaced at, the stage that **owned** it, the
565
567
  root cause, the fix, and the check that catches it the first time from now on.
566
568
 
@@ -572,7 +574,8 @@ root cause, the fix, and the check that catches it the first time from now on.
572
574
  | 2 — standing instruction | a rule agents read, for what no check can decide | one of ten slots, and its retirement trigger must be written at birth |
573
575
  | 3 — a note | something still being understood | expires in two runs, then it is promoted or deleted |
574
576
 
575
- **The prune is mandatory and runs before anything is added.** Every standing
577
+ **The prune is mandatory, and it runs after the stamp and before anything is added.**
578
+ Every standing
576
579
  instruction is checked against three retirement triggers — *it became a check* ·
577
580
  *every path or command it names is gone* · *it has not fired in the last five run
578
581
  stamps* — and the list is held to a **hard cap of ten**. At eleven, the oldest
package/SKILL-CARD.md CHANGED
@@ -12,10 +12,10 @@ 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.23.1 |
15
+ | **Version** | 1.24.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
- | **Evaluation status** | Suite authored (15 evals, 5 categories). **Never executed** — see [`evals/RESULTS.md`](evals/RESULTS.md) |
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` |
19
19
 
20
20
  ## Risk-tier disclosure
21
21
 
@@ -34,8 +34,9 @@ apply.
34
34
 
35
35
  ## What to check before you trust it
36
36
 
37
- 1. Read `SKILL.md` and the 26 files under `references/` — that is the whole
38
- instruction surface, and every one is linked directly from `SKILL.md`.
37
+ 1. Read `SKILL.md` and every file under `references/` — that is the whole
38
+ instruction surface, and each one is linked directly from `SKILL.md`, so the
39
+ directory listing is the count.
39
40
  2. Read `templates/docgate.sh` before seeding it; it is the only shipped script a
40
41
  host project will run on its own repository.
41
42
  3. Run `npm run test:all` — every guard has a negative self-test that plants a
@@ -54,7 +55,9 @@ apply.
54
55
  - **Versions are pinned by git tag** and mirrored into `sshlg-skills`'s catalogue.
55
56
  Rollback is `git checkout v<previous>` or pinning the previous plugin version;
56
57
  the previous version is never deleted.
57
- - **Behavioural evidence is missing, not merely thin.** The structural guards prove
58
- the skill is well-formed. Until `evals/RESULTS.md` carries a dated run, nothing in
59
- this repository proves it *behaves* triggers correctly, stays quiet on a
60
- question, or performs the steps it documents.
58
+ - **Behavioural evidence is thin to the point of absent.** The structural guards prove
59
+ the skill is well-formed. `evals/RESULTS.md` carries **one** dated run, and it was
60
+ self-observed by the authoran observation of instruction-following, not an
61
+ evaluation. **No blind run has been made on any model.** Nothing in this repository
62
+ yet proves the skill *behaves* — triggers correctly, stays quiet on a question, or
63
+ performs the steps it documents.
@@ -324,7 +324,12 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
324
324
  per project, not per run**. Every gate above is good at *this* run and blind
325
325
  across runs: the same class of failure gets caught, fixed and forgotten five
326
326
  times and nothing notices it is the same one. So, in this order —
327
- **1. Prune before you add.** Check every standing instruction against three
327
+ **1. Stamp the run first** date, topic, commit, verdict, counts. It costs one
328
+ line and it is the only thing that makes the next step computable: one retirement
329
+ trigger counts firings across the last five run stamps, so a prune placed ahead of
330
+ the stamp reads a counter its own stage writes afterwards and can never run on real
331
+ data.
332
+ **2. Then prune.** Check every standing instruction against three
328
333
  retirement triggers: it became a check (a test, a lint rule, a gate, a hook →
329
334
  delete it; the check is the memory, and keeping both means it is read twice and
330
335
  obeyed once); every path, command or stage it names is gone (→ delete, it
@@ -334,8 +339,6 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
334
339
  because "they all matter" is exactly the state in which the list stopped being
335
340
  read. **Every deletion writes one line in the log; silent deletion is
336
341
  forbidden** — the record stays, the instruction leaves.
337
- **2. Stamp the run** — date, topic, verdict, counts. That stamp is what makes
338
- "five runs" countable.
339
342
  **3. Write an entry, only if the run diverged** — symptom with evidence, the
340
343
  stage it *surfaced at*, the stage that **owned** it (usually earlier — a finding
341
344
  recorded against the stage that tripped over it comes back), the root cause
@@ -349,8 +352,8 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
349
352
  cap is not negotiable and the prune is a gate item, not a good intention.
350
353
  Gate: ladder walk ran, no REQ `unknown`, no ledger row without
351
354
  a home, every repository clean/pushed/pointed-at, user signs off, **and the
352
- retro is written — pruned before anything was added, at or under its cap, every
353
- deletion logged, the run stamped, and the counts printed beside this verdict**.
355
+ retro is written — stamped first, then pruned before anything was added, at or
356
+ under its cap, every deletion logged, and the counts printed beside this verdict**.
354
357
 
355
358
  Cross-cutting: answer from the brief's autonomy section rather than re-asking, log every deferral in the ledger, never narrow the task silently, track
356
359
  tasks, conventional commits, honest degradation (never claim a failed/skipped step
package/evals/RESULTS.md CHANGED
@@ -50,6 +50,13 @@ the split matters more than the total: a run the author watched, knowing the exp
50
50
  behaviour, is an observation of instruction-following and not an evaluation. Collapsing
51
51
  the two into one "runs recorded" number is how a self-check gets quoted as a result.
52
52
 
53
+ That split is **canon 5 applied to evaluation** — *green nobody watched turn red is not
54
+ evidence* ([`documentation.md`](../plugins/task-pipeline/skills/task-pipeline/references/documentation.md)
55
+ → *The canons*). A self-observed run is a green the author was steering; a blind run is
56
+ the only one that could have come back red for a reason nobody arranged. The code graph
57
+ surfaced this link before any document stated it, which is the divergence check earning
58
+ its keep.
59
+
53
60
  Everything else in this repository is proven by structural guards — the count is
54
61
  whatever `npm run test:all` prints, deliberately not restated here — and those check
55
62
  the *form*. These are the only checks that speak to the *behaviour*. Printed here so a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.23.1",
3
+ "version": "1.24.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.23.1",
5
+ "version": "1.24.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -31,7 +31,7 @@ language, ADRs for hard-to-reverse calls) and covering the **autonomy sweep** (w
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
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): **prune before you add** — 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), the list held to a hard cap of ten, every deletion logged as one line and never silent — then stamp the run, 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;
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), 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.
@@ -43,7 +43,7 @@ thing, the canon is the *why* and the rule is the *how*.
43
43
  | trust a mechanism that reports success | [`gates.md`](../task-pipeline/references/gates.md) → *False success* | the failure that removes the reason to look |
44
44
  | wire a check into the agent's own tooling | [`hooks.md`](../task-pipeline/references/hooks.md) | the hook contract, and why a crashed guard **allows** the action |
45
45
  | audit documentation a project already has | [`setup.md`](../task-pipeline/references/setup.md) | seven passes, cheapest first, output is a fix plan |
46
- | carry a lesson to the next run | [`retrospective.md`](../task-pipeline/references/retrospective.md) | prune first, cap of ten, every lesson names its commit |
46
+ | carry a lesson to the next run | [`retrospective.md`](../task-pipeline/references/retrospective.md) | stamp first (the cold trigger reads it), then prune to a cap of ten; every lesson names its commit |
47
47
  | seed a gate into a host project | [`templates/docgate.sh`](../task-pipeline/templates/docgate.sh) | it seeds **green**: dormant where there is no input yet |
48
48
  | take a whole change through to acceptance | [`task-pipeline`](../task-pipeline/SKILL.md) | this skill is the standard; that one is how a change reaches the repository |
49
49
 
@@ -154,14 +154,18 @@ plus a stable id, never a second act of thinking.
154
154
  and forgotten five times with nothing noticing it is the same one. The last act of
155
155
  stage 10 is therefore the **retrospective**
156
156
  ([`references/retrospective.md`](references/retrospective.md), written to
157
- `docs/superpowers/retro.md`): **prune first** — every standing instruction checked
158
- against its retirement triggers (it became a check · its surface is gone · it hasn't
159
- fired in five runs), the list held to a hard cap of **ten**, every deletion logged
160
- then stamp the run, then write an entry **only if the run diverged** (symptom, the
157
+ `docs/superpowers/retro.md`): **stamp the run first** — one line, and the only thing
158
+ that makes the next step computable **then prune**, every standing instruction
159
+ checked against its retirement triggers (it became a check · its surface is gone · it
160
+ hasn't fired in five run stamps), the list held to a hard cap of **ten**, every
161
+ deletion logged, then write an entry **only if the run diverged** (symptom, the
161
162
  stage that *owned* it, root cause, fix, and the check that catches it next time).
162
163
  Stage 0 reads those standing instructions in full, which is exactly why the prune is
163
164
  a gate criterion and not a good intention: a rule nobody reads to the end is worse
164
- than no rule, because everyone believes it is covered.
165
+ than no rule, because everyone believes it is covered. **The order is load-bearing,
166
+ not stylistic** — one retirement trigger counts firings across the last five run
167
+ stamps, so a prune placed ahead of the stamp reads a counter its own stage writes
168
+ afterwards and can never run on real data ([`references/learned.md`](references/learned.md) rule 21).
165
169
 
166
170
  Three things the grill does beyond clarifying the request:
167
171
  - **Domain awareness.** It reads the project's own `CONTEXT.md` / `docs/adr/` and
@@ -264,7 +268,7 @@ capable available — see `references/model-tiering.md`).
264
268
  | 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 |
265
269
  | 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report | auto |
266
270
  | 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 |
267
- | 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: prune, stamp, 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 — prune before entry, list at or under its cap, every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, run stamped with its commit, counts printed** | manual |
271
+ | 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** | manual |
268
272
 
269
273
 
270
274
  ### Stage 10 in a project of several repositories
@@ -176,16 +176,17 @@ whether the run was finished.
176
176
 
177
177
  After the closing question, before the run is called done:
178
178
  [`retrospective.md`](retrospective.md), written to `docs/superpowers/retro.md`.
179
- Every run **prunes and stamps**; only a run that *diverged* writes an entry.
179
+ Every run **stamps and prunes**; only a run that *diverged* writes an entry.
180
180
 
181
- The order is fixed, because a lesson that lands in a cluttered file is a lesson
182
- nobody reaches:
181
+ The order is fixed, and it is a **dependency, not a preference** step 2 reads the
182
+ counter step 1 writes ([`learned.md`](learned.md) rule 21):
183
183
 
184
- 1. **Prune first.** Every standing instruction is checked against its three
184
+ 1. **Stamp the run first** one line: date, topic, commit, verdict, retro counts. It
185
+ costs nothing and it is the only thing that makes the next step computable.
186
+ 2. **Then prune.** Every standing instruction is checked against its three
185
187
  retirement triggers — it became a check, its surface is gone, or it has not
186
188
  fired in the last five run stamps — and the list is held to its cap of **ten**.
187
189
  Every deletion writes one line in the log; silent deletion is forbidden.
188
- 2. **Stamp the run** — one line: date, topic, verdict, retro counts.
189
190
  3. **Write the entry, if the run diverged** — symptom, the stage it surfaced at,
190
191
  the stage that *owned* it, the root cause, the fix (mechanical > standing
191
192
  instruction > note with an expiry), and the check that catches it next time.
@@ -224,11 +225,14 @@ All of:
224
225
  shows no `+`, and each repo is clean and pushed. A submodule is finished when
225
226
  its parent points at it.
226
227
  9. **The operator answers the closing question** and signs off.
227
- 10. **The retrospective is written** ([`retrospective.md`](retrospective.md)) — the
228
- prune ran **before** anything was added (standing instructions checked against
229
- their retirement triggers, the list at or under its cap of ten, every deletion
230
- logged), the run is stamped, and a run that diverged has its entry with a root
231
- cause and a named check. The counts are printed beside this verdict, not filed.
228
+ 10. **The retrospective is written** ([`retrospective.md`](retrospective.md)) — **in
229
+ order**: the run is stamped with its commit first, **then** the prune runs before
230
+ anything is added (standing instructions checked against their retirement triggers,
231
+ the list at or under its cap of ten, every deletion logged), **then** a run that
232
+ diverged gets its entry with a root cause and a named check. The stamp precedes the
233
+ prune because a retirement trigger counts firings across the last five run stamps
234
+ ([`learned.md`](learned.md) rule 21). The counts are printed beside this verdict,
235
+ not filed.
232
236
 
233
237
  Manual by design. An automated check can prove the table is *well-formed*; only
234
238
  the person who asked can confirm it is *what they asked for*. Do not let a green
@@ -35,7 +35,7 @@ better, plus one that is required only for user-facing work.
35
35
  | 5 Build (isolation, subagents, fix loop) | `references/build.md` + `references/review.md` |
36
36
  | 5–6 TDD + suite gate | `references/tdd.md` |
37
37
  | 10 Acceptance (REQ close-out) | `references/acceptance.md` |
38
- | 10 Retrospective (the run's last act: prune, stamp, entry) | `references/retrospective.md` |
38
+ | 10 Retrospective (the run's last act: stamp, prune, entry) | `references/retrospective.md` |
39
39
  | 10 + any audit (finding what's missing) | `references/audit.md` |
40
40
  | any repeating loop | `references/loop-guard.md` |
41
41
 
@@ -286,7 +286,7 @@ The ledger is the stage-9 work list. For each row:
286
286
  document class or ratchet. Note that this list and the **propagation matrix** are
287
287
  different lists on purpose: the ledger is what you *read*, the matrix is what you
288
288
  *owe* ([`documentation.md`](documentation.md)), and stage 9 walks both.
289
- - **The retro** — prune, stamp, entry, and rotate what aged out into the archive
289
+ - **The retro** — stamp, prune, entry, and rotate what aged out into the archive
290
290
  ([`retrospective.md`](retrospective.md)).
291
291
  - **Anything the run proved stale** — including a doc that was "wrong but nobody
292
292
  had time": that's why the conflict was logged in phase 2 instead of only being
@@ -484,18 +484,19 @@ never that the work was skipped quietly.
484
484
  written to `docs/superpowers/retro.md` — one file per project, not per run. The
485
485
  pipeline's gates are good at *this* run and blind across runs: the same class of
486
486
  failure can be caught, fixed and forgotten five times and nothing in the flow
487
- notices it is the same one. So, in this order: **prune first** (every standing
488
- instruction against its three retirement triggers it became a check, its
489
- surface is gone, it hasn't fired in five run stamps and the list held to its cap
490
- of ten, every deletion logged **in the archive, with the commit that retired it**),
491
- **stamp the run**, then **write an entry only if
487
+ notices it is the same one. So, in this order: **stamp the run first** (one line,
488
+ with its commit and the only thing that makes the next step computable), **then
489
+ prune** (every standing instruction against its three retirement triggersit
490
+ became a check, its surface is gone, it hasn't fired in five run stamps — and the
491
+ list held to its cap of ten, every deletion logged **in the archive, with the
492
+ commit that retired it**), then **write an entry only if
492
493
  the run diverged** (symptom · the stage it surfaced at · the stage that *owned* it
493
494
  · root cause · fix, mechanical before instruction before expiring note · the check
494
- that catches it next time). Every run prunes and stamps; a retro left empty after
495
+ that catches it next time). Every run stamps and prunes; a retro left empty after
495
496
  a messy run is the failure the file exists to stop. Stage 0 reads the standing
496
497
  instructions in full next time, which is why the cap is not negotiable.
497
498
  - **GATE (manual):** the ladder walk ran and its absences became REQ rows before
498
- the table was written; **the retrospective is written — prune before entry, the
499
+ the table was written; **the retrospective is written — stamped first, then pruned, then the entry; the
499
500
  list at or under its cap, every deletion logged in the archive with its commit,
500
501
  entries older than five run stamps rotated into `docs/superpowers/retro/`, the run
501
502
  stamped with its commit, every SHA in either file resolvable, and the
@@ -20,7 +20,7 @@ from `super-ux`.
20
20
  | `hygiene.sh` | `scripts/check-hygiene.sh` | 0 seeds it · **5 runs it after every task** · 6 and 9 run it · 10 proves it |
21
21
  | `hooks.example.json` | the project's `.claude/settings.json` | 0 — offered, never installed silently |
22
22
  | `routing-rule.md` | the operator's `CLAUDE.md` — **offered by `setup`, never written silently** | 0 / `setup` |
23
- | `retro.md` | `docs/superpowers/retro.md` — **one per project, not per run** | 10 writes (prunestamp → entry), 0 reads it in full |
23
+ | `retro.md` | `docs/superpowers/retro.md` — **one per project, not per run** | 10 writes (stampprune → entry), 0 reads it in full |
24
24
  | `retro-archive.md` | `docs/superpowers/retro/YYYY-QN.md` | 10 rotates into it, 0 **queries** it |
25
25
 
26
26
  The documentation-track templates (`docmap.md`, `decisions.md`,
@@ -1,7 +1,9 @@
1
1
  # Pipeline retrospective — <project>
2
2
 
3
3
  One file per project, not per run. Written as the **last act of stage 10**:
4
- prune first, then stamp, then write an entry **only if the run diverged**.
4
+ **stamp first, then prune**, then write an entry **only if the run diverged**.
5
+ The order is load-bearing: the cold-retirement trigger reads the stamp this stage
6
+ writes, so a prune ahead of it can never run on real data (`learned.md` rule 21).
5
7
  Doctrine: `references/retrospective.md`.
6
8
 
7
9
  **What stage 0 reads in full:** *Standing instructions*, *Run stamps* and *Recent