task-pipeline-skill 1.27.0 → 1.28.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,49 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.28.0
4
+
5
+ ### Eight ways to say "I don't know", and no way to count them
6
+
7
+ This bundle has eight vocabularies for declining to claim — `partial`, `unknown`,
8
+ `cannot verify from diff`, `review`, `dormant`, `skip`, `recalled`, `ungated` — spread
9
+ across sixteen reference files. Only one of them, `unknown`, blocks anything. **None of
10
+ them appeared beside a verdict**, and `grep` for a counter returned zero.
11
+
12
+ So `PASS` read as *verified*. It never read as *"green, and here is what nobody claimed
13
+ and what nothing looked at"*, which is the only thing a gate can honestly mean.
14
+
15
+ **The obvious fix is a ratchet, and it is wrong.** A ratchet may only shrink. A count of
16
+ abstentions under that rule puts pressure on exactly one thing: **claiming more**. A run
17
+ that reaches `abstained: 0` is not more careful — it has stopped saying *I don't know*,
18
+ which is the cheapest way to make the number fall. Refusals and wrong answers are
19
+ communicating vessels; squeeze one column and it reappears in the other, silently, because
20
+ a wrong claim looks like a claim.
21
+
22
+ `gates.md` therefore gains a second kind of counted set — a **disclosure**. Printed beside
23
+ the verdict exactly like a ratchet, and carrying the opposite rule: **no floor, no
24
+ direction, and never a target.** A target on an abstention count is an instruction to guess.
25
+
26
+ Two of them, kept apart because they are different facts:
27
+
28
+ | | Counts | How to read it |
29
+ |---|---|---|
30
+ | `abstained` | claims the run **declined to make** — `partial`, `unknown`, `cannot verify from diff` | a **choice**. Rising can mean the work got harder or the run got honest |
31
+ | `unlooked` | checks that **did not look** — `dormant`, `skip` | a **state of the corpus**, not a decision; it falls as the project grows the inputs |
32
+
33
+ `recalled` and `ungated` are deliberately not counted: the first is a property of one claim
34
+ and already lives in the ledger, the second a property of the whole run and said once in
35
+ words. Collapsing all eight into one number would be the false precision this change exists
36
+ to avoid — a figure nobody can act on.
37
+
38
+ Both print beside every worked verdict in the doctrine, both are required by the stage-6 and
39
+ stage-10 gates, and a guard holds the four verdict formats together — one statement on four
40
+ surfaces is this repository's most recurrent defect.
41
+
42
+ **Where this came from.** The programme that produced it started from a review of the
43
+ hallucination-mitigation literature, whose one directly importable idea was that
44
+ *uncertain refusals* belong in the results table **next to** factual errors, because the two
45
+ trade off. Everything else in that literature the doctrine already had. This is the import.
46
+
3
47
  ## v1.27.0
4
48
 
5
49
  ### A retirement trigger whose counter only some work moves
