task-pipeline-skill 1.78.4 → 1.80.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +184 -2
  2. package/README.md +5 -3
  3. package/SKILL-CARD.md +1 -1
  4. package/cursor/rules/task-pipeline.mdc +3 -1
  5. package/evals/RESULTS.md +212 -9
  6. package/evals/evidence-docs.evals.json +109 -0
  7. package/evals/project-audit.evals.json +108 -0
  8. package/evals/run.py +47 -19
  9. package/package.json +1 -1
  10. package/plugins/task-pipeline/.claude-plugin/plugin.json +3 -2
  11. package/plugins/task-pipeline/commands/task-pipeline.md +2 -1
  12. package/plugins/task-pipeline/hooks/build-gate.sh +6 -1
  13. package/plugins/task-pipeline/hooks/gate-observer.sh +35 -14
  14. package/plugins/task-pipeline/hooks/release-gate.sh +70 -9
  15. package/plugins/task-pipeline/skills/evidence-docs/SKILL.md +33 -2
  16. package/plugins/task-pipeline/skills/project-audit/SKILL.md +7 -2
  17. package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +50 -57
  18. package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +4 -4
  19. package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +1 -1
  20. package/plugins/task-pipeline/skills/task-pipeline/references/adoption.md +15 -4
  21. package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +4 -2
  22. package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +6 -0
  23. package/plugins/task-pipeline/skills/task-pipeline/references/brainstorm.md +6 -1
  24. package/plugins/task-pipeline/skills/task-pipeline/references/build.md +11 -1
  25. package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +7 -0
  26. package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +33 -2
  27. package/plugins/task-pipeline/skills/task-pipeline/references/documentation.md +2 -2
  28. package/plugins/task-pipeline/skills/task-pipeline/references/exposure.md +7 -3
  29. package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +17 -185
  30. package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +1 -1
  31. package/plugins/task-pipeline/skills/task-pipeline/references/model-tiering.md +13 -0
  32. package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +2 -0
  33. package/plugins/task-pipeline/skills/task-pipeline/references/prioritisation.md +165 -0
  34. package/plugins/task-pipeline/skills/task-pipeline/references/probing.md +202 -0
  35. package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +8 -4
  36. package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +60 -1
  37. package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +52 -54
  38. package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +1 -1
  39. package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +28 -5
  40. package/plugins/task-pipeline/skills/task-pipeline/templates/backlog.md +6 -2
  41. package/plugins/task-pipeline/skills/task-pipeline/templates/brief.md +4 -3
  42. package/plugins/task-pipeline/skills/task-pipeline/templates/retro.md +6 -4
  43. package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: task-pipeline
3
- description: "Use when work changes the repository — feature, fix, refactor, migration, integration, rewrite, adoption or hardening; фича, фикс, рефактор, миграция, интеграция, доработать, починить, внедрить, перевести — or when the output is a finding that lands in it: audit/аудит, bug hunt/проверь ошибки, production check/проверь прод, PR review/ревью PR — or on 'run this through the pipeline' / 'прогони по конвейеру', 'full cycle, the full cycle' / 'полный цикл', /task-pipeline. Runs a substantial task through an intake grill, docs study, brainstorm, spec, plan, build, tests, deploy, post-deploy, docs/wiki sync and acceptance with explicit gates. 'checkup' / 'чекап' reports unconfirmed releases; 'setup' audits existing docs. Not for: answering a question, explaining code, a typo or a one-line edit — say 'без пайплайна' / 'quick' to opt out."
3
+ description: "Use when work changes the repository — feature, fix, refactor, migration, integration, rewrite, adoption or hardening; фича, фикс, рефактор, миграция, интеграция, доработать, починить, внедрить, перевести — or when the output is a finding that lands in it: audit/аудит, bug hunt/проверь ошибки, production check/проверь прод, PR review/ревью PR — or on 'run this through the pipeline' / 'прогони по конвейеру', 'full cycle, the full cycle' / 'полный цикл', /task-pipeline. Runs a substantial task through an intake grill, docs study, brainstorm, spec, plan, build, tests, deploy, post-deploy, docs/wiki sync and acceptance with explicit gates. 'checkup' / 'чекап' reports unconfirmed releases; 'setup' audits existing docs. Not for: answering a question, explaining code, a typo or a one-line edit, a mechanical rename, reconnaissance that lands nothing — say 'без пайплайна' / 'quick' to opt out."
4
4
  license: MIT
5
+ compatibility: "Doctrine runs on any agent. The bundled scripts need python3; the run needs git. Missing either degrades, never blocks — the graph verbs and seeded gates go unused, and the run says so."
5
6
  ---
6
7
 
7
8
  # task-pipeline
@@ -27,8 +28,11 @@ that encodes this plugin's own default flow (stage 0 intake + the 1→10 stages
27
28
  tabled below) and an optional, toggleable `release` block. Any project replaces it
28
29
  wholesale — any number of stages, run by its own skills/agents, with its own gate
