task-pipeline-skill 1.91.2 → 1.93.2
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 +168 -0
- package/CONTRIBUTING.md +12 -6
- package/HOW-IT-WORKS.md +9 -4
- package/README.md +32 -4
- package/SKILL-CARD.md +1 -1
- package/cursor/rules/task-pipeline.mdc +11 -2
- package/evals/RESULTS.md +1 -1
- package/evals/task-pipeline.evals.json +16 -1
- package/package.json +3 -3
- package/plugins/task-pipeline/.claude-plugin/plugin.json +2 -2
- package/plugins/task-pipeline/commands/task-pipeline.md +23 -8
- package/plugins/task-pipeline/hooks/hooks.json +11 -0
- package/plugins/task-pipeline/hooks/memory-nudge.sh +49 -0
- package/plugins/task-pipeline/skills/evidence-docs/references/hooks.md +3 -1
- package/plugins/task-pipeline/skills/project-audit/SKILL.md +2 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +10 -20
- package/plugins/task-pipeline/skills/task-pipeline/execution-packet.example.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/execution-packet.schema.json +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +8 -2
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +2 -1
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +7 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +4 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/brainstorm.md +6 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/build.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/continuity.md +20 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/decomposition.md +4 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/deploy-targets.md +31 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +14 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/hooks.md +3 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/planning.md +8 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +15 -7
- package/plugins/task-pipeline/skills/task-pipeline/references/waves.md +233 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +3 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/context_packets.py +8 -2
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +89 -5
- package/plugins/task-pipeline/skills/task-pipeline/scripts/packet.py +4 -2
- package/plugins/task-pipeline/skills/task-pipeline/scripts/plan_audit.py +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/stage_checkpoint.py +68 -1
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,171 @@
|
|
|
1
|
+
## v1.93.2 — v1.93.0's payload, with evidence a clone can follow
|
|
2
|
+
|
|
3
|
+
`v1.93.1` published nothing either: its release suite reached the documentation gate
|
|
4
|
+
(`npm run test:docs`, run by `release.yml` and not by the PR's checks) and refused 17
|
|
5
|
+
commit references in `docs/evidence/` — the wave-2 branch SHAs became unreachable when
|
|
6
|
+
PR #109 was squash-merged as `8260042`, and five CI run ids in backticks read as SHAs.
|
|
7
|
+
They now name the squash commit and the runs as plain numbers. Same payload; this is
|
|
8
|
+
the third tag for it, and `docgate.sh` passed locally before this one was pushed.
|
|
9
|
+
|
|
10
|
+
Guards: 438 → **438**; property checks 15 → **15**. No check changed.
|
|
11
|
+
|
|
12
|
+
## v1.93.1 — v1.93.0's payload, released with its stamp declaration
|
|
13
|
+
|
|
14
|
+
`v1.93.0` published nothing: `release.yml` ran the suite on the tag's own tree and
|
|
15
|
+
`validate.py` refused it, because `docs/evidence/retro.md` → *Releases that carry no
|
|
16
|
+
stamp* did not name it — the check working as written (the same shape as `v1.91.1`).
|
|
17
|
+
The tag cannot be removed, so this release ships the same payload with that declaration.
|
|
18
|
+
Everything below under v1.93.0 is what 1.93.1 contains.
|
|
19
|
+
|
|
20
|
+
Guards: 438 → **438**; property checks 15 → **15**. No check changed.
|
|
21
|
+
|
|
22
|
+
## v1.93.0 — the negative self-tests leave the workflow; temp state leaves with the run
|
|
23
|
+
|
|
24
|
+
Integration wave 2 of the family's waves run (R07–R16), one release. The headline is
|
|
25
|
+
the workflow: `.github/workflows/validate.yml` was **507,836 of GitHub's 512,000 bytes**,
|
|
26
|
+
and past that limit a workflow does not go red — it creates no runs and `gh pr checks`
|
|
27
|
+
says *no checks reported*. 448 of its 464 steps were plants and property checks, run one
|
|
28
|
+
after another in one job for 90–111 minutes (runs 38127381666, 38112068258,
|
|
29
|
+
38104711459).
|
|
30
|
+
|
|
31
|
+
- **Every plant is a file (R08, #91).** The 433 negative self-tests and 15 property checks
|
|
32
|
+
moved verbatim into `test/negatives/NNN-<slug>.sh`: line 1 the shebang, line 2
|
|
33
|
+
`# name: <the step's name>`, then the step's `run` value exactly as GitHub parsed it —
|
|
34
|
+
checked byte for byte against the YAML on the commit that moved them. The directory is
|
|
35
|
+
the only list. `validate.yml` fell to 12,181 bytes.
|
|
36
|
+
- **CI shards them.** A `negatives` job runs `python3 test/negatives.py --shard N/8` on an
|
|
37
|
+
eight-value matrix, fail-fast off; each shard is its own runner, so the fixed
|
|
38
|
+
`/tmp/<name>-copy` scratch names still never meet. `--shard I/N` takes every Nth check
|
|
39
|
+
by position, so a red shard is the same set of checks on a maintainer's machine.
|
|
40
|
+
`--list` and `-k` work as before and with `--shard`.
|
|
41
|
+
- **The runner reads the directory, and refuses what it cannot read.** A file with no
|
|
42
|
+
`# name:` header, a name that is neither kind, a bad file name, a duplicate number or
|
|
43
|
+
name — each one stops the run before it starts, and `test/validate.py` fails on the
|
|
44
|
+
same list, because a check the loader drops is a guard nobody proves while every count
|
|
45
|
+
stays green. MIN_EXPECTED and MIN_PROPS count the directory, before any shard.
|
|
46
|
+
- **The runner runs `bash -e`, what GitHub ran.** A `run:` block with no `shell:` is
|
|
47
|
+
`bash -e {0}`; the local runner used plain `bash -c`, and it is now the thing CI runs.
|
|
48
|
+
- **Scratch copies are judged and removed inside each worker.** They were swept only
|
|
49
|
+
after the whole pool returned, so one local run held every copy at once — 433 copies of
|
|
50
|
+
the tree with its `.git`, ~6 GB, measured filling a disk with 4 GB free.
|
|
51
|
+
- **Every check that read the workflow reads the directory**, through the runner's own
|
|
52
|
+
loader: the guard and property counts, the newest CHANGELOG section's counts, the
|
|
53
|
+
floors, `sed -i`, scratch-directory reuse, a scratch dir wiped by a step that does not
|
|
54
|
+
own it, the plant-landed assertion, and the anchor census (`test/anchors.py`). The
|
|
55
|
+
plant-landed check used to skip a name with `)` inside its parentheses; it reads every
|
|
56
|
+
one now. The ten plants whose payload was the workflow text were re-pointed to the
|
|
57
|
+
check files and assert on the value the re-pointed guard reads; the YAML plant breaks
|
|
58
|
+
the first plain step name that is still in the workflow.
|
|
59
|
+
- **New guards, each with its plant:** a `Negative self-test` or `Property check` written
|
|
60
|
+
inline in the workflow again; a shard matrix that does not list every slice the
|
|
61
|
+
runner cuts; a check file the loader cannot read. The workflow-size guard had no
|
|
62
|
+
plant while the file sat 4 KB under the limit — it has one now.
|
|
63
|
+
- **Temp state leaves with the run (R07).** `tp-b80` in `test/validate.py`, the
|
|
64
|
+
`tp-stage-ckpt` trees and 15 test files with bare `mkdtemp` clean up after
|
|
65
|
+
themselves; one machine's TMPDIR held 15,146 `tp-b80-*` trees. A new validator check
|
|
66
|
+
refuses a test file under `test/` — the check files included — that calls `mkdtemp(`,
|
|
67
|
+
`mkstemp(` or keeps a `NamedTemporaryFile(..., delete=False)` and carries no cleanup.
|
|
68
|
+
It is per file, so a file with one cleanup and two leaks passes; writing it found two
|
|
69
|
+
such leaks in `test/validate.py` itself — the graph-coverage tree and the installers'
|
|
70
|
+
fake HOME, ~1.8 MB per validator run and so per plant — and both are fixed.
|
|
71
|
+
- **Budget (R09).** The description is 890 of 1024 chars (909 before; ≤ 900 was the
|
|
72
|
+
target, B-154 in the family board), and the `SKILL.md` body 4646 of the 4750-token
|
|
73
|
+
working limit (4736 before; B-120 asked for 100 spare, and 104 are). The Optional-bridge
|
|
74
|
+
paragraph is trimmed to a pointer (its full text was already in
|
|
75
|
+
`references/companion-skills.md`); the kernel-precedence rule stays
|
|
76
|
+
in `SKILL.md`, which `fix-tp-03.01` pins.
|
|
77
|
+
- **Execution packets carry a namespaced id (R14):** `task-pipeline/execution-packet/1`.
|
|
78
|
+
Fabric's former packet used the bare `execution-packet/1` until it renamed its format
|
|
79
|
+
`session-handoff/1`; `packet.py`, `context_packets.py` and the schema still read the bare
|
|
80
|
+
id: 19 live packets in one consumer repository carry it (B-135), so it is refused only
|
|
81
|
+
after they are migrated.
|
|
82
|
+
- **Wave mode reads declared task sources (R13).** Where a repository declares them in
|
|
83
|
+
`docs/backlog-sources.json`, the harvest reads exactly those, updates status only in
|
|
84
|
+
the owning files and never edits a generated view.
|
|
85
|
+
- **The release stage reads the approval mode (R16).** `pipeline.json` `release.approval`
|
|
86
|
+
is `checks` (tag, watch, report) or `reviewers` (the direct link to the run that is
|
|
87
|
+
actually waiting); absent, it is read from the organisation or the environment, never
|
|
88
|
+
assumed.
|
|
89
|
+
- **Fabric's pipeline adapter is a pinned contract (R15).** `test/fixtures/
|
|
90
|
+
fabric-pipeline-contract.json` pins `passioncode-ai/fabric` main `5bf15e5c`, and
|
|
91
|
+
`fix-pf-06.01` checks the gate types and the example config against it with no Fabric
|
|
92
|
+
checkout.
|
|
93
|
+
- **Continuity through Observatory (R11).** `stage_checkpoint.py` gains `handoff` and
|
|
94
|
+
`accept`; `hooks/memory-nudge.sh` reminds once per returned gate that wrote no memory
|
|
95
|
+
event.
|
|
96
|
+
- **Ledgers (R10).** The verification headers say *released*; this repository's merged
|
|
97
|
+
branches are gone.
|
|
98
|
+
|
|
99
|
+
Guards: 433 → **438**; property checks 15 → **15**. The five new plants are files in
|
|
100
|
+
`test/negatives/` (449–453); every guard's plant was run on this tree, and the CI wall
|
|
101
|
+
clock per shard is in `docs/evidence/verification.md`.
|
|
102
|
+
|
|
103
|
+
## v1.92.0 — wave mode: the whole board, closed in its final form; the grill asks one batch
|
|
104
|
+
|
|
105
|
+
The operator's standard approach, decided on 2026-10-11 and codified here: when the request
|
|
106
|
+
is not one change but **the whole board** — every open item plus the new requests — gather
|
|
107
|
+
it all first, close every question the sources can close, ask what remains **once, as one
|
|
108
|
+
batch, at the end of planning**, lay the target state over the current logic on one canvas,
|
|
109
|
+
plan from the post-integration target, and cut the work into waves that each close in one
|
|
110
|
+
pass, with a verification, finishing, fixing and documentation pass after every wave. The
|
|
111
|
+
run takes the next wave without asking, says once when the board is empty, and leaves every
|
|
112
|
+
sign-in, consent, payment, message to a person and outward act to a human. The rule under
|
|
113
|
+
all of it: **build the system in its final form, never through intermediate states.**
|
|
114
|
+
|
|
115
|
+
- **`references/waves.md`, invoked as `/task-pipeline waves`** — a third mode beside `setup`
|
|
116
|
+
and `checkup`, and a program mode of the existing stages, not a parallel cycle: stages 0–4
|
|
117
|
+
once for the whole board, 5–8 per wave, 9–10 to close the release. Wave 0 is the survey
|
|
118
|
+
(with `project-audit` as a read-only sidecar for whole-project scope) and **one
|
|
119
|
+
machine-readable inventory**, every item by id with `id`, `source`, `status`, `area`,
|
|
120
|
+
`node`, `wave`, `release`, verified against the code — stale rows closed with their
|
|
121
|
+
receipt, duplicates clustered — and assigned to nodes and waves by a committed,
|
|
122
|
+
deterministic script. The **canvas** extends the module map: as-is → to-be per module and
|
|
123
|
+
contract, the integration seams, REQ → module → wave, and what the new version deletes.
|
|
124
|
+
No wave builds a shape a later wave undoes; a stub only at a declared contract with its
|
|
125
|
+
removal named. Wave 1 is the walking skeleton, and each wave names its exit criteria
|
|
126
|
+
before it starts. The close pass after each wave certifies, re-measures `audit.md`'s
|
|
127
|
+
exit, runs **one fix round** under the loop guard's caps, documents through the Doc Loop
|
|
128
|
+
scoped to the wave, marks the canvas, re-reads the goal, and re-cuts what is left. A board
|
|
129
|
+
bigger than one release becomes a program, carried on the canvas by node, never dropped.
|
|
130
|
+
The name is not "dynamic": that word is `run.loop.mode: dynamic`'s.
|
|
131
|
+
- **The grill's default changed — a decision by the operator, 2026-10-11.** It was *one
|
|
132
|
+
question per turn, never bundle*. It is now: close from the sources first, then ONE batch
|
|
133
|
+
of the material unknowns, ordered by dependency, each with a recommended answer and what
|
|
134
|
+
each answer changes; one question at a time only where answers depend on each other
|
|
135
|
+
(then depth-first) or when the operator asks for it. The reason is the operator's time: a
|
|
136
|
+
question asked alone costs a human round and a batch costs one, and
|
|
137
|
+
`prioritisation.md` → *5. Where the human goes* already said so for the rest of the run.
|
|
138
|
+
Mirrored in `grill.md`, `stages.md` (stages 0 and 2), `brainstorm.md`, the command, the
|
|
139
|
+
Cursor rule, `HOW-IT-WORKS.md`, the README, `pipeline.example.json`, this repository's
|
|
140
|
+
`pipeline.json`, and eval TRIG-01; TRIG-11 is the wave-mode trigger in Russian.
|
|
141
|
+
- **`continuity.md`: a block or an ambiguity stops its node, not the run.** The node is
|
|
142
|
+
parked `needs-operator` with the question written into it, the run continues on what it
|
|
143
|
+
does not block, and stops only when the whole frontier is blocked. An empty board is said
|
|
144
|
+
once. A goal re-read that moves the queue is a committed `revisions` entry.
|
|
145
|
+
- **`planning.md`: a wave re-cut keeps the static-graph decision** — every move is a
|
|
146
|
+
`revisions` entry plus a canvas edit, written before the next pass begins.
|
|
147
|
+
**`decomposition.md`**: the whole board runs one wave at a time, and a wave may hold several
|
|
148
|
+
bricks. **`build.md`**: "fix wave" is now "fix round", so *wave* means one thing.
|
|
149
|
+
**`project-audit`**: its rows and sidecar are wave mode's wave-0 input.
|
|
150
|
+
- **The work graph carries the wave.** `graph.schema.json` gains `nodes[].wave` (an integer
|
|
151
|
+
from 1) and the `wave` revision verb. `graph.py validate` refuses an edge from a later
|
|
152
|
+
wave's node into an earlier wave's node; `graph.py next --wave N` prints that wave's
|
|
153
|
+
frontier only, exiting `3` when the wave is done; `graph.py wave N-007 --to 3 --why …`
|
|
154
|
+
moves a node, writes the revision, and refuses a move that breaks the order, a `done`
|
|
155
|
+
node, or no reason. `test/graph_test.py` 158 → **166** cases.
|
|
156
|
+
- **The description names the mode** and paid for it: `'waves' / 'волнами' closes the whole
|
|
157
|
+
board`, while the stage list reads *through gated stages: …* instead of *… with explicit
|
|
158
|
+
gates*, `docs study` reads `docs`, and `docs/wiki sync` reads `docs/wiki`. 901 → 909 of
|
|
159
|
+
1024 chars — inside the umbrella's 60-character reserve below the 970 working limit,
|
|
160
|
+
which a longer description would have broken. The `SKILL.md` body is 4736 tokens
|
|
161
|
+
(cl100k), one under where it was: the new sentence in *How to run* displaced a restated
|
|
162
|
+
kernel clause and the compiler sentence's tail.
|
|
163
|
+
|
|
164
|
+
Guards: 430 → **433**. The three new negatives live in `test/plant_wave.py` (the workflow
|
|
165
|
+
sits near GitHub's 512 000-byte limit) and disarm the order check, the `--wave` filter and
|
|
166
|
+
the re-cut's revision in turn; each was watched turning `test/graph_test.py` red before the
|
|
167
|
+
step was written.
|
|
168
|
+
|
|
1
169
|
## v1.91.2 — v1.91.1's payload, released with its no-stamp declaration
|
|
2
170
|
|
|
3
171
|
`release.yml` refused the `v1.91.1` tag's own tree: the release carried no run stamp and was
|
package/CONTRIBUTING.md
CHANGED
|
@@ -27,9 +27,13 @@ npm run test:negatives # python3 test/negatives.py
|
|
|
27
27
|
npm run test:all # both, in order
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
The corruptions live in [
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
The corruptions live in [`test/negatives/`](test/negatives/), one file per check —
|
|
31
|
+
`#!/usr/bin/env bash`, then `# name: Negative self-test (<what is planted>)`, then
|
|
32
|
+
the script, run from the repository root. `test/negatives.py` reads that directory
|
|
33
|
+
and nothing else, so it is the only list; CI runs it in eight shards
|
|
34
|
+
(`--shard N/8`, the `negatives` job in `validate.yml`). Until v1.93.0 every plant was
|
|
35
|
+
an inline workflow step, and the workflow reached 507,836 of GitHub's 512,000 bytes —
|
|
36
|
+
past the limit a workflow creates no runs rather than going red. The runner also tells a **broken
|
|
33
37
|
test** from a **guard that didn't fire**: if a planted defect changed nothing, the
|
|
34
38
|
validator passing means the test proved nothing, and it is reported as `BROKEN`
|
|
35
39
|
rather than as a failure of the guard.
|
|
@@ -37,7 +41,7 @@ rather than as a failure of the guard.
|
|
|
37
41
|
**Corrupt files in python, never with `sed -i`.** BSD sed needs an argument GNU sed
|
|
38
42
|
refuses, and `0,/re/` does not exist on BSD at all — there it edits nothing
|
|
39
43
|
silently, and the test reads as a guard that failed. The validator rejects `sed -i`
|
|
40
|
-
in
|
|
44
|
+
in a check file for exactly this reason: a self-test that only runs on CI cannot be
|
|
41
45
|
used while you are writing the guard, which is the moment it is worth most.
|
|
42
46
|
|
|
43
47
|
To try your change in a real agent:
|
|
@@ -616,8 +620,10 @@ pass over an empty set is a refused measurement.
|
|
|
616
620
|
`pipeline.example.json`, the command, the Cursor rule and the README before you
|
|
617
621
|
commit. The validator catches much of this — do not rely on it to think for you.
|
|
618
622
|
- **A new guard needs a negative self-test.** If you teach `test/validate.py` a new
|
|
619
|
-
rule, add
|
|
620
|
-
asserts the validator fails, then watch it with
|
|
623
|
+
rule, add the next-numbered file to `test/negatives/` that corrupts a copy and
|
|
624
|
+
asserts the validator fails, then watch it with
|
|
625
|
+
`python3 test/negatives.py -k <words from its name>`. Never a step inline in the
|
|
626
|
+
workflow: the validator refuses one, because it would run on CI only. A guard
|
|
621
627
|
nobody proved can fail is decoration. **Check the base is green first** — if the
|
|
622
628
|
repo already fails your new rule, the self-test passes for the wrong reason and
|
|
623
629
|
proves nothing.
|
package/HOW-IT-WORKS.md
CHANGED
|
@@ -46,7 +46,9 @@ It is written in three parts, and the middle one was learned the hard way:
|
|
|
46
46
|
the pipeline entirely.
|
|
47
47
|
|
|
48
48
|
Two modes need no task at all. `checkup` reports what has shipped without anyone
|
|
49
|
-
confirming it. `setup` audits the documentation a project already has.
|
|
49
|
+
confirming it. `setup` audits the documentation a project already has. A third,
|
|
50
|
+
`waves`, takes the whole board as the task: one inventory, one canvas of the target
|
|
51
|
+
state, one batch of questions, then waves that each close in one pass.
|
|
50
52
|
|
|
51
53
|
**Honest limit:** this measures the *description's* discriminating power, not the
|
|
52
54
|
host's selection machinery. Three measured runs scored 7/10, 9/10 and 8/10 — and
|
|
@@ -92,8 +94,10 @@ An absent source that is never named looks identical to a source that was read.
|
|
|
92
94
|
|
|
93
95
|
### Then the grill, and it is mandatory
|
|
94
96
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
Close what the sources can answer, then ask the material unknowns in one batch,
|
|
98
|
+
ordered by dependency, each with a recommended answer — one at a time only where the
|
|
99
|
+
answers depend on each other or the operator asks — until every decision branch is
|
|
100
|
+
resolved.
|
|
97
101
|
|
|
98
102
|
- **Every answer is validated against the harvested sources.** The operator
|
|
99
103
|
outranks any document — but only *out loud*, and a document the run proves stale
|
|
@@ -238,7 +242,8 @@ This is the part most pipelines skip, and it is the reason this one is trustwort
|
|
|
238
242
|
rather than merely tidy.
|
|
239
243
|
|
|
240
244
|
**Every guard is proven against a planted defect.** `npm run test:all` breaks the
|
|
241
|
-
thing each
|
|
245
|
+
thing each check is about, and requires that check to reject it — one file per
|
|
246
|
+
check in `test/negatives/`, eight shards on CI. A
|
|
242
247
|
guard that has never been watched failing is not a guard; it is a comment.
|
|
243
248
|
|
|
244
249
|
**The neighbour probe.** A check has a *subject* — the rule it is about — and
|
package/README.md
CHANGED
|
@@ -200,6 +200,8 @@ until it is installed.
|
|
|
200
200
|
| 3 + 4 · every spec and plan | the self-review reads its rules back — is every named check real, does anything contradict a locked decision or a rejected option, and what does this cost now versus at design time. Answers land as a committed `## Self-review` of computed numbers |
|
|
201
201
|
| 6–10 + any check you write | [`gates.md`](plugins/task-pipeline/skills/task-pipeline/references/gates.md) — the three axes, the promotion ladder, gate anatomy, the probe recipe, ratchet floors |
|
|
202
202
|
| any agent-time enforcement | [`hooks.md`](plugins/task-pipeline/skills/task-pipeline/references/hooks.md) — the `PreToolUse` contract, the fail-open hazard, the Claude-Code-only limit |
|
|
203
|
+
| 7 · the tag | [`deploy-targets.md`](plugins/task-pipeline/skills/task-pipeline/references/deploy-targets.md) → *When the release waits for an approval* — `pipeline.json` → `release.approval`: `checks` (tag, watch the run selected by the tag, report) or `reviewers` (the direct link to the run that is `waiting`) |
|
|
204
|
+
| between stages | [`continuity.md`](plugins/task-pipeline/skills/task-pipeline/references/continuity.md) Part 3 — workflow memory through Observatory, a planned handoff (`stage_checkpoint.py handoff` / `accept`), and `hooks/memory-nudge.sh`, which reminds once when a gate returned with no memory line after it |
|
|
203
205
|
|
|
204
206
|
**Ported, not depended on.** Stage 0 is adapted from
|
|
205
207
|
[Matt Pocock's `grilling` / `grill-with-docs`](https://github.com/mattpocock/skills)
|
|
@@ -214,9 +216,11 @@ an external provider.
|
|
|
214
216
|
|
|
215
217
|
### The intake grill (stage 0) — mandatory
|
|
216
218
|
|
|
217
|
-
Before any technical work, task-pipeline
|
|
218
|
-
|
|
219
|
-
|
|
219
|
+
Before any technical work, task-pipeline closes every question the codebase and the
|
|
220
|
+
project's records can answer, then asks you the rest in **one batch**, ordered by
|
|
221
|
+
dependency, each with a recommended answer — one at a time only where the answers
|
|
222
|
+
depend on each other or you ask for it — until every decision branch is resolved and
|
|
223
|
+
locked into a **task brief**. There is
|
|
220
224
|
no "clear enough task" exemption: no stage-1 work starts without a committed,
|
|
221
225
|
confirmed brief.
|
|
222
226
|
|
|
@@ -444,6 +448,29 @@ stopped. Each module's spec is a full dossier: architecture, entities and
|
|
|
444
448
|
ownership, contracts in and out with their failure behavior, business rules, edge
|
|
445
449
|
and failure cases, UI/Figma chain, limits, open questions.
|
|
446
450
|
|
|
451
|
+
### Wave mode — the whole board, closed in its final form
|
|
452
|
+
|
|
453
|
+
`/task-pipeline waves` takes every open item a project carries — the board, the
|
|
454
|
+
carry-over ledgers, plan rows, unverified rows, uncovered scenarios, other products'
|
|
455
|
+
asks — plus your new requests, and closes them **in the system's final form rather
|
|
456
|
+
than through intermediate states**
|
|
457
|
+
([`waves.md`](plugins/task-pipeline/skills/task-pipeline/references/waves.md)). It is
|
|
458
|
+
a program mode of the same stages: 0–4 once for the whole board, 5–8 once per wave,
|
|
459
|
+
9–10 to close.
|
|
460
|
+
|
|
461
|
+
Wave 0 is the survey: one machine-readable inventory of every item by id, each verified
|
|
462
|
+
against the code — stale rows closed with their receipt, duplicates clustered. Questions
|
|
463
|
+
are closed from the sources first; what is genuinely yours (access, consent, money,
|
|
464
|
+
direction, an outward act) reaches you **once, as one batch, at the end of planning**,
|
|
465
|
+
each with a recommendation. A committed **canvas** lays the target state over the
|
|
466
|
+
current logic — as-is → to-be per module and contract, the integration seams, REQ →
|
|
467
|
+
module → wave, and what the new version deletes. The work is then cut into waves that
|
|
468
|
+
each close in one pass, the walking skeleton first, each with its exit criteria named
|
|
469
|
+
before it starts, and no wave builds a shape a later wave undoes. After every wave a
|
|
470
|
+
close pass verifies, runs one fix round, updates the docs, re-measures the inventory
|
|
471
|
+
and re-cuts what is left. The run takes the next wave without asking; a board too big
|
|
472
|
+
for one release becomes a program, carried on the canvas, never dropped.
|
|
473
|
+
|
|
447
474
|
### Loop guard — churn is detected, not endured
|
|
448
475
|
|
|
449
476
|
Any repeating pass can start undoing the previous one: two shapes alternating, the
|
|
@@ -587,7 +614,7 @@ must say so.
|
|
|
587
614
|
### Held to Anthropic's own Skill authoring guidance
|
|
588
615
|
|
|
589
616
|
Audited against the four Agent Skills pages. Most of it already held — `name`
|
|
590
|
-
13/64 chars, `description`
|
|
617
|
+
13/64 chars, `description` 890/1024 chars, `SKILL.md` 268/500 lines, all 40 references
|
|
591
618
|
linked **directly** from `SKILL.md`, and the bundle far under the 30 MB ceiling. What
|
|
592
619
|
did not, now does:
|
|
593
620
|
|
|
@@ -942,6 +969,7 @@ recommendation, so you arm the whole run in one exchange. Detail:
|
|
|
942
969
|
| [`references/model-tiering.md`](plugins/task-pipeline/skills/task-pipeline/references/model-tiering.md) | model policy, the `/model` reminder, overrides |
|
|
943
970
|
| [`templates/`](plugins/task-pipeline/skills/task-pipeline/templates/README.md) | brief, carry-over ledger, `CONTEXT.md` and ADR skeletons, the doc map, both registers, the retro and its archive, the seeded `docgate.sh` and `hygiene.sh`, a worked hook |
|
|
944
971
|
| [`references/adoption.md`](plugins/task-pipeline/skills/task-pipeline/references/adoption.md) | the first run in a project: greenfield seeding, and the brownfield walkthrough |
|
|
972
|
+
| [`references/waves.md`](plugins/task-pipeline/skills/task-pipeline/references/waves.md) | wave mode: the whole board as one inventory, one canvas of the target state, one question batch, then waves that each close in one pass |
|
|
945
973
|
| [`references/setup.md`](plugins/task-pipeline/skills/task-pipeline/references/setup.md) | the entry audit: seven passes over the docs a project already has, offered once, output as a fix plan |
|
|
946
974
|
| [`references/portability.md`](plugins/task-pipeline/skills/task-pipeline/references/portability.md) | the manifest of workflow decisions and their homes in the bundle, and the boundary against a project's own answers |
|
|
947
975
|
| [`references/learned.md`](plugins/task-pipeline/skills/task-pipeline/references/learned.md) | rules earned by failure on a real multi-repository build, each with its incident, its check and its exit criterion — the table is the count, and it grows |
|
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.93.2 |
|
|
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` |
|
|
@@ -108,7 +108,9 @@ built, recommend it once and continue: `uv tool install graphifyy` →
|
|
|
108
108
|
|
|
109
109
|
**Phase 2 — grill the user against that harvest**, then run the rest without
|
|
110
110
|
mid-flight questions:
|
|
111
|
-
1.
|
|
111
|
+
1. Close what the sources answer; ask the rest in ONE batch, ordered by
|
|
112
|
+
dependency. One at a time only when answers depend on each other or the user
|
|
113
|
+
asks.
|
|
112
114
|
2. Give a recommended answer with every question (+ one-line rationale).
|
|
113
115
|
3. Explore the codebase before asking — if a search/read answers it, do that.
|
|
114
116
|
4. **Validate every answer against the harvest.** When what the user says
|
|
@@ -211,7 +213,14 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
|
|
|
211
213
|
first**, then topologically, no cycles (a cycle means the cut is wrong). Every REQ
|
|
212
214
|
maps to exactly one module. Then stages 3→10 run **per module**, one brick at a
|
|
213
215
|
time; stages 0–2 run once, and the map's status column is the resume point. Single
|
|
214
|
-
module → record "single module: <name>" and move on.
|
|
216
|
+
module → record "single module: <name>" and move on. **If the request is the whole
|
|
217
|
+
board** (wave mode, `waves`) — every open item plus the new requests — stages 0–4
|
|
218
|
+
run once over one machine-readable inventory verified against the code and a
|
|
219
|
+
committed canvas of the target state; the work is cut into waves that each close
|
|
220
|
+
in one pass (wave 1 the walking skeleton, exit criteria named first); stages 5–8
|
|
221
|
+
run per wave with a close pass after each — verify, one fix round, docs,
|
|
222
|
+
re-measure, re-cut — and 9–10 close the release. No wave builds a shape a later
|
|
223
|
+
wave undoes.
|
|
215
224
|
3. **Spec** (manual) — write and commit the design; lock every shared contract
|
|
216
225
|
(types, schemas, signatures, file layout) plus a **Global Constraints** block of
|
|
217
226
|
exact values every later task inherits. Self-review it for placeholders,
|
package/evals/RESULTS.md
CHANGED
|
@@ -40,7 +40,7 @@ or it belongs in a check.
|
|
|
40
40
|
|
|
41
41
|
| Metric | Value | Computed by | As of |
|
|
42
42
|
|---|---|---|---|
|
|
43
|
-
| Evals authored |
|
|
43
|
+
| Evals authored | 47 (three suites: task-pipeline 29, evidence-docs 9, project-audit 9) | `python3 evals/run.py` → `suite: N evals` | 2026-10-11 |
|
|
44
44
|
| Categories covered | 5 of 5, per suite | the suite's own `category` fields | 2026-08-31 |
|
|
45
45
|
| Dated runs recorded | **4** | `python3 evals/run.py` → `recorded runs: N` | 2026-08-31 |
|
|
46
46
|
| …of those, **blind** | **3** | run headings not marked `self-observed` | 2026-08-31 |
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"expected_behavior": [
|
|
18
18
|
"Invokes the task-pipeline skill rather than starting to design or code inline",
|
|
19
19
|
"Runs the stage-0 knowledge harvest BEFORE the first interview question, and writes a source ledger",
|
|
20
|
-
"Asks interview questions one
|
|
20
|
+
"Asks the material interview questions in one batch ordered by dependency, each with a recommended answer, after closing what the sources answer",
|
|
21
21
|
"Writes no implementation code before a brief is committed and confirmed"
|
|
22
22
|
],
|
|
23
23
|
"why": "The explicit invocation phrase is the primary trigger; the failure it guards is jumping to code."
|
|
@@ -361,6 +361,21 @@
|
|
|
361
361
|
],
|
|
362
362
|
"why": "Measured before the change: answered `none` because no description offered a phrase for reviewing a PR, while review.md owns exactly that contract."
|
|
363
363
|
},
|
|
364
|
+
{
|
|
365
|
+
"id": "TRIG-11",
|
|
366
|
+
"category": "should_trigger",
|
|
367
|
+
"skills": [
|
|
368
|
+
"task-pipeline"
|
|
369
|
+
],
|
|
370
|
+
"query": "собери все задачи с доски и новые запросы и закрой их волнами",
|
|
371
|
+
"expected_behavior": [
|
|
372
|
+
"Recognises this as wave mode and runs `/task-pipeline waves`, not one change at a time",
|
|
373
|
+
"Builds one machine-readable inventory of every open item by id, each verified against the code, before any design",
|
|
374
|
+
"Closes questions from the sources first and asks the operator the rest once, as one batch with a recommendation each, at the end of planning",
|
|
375
|
+
"Cuts the work into waves that each close in one pass, wave 1 the walking skeleton, each with its exit criteria named before it starts"
|
|
376
|
+
],
|
|
377
|
+
"why": "Wave mode is the operator's standard approach for a whole board (2026-10-11). A model that cannot reach it from the natural Russian request runs the board item by item and builds the intermediate states the mode exists to refuse."
|
|
378
|
+
},
|
|
364
379
|
{
|
|
365
380
|
"id": "NOTRIG-06",
|
|
366
381
|
"category": "should_not_trigger",
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.93.2",
|
|
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"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "python3 test/validate.py && python3 test/graph_test.py && python3 test/project_audit_test.py && python3 test/packet_schema_test.py && python3 test/browser_claims_test.py && python3 test/visual_gate_test.py && python3 test/stage_checkpoint_test.py && npm run test:audit-regressions",
|
|
10
|
-
"test:all": "python3 test/validate.py && python3 test/graph_test.py && python3 test/project_audit_test.py && python3 test/packet_schema_test.py && python3 test/browser_claims_test.py && python3 test/visual_gate_test.py && python3 test/stage_checkpoint_test.py && python3 test/negatives.py && npm run test:certify && npm run test:exposure && npm run test:probe && npm run test:anchors && npm run test:runner && npm run test:hooks && npm run test:artifacts && npm run test:docs && npm run test:audit-regressions",
|
|
9
|
+
"test": "python3 test/validate.py && python3 test/graph_test.py && python3 test/project_audit_test.py && python3 test/packet_schema_test.py && python3 test/browser_claims_test.py && python3 test/visual_gate_test.py && python3 test/stage_checkpoint_test.py && python3 test/memory_nudge_test.py && npm run test:audit-regressions",
|
|
10
|
+
"test:all": "python3 test/validate.py && python3 test/graph_test.py && python3 test/project_audit_test.py && python3 test/packet_schema_test.py && python3 test/browser_claims_test.py && python3 test/visual_gate_test.py && python3 test/stage_checkpoint_test.py && python3 test/memory_nudge_test.py && python3 test/negatives.py && npm run test:certify && npm run test:exposure && npm run test:probe && npm run test:anchors && npm run test:runner && npm run test:hooks && npm run test:artifacts && npm run test:docs && npm run test:audit-regressions",
|
|
11
11
|
"test:negatives": "python3 test/negatives.py",
|
|
12
12
|
"test:exposure": "python3 test/exposure_test.py",
|
|
13
13
|
"test:probe": "python3 test/probe.py --self-test",
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "task-pipeline",
|
|
4
4
|
"displayName": "Task Pipeline",
|
|
5
|
-
"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/judgment/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.",
|
|
6
|
-
"version": "1.
|
|
5
|
+
"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/judgment/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); a third, `waves`, takes the whole board and closes it in waves that each finish in one pass. Retro insights can publish upstream as issues, opt-in and redacted.",
|
|
6
|
+
"version": "1.93.2",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "ssheleg",
|
|
9
9
|
"url": "https://x.com/sshlg93"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Run a task through task-pipeline's gated stages (intake grill → docs → brainstorm → spec → plan → build → tests → deploy → post-deploy → docs/wiki → acceptance). Also: `setup` — audit the docs you already have; `checkup` — what has shipped unverified, with no task running."
|
|
3
|
-
argument-hint: "<one-line task> | setup | checkup"
|
|
2
|
+
description: "Run a task through task-pipeline's gated stages (intake grill → docs → brainstorm → spec → plan → build → tests → deploy → post-deploy → docs/wiki → acceptance). Also: `waves` — close the whole board in waves; `setup` — audit the docs you already have; `checkup` — what has shipped unverified, with no task running."
|
|
3
|
+
argument-hint: "<one-line task> | waves | setup | checkup"
|
|
4
4
|
---
|
|
5
5
|
Run the task below through `task-pipeline`'s gated stages. **Every stage's doctrine
|
|
6
6
|
ships inside the skill** — no companion plugin is required for any of it. The
|
|
@@ -8,9 +8,10 @@ reference files are indexed in `SKILL.md`; this page is the run order, not the i
|
|
|
8
8
|
|
|
9
9
|
Task: $ARGUMENTS
|
|
10
10
|
|
|
11
|
-
> **
|
|
12
|
-
> `
|
|
13
|
-
>
|
|
11
|
+
> **Three other modes.** `waves` takes the whole board instead of one task;
|
|
12
|
+
> `setup` audits the documentation this project already has; `checkup` reports what
|
|
13
|
+
> has shipped without a person confirming it, with no task in flight. All three are at
|
|
14
|
+
> the bottom of this page.
|
|
14
15
|
|
|
15
16
|
**Idempotent entry — inspect state first, never restart blindly.** If a pipeline
|
|
16
17
|
TaskList from a previous run exists for this task, **resume** from the first incomplete
|
|
@@ -59,9 +60,10 @@ Pull what the project already knows about *this task*:
|
|
|
59
60
|
|
|
60
61
|
Write the **source ledger** into the brief: a row per source, or an explicit *none found*.
|
|
61
62
|
|
|
62
|
-
**Then the grill, and it is mandatory** (`references/grill.md`).
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
**Then the grill, and it is mandatory** (`references/grill.md`). Close what the sources
|
|
64
|
+
can, then ask the material unknowns in ONE batch, ordered by dependency, each with a
|
|
65
|
+
recommended answer — one at a time only where answers depend on each other or the
|
|
66
|
+
operator asks — until every decision branch is resolved.
|
|
65
67
|
|
|
66
68
|
- **Validate every answer against the harvested sources.** The operator outranks any
|
|
67
69
|
document — but only out loud, and a doc the run proves stale is logged for stage 9.
|
|
@@ -188,6 +190,19 @@ Where you ask it to file what it found, it appends board rows whose `Source` nam
|
|
|
188
190
|
checkup and its date — printing what it would add first, never silently.
|
|
189
191
|
Doctrine: `references/exposure.md`.
|
|
190
192
|
|
|
193
|
+
## `/task-pipeline waves`
|
|
194
|
+
|
|
195
|
+
**The whole board, closed in its final form.** Every open item — board, ledgers, plan
|
|
196
|
+
rows, unverified rows, uncovered scenarios, other products' asks — plus the new requests,
|
|
197
|
+
in one machine-readable inventory verified against the code. Questions are closed from
|
|
198
|
+
the sources; what remains goes to the operator once, as one batch, at the end of
|
|
199
|
+
planning. A committed canvas lays the target state over the current logic, and the work
|
|
200
|
+
is cut into waves that each close in one pass. Stages 0–4 run once, 5–8 per wave with a
|
|
201
|
+
close pass after each (verify, one fix round, docs, re-measure, re-cut), 9–10 to close.
|
|
202
|
+
It takes the next wave without asking, says once when the board is empty, and leaves
|
|
203
|
+
every sign-in, consent, payment and outward act to a person.
|
|
204
|
+
Doctrine: `references/waves.md`.
|
|
205
|
+
|
|
191
206
|
## `/task-pipeline setup`
|
|
192
207
|
|
|
193
208
|
**The entry audit instead of a feature.** Seven passes over the documentation this
|
|
@@ -37,6 +37,17 @@
|
|
|
37
37
|
"timeout": 20
|
|
38
38
|
}
|
|
39
39
|
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"matcher": "Bash|Edit|Write|MultiEdit",
|
|
43
|
+
"hooks": [
|
|
44
|
+
{
|
|
45
|
+
"type": "command",
|
|
46
|
+
"shell": "bash",
|
|
47
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/memory-nudge.sh\"",
|
|
48
|
+
"timeout": 20
|
|
49
|
+
}
|
|
50
|
+
]
|
|
40
51
|
}
|
|
41
52
|
],
|
|
42
53
|
"PostToolUseFailure": [
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PostToolUse — a stage gate returned and no workflow-memory line follows it.
|
|
3
|
+
#
|
|
4
|
+
# The checkpoint doctrine (references/continuity.md, Part 3) asked every returned gate to
|
|
5
|
+
# write an Observatory checkpoint, or to record that memory is unavailable. It was a step
|
|
6
|
+
# the agent had to remember, and the measured adoption was one write in 293 sessions over
|
|
7
|
+
# fourteen days (sshlg-skills waves, 2026-10-11). This hook reminds at the moment it
|
|
8
|
+
# matters: once per stage line, as context the model reads, and never again for the same
|
|
9
|
+
# line. It decides nothing and blocks nothing.
|
|
10
|
+
#
|
|
11
|
+
# Silent everywhere else: no ledger means exit 0 after one file test.
|
|
12
|
+
set -uo pipefail
|
|
13
|
+
ledger="${CLAUDE_PROJECT_DIR:-$PWD}/.task-pipeline/run.md"
|
|
14
|
+
[ -f "$ledger" ] || exit 0
|
|
15
|
+
python3 - "$ledger" <<'PY' 2>/dev/null || true
|
|
16
|
+
import hashlib, json, os, re, sys
|
|
17
|
+
ledger = sys.argv[1]
|
|
18
|
+
try:
|
|
19
|
+
lines = open(ledger, encoding="utf-8").read().splitlines()
|
|
20
|
+
except OSError:
|
|
21
|
+
sys.exit(0)
|
|
22
|
+
last_stage = last_mem = -1
|
|
23
|
+
for i, l in enumerate(lines):
|
|
24
|
+
if re.match(r"^stage:\s*\S+\s", l):
|
|
25
|
+
last_stage = i
|
|
26
|
+
elif l.startswith("event: memory"):
|
|
27
|
+
last_mem = i
|
|
28
|
+
if last_stage < 0 or last_mem > last_stage:
|
|
29
|
+
sys.exit(0)
|
|
30
|
+
line = lines[last_stage]
|
|
31
|
+
mark = os.path.join(os.path.dirname(ledger), ".memory-nudged")
|
|
32
|
+
key = hashlib.sha256(line.encode()).hexdigest()[:16]
|
|
33
|
+
try:
|
|
34
|
+
if open(mark).read().strip() == key:
|
|
35
|
+
sys.exit(0)
|
|
36
|
+
except OSError:
|
|
37
|
+
pass
|
|
38
|
+
try:
|
|
39
|
+
open(mark, "w").write(key + "\n")
|
|
40
|
+
except OSError:
|
|
41
|
+
pass
|
|
42
|
+
sid = re.match(r"^stage:\s*(\S+)", line).group(1)
|
|
43
|
+
msg = (f"task-pipeline: stage {sid}'s gate returned and no workflow-memory line follows it. "
|
|
44
|
+
"With Observatory's tools: `scripts/stage_checkpoint.py emit` → observatory_checkpoint_write "
|
|
45
|
+
"→ `stage_checkpoint.py record --answer -`. Without them: "
|
|
46
|
+
"`stage_checkpoint.py record --unavailable \"<why>\"`. (references/continuity.md, Part 3)")
|
|
47
|
+
print(json.dumps({"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": msg}}))
|
|
48
|
+
PY
|
|
49
|
+
exit 0
|
|
@@ -218,7 +218,9 @@ Since v1.50.0 the plugin carries hooks of its own. `hooks/release-gate.sh`
|
|
|
218
218
|
(`PreToolUse` on `Bash`) refuses an **outward, irreversible act** — `git tag`, a
|
|
219
219
|
tag push, `gh release create`, `npm publish` — while the run says the suite has not
|
|
220
220
|
passed. `hooks/gate-observer.sh` (`PostToolUse` and `PostToolUseFailure`) records
|
|
221
|
-
what the declared gate command actually did.
|
|
221
|
+
what the declared gate command actually did. `hooks/memory-nudge.sh` (`PostToolUse` on `Bash|Edit|Write|MultiEdit`) reminds,
|
|
222
|
+
once per returned gate, that no workflow-memory line follows it
|
|
223
|
+
([`continuity.md`](https://github.com/ssheleg/task-pipeline/blob/main/plugins/task-pipeline/skills/task-pipeline/references/continuity.md), Part 3).
|
|
222
224
|
|
|
223
225
|
**Two lessons from v1.50.0, both shipped as defects and both fixed in v1.51.0.**
|
|
224
226
|
|
|
@@ -121,7 +121,8 @@ default is `Sev × Blast + age_bonus` ([`references/portable-method.md`](referen
|
|
|
121
121
|
the local priority contract) — and the operator accepts them. Effort never ranks inside an
|
|
122
122
|
audit: what a fix costs is the fixer's decision, not the finder's
|
|
123
123
|
([`references/portable-method.md`](references/portable-method.md)). An audit
|
|
124
|
-
that edits while it reads cannot be re-run to check itself.
|
|
124
|
+
that edits while it reads cannot be re-run to check itself. In `task-pipeline`'s wave
|
|
125
|
+
mode these rows and the JSON sidecar are wave 0's input: they join its inventory by id.
|
|
125
126
|
|
|
126
127
|
## A finding keeps its axes apart, or it is a guess wearing a verdict
|
|
127
128
|
|