task-pipeline-skill 1.66.0 → 1.68.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 +91 -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/SKILL.md +82 -135
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +33 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +45 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/verification.md +34 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/exposure.sh +14 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.68.0 — the worst body in the family, and the rule that was wrong about it
|
|
4
|
+
|
|
5
|
+
**6685 tokens against a 5000 budget → 4735**, under the 4750 working limit, by
|
|
6
|
+
splitting rather than trimming. This was the largest `SKILL.md` body in the
|
|
7
|
+
ssheleg family and the furthest over — 34% — and the body loads on every turn of
|
|
8
|
+
every session that resolves the skill.
|
|
9
|
+
|
|
10
|
+
Most of the overrun sat in the **stage table's Gate column**, which restated
|
|
11
|
+
`references/stages.md` under a heading that literally says *(detail in
|
|
12
|
+
`references/stages.md`)*. The table is the index and the run order now; the
|
|
13
|
+
reference is what you read while standing in the stage. Nothing was deleted:
|
|
14
|
+
|
|
15
|
+
| Moved | To | Why there |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Stage 10 in a project of several repositories | `references/acceptance.md` | it owns stage-10 close-out |
|
|
18
|
+
| Step 5's cross-cutting rules | `references/gates.md` | they fire at any stage, not inside step 5 |
|
|
19
|
+
|
|
20
|
+
and five *Prerequisites* paragraphs that restated a reference in full were cut to
|
|
21
|
+
the rule plus the failure it prevents — which is what a body is for — with the
|
|
22
|
+
procedure left in the file that owns it.
|
|
23
|
+
|
|
24
|
+
**All 38 routed trigger phrases across both skills survive verbatim**
|
|
25
|
+
(`node test/advertised_check.js`), and the stage list still matches across the
|
|
26
|
+
three surfaces the validator compares mechanically.
|
|
27
|
+
|
|
28
|
+
### The description rule was wrong, and this repository was already right
|
|
29
|
+
|
|
30
|
+
The family's shared auditor demands a description **start** with `Use when …`.
|
|
31
|
+
This repository's own validator refuses exactly that, and its comment says why:
|
|
32
|
+
Anthropic's guidance asks for **both** halves — what the skill does and when to
|
|
33
|
+
use it — and their own example leads with the capability (*"Extracts text and
|
|
34
|
+
tables from PDF files… Use when working with PDF files."*). Demanding `Use when`
|
|
35
|
+
at position 0 enforces the WHEN half and leaves the WHAT half optional.
|
|
36
|
+
|
|
37
|
+
So the 2026-08-16 audit's finding that this description *"does not open with Use
|
|
38
|
+
when, against the house rule its sibling obeys"* is **withdrawn — the house rule
|
|
39
|
+
is the one that is wrong**, and this repository had corrected its own copy of it
|
|
40
|
+
already. Applying the corrected rule to the family measures **22 of 24 skills**
|
|
41
|
+
opening with the trigger, so flipping it rewrites 22 descriptions that carry live
|
|
42
|
+
routing phrases. That is a family decision rather than a member's, and it is
|
|
43
|
+
filed as umbrella `B-76` rather than taken here.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- A negative self-test was pinned to a literal containing a **line break**, so it
|
|
48
|
+
stopped landing the moment the paragraph reflowed — the guard then read green
|
|
49
|
+
while proving nothing. Matched by regex now. Same class as the two that refused
|
|
50
|
+
`seo-aeo-audit`'s release earlier the same day, and the reason the local gate
|
|
51
|
+
there learned to catch it before the tag.
|
|
52
|
+
|
|
53
|
+
Guards: 351 → **351**. No guard was added or removed — one plant was repaired, and
|
|
54
|
+
the suite that reports `all 351 guards provably reject their planted defect` was
|
|
55
|
+
red until it was, which is the whole point of counting them.
|
|
56
|
+
|
|
57
|
+
Found by the nine-repository audit of 2026-08-16 (umbrella `B-66`;
|
|
58
|
+
`F-task-pipeline-01`, and `F-task-pipeline-02` withdrawn).
|
|
59
|
+
|
|
60
|
+
## v1.67.0 — a ledger records two different things, and most record only one
|
|
61
|
+
|
|
62
|
+
**A ledger records two different things, and most record only one.** *What confirmed it*
|
|
63
|
+
is evidence — a command, a CI run id, a fixture name. *Whether a person looked* is the
|
|
64
|
+
`Human` axis, and it is the only one the exposure line is defined over.
|
|
65
|
+
|
|
66
|
+
Measured across this family: nine repositories, **ten** header shapes, **815** rows.
|
|
67
|
+
|
|
68
|
+
| what the state column can say | rows | repositories |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| whether a **person** looked (`Human`) | **126** | 1 |
|
|
71
|
+
| a date and what was watched (`Last verified`) | 180 | 1 |
|
|
72
|
+
| `verified` — by a person **or** a command, indistinguishable | 391 | 4 |
|
|
73
|
+
| nothing: evidence recorded, no state column at all | 118 | 3 |
|
|
74
|
+
|
|
75
|
+
So `never` is measurable in **one repository of nine, over 15% of the rows**, and the
|
|
76
|
+
number this doctrine is written around is undefined in the rest. That is not a defect in
|
|
77
|
+
those ledgers — recording what confirmed something is the Auto job done properly. **The
|
|
78
|
+
defect is doctrine that speaks as though the column were there**, so `references/verification.md`
|
|
79
|
+
now states the split, and three rules follow from it: where there is no state column the
|
|
80
|
+
line says so and prints no number; a `verified` that cannot separate a person from a
|
|
81
|
+
command may not be reported as human confirmation; and adding the column later never
|
|
82
|
+
reaches backwards, because a back-filled ledger answers the question wrongly instead of not
|
|
83
|
+
at all.
|
|
84
|
+
|
|
85
|
+
`exposure.sh` also stops calling a self-explaining status unreadable. `**observed** — the
|
|
86
|
+
row exists because the miss happened in this run` is an ordinary way to write a state, and
|
|
87
|
+
four rows in this family were reported unparseable for explaining themselves. The
|
|
88
|
+
vocabulary now matches the **leading word**, with the empty cell tested before the word is
|
|
89
|
+
taken so a blank still counts as unconfirmed.
|
|
90
|
+
|
|
91
|
+
Guards: 351 → **351**. Fixtures 20 → **20**; these are behaviours the existing cases
|
|
92
|
+
exercise by running the script, and all nine family ledgers were run through it by hand.
|
|
93
|
+
|
|
3
94
|
## v1.66.0 — the shape is not fixed, so nothing may assume it
|
|
4
95
|
|
|
5
96
|
**The check-list printed the size of the work labelled as who it hurts, in every seeded
|
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.68.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.68.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.68.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: task-pipeline
|
|
3
|
-
description: "Runs a substantial task through a full delivery pipeline: an intake grill that locks the request into a brief, then docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy
|
|
3
|
+
description: "Runs a substantial task through a full delivery pipeline: an intake grill that locks the request into a brief, then docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki sync and acceptance. Use when work changes the repository — a 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' / 'прогони по конвейеру', 'the full cycle' / 'полный цикл', /task-pipeline. Two modes need no task at all: 'checkup' / 'чекап' reports what shipped unconfirmed and what to look at first; 'setup' audits existing documentation. Not for: answering a question, explaining code, a typo or a one-line edit — say 'без пайплайна' / 'quick' to opt out."
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -79,76 +79,60 @@ gate stops until it is installed.
|
|
|
79
79
|
| 6–10 · How the host project's CLAUDE.md is read | `references/conventions.md` |
|
|
80
80
|
| preflight · Model map, ids and the override | `references/model-tiering.md` |
|
|
81
81
|
|
|
82
|
-
**Optional bridge.** An equivalent skill set the operator already runs
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
built-in doctrine is normative, the gates in `references/stages.md` still govern, and
|
|
87
|
-
nothing detects, recommends or waits for an external provider.
|
|
82
|
+
**Optional bridge.** An equivalent skill set the operator already runs can be mapped
|
|
83
|
+
onto stages 2/4/5/6 in `pipeline.json` → `skills[]`. That is a **substitution, never a
|
|
84
|
+
requirement**: the built-in doctrine is normative, the gates in `references/stages.md`
|
|
85
|
+
still govern, and nothing detects, recommends or waits for an external provider.
|
|
88
86
|
|
|
89
87
|
**super-ux — recommended for ANY user-facing task**, and the one thing that can stop a
|
|
90
|
-
gate. The moment a task implies an interface (web / mobile / CLI / TUI
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
gate stops** — offer `/plugin marketplace add ssheleg/super-ux` and
|
|
95
|
-
`/plugin install super-ux@super-ux` (or `npx skills add ssheleg/super-ux`) and wait.
|
|
96
|
-
Details: `references/companion-skills.md`.
|
|
88
|
+
gate. The moment a task implies an interface (web / mobile / CLI / TUI), the
|
|
89
|
+
WHY→UI→scenario chain runs through `/ux` and its linter, which belongs in the host's
|
|
90
|
+
CI so UX drift cannot merge. **Not installed on a UI task? The stage-3 spec gate
|
|
91
|
+
stops** — offer the install and wait (`references/companion-skills.md`).
|
|
97
92
|
|
|
98
93
|
**The grill is built in and mandatory** (`references/grill.md`). No "clear enough task"
|
|
99
|
-
exemption
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
mechanical set-comparison against them, and **stage 10 accounts for every one**, which
|
|
104
|
-
is what turns the pipeline from a funnel into a circle.
|
|
94
|
+
exemption and no stage 1 without a committed, operator-confirmed brief. It produces the
|
|
95
|
+
**REQ spine** — the request as an addressable list, each row naming how it is verified —
|
|
96
|
+
which stages 3–5 trace to, stage 4 set-compares against, and **stage 10 accounts for
|
|
97
|
+
every one of**, turning the pipeline from a funnel into a circle.
|
|
105
98
|
|
|
106
99
|
**Harvest before you ask** (`references/knowledge-sources.md`). Stage 0 opens by
|
|
107
|
-
pulling what the project already knows about *this* task
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*against* it: every answer touching a source is checked against it, and the operator
|
|
115
|
-
outranks any document — **but only out loud**, so an override is a recorded decision
|
|
116
|
-
rather than an undetected divergence. That ledger is also stage 9's work list.
|
|
100
|
+
pulling what the project already knows about *this* task, writes the source ledger
|
|
101
|
+
into the brief, and then interviews **against** it — so the operator outranks any
|
|
102
|
+
document, **but only out loud**, and an override is a recorded decision rather than
|
|
103
|
+
an undetected divergence. That ledger is also stage 9's work list. Which sources,
|
|
104
|
+
and the two ways the retro is read — standing instructions in full because they
|
|
105
|
+
bind this run, the log queried because nothing caps it — are in
|
|
106
|
+
`references/knowledge-sources.md` and `references/retrospective.md`.
|
|
117
107
|
|
|
118
108
|
**Three artifacts close a run, not two — and they are a convergence, not a sequence.**
|
|
119
|
-
Stage 9 syncs the docs, the wiki **and the code graph
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
why it is not optional where a graph exists
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
a wrong doc gets argued with, a wrong graph gets believed. Refreshing it buys the
|
|
126
|
-
graph↔docs divergence check; doc-side findings are fixed at stage 9, absences become
|
|
127
|
-
REQ rows at stage 10 (`references/knowledge-graph.md`, `references/audit.md`).
|
|
109
|
+
Stage 9 syncs the docs, the wiki **and the code graph**. None consumes another; all three
|
|
110
|
+
consume the same change, and the **graph↔docs divergence check is the gate over their
|
|
111
|
+
convergence** — the only thing that compares two of the three against each other, which
|
|
112
|
+
is why it is not optional where a graph exists. A stale graph is a false premise
|
|
113
|
+
**carrying the authority of a machine**: a wrong doc gets argued with, a wrong graph gets
|
|
114
|
+
believed (`references/knowledge-graph.md`, `references/audit.md`).
|
|
128
115
|
|
|
129
116
|
**Documentation is a deliverable, and it has a gate** (`references/documentation.md`).
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
matrix names what you *owe*); and *"docs in sync"* becomes a command with an exit code.
|
|
117
|
+
Stage 0 answers the four questions that make docs a *system* into `docs/DOCMAP.md`;
|
|
118
|
+
from then the **Doc Loop** fires whenever anything is settled, at **any** stage rather
|
|
119
|
+
than only at stage 9, the stage-9 sweep walks the **propagation matrix** — the harvest
|
|
120
|
+
ledger names what you *read*, the matrix names what you *owe* — and *"docs in sync"*
|
|
121
|
+
becomes a command with an exit code.
|
|
136
122
|
|
|
137
123
|
**The run teaches the next run, and the list stays short**
|
|
138
124
|
(`references/retrospective.md`). Every gate is good at *this* run and blind across
|
|
139
125
|
runs, so one class of failure can be caught, fixed and forgotten five times with
|
|
140
|
-
nothing noticing it is the same one. Stage 10's last act
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
stamps, so a prune placed ahead of the stamp reads a counter its own stage writes
|
|
151
|
-
afterwards and can never run on real data (`references/learned.md` rule 21).
|
|
126
|
+
nothing noticing it is the same one. Stage 10's last act, **in this order and the
|
|
127
|
+
order is load-bearing**: stamp the run, then prune, then write the entry — a
|
|
128
|
+
retirement trigger counts firings across the last five stamps, so a prune placed
|
|
129
|
+
ahead of the stamp reads a counter its own stage has not written yet. The cap, the
|
|
130
|
+
triggers and what an entry must carry are in `references/retrospective.md`; why
|
|
131
|
+
the order cannot be swapped is `references/learned.md` rule 21.
|
|
132
|
+
|
|
133
|
+
Stage 0 reads those standing instructions in full, which is why the prune is a gate
|
|
134
|
+
criterion and not a good intention: a rule nobody reads to the end is worse than no
|
|
135
|
+
rule, because everyone believes it is covered.
|
|
152
136
|
|
|
153
137
|
Three things the grill does beyond clarifying the request:
|
|
154
138
|
- **Domain awareness.** It reads the project's own `CONTEXT.md` / `docs/adr/` and
|
|
@@ -210,40 +194,13 @@ Three things the grill does beyond clarifying the request:
|
|
|
210
194
|
stop/return on fail; for `manual`, present the result and **wait for the
|
|
211
195
|
operator's explicit "continue"/go** — an auto gate never substitutes for a
|
|
212
196
|
required manual approval.
|
|
213
|
-
5.
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
than asking again** — it was grilled precisely so you wouldn't have to;
|
|
221
|
-
**anything deferred, dropped or left half-done goes into the carry-over ledger
|
|
222
|
-
the moment it's said** — deferred out loud is forgotten; **never narrow the task
|
|
223
|
-
silently** — the REQ list is frozen, adding is free, removing needs the
|
|
224
|
-
operator's explicit agreement; **when a loop starts undoing an earlier pass —
|
|
225
|
-
the same file edited twice for the same reason, a closed finding coming back, a
|
|
226
|
-
third entry into one stage — stop and run the loop guard**
|
|
227
|
-
(`references/loop-guard.md`): name the two shapes, escalate to the layer that
|
|
228
|
-
owns the conflict, re-plan the check as an ordered list, then go through it one
|
|
229
|
-
item at a time; **when a pass is *searching* rather than editing and starts
|
|
230
|
-
finding mostly what the previous pass's own fixes broke, the axis is exhausted —
|
|
231
|
-
rotate it, don't look harder** (`references/audit.md`); **every gate
|
|
232
|
-
prints `holds: N` — what this run left running** across the eight classes
|
|
233
|
-
(background shells, monitors, scheduled loops, coordination leases, worktrees,
|
|
234
|
-
containers, scratch files, remote state), enumerated **by class and never by a
|
|
235
|
-
single tool**, and stage 10 does not close while this run's residue is live and
|
|
236
|
-
unaccounted (`references/residue.md`); and remember that a
|
|
237
|
-
green from a check nobody has watched fail is not evidence; task
|
|
238
|
-
tracker + conventional commits per host conventions; worktree isolation for the
|
|
239
|
-
build, integrated back per the brief's branch policy before stage 7; honest
|
|
240
|
-
degradation (never claim a failed/skipped step succeeded);
|
|
241
|
-
outward/irreversible actions (deploy, publish, repo create, opening a PR,
|
|
242
|
-
**editing a shared design file — frames are read by designers and stakeholders,
|
|
243
|
-
so drawing in one is publishing — and above all *creating* one, which needs a
|
|
244
|
-
named team and never happens while a recorded file resolves**) need explicit
|
|
245
|
-
operator go — or a **specific** standing authorization recorded in the brief
|
|
246
|
-
(named target + preconditions; a vague "do everything" is not one).
|
|
197
|
+
5. **The cross-cutting rules fire at any stage**, not only here — the Doc Loop, the
|
|
198
|
+
loop guard, the audit's exit, the frozen REQ list, the carry-over ledger, and
|
|
199
|
+
what counts as evidence, and **every gate prints `holds: N`** — what this run left
|
|
200
|
+
running, across all eight classes, enumerated by class and never by a single
|
|
201
|
+
tool — and stage 10 does not close while this run's residue is live and
|
|
202
|
+
unaccounted (`references/residue.md`). The rest are in
|
|
203
|
+
[`references/gates.md`](references/gates.md) → *Cross-cutting, at every stage*.
|
|
247
204
|
|
|
248
205
|
## Stages (detail in `references/stages.md`)
|
|
249
206
|
|
|
@@ -252,44 +209,36 @@ capable available — see `references/model-tiering.md`).
|
|
|
252
209
|
|
|
253
210
|
| # | Stage | Gate | Type |
|
|
254
211
|
|---|---|---|---|
|
|
255
|
-
| 0 | Intake grill — **mandatory** | source ledger written
|
|
212
|
+
| 0 | Intake grill — **mandatory** | source ledger written with its `Contradictions:` line; `docs/DOCMAP.md` answered and intent reconciled against as-built; the retro read in full; autonomy sweep covered; brief locked and confirmed | manual |
|
|
256
213
|
| 1 | Docs study | contracts grounded on fetched docs | auto |
|
|
257
214
|
| 2 | Brainstorm + decompose | design approved; UI verdict recorded; every REQ answered; platform: module map approved | manual |
|
|
258
|
-
| 3 | Spec | committed + reviewed; UI: chain validated, linter green, scenarios
|
|
259
|
-
| 4 | Plan | parallel-ready, DoD per task; **every edge names what it carries** — the fake-edge test run
|
|
260
|
-
| 5 | Dev | tasks DONE, TDD green per task, branch integrated per the brief;
|
|
261
|
-
| 6 | Tests | full suite green
|
|
262
|
-
| 7 | Lint + deploy | lint clean
|
|
263
|
-
| 8 | Post-deploy | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and
|
|
264
|
-
| 9 | Docs + wiki | every stale row of the stage-0 source ledger updated;
|
|
265
|
-
| 10 | **Acceptance** | ladder walk ran
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
exactly this plus *no lease left held*, and `--gates` adds the project's own gate commands.
|
|
286
|
-
|
|
287
|
-
The fix, when it fails, is two commands and the second is the one that gets forgotten:
|
|
288
|
-
|
|
289
|
-
```bash
|
|
290
|
-
git -C <submodule> push
|
|
291
|
-
git add <submodule> && git commit -m "chore: bump <name> submodule — <why>"
|
|
292
|
-
```
|
|
215
|
+
| 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 |
|
|
216
|
+
| 4 | Plan | parallel-ready, DoD per task; **every edge names what it carries** — the fake-edge test run and its `Edges:` count computed | auto |
|
|
217
|
+
| 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 |
|
|
218
|
+
| 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 |
|
|
219
|
+
| 7 | Lint + deploy | lint clean and suite green before deploy; deploy needs a go, or the brief's specific standing authorization | manual |
|
|
220
|
+
| 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 |
|
|
221
|
+
| 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 |
|
|
222
|
+
| 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 |
|
|
223
|
+
|
|
224
|
+
**Every gate above is the short form**, and the long form is the point of
|
|
225
|
+
[`references/stages.md`](references/stages.md) — one section per stage. What the
|
|
226
|
+
ladder walk is, which eight environment classes stage 10 enumerates, what makes an
|
|
227
|
+
edge fake, why a `200` is not a working page: all there, none here.
|
|
228
|
+
|
|
229
|
+
That split is the budget rule this pack states for everyone else, applied to
|
|
230
|
+
itself: the body was **6685 tokens against a 5000 budget**, the worst in the
|
|
231
|
+
family, and most of the overrun sat in this table's Gate column restating files
|
|
232
|
+
that already load on demand.
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
**Several repositories?** A submodule is finished when its parent says so — the
|
|
237
|
+
work can be committed, pushed and green while a clone of the parent still gets the
|
|
238
|
+
commit before it, and neither repository looks wrong alone. The two commands that
|
|
239
|
+
prove it, and the two-command fix whose second half gets forgotten, are in
|
|
240
|
+
[`references/acceptance.md`](references/acceptance.md) → *A project of several
|
|
241
|
+
repositories*.
|
|
293
242
|
|
|
294
243
|
## Model — ask once, at preflight
|
|
295
244
|
|
|
@@ -309,14 +258,12 @@ pinned to the confirmed model automatically. Detail: `references/model-tiering.m
|
|
|
309
258
|
|
|
310
259
|
## Bring your own skills
|
|
311
260
|
|
|
312
|
-
The stages above
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
no fixed stage count and no opinion on which gates are manual or whether release
|
|
319
|
-
automation is on — `pipeline.schema.json` is the only contract.
|
|
261
|
+
The stages above are the **example** flow. A host project owns its pipeline: copy
|
|
262
|
+
`pipeline.example.json` → `pipeline.json`, define its **own** stages (any count),
|
|
263
|
+
point each `skills[]` at what its environment resolves, set each `gate.type`
|
|
264
|
+
(`auto`/`manual`) to fit its process, and toggle its own `release` block. The
|
|
265
|
+
framework ships no fixed stage count and no opinion on which gates are manual —
|
|
266
|
+
`pipeline.schema.json` is the only contract.
|
|
320
267
|
|
|
321
268
|
## References
|
|
322
269
|
|
|
@@ -22,6 +22,7 @@ requirement.** It is what turns the pipeline from a funnel into a circle.
|
|
|
22
22
|
- A seam is not a deliverable, and REQ rows are written against deliverables
|
|
23
23
|
- GATE (manual)
|
|
24
24
|
- When the answer is "something's missing"
|
|
25
|
+
- A project of several repositories
|
|
25
26
|
|
|
26
27
|
## Why a stage and not a gate
|
|
27
28
|
|
|
@@ -361,3 +362,35 @@ or a tracked follow-up. Both are legitimate outcomes of this stage. Closing the
|
|
|
361
362
|
run with a known gap is fine **if the gap is written down** — closing it with the
|
|
362
363
|
gap only in someone's memory is the failure mode this whole spine exists to
|
|
363
364
|
prevent.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## A project of several repositories
|
|
369
|
+
|
|
370
|
+
**A submodule is finished when its parent says so.** A parent repository records each submodule as
|
|
371
|
+
a pointer to one commit, and moving the submodule does not move the pointer. So the work is
|
|
372
|
+
committed, pushed, its CI is green and its own roadmap says done — and anyone who clones the parent
|
|
373
|
+
gets the commit **before** the change. Nothing looks wrong in either repository on its own; the
|
|
374
|
+
disagreement exists only between them, which is why it survives every check that runs inside one.
|
|
375
|
+
|
|
376
|
+
Stage 10 does not close until:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
git submodule status # no line begins with '+' (a '+' is the missing bump)
|
|
380
|
+
git -C <each repo> status --porcelain && git -C <each repo> log @{u}..HEAD --oneline
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
report nothing — for the parent as well as every submodule. Where
|
|
384
|
+
[agent-sync](https://github.com/ssheleg/agent-sync) is installed, `/agent-sync finish` runs
|
|
385
|
+
exactly this plus *no lease left held*, and `--gates` adds the project's own gate commands.
|
|
386
|
+
|
|
387
|
+
The fix, when it fails, is two commands and the second is the one that gets forgotten:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
git -C <submodule> push
|
|
391
|
+
git add <submodule> && git commit -m "chore: bump <name> submodule — <why>"
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
Moved out of `SKILL.md` on 2026-08-16: the body was 6685 tokens against a
|
|
395
|
+
< 5000 budget, and stage-10 close-out is what this file is for.
|
|
396
|
+
|
|
@@ -40,6 +40,7 @@ elsewhere and is not restated here:
|
|
|
40
40
|
- Where a gate runs
|
|
41
41
|
- Adding a check to an existing gate
|
|
42
42
|
- Rationalizations
|
|
43
|
+
- Cross-cutting, at every stage
|
|
43
44
|
|
|
44
45
|
## Axis A — the stage gate type
|
|
45
46
|
|
|
@@ -589,3 +590,47 @@ of is deleted in the next refactor by someone who assumed it was dead.
|
|
|
589
590
|
| "The gate would be red on day one, so I'll add it later" | Make the section dormant instead. Dormant is visible and green; "later" is neither. |
|
|
590
591
|
| "I raised the floor to get the build green" | Then say so in the log, in the same commit. A floor raised silently is a ratchet running backwards. |
|
|
591
592
|
| "A hook is overkill, CI catches it" | CI catches it after the edit, the commit and the push. If the point is to stop the edit, CI is the wrong rung — and if it is not, do not pay the latency. |
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Cross-cutting, at every stage
|
|
597
|
+
|
|
598
|
+
5. Cross-cutting, every stage: **when anything is settled — scope, a contract, a
|
|
599
|
+
name, a policy, a vocabulary — run the Doc Loop
|
|
600
|
+
(`references/documentation.md`) before the run moves on**: reserve the id,
|
|
601
|
+
record it, resolve the question it answers, propagate by the matrix, commit
|
|
602
|
+
with the ids. A decision that lives only in the spec dies with the spec, and one
|
|
603
|
+
that lives only in the conversation was never made;
|
|
604
|
+
**answer from the brief's autonomy section rather
|
|
605
|
+
than asking again** — it was grilled precisely so you wouldn't have to;
|
|
606
|
+
**anything deferred, dropped or left half-done goes into the carry-over ledger
|
|
607
|
+
the moment it's said** — deferred out loud is forgotten; **never narrow the task
|
|
608
|
+
silently** — the REQ list is frozen, adding is free, removing needs the
|
|
609
|
+
operator's explicit agreement; **when a loop starts undoing an earlier pass —
|
|
610
|
+
the same file edited twice for the same reason, a closed finding coming back, a
|
|
611
|
+
third entry into one stage — stop and run the loop guard**
|
|
612
|
+
(`references/loop-guard.md`): name the two shapes, escalate to the layer that
|
|
613
|
+
owns the conflict, re-plan the check as an ordered list, then go through it one
|
|
614
|
+
item at a time; **when a pass is *searching* rather than editing and starts
|
|
615
|
+
finding mostly what the previous pass's own fixes broke, the axis is exhausted —
|
|
616
|
+
rotate it, don't look harder** (`references/audit.md`); **every gate
|
|
617
|
+
prints `holds: N` — what this run left running** across the eight classes
|
|
618
|
+
(background shells, monitors, scheduled loops, coordination leases, worktrees,
|
|
619
|
+
containers, scratch files, remote state), enumerated **by class and never by a
|
|
620
|
+
single tool**, and stage 10 does not close while this run's residue is live and
|
|
621
|
+
unaccounted (`references/residue.md`); and remember that a
|
|
622
|
+
green from a check nobody has watched fail is not evidence; task
|
|
623
|
+
tracker + conventional commits per host conventions; worktree isolation for the
|
|
624
|
+
build, integrated back per the brief's branch policy before stage 7; honest
|
|
625
|
+
degradation (never claim a failed/skipped step succeeded);
|
|
626
|
+
outward/irreversible actions (deploy, publish, repo create, opening a PR,
|
|
627
|
+
**editing a shared design file — frames are read by designers and stakeholders,
|
|
628
|
+
so drawing in one is publishing — and above all *creating* one, which needs a
|
|
629
|
+
named team and never happens while a recorded file resolves**) need explicit
|
|
630
|
+
operator go — or a **specific** standing authorization recorded in the brief
|
|
631
|
+
(named target + preconditions; a vague "do everything" is not one).
|
|
632
|
+
|
|
633
|
+
Moved out of `SKILL.md` on 2026-08-16 for the same budget reason as the
|
|
634
|
+
multi-repository block: these fire at any stage, so they belong with the gate
|
|
635
|
+
doctrine rather than inside step 5 of the run order.
|
|
636
|
+
|
|
@@ -22,6 +22,7 @@ the run*. Three things it does not say, and each is why this file exists:
|
|
|
22
22
|
|
|
23
23
|
- Why it keys to the brief, not to the coverage table
|
|
24
24
|
- `never` is a fact
|
|
25
|
+
- A ledger records two different things, and most record only one
|
|
25
26
|
- What stage 8 writes and what stage 10 refuses
|
|
26
27
|
- Rationalizations
|
|
27
28
|
|
|
@@ -53,6 +54,39 @@ So the count has **no floor, no direction, and may never be given a target**, ex
|
|
|
53
54
|
like the disclosures in [`gates.md`](gates.md). A project with forty `never` rows is not
|
|
54
55
|
failing; it is a project that now knows something it could not previously ask.
|
|
55
56
|
|
|
57
|
+
## A ledger records two different things, and most record only one
|
|
58
|
+
|
|
59
|
+
**What confirmed it** and **whether a person looked** are separate facts. The first is
|
|
60
|
+
evidence: a command, a CI run id, a fixture name. The second is the `Human` axis, and it is
|
|
61
|
+
the one the exposure line is defined over.
|
|
62
|
+
|
|
63
|
+
A ledger may carry either or both, and most carry only the first. Measured across this
|
|
64
|
+
family on 2026-08-16 — nine repositories, **ten** header shapes, **815** rows:
|
|
65
|
+
|
|
66
|
+
| what the state column can say | rows | repositories |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| whether a **person** looked (`Human`) | **126** | 1 |
|
|
69
|
+
| a date and what was watched (`Last verified`) | 180 | 1 |
|
|
70
|
+
| `verified` — by a person **or** a command, indistinguishable | 391 | 4 |
|
|
71
|
+
| nothing: the ledger records evidence and carries no state column | 118 | 3 |
|
|
72
|
+
|
|
73
|
+
So **`never` is measurable in one repository of nine, over 15% of the rows**, and the exposure line — which this
|
|
74
|
+
doctrine defines over it — is undefined in the rest. That is not a defect in those
|
|
75
|
+
ledgers. Recording *what confirmed it* is the Auto job done properly, and a project that
|
|
76
|
+
never asks the human question is making a choice.
|
|
77
|
+
|
|
78
|
+
What is a defect is **doctrine that speaks as though the column were there**. So:
|
|
79
|
+
|
|
80
|
+
- **Where there is no state column, the exposure line says so** and prints no number.
|
|
81
|
+
`templates/exposure.sh` reports `dormant` and names the column headings it looked for.
|
|
82
|
+
A zero would be the reassuring answer to a question nobody asked.
|
|
83
|
+
- **A `verified` that cannot separate a person from a command may not be reported as
|
|
84
|
+
human confirmation.** The script names the column it read, for exactly this reason.
|
|
85
|
+
- **Adding the column later never reaches backwards.** New rows start at `never`;
|
|
86
|
+
retrospective statuses for work nobody actually checked are the failure the
|
|
87
|
+
`evidence-docs` router exists to name, and a back-filled ledger is worse than an absent
|
|
88
|
+
one because it answers the question wrongly instead of not at all.
|
|
89
|
+
|
|
56
90
|
## What stage 8 writes and what stage 10 refuses
|
|
57
91
|
|
|
58
92
|
**A coverage verdict of `review` becomes `none`.** *No check can decide this* is not
|
|
@@ -123,9 +123,15 @@ fi
|
|
|
123
123
|
# file's purpose.
|
|
124
124
|
# NORMALISED first: these ledgers write `**never**`, not `never`. Bold hid three real
|
|
125
125
|
# unverified rows in one member and seven in another, and both reported zero.
|
|
126
|
+
# THE LEADING WORD, not the whole cell. `**observed** — the row exists because …` is a
|
|
127
|
+
# normal way to write a status, and four rows in this family were reported unreadable for
|
|
128
|
+
# explaining themselves. An empty cell still counts, which is why the emptiness test comes
|
|
129
|
+
# before the word is taken.
|
|
126
130
|
awk -F'\t' '{ s=tolower($2); gsub(/[*`]/, "", s); gsub(/^[ \t]+|[ \t]+$/, "", s);
|
|
127
|
-
if (s=="
|
|
128
|
-
|
|
131
|
+
if (s=="") { print; next }
|
|
132
|
+
w=s; sub(/[ \t].*$/, "", w); sub(/[.,;:—-]+$/, "", w);
|
|
133
|
+
if (w=="never" || w=="-" || w=="no" || w=="unverified" ||
|
|
134
|
+
w=="pending" || w=="none") print }' \
|
|
129
135
|
"$TMP/rows" > "$TMP/unverified"
|
|
130
136
|
UNVERIFIED=$(grep -c '' "$TMP/unverified" 2>/dev/null) || UNVERIFIED=0
|
|
131
137
|
|
|
@@ -134,11 +140,13 @@ UNVERIFIED=$(grep -c '' "$TMP/unverified" 2>/dev/null) || UNVERIFIED=0
|
|
|
134
140
|
# it as confirmed is how a shrug becomes a clean bill, which the fixture for this line
|
|
135
141
|
# caught the moment it was written.
|
|
136
142
|
awk -F'\t' '{ s=tolower($2); gsub(/[*`]/, "", s); gsub(/^[ \t]+|[ \t]+$/, "", s);
|
|
137
|
-
if (s=="
|
|
138
|
-
|
|
143
|
+
if (s=="") next;
|
|
144
|
+
w=s; sub(/[ \t].*$/, "", w); sub(/[.,;:—-]+$/, "", w);
|
|
145
|
+
if (w=="never" || w=="-" || w=="no" || w=="unverified" ||
|
|
146
|
+
w=="pending" || w=="none") next;
|
|
139
147
|
if ($2 ~ /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/) next;
|
|
140
|
-
if (
|
|
141
|
-
|
|
148
|
+
if (w=="pass" || w=="yes" || w=="verified" || w=="ok" || w=="observed" ||
|
|
149
|
+
w=="confirmed" || w=="green" || w=="planted") next;
|
|
142
150
|
print }' "$TMP/rows" > "$TMP/unreadable"
|
|
143
151
|
UNREADABLE=$(grep -c '' "$TMP/unreadable" 2>/dev/null) || UNREADABLE=0
|
|
144
152
|
|