29
30
  types (see *Bring your own skills*). Each gate has a **type**: `auto` (the
30
- orchestrator verifies the `check` itself, pass/fail) or `manual` (wait for an
31
- explicit operator go); which stages are manual is the operator's call. In the
31
+ orchestrator verifies the `check` itself, pass/fail), `judgment` (no complete
32
+ deterministic check exists a named judge rules, and the ruling is recorded as
33
+ judgement, never as a measurement; `references/gates.md` → *The judgment gate*)
34
+ or `manual` (wait for an explicit operator go); which stages are manual is the
35
+ operator's call. In the
32
36
  example's `skills[]`, `task-pipeline:<name>` denotes this skill's own built-in
33
37
  doctrine (`references/<name>.md`) and `host:<name>` denotes the host project's own
34
38
  command for that job (`references/conventions.md`); everything else is a real skill
@@ -59,7 +63,7 @@ gate stops until it is installed.
59
63
  | 3 Spec | `references/spec.md` |
60
64
  | 4 Plan | `references/planning.md` |
61
65
  | the queue the loop walks | `references/work-graph.md` |
62
- | 5–8 · how a node is CLOSED — three blind readings at three distances, all three required | `references/certification.md` |
66
+ | 5–8 · how a **work-graph node** is CLOSED — three blind readings at three distances, all three required (ceiling 3); a **prose-plan task** closes through `review.md` instead — one reviewer, five-round cap | `references/certification.md` |
63
67
  | 5 Build (worktree, subagents, fix loop) | `references/build.md` + `references/review.md` |
64
68
  | 5–6 TDD + suite gate | `references/tdd.md` |
65
69
  | 5, 6, 8 The browser — the look, the spec suite, and the difference | `references/browser.md` |
@@ -73,7 +77,7 @@ gate stops until it is installed.
73
77
  | run-wide · what the run **leaves running and leaves behind** — every gate, and stage 10 | `references/residue.md` |
74
78
  | run-wide · what the run **prints about itself** — the rail, the iteration line | `references/progress.md` |
75
79
  | run-wide · how a run keeps going (the loop mode + the context budget) | `references/continuity.md` |
76
- | run-wide · the work-list **between** runs, and how its priority is computed | `references/backlog.md` |
80
+ | run-wide · the work-list **between** runs, and the order it comes off | `references/backlog.md` + `references/prioritisation.md` |
77
81
  | run-wide · whether a **human** ever confirmed what shipped, and when | `references/verification.md` |
78
82
  | run-wide · how much unconfirmed work has piled up, and what to look at first | `references/exposure.md` |
79
83
  | any stage · Where each artifact belongs | `references/artifacts.md` |
@@ -108,12 +112,11 @@ bind this run, the log queried because nothing caps it — are in
108
112
  `references/knowledge-sources.md` and `references/retrospective.md`.
109
113
 
110
114
  **Three artifacts close a run, not two — and they are a convergence, not a sequence.**
111
- Stage 9 syncs the docs, the wiki **and the code graph**. None consumes another; all three
112
- consume the same change, and the **graph↔docs divergence check is the gate over their
113
- convergence** — the only thing that compares two of the three against each other, which
114
- is why it is not optional where a graph exists. A stale graph is a false premise
115
- **carrying the authority of a machine**: a wrong doc gets argued with, a wrong graph gets
116
- believed (`references/knowledge-graph.md`, `references/audit.md`).
115
+ Stage 9 syncs the docs, the wiki **and the code graph**; none consumes another, and the
116
+ **graph↔docs divergence check is the gate over their convergence** — the only thing
117
+ comparing two of the three against each other, so it is not optional where a graph
118
+ exists. A stale graph is a false premise **carrying the authority of a machine**
119
+ (`references/knowledge-graph.md`, `references/audit.md`).
117
120
 
118
121
  **Documentation is a deliverable, and it has a gate** (`references/documentation.md`).
119
122
  Stage 0 answers the four questions that make docs a *system* into `docs/DOCMAP.md`;
@@ -133,26 +136,14 @@ triggers and what an entry must carry are in `references/retrospective.md`; why
133
136
  the order cannot be swapped is `references/learned.md` rule 21.
134
137
 
135
138
  Stage 0 reads those standing instructions in full, which is why the prune is a gate
136
- criterion and not a good intention: a rule nobody reads to the end is worse than no
137
- rule, because everyone believes it is covered.
139
+ criterion: a rule nobody reads to the end is worse than no rule, because everyone
140
+ believes it is covered.
138
141
 
139
- Three things the grill does beyond clarifying the request:
140
- - **Domain awareness.** It reads the project's own `CONTEXT.md` / `docs/adr/` and
141
- holds the operator to them challenging terms that conflict with the glossary,
142
- sharpening overloaded words, stress-testing with concrete scenarios, and
143
- flagging where the code contradicts what was just said. Resolved terms are
144
- written to `CONTEXT.md` as they land; genuinely hard-to-reverse decisions get an
145
- ADR.
146
- - **The autonomy sweep.** It pre-resolves what would otherwise stop stages 1→10
147
- mid-flight (test/lint/deploy commands, branch policy, log locations, docs
148
- targets, the model decision, deploy authorization). Autonomy is bought here or
149
- not at all — an unasked question is a scheduled interruption.
150
- - **The design destination**, when the project designs in Figma: *which* file, in
151
- which team — a stage-0 decision, never a stage-3 side effect. Left to drawing
152
- time the question is answered by whoever is holding the brush, and the answer is
153
- usually *create a new file* — which is how a project ends up with three files
154
- called some variation of "Design", each with real work in it and no way to tell
155
- which one the team opens.
142
+ Three things the grill does beyond clarifying the request, each in full in
143
+ [`references/grill.md`](references/grill.md):
144
+ - **Domain awareness** — it reads the project's `CONTEXT.md` / `docs/adr/` and holds the operator to them, writing resolved terms back as they land.
145
+ - **The autonomy sweep** — it pre-resolves what would otherwise stop stages 1→10 mid-flight. Autonomy is bought here or not at all; an unasked question is a scheduled interruption.
146
+ - **The design destination** with Figma on *which* file, in which team, decided at stage 0. Left to drawing time it is answered by whoever holds the brush, and the answer is usually *create a new file*.
156
147
 