package/CONTRIBUTING.md CHANGED
@@ -317,7 +317,19 @@ stall, which is why it is not belt-and-braces. Entry **rotation** ("entries olde
317
317
  stamps move to the archive") is a different mechanism and is deliberately out of scope.
318
318
  *(guard: `states the cold-retirement condition as five run stamp`)*
319
319
 
320
- **38. 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
320
+ **38. Every worked GATE verdict prints both disclosures.** `abstained` what the run
321
+ declined to claim — and `unlooked` — what a check never looked at. Without them a `PASS`
322
+ reads as *verified* rather than as *"green, and here is what nobody claimed"*. They are
323
+ **not** ratchets and the distinction is load-bearing: a ratchet may only shrink, and an
324
+ abstention count under that rule pressures exactly one thing — claiming more. A run
325
+ reporting `abstained: 0` is not more careful; it stopped saying *I don't know*. Refusals
326
+ and wrong answers are communicating vessels, so a disclosure has no floor, no direction,
327
+ and **may never be given a target** — a target on an abstention count is an instruction to
328
+ guess. This repository had eight vocabularies for declining to claim and, until v1.28.0,
329
+ zero counters.
330
+ *(guard: `a worked GATE verdict omits `)*
331
+
332
+ **39. 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
321
333
  an audit measured it. A claim of enforcement is now checked like any other claim.
322
334
  *(guard: `whose message does not appear in`)* — and a cited literal must lie inside
323
335
  a **single** string in `test/validate.py`: the check reads that file as text, so a
package/SKILL-CARD.md CHANGED
@@ -12,7 +12,7 @@ harmless.
12
12
  |---|---|
13
13
  | **Purpose** | Runs a substantial task through ten gated delivery stages — intake grill, docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs+registers, acceptance — refusing to advance until each gate passes |
14
14
  | **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
15
- | **Version** | 1.27.0 |
15
+ | **Version** | 1.28.0 |
16
16
  | **Surface** | Claude Code (filesystem skill + plugin) and the vercel `skills` CLI. **Not** uploaded to the Skills API; custom Skills do not sync across surfaces |
17
17
  | **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
18
18
  | **Evaluation status** | Suite authored, 5 categories. One recorded run, **self-observed by the author**; **zero blind runs on zero of three models** — the split, and the numbers, live in [`evals/RESULTS.md`](evals/RESULTS.md) and are computed by `evals/run.py` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.27.0",
3
+ "version": "1.28.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.27.0",
5
+ "version": "1.28.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -269,7 +269,7 @@ capable available — see `references/model-tiering.md`).
269
269
  | 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 |
270
270
  | 8 | Post-deploy | tail deploy logs / health-check | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and says nothing about a 404'd bundle or a console full of errors on load (`chrome-devtools`; absent → call it an HTTP response, which is its honest name) | auto |
271
271
  | 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 |
272
- | 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 |
272
+ | 10 | **Acceptance** | built in: [`references/audit.md`](references/audit.md) (ladder walk) → [`references/acceptance.md`](references/acceptance.md) (coverage table) → [`references/retrospective.md`](references/retrospective.md) (retro: stamp, prune, entry) | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **both disclosures printed beside the verdict** — `abstained` (what the run declined to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither with a floor, neither ever a target ([`references/gates.md`](references/gates.md) → *Disclosures*) | manual |
273
273
 
274
274
 
275
275
  ### Stage 10 in a project of several repositories
@@ -198,6 +198,7 @@ ledger's, so a list that quietly grew back is visible at the moment it happened:
198
198
  ```
199
199
  GATE 10 acceptance: PASS — 14/14 REQ verified
200
200
  carry-over: 0 unresolved · retro: 7 standing (was 9) · retired 3 · added 1
201
+ abstained: 2 (1 partial · 1 cannot-verify) · unlooked: 3 dormant
201
202
  ```
202
203
 
203
204
  ## GATE (manual)
@@ -222,6 +223,13 @@ All of:
222
223
  ledger or here) and, for `deferred`, a tracker entry.
223
224
  7. **No carry-over row is left `unresolved`** — every one has a home, and the
224
225
  ledger's counts are printed with this verdict, not just filed.
226
+ 7a. **Both disclosures are printed** ([`gates.md`](gates.md) → *Disclosures*):
227
+ `abstained` — every REQ closing `partial`, every `unknown`, every ⚠️ *cannot verify
228
+ from diff* the controller could not resolve — and `unlooked`, every check that
229
+ reported `dormant` or `skip`. They are **not** ratchets: no floor, no direction, and
230
+ a movement either way wants one sentence. A run reporting `abstained: 0` is claiming
231
+ it knew everything, which is a stronger statement than any run this stage has ever
232
+ seen close honestly.
225
233
  8. **Every repository is closed, the parent included** — `git submodule status`
226
234
  shows no `+`, and each repo is clean and pushed. A submodule is finished when
227
235
  its parent points at it.
@@ -310,6 +310,7 @@ beside the verdict**:
310
310
  ```
311
311
  GATE 6 tests: PASS — full suite green (247 tests)
312
312
  carry-over: 4 open (was 6) · unresolved: 0 · audit findings deferred: 2
313
+ abstained: 1 (1 cannot-verify) · unlooked: 2 dormant
313
314
  ```
314
315
 
315
316
  The difference from a TODO is not bookkeeping. A TODO is invisible until somebody
@@ -32,6 +32,7 @@ elsewhere and is not restated here:
32
32
  - Probing — plant, run, restore
33
33
  - The false-positive budget
34
34
  - Ratchets
35
+ - Disclosures — counted like a ratchet, and deliberately not monotone
35
36
  - Where a gate runs
36
37
  - Adding a check to an existing gate
37
38
  - Rationalizations
@@ -300,10 +301,58 @@ A **ratchet** is a named, counted set that may only shrink, printed on every run
300
301
 
301
302
  ```
302
303
  GATE 9 docs: PASS — propagation backlog: 121 (was 162) · unmarked residue: 0
304
+ abstained: 0 · unlooked: 4 (3 dormant · 1 skip — no submodules in this repo)
303
305
  ```
304
306
 
305
307
  A ratchet nobody prints is a TODO with a better name.
306
308
 
309
+ ## Disclosures — counted like a ratchet, and deliberately not monotone
310
+
311
+ A ratchet may only shrink. **Some numbers must not be**, and printing them under a
312
+ ratchet's discipline inverts the thing they measure.
313
+
314
+ **Abstention is the case that matters.** This bundle has eight vocabularies for declining
315
+ to claim — `partial`, `unknown`, `cannot verify from diff`, `review`, `dormant`, `skip`,
316
+ `recalled`, `ungated` — and until they were counted, none of them appeared beside a
317
+ verdict. So `PASS` read as *verified* rather than as *"green, and here is what nobody
318
+ claimed"*.
319
+
320
+ The obvious fix is a ratchet, and it is wrong. A count of abstentions that may only shrink
321
+ puts pressure on exactly one thing: **claiming more**. A run reaching `abstained: 0` is not
322
+ more careful; it is a run that stopped saying *I don't know*, which is the cheapest way to
323
+ make the number fall. Refusals and wrong answers are communicating vessels — squeeze one
324
+ column and it reappears in the other, silently, because a wrong claim looks like a claim.
325
+
326
+ So a **disclosure** is printed beside the verdict like a ratchet and carries the opposite
327
+ rule: **no floor, no direction, and a movement in either direction wants one sentence.**
328
+
329
+ Two disclosures, kept separate because they are different facts:
330
+
331
+ | Disclosure | Counts | Reading it |
332
+ |---|---|---|
333
+ | `abstained: N` | claims the run **declined to make** — `partial`, `unknown`, `cannot verify from diff` | a *choice*. Rising can mean the work got harder or the run got honest; falling can mean either the reverse |
334
+ | `unlooked: N` | checks that **did not look** — `dormant`, `skip` | a *state of the corpus*, not a decision. It falls as the project grows the inputs those checks need |
335
+
336
+ Three are deliberately **not** counted, and saying which is part of the disclosure:
337
+
338
+ - **`review`** — *no check can decide this* — is an abstention, and it is the one this
339
+ section first listed and then forgot, which is exactly the failure it exists to catch.
340
+ It stays out of `abstained` because it is not a claim the run declined: it is a rule
341
+ that **declined to be mechanical**, recorded once at rung 2 with its reason (→ *Axis B*).
342
+ Counted per run it would report the same standing number every time and say nothing
343
+ about the run.
344
+ - **`recalled`** — a property of one claim, already carried in the ledger beside the
345
+ command that would re-derive it.
346
+ - **`ungated`** — a property of the whole run, said once, in words.
347
+
348
+ A vocabulary that is named and then left out of every bucket is the one that goes
349
+ uncounted forever. So each gets its line, including the one that got missed here.
350
+
351
+ **What makes a disclosure honest rather than decorative** is the same thing that makes a
352
+ ratchet honest: it is *computed*, and it is printed whether or not anyone likes the
353
+ number. What makes it different is that **nobody may set a target for it.** A target on an
354
+ abstention count is an instruction to guess.
355
+
307
356
  ---
308
357
 
309
358
  ## Where a gate runs
@@ -196,6 +196,7 @@ does ([`audit.md`](audit.md) → *What can't be fixed now becomes a ratchet, nev
196
196
  ```
197
197
  GATE 10 acceptance: PASS — 14/14 REQ verified
198
198
  carry-over: 0 unresolved · retro: 7 standing (was 9) · retired 3 · added 1
199
+ abstained: 2 · unlooked: 3
199
200
  ```
200
201
 
201
202
  A pruned list that nobody prints is a list that quietly grows back.
@@ -330,7 +330,10 @@ never that the work was skipped quietly.
330
330
  is covered; no `skip`/`xfail` smuggling a red suite past the gate. Never advance
331
331
  to deploy on a red or partial run. **The carry-over count is printed beside this
332
332
  verdict** — a ratchet nobody prints is a TODO with a better name
333
- ([`audit.md`](audit.md)).
333
+ ([`audit.md`](audit.md)) — **and so are the two disclosures**, `abstained` and
334
+ `unlooked` ([`gates.md`](gates.md) → *Disclosures*): what the run declined to claim,
335
+ and what a check never looked at. Neither has a floor and neither may be targeted; a
336
+ target on an abstention count is an instruction to guess.
334
337
  - **Web front end? Then the surface is checked in a browser, not in the diff.**
335
338
  A passing suite proves the code does what its assertions say. It does not prove the
336
339
  page rendered — a component can be correct and land under a fixed header, a request
@@ -513,7 +516,10 @@ never that the work was skipped quietly.
513
516
  a messy run is the failure the file exists to stop. Stage 0 reads the standing
514
517
  instructions in full next time, which is why the cap is not negotiable.
515
518
  - **GATE (manual):** the ladder walk ran and its absences became REQ rows before
516
- the table was written; **the retrospective is written stamped first, then pruned, then the entry; the
519
+ the table was written; **both disclosures printed beside the verdict** `abstained` (what the run declined
520
+ to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither
521
+ with a floor, neither ever a target ([`gates.md`](gates.md) → *Disclosures*); **the
522
+ retrospective is written — stamped first, then pruned, then the entry; the
517
523
  list at or under its cap, every deletion logged in the archive with its commit,
518
524
  entries older than five run stamps rotated into `docs/superpowers/retro/`, the run
519
525
  stamped with its commit, every SHA in either file resolvable, and the
@@ -36,6 +36,7 @@ set that may only shrink, and it is printed beside every gate verdict:**
36
36
  ```
37
37
  GATE 6 tests: PASS — full suite green (247 tests)
38
38
  carry-over: 4 open (was 6) · unresolved: 0 · audit findings deferred: 2
39
+ abstained: 1 (1 cannot-verify) · unlooked: 2 dormant
39
40
  ```
40
41
 
41
42
  That one line is the whole mechanism. Without it, `PASS` reads as *verified*; with