task-pipeline-skill 1.74.0 → 1.75.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 +66 -0
- package/SKILL-CARD.md +1 -1
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/documentation.md +17 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +92 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.75.0 — 2026-08-22 — the day's findings become doctrine
|
|
4
|
+
|
|
5
|
+
Nothing new ships behind a flag here; what ships is the doctrine the previous release
|
|
6
|
+
earned, written where the next run will read it instead of in a changelog nobody greps.
|
|
7
|
+
|
|
8
|
+
**`documentation.md` canon 2 gains its dual.** *Numbers are computed, never restated* had
|
|
9
|
+
a half nobody had written down: **an example that instantiates a number IS one.** A release
|
|
10
|
+
note explaining that a count was written in the wrong shape — with the digits in it — places
|
|
11
|
+
a second readable count in a section a gate reads, so a probe that removes the real one
|
|
12
|
+
leaves the narrative matching and the guard silent. Measured three times in one hour, each
|
|
13
|
+
time inside prose *about* this very failure. The umbrella already said it for commands:
|
|
14
|
+
name a dead command, never claim it. It holds for a number, a version and a shape.
|
|
15
|
+
|
|
16
|
+
**`gates.md` gains three sections.**
|
|
17
|
+
|
|
18
|
+
*A probe rots, and every way it rots reports green.* The three assertions prove a probe
|
|
19
|
+
works today; the thing it guards is the thing that moves it. An anchor pinned to a literal
|
|
20
|
+
dies on the release that changes the number it guards. A precondition inherited from the
|
|
21
|
+
tree evaporates **when the system works correctly** — an honest run stamp leaves nothing
|
|
22
|
+
"after the newest stamp", a release absorbs the `## Unreleased` section — and the probe
|
|
23
|
+
lands and proves nothing. The triage is one question: *what does this probe look for, and
|
|
24
|
+
who is allowed to change it?*
|
|
25
|
+
|
|
26
|
+
*A ratchet prices the rule, not the exception.* A coverage check that asserts once per
|
|
27
|
+
exception and falls through on the ordinary case makes the correct remediation lower the
|
|
28
|
+
count — so the gate goes red on the stricter answer and a legitimate lowering becomes
|
|
29
|
+
indistinguishable from the failure the floor exists to catch. One assertion per subject
|
|
30
|
+
examined, whatever its verdict. And measure the floor **after** the last edit: read, keep
|
|
31
|
+
editing, restate is how every floor ends up below its true count, silently, because a floor
|
|
32
|
+
is a minimum.
|
|
33
|
+
|
|
34
|
+
*Run the whole suite locally before you push the tag.* Also **R-010**, because it is a
|
|
35
|
+
run-level obligation rather than a note. One tag took five CI rounds where the last four
|
|
36
|
+
were a single twelve-minute local run apart — and the second half is what makes it a rule:
|
|
37
|
+
a branch push cannot see a tag that does not exist yet, so three checks have no earlier
|
|
38
|
+
chance to fire.
|
|
39
|
+
|
|
40
|
+
### And R-010 failed on its own release, which is the finding
|
|
41
|
+
|
|
42
|
+
The local suite was green and CI was not. The difference was one precondition asking
|
|
43
|
+
`os.path.isdir(".git")` — false in a **submodule** checkout, where `.git` is a file holding a
|
|
44
|
+
gitdir pointer. The whole release-gap check had been switching itself off in the only checkout
|
|
45
|
+
this family is developed in, since the day it was written, with no line of output. It ran in CI
|
|
46
|
+
alone, which clones standalone, so a class of defect reached four tag pushes before anyone asked
|
|
47
|
+
why the local run was green.
|
|
48
|
+
|
|
49
|
+
This repository had already recorded that class **twice**, in `docgate.sh` and in the retro log,
|
|
50
|
+
both naming `[ -d .git ]` as the wrong question. This instance was missed both times. Knowing a
|
|
51
|
+
class is not sweeping it — which is standing instruction R-003, also already in force.
|
|
52
|
+
|
|
53
|
+
Two fixes, and the second is the general one: ask `exists`, never `isdir`, of anything named
|
|
54
|
+
`.git`; and **a precondition that fails must disclose rather than skip**. A check guarded by a
|
|
55
|
+
bare `and` evaporates without output, and it evaporates most reliably in the environment its
|
|
56
|
+
authors work in. R-010 gains the half it learned by failing: *a green local suite is not
|
|
57
|
+
evidence until you know which checks looked* — tag locally first, run, then read the `unlooked`
|
|
58
|
+
line before believing the exit code.
|
|
59
|
+
|
|
60
|
+
Seven board citations into `gates.md` were re-pointed across two passes, which is the ordinary
|
|
61
|
+
cost of inserting text above them and the reason those citations carry a phrase as well as a
|
|
62
|
+
range.
|
|
63
|
+
|
|
64
|
+
Guards: 412 → **412**. Flat by construction: this release adds doctrine, not checks, and a
|
|
65
|
+
guard count that rose on a documentation change would be a number borrowed from a suite that
|
|
66
|
+
never ran. The shape of that line is the one canon 2's new half is about, so it is written
|
|
67
|
+
here in the form the guard reads and described nowhere else in this section.
|
|
68
|
+
|
|
3
69
|
## v1.74.0 — 2026-08-20 — a node is closed by three readings, not one
|
|
4
70
|
|
|
5
71
|
**A verifier reads the diff it was handed, and that is the definition of its context, not 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.
|
|
15
|
+
| **Version** | 1.75.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, and **one of two browser channels** — `playwright` (CLI or MCP) or `chrome-devtools` (MCP); either satisfies the browser step and neither is required. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
|
|
18
18
|
| **Evaluation status** | Suite authored, 5 categories. One recorded run, **self-observed by the author**; **zero blind runs on zero of three models** — the split, and the numbers, live in [`evals/RESULTS.md`](evals/RESULTS.md) and are computed by `evals/run.py` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.75.0",
|
|
4
4
|
"description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"task-pipeline": "bin/task-pipeline.js"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "task-pipeline",
|
|
3
3
|
"displayName": "Task Pipeline",
|
|
4
4
|
"description": "Runs a substantial task through a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine is built into the skill — no companion plugin required — with typed auto/manual gates, a frozen requirement spine that closes with evidence, a work board and a verification ledger that outlive a run, an exposure line naming what shipped unconfirmed, a progress rail computed from the project's own config, a loop guard whose review ceiling measures rather than stops, and stage-3 tracks for what a product does, how it sounds and how it looks. Two modes need no task: `checkup` (what is unverified) and `setup` (audit existing docs). Retro insights can publish upstream as issues, opt-in and redacted.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.75.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -49,9 +49,23 @@ the same run and a description of the behaviour is not the behaviour. → the re
|
|
|
49
49
|
SHA-resolution guard; the finding shape in [`setup.md`](setup.md); [`tdd.md`](tdd.md) →
|
|
50
50
|
*When the thing under test is an agent*.
|
|
51
51
|
|
|
52
|
-
**2. Numbers are computed, never restated
|
|
53
|
-
|
|
54
|
-
same object. → [`learned.md`](learned.md)
|
|
52
|
+
**2. Numbers are computed, never restated — and an example that instantiates a number
|
|
53
|
+
IS one.** A count in prose is a number that was true once. Derive it at check time and
|
|
54
|
+
compare the stated one against the computed one as the same object. → [`learned.md`](learned.md)
|
|
55
|
+
rule 8.
|
|
56
|
+
|
|
57
|
+
The half that costs more, because it is written by the person who understands the rule:
|
|
58
|
+
**a document quoting a form as an example is indistinguishable from the form.** A release
|
|
59
|
+
note explaining *"the count was written wrongly as `Guards: 412 → 412`"* has just placed a
|
|
60
|
+
second readable count in a section whose count a gate reads — so when the probe removes the
|
|
61
|
+
real one, the narrative still matches and the guard reports green over a section that states
|
|
62
|
+
nothing. Measured three times in one hour on 2026-08-22, each time inside prose *about* this
|
|
63
|
+
very failure: the release note, the board row filed against it, and the repair to the probe.
|
|
64
|
+
|
|
65
|
+
The rule the umbrella already states for commands — **name a dead command, never claim it**
|
|
66
|
+
— holds for a number, a version and a shape. Describe the wrong form; do not write it.
|
|
67
|
+
*"the bold sat around the whole phrase instead of around the second number"* is checkable by
|
|
68
|
+
a reader and invisible to a pattern; the same sentence with the digits in it is a live claim.
|
|
55
69
|
|
|
56
70
|
**3. Every fact has exactly one home.** Other documents link to it; they never restate
|
|
57
71
|
it. Two homes do not disagree on the day they are written — they disagree on the day one
|
|
@@ -31,6 +31,9 @@ elsewhere and is not restated here:
|
|
|
31
31
|
- Anatomy of a project gate
|
|
32
32
|
- Writing the check itself
|
|
33
33
|
- Probing — plant, run, restore
|
|
34
|
+
- A probe rots, and every way it rots reports green
|
|
35
|
+
- A ratchet prices the rule, not the exception
|
|
36
|
+
- Run the whole suite locally before you push the tag
|
|
34
37
|
- The neighbour probe — plant the evidence outside the subject
|
|
35
38
|
- A ratchet's matcher is itself a check, and it needs a near-miss
|
|
36
39
|
- A green probe is evidence only if the mutation is known to have landed
|
|
@@ -385,6 +388,95 @@ Otherwise the next reader has to redo it to know whether it was ever done.
|
|
|
385
388
|
|
|
386
389
|
---
|
|
387
390
|
|
|
391
|
+
## A probe rots, and every way it rots reports green
|
|
392
|
+
|
|
393
|
+
The three assertions above prove a probe works **today**. They say nothing about the
|
|
394
|
+
day after, and a probe is uniquely exposed: the thing it guards is the thing that moves
|
|
395
|
+
it. Four rotted in one release on 2026-08-22, and none of them failed loudly — two
|
|
396
|
+
reported `caught`, two reported nothing at all.
|
|
397
|
+
|
|
398
|
+
**1. The anchor is a literal the guarded thing moves.** A probe pinned to *"the bundle
|
|
399
|
+
is N reference files"* stops landing the day a reference file is added — on the release
|
|
400
|
+
that changes the very number it guards. Same for a version, a count word, a phrase a
|
|
401
|
+
release rewrites. **Derive the anchor**: read whatever the text currently says and make
|
|
402
|
+
*that* wrong. A probe that computes `wrong = stated - 1` never needs maintaining.
|
|
403
|
+
|
|
404
|
+
**2. The precondition is inherited from the tree rather than created.** This is the
|
|
405
|
+
subtle one, because it is triggered by the system working correctly. A probe that
|
|
406
|
+
narrows a declared gap to expose *releases after the newest run stamp* has nothing to
|
|
407
|
+
expose the moment a release writes an honest stamp — the newest release is now the
|
|
408
|
+
newest stamp. A probe requiring an `## Unreleased` section has none the moment a release
|
|
409
|
+
absorbs it. **Both landed. Both proved nothing.** A probe must construct the state it
|
|
410
|
+
needs: remove the stamp, write the section, then plant the defect.
|
|
411
|
+
|
|
412
|
+
**3. The document quotes the form the probe removes.** Covered as
|
|
413
|
+
[`documentation.md`](documentation.md) canon 2's second half, and it belongs here too
|
|
414
|
+
because the probe is where it surfaces: prose describing the wrong shape *with real
|
|
415
|
+
values in it* is a second instance of the shape. The probe deletes the real one, the
|
|
416
|
+
narrative still matches, the guard is silent.
|
|
417
|
+
|
|
418
|
+
**How to see it before CI does.** Ask one question per probe: *what does this probe
|
|
419
|
+
LOOK FOR, and who is allowed to change it?* Where the answer is "the thing it guards",
|
|
420
|
+
it is rotting already. A repository-wide sweep is one grep — a two-digit literal inside
|
|
421
|
+
a needle, an `assert` or a `replace` — and the triage is: the number a probe **writes**
|
|
422
|
+
is correct, the number it **looks for** is the defect.
|
|
423
|
+
|
|
424
|
+
## A ratchet prices the rule, not the exception
|
|
425
|
+
|
|
426
|
+
A floor that counts assertions is a floor that can be lowered by improving the code, if
|
|
427
|
+
the assertions are attached to the wrong things.
|
|
428
|
+
|
|
429
|
+
Measured: a coverage check called `check()` once per *exception* — a silent value, a kept
|
|
430
|
+
value, a promise — and simply `continue`d on the ordinary case. Collapsing four kept
|
|
431
|
+
values, **the remediation the requirement names first**, therefore dropped the count by
|
|
432
|
+
four against its floor and turned the suite red on the stricter answer. The only way
|
|
433
|
+
through was lowering a ratchet whose own reason says a falling count is how a deleted
|
|
434
|
+
requirement hides — so a legitimate lowering and the failure the floor exists to catch
|
|
435
|
+
became indistinguishable.
|
|
436
|
+
|
|
437
|
+
**One assertion per subject examined, whatever its verdict.** The ordinary case asserts
|
|
438
|
+
too. Then the floor is a function of how large the corpus is, not of how many exceptions
|
|
439
|
+
it happens to contain, and doing the right thing can never lower it.
|
|
440
|
+
|
|
441
|
+
**And measure the floor after the last edit, not before it.** Read the count, keep
|
|
442
|
+
editing, restate the count you read — every floor set that way sits below the true one,
|
|
443
|
+
and a floor is a minimum, so nothing ever says so. Where the gate cannot enforce
|
|
444
|
+
equality — it must not, or the ratchet stops allowing growth — it can still **print the
|
|
445
|
+
gap**: `floor 4026, ran 4027: 1 check is not pinned` turns a silent difference into a
|
|
446
|
+
visible one for the cost of one line.
|
|
447
|
+
|
|
448
|
+
## Run the whole suite locally before you push the tag
|
|
449
|
+
|
|
450
|
+
Not a preference: an arithmetic. A release workflow that runs the full suite takes
|
|
451
|
+
twenty-five to forty minutes per round, and it reports one failure at a time. The same
|
|
452
|
+
suite on the machine that wrote the change takes twelve and reports all of them at once.
|
|
453
|
+
|
|
454
|
+
On 2026-08-22 one tag took **five CI rounds** — a stray key in a `run:` block, a missing
|
|
455
|
+
run stamp, a stamp cap, and then four rotted probes — where a single local `test:all`
|
|
456
|
+
before the first push would have found the last four together. Every refusal was correct.
|
|
457
|
+
The cost was entirely in asking the wrong machine.
|
|
458
|
+
|
|
459
|
+
**A green local suite is not evidence until you know which checks LOOKED.** This
|
|
460
|
+
instruction failed on its own release: the local run was green, CI was not, and the
|
|
461
|
+
difference was a precondition asking `os.path.isdir(".git")` — false in a submodule
|
|
462
|
+
checkout, where `.git` is a *file* holding a gitdir pointer. One check switched itself
|
|
463
|
+
off in the only checkout the family is developed in, silently, and had been doing so
|
|
464
|
+
since it was written. The repository had recorded that class **twice** already, in two
|
|
465
|
+
other files, and this instance was missed both times: knowing a class is not sweeping
|
|
466
|
+
it. Two consequences, and the second is the general one:
|
|
467
|
+
|
|
468
|
+
- ask `exists`, never `isdir`, of anything named `.git`;
|
|
469
|
+
- **a precondition that fails must disclose, not skip.** Where a check cannot run, it
|
|
470
|
+
appends to the unlooked list and the run prints it. A check guarded by a bare `and`
|
|
471
|
+
evaporates without a line of output, which is the one thing this file's own canon
|
|
472
|
+
forbids — and it evaporates most reliably in the environment its authors use.
|
|
473
|
+
|
|
474
|
+
The rule has a second half, and it is the one that makes it stick: **a tag is the only
|
|
475
|
+
thing that runs some checks.** A branch push cannot see a tag that does not exist yet, so
|
|
476
|
+
the tag-ancestry check, the version-sync check and the run-stamp check have no earlier
|
|
477
|
+
opportunity to fire. Locally, run them the way the release does — against the tree you are
|
|
478
|
+
about to tag, with the suite the release claims.
|
|
479
|
+
|
|
388
480
|
## The neighbour probe — plant the evidence outside the subject
|
|
389
481
|
|
|
390
482
|
A probe proves a guard rejects **the phrasing its author had in mind**. That is less than
|