157
148
  ## How to run
158
149
 
@@ -165,7 +156,9 @@ Three things the grill does beyond clarifying the request:
165
156
  the most capable model available, let the operator confirm or override, record
166
157
  it. Ask once, here. **The same block carries the run mode**
167
158
  (`references/continuity.md`): read `pipeline.json` → `run.loop`; where it is
168
- recorded, arm it and print the job id and the cancel command the config is
159
+ recorded, arm it **at the point `run.loop.arm` names** here at preflight, or
160
+ at stage 2's close for `after-decomposition`, once the queue exists — and when
161
+ it arms, print the job id and the cancel command; the config is
169
162
  the authorization, so re-asking rebuilds the habit it exists to retire. Where
170
163
  it is **absent, the mode is off**; recommend it in one line and move on.
171
164
  Silence arms nothing, and the mode never collapses a `manual` gate.
@@ -193,9 +186,10 @@ Three things the grill does beyond clarifying the request:
193
186
  status column is the resume point (`references/stages.md` → *The program loop*).
194
187
  4. Do **not** advance until the stage **gate** passes (`references/stages.md`).
195
188
  Honor the gate **type**: for `auto`, verify the gate's `check` yourself and
196
- stop/return on fail; for `manual`, present the result and **wait for the
197
- operator's explicit "continue"/go** an auto gate never substitutes for a
198
- required manual approval.
189
+ stop/return on fail; for `judgment`, record the named judge's ruling as
190
+ judgement, never as a measurement; for `manual`, present the result and
191
+ **wait for the operator's explicit "continue"/go** — neither of the other
192
+ two ever substitutes for a required manual approval.
199
193
  5. **The cross-cutting rules fire at any stage**, not only here — the Doc Loop, the
200
194
  loop guard, the audit's exit, the frozen REQ list, the carry-over ledger, and
201
195
  what counts as evidence, and **every gate prints `holds: N`** — what this run left
@@ -217,9 +211,9 @@ capable available — see `references/model-tiering.md`).
217
211
  | 3 | Spec | committed + reviewed; UI: chain validated, linter green, scenarios and `SCR-` traced; COPY and VISUAL are a parallel layer after UX, and where both ran their convergence check is recorded | manual |
218
212
  | 4 | Plan | parallel-ready, DoD per task; **every edge names what it carries** — the fake-edge test run and its `Edges:` count computed | auto |
219
213
  | 5 | Dev | tasks DONE, TDD green per task, branch integrated per the brief; a fanned-out group gets **one convergence check over all its diffs together** before the first worktree lands | auto |
220
- | 6 | Tests | full suite green, new and changed code covered, every new check probed both ways and asserted on its exit code; **a web surface is checked in a browser, not in the diff** | auto |
214
+ | 6 | Tests | full suite green, new and changed code covered, every new check probed both ways and asserted on its exit code; **a web surface is checked in a browser, not in the diff** — where a browser channel is connected; absent, the weaker claim is recorded | auto |
221
215
  | 7 | Lint + deploy | lint clean and suite green before deploy; deploy needs a go, or the brief's specific standing authorization | manual |
222
- | 8 | Post-deploy | clean boot or an honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and nothing else | auto |
216
+ | 8 | Post-deploy | clean boot or an honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and nothing else; where no browser channel is connected, the weaker claim is recorded | auto |
223
217
  | 9 | Docs + wiki | every stale row of the stage-0 source ledger updated; the propagation matrix walked for every change type this run produced; the documentation gate green with its ratchets printed; docs, wiki and the code graph synced and checked against each other | auto |
224
218
  | 10 | **Acceptance** | the ladder walk ran and its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; no unresolved ledger row; **every repository clean, pushed and pointed at**; the hand-back written and the environment given back; the retrospective written **last**, and in order | manual |
225
219
 
@@ -228,42 +222,41 @@ capable available — see `references/model-tiering.md`).
228
222
  ladder walk is, which eight environment classes stage 10 enumerates, what makes an
229
223
  edge fake, why a `200` is not a working page: all there, none here.
230
224
 
231
- **Several repositories?** A submodule is finished when its parent says so — the
232
- work can be committed, pushed and green while a clone of the parent still gets the
233
- commit before it, and neither repository looks wrong alone. The two commands that
234
- prove it, and the two-command fix whose second half gets forgotten, are in
225
+ **Several repositories?** A submodule is finished when its parent says so — a clone
226
+ can still get the commit before it while neither repository looks wrong alone. The
227
+ commands that prove it are in
235
228
  [`references/acceptance.md`](references/acceptance.md) → *A project of several
236
229
  repositories*.
237
230
 
238
231
  ## Model — ask once, at preflight
239
232
 
240
- Default recommendation: **the most capable reasoning model the environment
241
- offers** (currently the latest Opus generation read that as a tier, not a
242
- string). **Never hardcode a model id**: generations ship, tiers get renamed, and
243
- the operator may be on another provider entirely resolve the top tier available
244
- at runtime. Stage configs use provider-agnostic tokens (`default` / `inherit`).
233
+ Recommend **the most capable reasoning model available** — a tier resolved at
234
+ runtime, **never a hardcoded id**; stage configs use `default` / `inherit`. The
235
+ block to emit is `references/model-tiering.md` *Mechanic*, and it is a
236
+ reminder: no such tier means say which one is in use and continue. Record the
237
+ answer in the brief, don't re-ask per stage; stage-5 subagents are pinned to it
238
+ automatically.
245
239
 
246
- > 🧠 **Model for this run:** recommended **`<top tier available>`**. You're on
247
- > `<current>`. `/model <id>` to switch, or "keep current", or name per-stage
248
- > overrides. *(Reminder only — if that tier isn't available, say which one you're
249
- > using and continue.)*
240
+ ## Degradation
250
241
 
251
- Record the answer in the brief; don't re-ask per stage. Stage-5 subagents are
252
- pinned to the confirmed model automatically. Detail: `references/model-tiering.md`.
242
+ - **No python3** → the work-graph verbs and the seeded gate scripts cannot run: the queue degrades to a prose plan, the gates to checklists — said out loud, never silently.
243
+ - **No git** no worktree isolation and no commit-addressed evidence: the run records the weaker claim instead of pretending to the stronger one.
244
+ - **No browser channel** → a web surface is verified by reading the diff, and the close-out records that as the weaker claim it is.
253
245
 
254
246
  ## Bring your own skills
255
247
 
256
248
  The stages above are the **example** flow. A host project owns its pipeline: copy
257
249
  `pipeline.example.json` → `pipeline.json`, define its **own** stages (any count),
258
250
  point each `skills[]` at what its environment resolves, set each `gate.type`
259
- (`auto`/`manual`) to fit its process, and toggle its own `release` block. The
251
+ (`auto`/`judgment`/`manual`) to fit its process, and toggle its own `release`
252
+ block. The
260
253
  framework ships no fixed stage count and no opinion on which gates are manual —
261
254
  `pipeline.schema.json` is the only contract.
262
255
 
263
256
  ## References
264
257
 
265
- Every reference is routed from the **Built-in doctrine** table above, keyed by
266
- the stage that sends you there one home for that mapping rather than two. The
267
- two config contracts sit beside this file: `pipeline.schema.json` (the universal
268
- stages + release contract) and `pipeline.example.json` (this plugin's default
269
- flow as config).
258
+ Most references are routed from the **Built-in doctrine** table above, keyed by
259
+ the stage that sends you there. The rest are routed by prose: `stages.md` (named
260
+ at every stage of *How to run*), `learned.md` (cited where a rule binds) and
261
+ `probing.md` (from `gates.md`, whose checks it proves). The config contracts sit
262
+ beside this file: `pipeline.schema.json` and `pipeline.example.json`.
@@ -65,7 +65,7 @@
65
65
  ],
66
66
  "gate": {
67
67
  "type": "manual",
68
- "check": "UX track ran FIRST for user-facing tasks (/ux -> ux-foundation CJM -> ux-flows screens -> ux-scenarios -> /ux-lint green); spec committed and user-reviewed; every user-facing requirement traces to a scenario ID. Every spec section carries covers: REQ-... and every REQ appears in at least one section. With Figma on: the destination the brief named was used — the canonical record (docs/ux/foundation.md -> Design tooling) holds exactly one file, no file was created while a recorded one resolved, and every screens.md frame link carries that same :fileKey (a string match, not a judgement — a differing key means the run drew in a second file nobody will open)."
68
+ "check": "UX track ran FIRST for user-facing tasks (/ux -> ux-foundation CJM -> ux-flows screens -> ux-scenarios -> /ux-lint green); spec committed and user-reviewed; every user-facing requirement traces to a scenario ID. Every spec section carries covers: REQ-... and every REQ appears in at least one section. With Figma on: the destination the brief named was used — the canonical record (docs/ux/foundation.md -> Design tooling) holds exactly one file, no file was created while a recorded one resolved, and every screens.md frame link carries that same :fileKey (a string match, not a judgement — a differing key means the run drew in a second file nobody will open). COPY and VISUAL are a parallel layer after UX: every user-facing string went through the COPY track or the refusal is recorded, the visual layer went through the VISUAL track or the refusal is recorded, and where both tracks ran their convergence check is recorded - findings with the ruling, or 'Tracks converge: clean'."
69
69
  }
70
70
  },
71
71
  {
@@ -167,14 +167,14 @@
167
167
  ],
168
168
  "gate": {
169
169
  "type": "manual",
170
- "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/evidence/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/evidence/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
+ "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/evidence/retro.md — one file per project, not per run, because every gate in this flow is good at THIS run and blind across runs): STAMP THE RUN FIRST (date, topic, verdict, counts) the order is load-bearing, not style: the cold-retirement trigger reads the stamp this stage writes, so a prune placed ahead of the stamp can never run on real data; THEN PRUNE — every standing instruction checked against its retirement triggers (it became a check; every path/command/stage it names is gone; it has not fired in the last five run stamps, or in the last sixty days), 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, 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/evidence/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."
171
171
  }
172
172
  }
173
173
  ],
174
- "_run_note": "Run-wide pacing. Shipped explicitly OFF so this example DEMONSTRATES the default rather than relying on its absence — see references/continuity.md. Set mode to 'interval' and a project stops being asked whether to run item-by-item; it still stops at every manual gate. There is no context-budget field here on purpose: the threshold is not measurable, so it is unconditional doctrine, not config.",
174
+ "_run_note": "Run-wide pacing. Shipped explicitly OFF so this example DEMONSTRATES the default rather than relying on its absence — see references/continuity.md. (It shipped saying this while mode was 'dynamic' — an example whose note and config disagree arms a loop in every project that copies it verbatim, which is the opposite of demonstrating the default.) The queue, arm and command keys stay filled in as documentation of the shape a project switches on; only mode arms anything. Set mode to 'interval' or 'dynamic' and a project stops being asked whether to run item-by-item; it still stops at every manual gate. There is no context-budget field here on purpose: the threshold is not measurable, so it is unconditional doctrine, not config.",
175
175
  "run": {
176
176
  "loop": {
177
- "mode": "dynamic",
177
+ "mode": "off",
178
178
  "queue": "module-map",
179
179
  "arm": "after-decomposition",
180
180
  "command": "/loop"
@@ -354,7 +354,7 @@ All of:
354
354
  the table was written, and the two pass counts recorded.
355
355
  3. **Every check this gate leans on has been seen failing** at least once against a
356
356
  planted defect (`audit.md` → *Exit criterion*; the procedure, with the commands,
357
- is [`gates.md`](gates.md) → *Probing*). An unproven check's green is not
357
+ is [`probing.md`](probing.md) → *Probing — plant, run, restore*). An unproven check's green is not
358
358
  evidence. That includes **the documentation gate** the project's doc map names
359
359
  ([`documentation.md`](documentation.md)) — stage 9 ran it, this stage is where it
360
360
  is *proven*, and its **ratchet counts are printed beside this verdict**. A
@@ -80,12 +80,23 @@ being *unrecorded* is the defect, not the choice.
80
80
  Usually the map and the gate; often the register already exists in some shape.
81
81
 
82
82
  ```bash
83
- cp <skill>/templates/docmap.md docs/DOCMAP.md # only if absent
84
- cp <skill>/templates/docgate.sh scripts/check-docs.sh # only if absent
85
- cp <skill>/templates/exposure.sh scripts/exposure.sh # only if absent
86
- chmod +x scripts/check-docs.sh scripts/exposure.sh
83
+ cp <skill>/templates/docmap.md docs/DOCMAP.md # only if absent
84
+ cp <skill>/templates/docgate.sh scripts/check-docs.sh # only if absent
85
+ cp <skill>/templates/exposure.sh scripts/exposure.sh # only if absent
86
+ cp <skill>/templates/hygiene.sh scripts/check-hygiene.sh # only if absent
87
+ cp <skill>/templates/stage-coverage.sh scripts/stage-coverage.sh # only if absent
88
+ cp <skill>/templates/convergence.sh scripts/check-convergence.sh # only if absent, and only where the project pins components
89
+ chmod +x scripts/check-docs.sh scripts/exposure.sh scripts/check-hygiene.sh \
90
+ scripts/stage-coverage.sh scripts/check-convergence.sh
87
91
  ```
88
92
 
93
+ The last three are the scripts the later gates run — stage 5 runs
94
+ `check-hygiene.sh` after every task, stage 10 runs `stage-coverage.sh` before the
95
+ coverage table and `check-convergence.sh` where components are pinned
96
+ ([`../templates/README.md`](../templates/README.md) is the full seeding map). A
97
+ fresh host that skips them reaches gates whose commands do not resolve, which
98
+ reads as a broken gate rather than a skipped seeding.
99
+
89
100
  **Seeding never overwrites.** An existing brief, register or map is the project's
90
101
  memory; the template is a skeleton.
91
102
 
@@ -89,8 +89,10 @@ validator). `test/artifact_root_test.py` runs both against one case table and fa
89
89
  they disagree — which is why one rule is allowed two implementations here.
90
90
 
91
91
  **Every** run keeps a **git-ignored** run ledger at `.task-pipeline/run.md`, seeded at
92
- stage 0 from [`../templates/run.md`](../templates/run.md). Three line shapes: a
93
- `stage:` verdict when a gate returns, an `iter:` line when an iteration closes, and a
92
+ stage 0 from [`../templates/run.md`](../templates/run.md), whose *Lines* section
93
+ declares every line shape the list is the count, and a count restated here said
94
+ *three* over a template of eight. Among them: a `stage:` verdict when a gate
95
+ returns, an `iter:` line when an iteration closes, and a
94
96
  `touch:` line per file per repeating pass. Two readers depend on it —
95
97
  [`loop-guard.md`](loop-guard.md) detects churn from the `touch:` lines after a lost
96
98
  context, and [`progress.md`](progress.md) derives the stage rail and the iteration
@@ -122,6 +122,12 @@ Two consequences worth stating, because both are the point:
122
122
  `sev` and `blast` are judgement, and they are written down *as* judgement: two small
123
123
  integers a reader can disagree with, rather than a ranking they can only accept.
124
124
 
125
+ **This column ranks findings against each other.** When findings and product work compete
126
+ in one list — which is what happens the moment somebody asks *what next* — the order comes
127
+ from [`prioritisation.md`](prioritisation.md): an impact ladder that dominates, then
128
+ confidence × ease inside the rung. `sev × blast` is evidence for the rung there, not a
129
+ substitute for it.
130
+
125
131
  ## The shape is not fixed, so nothing may assume it
126
132
 
127
133
  This template ships one shape. Projects change it, and they are right to — the family
@@ -142,7 +142,12 @@ The operator approves the design, **the UI verdict is recorded**, and — where
142
142
  is either covered now or explicitly dropped by the operator, with the drop written
143
143
  into the carry-over ledger. For a platform, the module map
144
144
  ([`decomposition.md`](decomposition.md)) is committed and approved as part of this
145
- same gate. Then, and only then, stage 3 writes it up.
145
+ same gate. Two more criteria close it, and the gate of record —
146
+ [`stages.md`](stages.md) → *2 — Brainstorm + decompose* — states both in full:
147
+ **the queue is an artifact rather than a recollection** (where it is a work graph,
148
+ `graph.py validate` exits 0 and `graph.py coverage` names any requirement no node
149
+ serves), and **the loop's arming state is printed** — armed with its queue and
150
+ pacing, or not armed with the reason. Then, and only then, stage 3 writes it up.
146
151
 
147
152
  ## Rationalizations
148
153
 
@@ -374,6 +374,13 @@ satisfied**, and code quality. The implementer's self-review never substitutes f
374
374
  it. Rubric, inputs, prompt templates and how to build the diff package:
375
375
  [`review.md`](review.md).
376
376
 
377
+ **The boundary with certification:** this review closes a **prose-plan task** —
378
+ one reviewer, the five-round cap of §4.5. A **work-graph node** is closed by the
379
+ three blind tiers and `graph.py certify` instead
380
+ ([`certification.md`](certification.md), ceiling 3); the artifact the queue is —
381
+ plan or graph — decides which protocol closes the work, never whichever is
382
+ cheaper at the moment of closing.
383
+
377
384
  The REQ verdict is the one the other two can't produce: a task can meet every line
378
385
  of its brief and still miss the requirement it was written to deliver. A ❌ there
379
386
  enters the fix loop like any Important finding.
@@ -561,7 +568,10 @@ stages 7–9 run against an unintegrated branch.
561
568
 
562
569
  ## GATE (auto)
563
570
 
564
- All plan tasks DONE with all three review verdicts (spec compliance, REQ satisfied,
571
+ **The hygiene gate green in diff mode after every task** (*The hygiene gate*,
572
+ above) — six checks over what that task changed, no floor, a finding fixed
573
+ in-task or carried over with a reason;
574
+ all plan tasks DONE with all three review verdicts (spec compliance, REQ satisfied,
565
575
  code quality); **every group that actually fanned out has run its convergence check
566
576
  (§4.2a) before its first worktree was integrated, and logged a line either way** —
567
577
  findings with their ruling, or `convergence check clean`; the full test suite green;
@@ -4,6 +4,13 @@ A node is not closed by one agent's opinion. It is closed by **three independent
4
4
  readings at escalating visibility**, and the run may not advance until all three
5
5
  pass.
6
6
 
7
+ **The boundary: this closes a node of the work graph.** Where the queue is a
8
+ prose plan rather than a graph, a task closes through the per-task review instead
9
+ ([`build.md`](build.md) §4.4 and [`review.md`](review.md) — one reviewer, a
10
+ five-round fix loop with an explicit breaker). Two closure protocols with no
11
+ boundary sentence were how a run picked whichever was cheaper; the artifact the
12
+ queue is — graph or plan — is what decides, not the mood of the closer.
13
+
7
14
  ## Contents
8
15
 
9
16
  - Why one verifier is not enough, stated as the failure it produces
@@ -58,6 +58,10 @@ better, plus one that is required only for user-facing work.
58
58
  | **playwright** (CLI — `playwright-cli open`, `snapshot`, `click`, `type`, and the two this pipeline actually asks for: `console` and `requests`; or MCP — `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_console_messages`, `browser_network_requests`) | **stages 5–6 on any project with a web front end**, and **stage 8** on a deployed target — the same job as the row below: open the surface, snapshot it, read the console and the network log. Its own difference is **the channel a look arrives on**: the CLI is a shell command, so it does not put a tool schema in the context window the way an MCP channel does — that is upstream's own comparison and it is *CLI against MCP*, which makes it a claim about this row's own two halves before it is a claim about the row below. Both channels default to an **accessibility-tree snapshot rather than pixels**, so the ordinary look costs a page of text and no vision model; `screenshot` exists in both and costs one when you ask for it | **Recommended** — never a gate; absent → say the surface was verified **by reading the diff** and treat that as the weaker claim it is | CLI: `npm install -D @playwright/cli@latest` → `npx playwright-cli --help` (or `npm i -g` for the global binary; `playwright-cli install --skills` adds its agent skills, `--global` to the home directory). MCP: `claude mcp add playwright npx @playwright/mcp@latest` |
59
59
  | **chrome-devtools** (MCP — `list_pages`, `navigate_page`, `take_snapshot`, `take_screenshot`, `evaluate_script`, `list_console_messages`, `list_network_requests`, `lighthouse_audit`, `performance_start_trace`, `take_heapsnapshot`) | **stages 5–6 on any project with a web front end** — verify the **rendered** surface rather than the diff: computed layout, console errors, failed requests. **Stage 8** on a deployed web target: load the page and read what the browser did, not what the deploy said. Its own difference is **reach past the page**: a Lighthouse category (`lighthouse_audit`, which `seo-aeo-audit` builds on) and a heap snapshot have no equivalent in the row above. A performance trace has one — `playwright-cli tracing-start` records one — but only this row's arrives with `performance_analyze_insight` over it | **Recommended** — never a gate; absent → say the surface was verified **by reading the diff** and treat that as the weaker claim it is | `/plugin install chrome-devtools-mcp@claude-plugins-official` (or connect the MCP server directly) |
60
60
  | **[agent-sync](https://github.com/ssheleg/agent-sync)** (`/agent-sync`, **≥ 1.3.0** — `finish` did not exist before it, so an older install turns the stage-10 close-out into a command that is not there) | **guarded registers** — a lease before writing one, `reserve` before minting an id, `reconcile`/`record` for intent vs as-built, and `finish` for the stage-10 multi-repository close-out ([`documentation.md`](documentation.md)) | **Recommended** — never a gate. Absent → the run is **`ungated`** and must say so out loud; the discipline still applies, only the arbitration is missing | `npx sshlg-skills install` |
61
+ | **sheleg-dev** (`stripe-billing`, `crypto-payments`, `error-tracking`, `ad-tracking`, `google-signin`, `google-auth`, `frontend-performance`) | **stage 5 when the task wires money, tracking, sign-in or page speed** — the seams a generated integration gets wrong in ways no screen shows: the webhook is the payment, a thank-you-page event cannot know the charge cleared, a duplicated `event_id` counts revenue twice | **Recommended** — never a gate; absent → the integration ships on the host's own doctrine and the close-out names the seam nobody checked | `/plugin marketplace add ssheleg/sheleg-dev` → `/plugin install sheleg-dev@sheleg-dev` |
62
+ | **agent-stack** (`agent-orchestrator`, `agent-evals`, `agent-interop`, `agent-harness`) | **stage 5 when the thing being BUILT is an agent system** — the orchestrator's loop, evals that say whether it got better, the protocols it speaks (MCP/A2A), the wallet under LLM resale. Not for coordinating the agents editing this repository (that is agent-sync, above) | **Recommended** — never a gate; absent → the agent layer ships unevaluated and the close-out says so | `/plugin marketplace add ssheleg/agent-stack` → `/plugin install agent-stack@agent-stack` |
63
+ | **telegram-dev** (`telegram-bots`, `telegram-userbots`, `telegram-miniapps`) | **stage 5 when Telegram is the platform, not the transport** — `update_id` as the only idempotency key, a session file that is a logged-in person, a Mini App authenticated by one signed query string | **Recommended** — never a gate; absent → the surface ships on the Bot API docs alone and the close-out names the dedup and auth seams unverified | `/plugin marketplace add ssheleg/telegram-dev` → `/plugin install telegram-dev@telegram-dev` |
64
+ | **seo-aeo-audit** (`/seo-aeo-audit`) | **stage 8 when a logged-out reader or a crawler will see the shipped surface** — the check that a machine will find it; the design-time rule lives with the host, this is the audit after | **Recommended** — never a gate; absent → visibility ships undesigned and unaudited, said in those words | `/plugin marketplace add ssheleg/seo-aeo-audit` → `/plugin install seo-aeo-audit@seo-aeo-audit` |
61
65
  | ~~superpowers~~ | — | **Not a dependency.** Stages 2/4/5/6 run on the built-in doctrine above. See *Optional bridge* | — |
62
66
  | ~~grill-me / grilling~~ | — | **Not a dependency.** The stage-0 grill is built in (`references/grill.md`) | — |
63
67
 
@@ -127,6 +131,23 @@ Pipeline companions (stage doctrine is built in — nothing to install for it):
127
131
  claude mcp add playwright npx @playwright/mcp@latest
128
132
  (running without it — see the line below; without BOTH,
129
133
  the surface is verified by reading the diff)
134
+ ✗ sheleg-dev — this task wires money, tracking, sign-in or page speed;
135
+ it owns the seams no screen shows (the webhook IS the
136
+ payment, a thank-you event cannot know the charge cleared):
137
+ /plugin marketplace add ssheleg/sheleg-dev
138
+ /plugin install sheleg-dev@sheleg-dev
139
+ ✗ agent-stack — the thing being BUILT here is an agent system; it owns
140
+ the loop, the evals, the protocols and the wallet:
141
+ /plugin marketplace add ssheleg/agent-stack
142
+ /plugin install agent-stack@agent-stack
143
+ ✗ telegram-dev — Telegram is this task's platform, not its transport;
144
+ it owns update dedup, session files and Mini App auth:
145
+ /plugin marketplace add ssheleg/telegram-dev
146
+ /plugin install telegram-dev@telegram-dev
147
+ ✗ seo-aeo-audit — a logged-out reader will see the shipped surface;
148
+ stage 8 can audit what a machine will find:
149
+ /plugin marketplace add ssheleg/seo-aeo-audit
150
+ /plugin install seo-aeo-audit@seo-aeo-audit
130
151
  ✗ chrome-devtools — recommended when this project has a web front end:
131
152
  stages 5-6 check the RENDERED surface instead of the
132
153
  diff, stage 8 reads what the browser did after a deploy.
@@ -204,14 +225,24 @@ Rules:
204
225
  the MCP and then *continues text-only on its own*, so without a recorded answer
205
226
  the run silently narrows from "designed" to "described". The sweep row is
206
227
  `3 Design surface` ([`grill.md`](grill.md) → *The autonomy sweep*).
228
+ - **The four domain companions print only when stage-0's own reading warrants
229
+ them** — sheleg-dev when the task wires money, tracking, sign-in or speed;
230
+ agent-stack when the thing being built is an agent system; telegram-dev when
231
+ Telegram is the platform; seo-aeo-audit when a logged-out reader will see the
232
+ surface. A block that offers all four on a CSV parser teaches the operator to
233
+ stop reading the block.
207
234
  - **agent-sync**: detect via a resolving `/agent-sync` or a `.claude/agent-sync.json`
208
235
  in the project. Present → take a lease before writing a guarded register and
209
236
  reserve ids before minting them. Absent → print the line **once**, continue, and
210
237
  **record the run as `ungated`** — never describe the project as protected
211
238
  ([`documentation.md`](documentation.md) → *Registers are shared state*).
212
- - **The behaviour line prints whenever `evals/RESULTS.md` records no blind run**, and
239
+ - **The behaviour line prints whenever the eval ledger records no blind run**, and
213
240
  disappears the moment one is recorded — it is a state of the evidence, not a warning
214
- and not a ratchet. This bundle asks every project it touches for evidence rather than
241
+ and not a ratchet. The ledger is `evals/RESULTS.md` **in this skill's own
242
+ repository** (github.com/ssheleg/task-pipeline) — it does not ship in the bundle,
243
+ so an installed copy that cannot resolve it prints the line with `unknown` in
244
+ place of the counts rather than dropping it: an unreadable ledger and a clean one
245
+ are different facts. This bundle asks every project it touches for evidence rather than
215
246
  assertion, and until 2026-08-10 it made the opposite claim about itself by saying
216
247
  nothing: **one self-observed run by the author, zero blind runs on zero models**, with
217
248
  a preflight that reported companion availability in detail and its own confidence not
@@ -80,8 +80,8 @@ under every link checker, because the checker resolves from the file's home. →
80
80
  planted defect before its pass means anything — and the plant must be proven to have
81
81
  landed in the text the check actually parses. **A model used as a judge is the same
82
82
  object**: until it has been seen disagreeing with a human label on a case known to be
83
- bad, its pass is an opinion with a number attached. → [`gates.md`](gates.md) →
84
- *Probing*; [`learned.md`](learned.md) rules 4 and 5; [`tdd.md`](tdd.md) → *When the
83
+ bad, its pass is an opinion with a number attached. → [`probing.md`](probing.md) →
84
+ *Probing — plant, run, restore*; [`learned.md`](learned.md) rules 4 and 5; [`tdd.md`](tdd.md) → *When the
85
85
  thing under test is an agent*.
86
86
 
87
87
  **6. A check proves its scope and nothing beyond it.** Every gate carries what it does
@@ -82,9 +82,13 @@ invisible *precisely because nobody is running a pipeline*; a check that only ex
82
82
  inside a run can never say *"stop, fourteen things are unconfirmed."* So it takes no
83
83
  brief, opens no grill, and writes nothing on its own.
84
84
 
85
- It prints four sections, each read from a file this pipeline already keeps: the exposure
86
- line and its check-list, the board's open rows by computed priority, the carry-over
87
- ledgers' unresolved count, and the code graph's staleness where one exists.
85
+ It prints one section per source, each read from a file this pipeline already keeps: the
86
+ exposure line and its check-list, the board's open rows by computed priority, the
87
+ carry-over ledgers' unresolved count, the code graph's staleness where one exists — and
88
+ **abandoned runs**: any run ledger whose last `event:` line is `session-end` short of
89
+ acceptance ([`progress.md`](progress.md) → *The run's own lifecycle*). Before that
90
+ last one, a ledger that simply stopped was indistinguishable from a run still in
91
+ progress, which is exactly the invisibility this mode exists to end.
88
92
 
89
93
  **Where the operator asks it to file findings**, it appends board rows whose `Source`
90
94
  names the checkup and its date — so a row a machine created is distinguishable from one a