task-pipeline-skill 1.95.0 → 1.97.1
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 +70 -0
- package/README.md +13 -9
- package/SKILL-CARD.md +2 -2
- package/cursor/rules/task-pipeline.mdc +11 -7
- package/evals/RESULTS.md +55 -8
- package/evals/cases/task-pipeline.json +139 -0
- package/evals/fixtures/lessons/expect-match.sh +30 -0
- package/evals/fixtures/lessons/index.jsonl +2 -0
- package/evals/fixtures/waves-unclaimed/expect-refusal.sh +26 -0
- package/evals/fixtures/waves-unclaimed/inventory.json +33 -0
- package/evals/fixtures/waves-unclaimed/modules.json +4 -0
- package/evals/fixtures/waves-unclaimed/plan.json +5 -0
- package/evals/task-pipeline.evals.json +104 -0
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +5 -2
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +4 -0
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +19 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/audit.md +5 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +48 -11
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +32 -24
- package/plugins/task-pipeline/skills/task-pipeline/references/continuity.md +7 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/finish-line.md +145 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/iteration.md +9 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +5 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +8 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/review.md +7 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-05-dev.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/stage-08-post-deploy.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +9 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/tdd.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/waves.md +9 -6
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/waves.py +219 -3
- package/plugins/task-pipeline/skills/task-pipeline/templates/brief.md +14 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/browser-claims.json +5 -5
- package/plugins/task-pipeline/skills/task-pipeline/templates/inventory.schema.json +15 -1
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +26 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "task-pipeline",
|
|
4
4
|
"displayName": "Task Pipeline",
|
|
5
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.
|
|
6
|
+
"version": "1.97.1",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "ssheleg",
|
|
9
9
|
"url": "https://x.com/sshlg93"
|
|
@@ -179,6 +179,9 @@ before drawing, never invented by the drawing agent).
|
|
|
179
179
|
around the waves — survey, module dossiers, one design, parallel build, checks that
|
|
180
180
|
start as each node lands, release, post-release check, next pool — is
|
|
181
181
|
`references/iteration.md`. A finding joins the inventory; it is not fixed alone.
|
|
182
|
+
**Findings are triaged when found, and the iteration stops at its finish line** —
|
|
183
|
+
exit checks green on the artefact, two rounds with no new blocking finding, or the
|
|
184
|
+
budget spent (`references/finish-line.md`).
|
|
182
185
|
4. Do **not** advance until the stage **gate** passes (`references/stages.md`).
|
|
183
186
|
Honor the gate **type**: for `auto`, verify the gate's `check` yourself and
|
|
184
187
|
stop/return on fail; for `judgment`, record the named judge's ruling as
|
|
@@ -186,8 +189,8 @@ before drawing, never invented by the drawing agent).
|
|
|
186
189
|
**operator's explicit go or standing authorization naming this act**. Other gate
|
|
187
190
|
types and generic loop flags cannot supply that authority (`references/continuity.md`).
|
|
188
191
|
5. **The cross-cutting rules fire at any stage**, not only here — the Doc Loop, the
|
|
189
|
-
loop guard, the audit's exit, the frozen REQ list, the carry-over
|
|
190
|
-
what counts as evidence, and **every gate prints `holds: N`** — what this run left
|
|
192
|
+
loop guard, the audit's exit, the finish line, the frozen REQ list, the carry-over
|
|
193
|
+
ledger, and what counts as evidence, and **every gate prints `holds: N`** — what this run left
|
|
191
194
|
running, across all eight classes, enumerated by class and never by a single
|
|
192
195
|
tool — and stage 10 does not close while this run's residue is live and
|
|
193
196
|
unaccounted (`references/residue.md`). The rest are in
|
|
@@ -156,6 +156,25 @@
|
|
|
156
156
|
"description": "Rounds per artifact before the run stops reviewing and measures. Counted from the run ledger's `touch:` pass numbers, never from memory; a round that finds nothing ends the loop by definition and is not counted."
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
+
},
|
|
160
|
+
"finish": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"additionalProperties": false,
|
|
163
|
+
"description": "The iteration's budget at its finish line. Absent, the defaults hold: 3 rounds and 2 releases. A round is every exit check once plus one independent reading over the scope; only new blocking findings count. Reaching either budget before done — a blocker open, or the second clean round still owed — stops the iteration and hands it back; no round runs past it without the operator's go, given with the numbers. Doctrine: references/finish-line.md; verdict: scripts/waves.py finish.",
|
|
164
|
+
"properties": {
|
|
165
|
+
"maxRounds": {
|
|
166
|
+
"type": "integer",
|
|
167
|
+
"minimum": 2,
|
|
168
|
+
"default": 3,
|
|
169
|
+
"description": "Finish-line rounds per iteration, at least 2: done needs two consecutive rounds with no new blocking finding. Rotating the audit axis happens inside this budget and never adds a round."
|
|
170
|
+
},
|
|
171
|
+
"maxReleases": {
|
|
172
|
+
"type": "integer",
|
|
173
|
+
"minimum": 1,
|
|
174
|
+
"default": 2,
|
|
175
|
+
"description": "Releases per iteration, the first included; every corrective release after a post-release failure counts against it."
|
|
176
|
+
}
|
|
177
|
+
}
|
|
159
178
|
}
|
|
160
179
|
}
|
|
161
180
|
},
|
|
@@ -344,7 +344,8 @@ construction**:
|
|
|
344
344
|
findings, and findings caused by the previous pass's own fixes. When the second
|
|
345
345
|
overtakes the first, the axis is exhausted — **rotate it, don't push harder.** Both
|
|
346
346
|
counts go in the ledger; an audit that reports only "found N" cannot see its own
|
|
347
|
-
exhaustion.
|
|
347
|
+
exhaustion. **Rotation happens inside the round budget**: a new axis is the next round's
|
|
348
|
+
reading, never an extra round ([`finish-line.md`](finish-line.md) → *Rounds and the stop*).
|
|
348
349
|
|
|
349
350
|
### 3. What can't be fixed now becomes a ratchet, never a TODO
|
|
350
351
|
|
|
@@ -380,7 +381,9 @@ explaining why; a ratchet nobody prints is a TODO with a better name.
|
|
|
380
381
|
produce findings and fixes rather than a feature, and the exit criterion above is
|
|
381
382
|
the stage-10 gate.
|
|
382
383
|
- **Never as an eighth "look again" pass.** If the last two passes found mostly
|
|
383
|
-
self-inflicted findings, the answer is rule 2, not another pass
|
|
384
|
+
self-inflicted findings, the answer is rule 2, not another pass — and rule 2's rotation
|
|
385
|
+
spends the iteration's round budget rather than extending it
|
|
386
|
+
([`finish-line.md`](finish-line.md)).
|
|
384
387
|
|
|
385
388
|
Once both axes are exhausted, the next finding of a known class should be caught by
|
|
386
389
|
a script — and if it cannot be, **that is the finding: write the check.**
|
|
@@ -12,7 +12,9 @@ which is how a run says *I checked the browser* and means *I ran the unit tests*
|
|
|
12
12
|
> **Every command and flag below was read from the tool's own `--help`**, not from a
|
|
13
13
|
> vendor page. Where the two disagreed, `--help` won and the page was wrong — see
|
|
14
14
|
> *Rationalizations*. Re-derive before quoting:
|
|
15
|
-
> `npx @playwright/cli@latest --help` and `npx @playwright/mcp@latest --help`.
|
|
15
|
+
> `npx @playwright/cli@latest --help` and `npx @playwright/mcp@latest --help`. The
|
|
16
|
+
> `--browser webkit` flag on both was last read from `@playwright/cli` 0.1.22 (`open
|
|
17
|
+
> --help`) and `@playwright/mcp` 0.0.83 on 2026-10-16.
|
|
16
18
|
>
|
|
17
19
|
> **Use the scoped name with `npx`.** `npx playwright-cli --help` fails outside a project
|
|
18
20
|
> that has already installed it (`could not determine executable to run`), and the bare
|
|
@@ -23,6 +25,7 @@ which is how a run says *I checked the browser* and means *I ran the unit tests*
|
|
|
23
25
|
|
|
24
26
|
## Contents
|
|
25
27
|
|
|
28
|
+
- Engine order — WebKit (Safari) first
|
|
26
29
|
- The one model: a tree, and a ref
|
|
27
30
|
- The look, as commands you can run
|
|
28
31
|
- Sessions, and why an agent needs them
|
|
@@ -35,6 +38,35 @@ which is how a run says *I checked the browser* and means *I ran the unit tests*
|
|
|
35
38
|
- What the channel can reach — the part a recommendation owes you
|
|
36
39
|
- Rationalizations
|
|
37
40
|
|
|
41
|
+
## Engine order — WebKit (Safari) first
|
|
42
|
+
|
|
43
|
+
**Check a rendered surface in WebKit first** (`DEC-0007`). The channel is how a look
|
|
44
|
+
arrives; the engine is what renders it, and the two are separate choices:
|
|
45
|
+
|
|
46
|
+
| Need | WebKit route — the default |
|
|
47
|
+
|---|---|
|
|
48
|
+
| A real browser | Safari itself, through `safaridriver` (WebDriver; enable it once with `sudo safaridriver --enable`) |
|
|
49
|
+
| Automation, the look | Playwright's `webkit`: `playwright-cli open --browser webkit <url>`, the MCP started with `--browser webkit`, a `webkit` project in `playwright.config.*`. Install the engine with `playwright-cli install-browser webkit` or `npx playwright install webkit` |
|
|
50
|
+
| Debugging | Safari Web Inspector |
|
|
51
|
+
| A page for a person, on macOS | `open -a Safari <url>` — never bare `open <url>`, which hands the page to the system default browser, and the default may be another browser |
|
|
52
|
+
| An automation library (browser-use and the like) | its WebKit or Safari backend, where it has one |
|
|
53
|
+
|
|
54
|
+
Name the engine every time. Without `--browser`, the CLI falls back to a Chromium-family
|
|
55
|
+
browser (read from its own bundle, 0.1.22, not from `--help`) — so a recipe that leaves
|
|
56
|
+
the flag off has chosen Chromium without saying so. Playwright's `webkit` is the engine,
|
|
57
|
+
not Safari itself: a question about Safari's own behaviour goes to `safaridriver`.
|
|
58
|
+
|
|
59
|
+
**Chromium is a stated fallback, never the default.** Use it only when the task needs
|
|
60
|
+
Chrome itself — a Chrome-only API, Lighthouse, a CDP performance trace, a heap snapshot,
|
|
61
|
+
the `chrome-devtools` MCP — and say which and why in the verdict. Prefer the Chrome Dev
|
|
62
|
+
build for that. When you launch your own Chrome or Chromium for a UI run, give it a
|
|
63
|
+
temporary profile (never the user's), record what you started, and close every process
|
|
64
|
+
you started before you finish ([`residue.md`](residue.md)).
|
|
65
|
+
|
|
66
|
+
**A surface checked only in Chromium is reported as exactly that** — *"checked in
|
|
67
|
+
Chromium (`chrome-devtools`, for `lighthouse_audit`)"*, never *"tested in a browser"*.
|
|
68
|
+
The engine is part of the claim, the same way the command is.
|
|
69
|
+
|
|
38
70
|
## The one model: a tree, and a ref
|
|
39
71
|
|
|
40
72
|
**Both channels drive the page through its accessibility tree, not its pixels.** You ask
|
|
@@ -68,14 +100,15 @@ The pipeline asks for the same four things every time: **open it, snapshot it, r
|
|
|
68
100
|
console, read the network.** In the CLI that is literally four commands:
|
|
69
101
|
|
|
70
102
|
```bash
|
|
71
|
-
playwright-cli open http://localhost:3000/checkout
|
|
103
|
+
playwright-cli open --browser webkit http://localhost:3000/checkout
|
|
72
104
|
playwright-cli snapshot
|
|
73
105
|
playwright-cli console warning # min-level: only warnings and errors
|
|
74
106
|
playwright-cli requests # then: request <n> for headers, body, response
|
|
75
107
|
```
|
|
76
108
|
|
|
77
109
|
The MCP is the same four moves under different names: `browser_navigate`,
|
|
78
|
-
`browser_snapshot`, `browser_console_messages`, `browser_network_requests
|
|
110
|
+
`browser_snapshot`, `browser_console_messages`, `browser_network_requests` — on WebKit
|
|
111
|
+
when the server was started with `--browser webkit`.
|
|
79
112
|
|
|
80
113
|
**Quote what you read, not that you looked.** *"Console clean, all requests fine"* is a
|
|
81
114
|
claim. *"`console warning` → empty; `requests` → no status ≥ 400"* is the same claim with
|
|
@@ -87,8 +120,9 @@ resources by default and says so in its own footer (*"N static request(s) not sh
|
|
|
87
120
|
appears without the flag — so *no status ≥ 400* is a safe claim and *14 requests* is not.
|
|
88
121
|
|
|
89
122
|
`chrome-devtools` takes the identical four moves — `navigate_page`, `take_snapshot`,
|
|
90
|
-
`list_console_messages`, `list_network_requests` —
|
|
91
|
-
the look is the
|
|
123
|
+
`list_console_messages`, `list_network_requests` — but only in Chrome. The moves are the
|
|
124
|
+
same look; the engine is not, so for the look it is the **stated Chromium exception**,
|
|
125
|
+
reached for when the question needs Chrome (*Engine order*, above).
|
|
92
126
|
|
|
93
127
|
## Sessions, and why an agent needs them
|
|
94
128
|
|
|
@@ -130,17 +164,17 @@ commonest way a run reports a green it does not have.
|
|
|
130
164
|
|---|---|---|---|
|
|
131
165
|
| **The look** | an agent driving a page: open, snapshot, console, network | that this surface renders, right now, and what the browser said while it did | the **functional look**, stage 6 — recommended, never a gate. Its **visual half** is a gate on a `flagship`, `product` or `ad` surface — *The visual half*, below |
|
|
132
166
|
| **The spec suite** | `playwright test` — the **test runner** | that the assertions someone wrote still hold, on the paths someone thought to write | the **suite** half of the stage-6 gate, counted with every other test |
|
|
133
|
-
| **The library** | `require('playwright')` — `chromium`/`firefox
|
|
167
|
+
| **The library** | `require('playwright')` — `webkit`/`chromium`/`firefox`, `devices`, `request`, `selectors` | whatever your own script asserts; it is an automation API, not a test framework | wherever the project already runs it |
|
|
134
168
|
|
|
135
|
-
The library and the runner are **separate APIs** — a script built on `
|
|
169
|
+
The library and the runner are **separate APIs** — a script built on `webkit.launch()`
|
|
136
170
|
has no `expect`, no fixtures, no reporter, and no retry. Choosing the library where a
|
|
137
171
|
runner was wanted is how a project ends up with a bespoke half-runner nobody trusts.
|
|
138
172
|
|
|
139
173
|
The minimal library shape, for reading a script that already exists:
|
|
140
174
|
|
|
141
175
|
```js
|
|
142
|
-
const {
|
|
143
|
-
const browser = await
|
|
176
|
+
const { webkit } = require('playwright');
|
|
177
|
+
const browser = await webkit.launch();
|
|
144
178
|
const page = await browser.newPage();
|
|
145
179
|
await page.goto('http://example.com');
|
|
146
180
|
await browser.close();
|
|
@@ -186,7 +220,8 @@ the close-out — the same rule as every other refusal in the pipeline.
|
|
|
186
220
|
|
|
187
221
|
1. **Deterministic.** The project linter — `python3 scripts/visual_gate.py lint <dir>`,
|
|
188
222
|
which runs sheleg-design's `--lint` where it is installed and answers **NOT_RUN (exit 3)**
|
|
189
|
-
where it is not — plus axe or Lighthouse
|
|
223
|
+
where it is not — plus axe or Lighthouse (the stated Chromium exception), the token
|
|
224
|
+
check, the type checker. An S1
|
|
190
225
|
finding blocks, whatever anyone says about the picture later. **With Figma on, the
|
|
191
226
|
token check includes the drift probe**: `python3 scripts/visual_gate.py tokens
|
|
192
227
|
--figma <variables.json> --css <tokens.css>` compares the variable names exported
|
|
@@ -266,7 +301,7 @@ and neither needs a password in a transcript.
|
|
|
266
301
|
|
|
267
302
|
```bash
|
|
268
303
|
mkdir -p .auth # state-save does not create it
|
|
269
|
-
playwright-cli open https://app.example.com/login
|
|
304
|
+
playwright-cli open --browser webkit https://app.example.com/login
|
|
270
305
|
# … sign in by hand, or drive the form …
|
|
271
306
|
playwright-cli state-save .auth/state.json # cookies + localStorage
|
|
272
307
|
playwright-cli state-load .auth/state.json # every later look starts signed in
|
|
@@ -387,4 +422,6 @@ On a CI box, headed is the failure you will spend an hour on.
|
|
|
387
422
|
| *"The tool list is in the docs."* | The page listed tools this version does not ship, and omitted that tracing, video and PDF need `--caps`. Ask the server: 24 tools default, 42 with all caps. |
|
|
388
423
|
| *"It's behind a login, so the look isn't possible."* | `state-save` / `state-load`, or `--storage-state`. Auth is a solved step, not an exemption. |
|
|
389
424
|
| *"No browser channel is installed, so the step doesn't apply."* | The step still applies; the claim weakens. Say *verified by reading the diff* and let the close-out record it as the weaker claim it is. |
|
|
425
|
+
| *"Tested in a browser."* | Which engine? A look taken only in Chromium is reported as *checked in Chromium*, with the reason Chrome was needed. WebKit is the default (*Engine order*). |
|
|
426
|
+
| *"I opened it with `open <url>`."* | That is the system default browser, which may not be Safari. `open -a Safari <url>` for a person; `--browser webkit` for automation. |
|
|
390
427
|
| *"I closed the browser."* | `list` is the evidence. The command you typed is not the state you left ([`residue.md`](residue.md)). |
|
|
@@ -27,6 +27,10 @@ one must never look alike.
|
|
|
27
27
|
> **`DEC-0006`** scopes that to the functional look: the **visual half** is a gate on a
|
|
28
28
|
> `flagship`, `product` or `ad` surface, and its absent tool reads NOT_RUN and stops to
|
|
29
29
|
> ask rather than passing ([`browser.md`](browser.md) → *The visual half*).
|
|
30
|
+
> **`DEC-0007`** ranks the **engine**, not the channel's quality: WebKit (Safari) first,
|
|
31
|
+
> Chromium a stated exception. `playwright` reaches WebKit and `chrome-devtools` does
|
|
32
|
+
> not, so `playwright` on WebKit is the default look and `chrome-devtools` is reached for
|
|
33
|
+
> when the question needs Chrome ([`browser.md`](browser.md) → *Engine order*).
|
|
30
34
|
|
|
31
35
|
## Contents
|
|
32
36
|
|
|
@@ -70,8 +74,8 @@ one must never look alike.
|
|
|
70
74
|
| **Figma** (MCP) | stage 3 UX track, when the project designs visually — super-ux mirrors each `SCR-` screen/state into a frame | Optional, **UI + Figma-on only**. Absent → super-ux degrades to text-only *by itself and never blocks*, so shipping a UI feature with no mockups becomes a silent scope call — which is why the stage-0 sweep decides it | connect the Figma MCP server (`/mcp`, or your claude.ai connectors) |
|
|
71
75
|
| **[obsidian-wiki](https://github.com/ar9av/obsidian-wiki)** (`wiki-query`, `wiki-update`) | **stage 0 harvest** (query what's already known) **+ stage 9 sync** | **Recommended** — never a gate; absent → harvest runs on repo docs alone | `pip install obsidian-wiki` → `obsidian-wiki setup --vault /path/to/your/vault` |
|
|
72
76
|
| **[graphify](https://github.com/Graphify-Labs/graphify)** (`/graphify`, `graphify query`, `graphify affected`, `graphify god-nodes`) | **stage 0 harvest** (reach: what calls this, what breaks if it moves) **+ stage 9 refresh + the graph↔docs divergence check** ([`knowledge-graph.md`](knowledge-graph.md)) | **Recommended** — never a gate; absent → the harvest greps instead, and the divergence axis is unavailable | `uv tool install graphifyy` → `graphify install` → `/graphify .` |
|
|
73
|
-
| **playwright** (CLI — `playwright-cli open`, `snapshot`, `click`, `type`, and the two this pipeline actually asks for: `console` and `requests`; or MCP — `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_console_messages`, `browser_network_requests`) | **
|
|
74
|
-
| **chrome-devtools** (MCP — `list_pages`, `navigate_page`, `take_snapshot`, `take_screenshot`, `evaluate_script`, `list_console_messages`, `list_network_requests`, `lighthouse_audit`, `performance_start_trace`, `take_heapsnapshot`) | **
|
|
77
|
+
| **playwright** (CLI — `playwright-cli open`, `snapshot`, `click`, `type`, and the two this pipeline actually asks for: `console` and `requests`; or MCP — `browser_navigate`, `browser_snapshot`, `browser_click`, `browser_console_messages`, `browser_network_requests`) | **The default route — WebKit first** (`DEC-0007`): `playwright-cli open --browser webkit`, or the MCP started with `--browser webkit`; on macOS, Safari itself through `safaridriver` and Safari Web Inspector to debug ([`browser.md`](browser.md) → *Engine order*). **Stages 5–6 on any project with a web front end**, and **stage 8** on a deployed target — the same job as the row below: open the surface, snapshot it, read the console and the network log. Its own difference is **the channel a look arrives on**: the CLI is a shell command, so it does not put a tool schema in the context window the way an MCP channel does — that is upstream's own comparison and it is *CLI against MCP*, which makes it a claim about this row's own two halves before it is a claim about the row below. Both channels default to an **accessibility-tree snapshot rather than pixels**, so the ordinary look costs a page of text and no vision model; `screenshot` exists in both and costs one when you ask for it | **Recommended** — never a gate; absent → say the surface was verified **by reading the diff** and treat that as the weaker claim it is | CLI: `npm install -D @playwright/cli@latest` → `npx playwright-cli --help` (or `npm i -g` for the global binary; `playwright-cli install --skills` adds its agent skills, `--global` to the home directory), then `playwright-cli install-browser webkit`. MCP: `claude mcp add playwright -- npx @playwright/mcp@latest --browser webkit` |
|
|
78
|
+
| **chrome-devtools** (MCP — `list_pages`, `navigate_page`, `take_snapshot`, `take_screenshot`, `evaluate_script`, `list_console_messages`, `list_network_requests`, `lighthouse_audit`, `performance_start_trace`, `take_heapsnapshot`) | **The stated Chromium exception** — it drives Chrome only, so it is reached for when the question needs Chrome, said with the reason, and a look taken only here is reported as *checked in Chromium*. **Stages 5–6 on any project with a web front end** — verify the **rendered** surface rather than the diff: computed layout, console errors, failed requests. **Stage 8** on a deployed web target: load the page and read what the browser did, not what the deploy said. Its own difference is **reach past the page**: a Lighthouse category (`lighthouse_audit`, which `seo-aeo-audit` builds on) and a heap snapshot have no equivalent in the row above. A performance trace has one — `playwright-cli tracing-start` records one — but only this row's arrives with `performance_analyze_insight` over it | **Recommended** — never a gate; absent → say the surface was verified **by reading the diff** and treat that as the weaker claim it is | `/plugin install chrome-devtools-mcp@claude-plugins-official` (or connect the MCP server directly) |
|
|
75
79
|
| **[agent-sync](https://github.com/ssheleg/agent-sync)** (`/agent-sync`, **≥ 1.3.0** — `finish` did not exist before it, so an older install turns the stage-10 close-out into a command that is not there) | **guarded registers** — a lease before writing one, `reserve` before minting an id, `reconcile`/`record` for intent vs as-built, and `finish` for the stage-10 multi-repository close-out ([`documentation.md`](documentation.md)) | **Recommended** — never a gate. Absent → the run is **`ungated`** and must say so out loud; the discipline still applies, only the arbitration is missing | `npx sshlg-skills install` |
|
|
76
80
|
| **sheleg-dev** (`stripe-billing`, `crypto-payments`, `error-tracking`, `ad-tracking`, `google-signin`, `google-auth`, `frontend-performance`) | **stage 5 when the task wires money, tracking, sign-in or page speed** — the seams a generated integration gets wrong in ways no screen shows: the webhook is the payment, a thank-you-page event cannot know the charge cleared, a duplicated `event_id` counts revenue twice | **Recommended** — never a gate; absent → the integration ships on the host's own doctrine and the close-out names the seam nobody checked | `/plugin marketplace add ssheleg/sheleg-dev` → `/plugin install sheleg-dev@sheleg-dev` |
|
|
77
81
|
| **agent-stack** (`agent-orchestrator`, `agent-evals`, `agent-interop`, `agent-harness`) | **stage 5 when the thing being BUILT is an agent system** — the orchestrator's loop, evals that say whether it got better, the protocols it speaks (MCP/A2A), the wallet under LLM resale. Not for coordinating the agents editing this repository (that is agent-sync, above) | **Recommended** — never a gate; absent → the agent layer ships unevaluated and the close-out says so | `/plugin marketplace add ssheleg/agent-stack` → `/plugin install agent-stack@agent-stack` |
|
|
@@ -94,11 +98,11 @@ required; an absent one is a check recorded as NOT_RUN with its reason.
|
|
|
94
98
|
| `review-animations`, `improve-animations` | reviews motion against its intent: timing, easing, interruption, reduced-motion fallback | stage 6, on a surface with motion; findings as triples |
|
|
95
99
|
| `mobile-native` | the mobile-web surface: viewport, safe areas, touch targets, keyboard-up states | stages 5–6, mobile-web frames of the matrix |
|
|
96
100
|
| `animate-expo` | React Native and Expo motion, built and reviewed on the platform's own primitives | stage 5, an RN or Expo surface |
|
|
97
|
-
| `webapp-testing
|
|
101
|
+
| `playwright-cli open --browser webkit` + `screenshot`, `webapp-testing`; `chrome-devtools` (`lighthouse_audit`, the stated Chromium exception) | the frames of the matrix at each viewport and theme, captured in WebKit first, and a Lighthouse pass as the deterministic floor | stage 6, the capture and the floor; stage 8 on a deployed target |
|
|
98
102
|
| `accessibility-review`, `a11y-debugging` | accessibility review of the rendered surface and debugging what it finds | stage 6, beside axe or Lighthouse |
|
|
99
103
|
| XCUITest `performAccessibilityAudit` | the iOS platform's own accessibility audit, run in UI tests | stage 6, a native iOS surface |
|
|
100
104
|
| Compose `enableAccessibilityChecks` | Android's accessibility checks in Compose UI tests | stage 6, a native Android surface |
|
|
101
|
-
| Playwright `toHaveScreenshot` | screenshot regression against the approved baseline, per state and theme | stage 6 (regression), and the nightly or release baseline after |
|
|
105
|
+
| Playwright `toHaveScreenshot` | screenshot regression against the approved baseline, per state and theme — the `webkit` project first | stage 6 (regression), and the nightly or release baseline after |
|
|
102
106
|
| axe-core | the deterministic accessibility floor of a web surface | stage 6, first in the cheap-first order |
|
|
103
107
|
| `figma-code-connect` (Figma's public plugin skill) | maps a design-system component in the file to its code component, so `get_design_context` hands the agent the real import instead of approximated markup | stage 5, **offered** for a core component the file draws and nothing maps — publishes to the file, so it needs a go ([`build.md`](build.md) → *Code Connect, kept*) |
|
|
104
108
|
|
|
@@ -164,11 +168,12 @@ Pipeline companions (stage doctrine is built in — nothing to install for it):
|
|
|
164
168
|
(running without it — no reach queries, no graph↔docs
|
|
165
169
|
divergence check)
|
|
166
170
|
✗ playwright — recommended when this project has a web front end.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this one for free:
|
|
171
|
+
The default look: it reaches WebKit (Safari's engine),
|
|
172
|
+
which is checked first; a project that already runs
|
|
173
|
+
Playwright has this one for free:
|
|
170
174
|
npm install -D @playwright/cli@latest (then npx playwright-cli)
|
|
171
|
-
|
|
175
|
+
playwright-cli install-browser webkit
|
|
176
|
+
claude mcp add playwright -- npx @playwright/mcp@latest --browser webkit
|
|
172
177
|
(running without it — see the line below; without BOTH,
|
|
173
178
|
the surface is verified by reading the diff)
|
|
174
179
|
✗ sheleg-dev — this task wires money, tracking, sign-in or page speed;
|
|
@@ -191,9 +196,9 @@ Pipeline companions (stage doctrine is built in — nothing to install for it):
|
|
|
191
196
|
✗ chrome-devtools — recommended when this project has a web front end:
|
|
192
197
|
stages 5-6 check the RENDERED surface instead of the
|
|
193
198
|
diff, stage 8 reads what the browser did after a deploy.
|
|
194
|
-
The
|
|
195
|
-
and heap snapshots, and
|
|
196
|
-
only recording one:
|
|
199
|
+
The stated Chromium exception: Chrome only, and it
|
|
200
|
+
alone reaches lighthouse_audit and heap snapshots, and
|
|
201
|
+
analyses a trace rather than only recording one:
|
|
197
202
|
/plugin install chrome-devtools-mcp@claude-plugins-official
|
|
198
203
|
(running without it — the surface is verified by reading
|
|
199
204
|
the diff, and the close-out says so in those words)
|
|
@@ -226,7 +231,8 @@ Rules:
|
|
|
226
231
|
`wiki-query`/`wiki-update`. Present → say `✓ ready` and use it in the harvest.
|
|
227
232
|
Absent → print the two install lines **once** and continue; never ask twice in a
|
|
228
233
|
run and never block a stage on it ([`knowledge-sources.md`](knowledge-sources.md)).
|
|
229
|
-
- **The browser channels — `playwright` and `chrome-devtools`, one rule for both
|
|
234
|
+
- **The browser channels — `playwright` and `chrome-devtools`, one rule for both, WebKit
|
|
235
|
+
first.**
|
|
230
236
|
Flag them only when the project **has a web front end** — an `index.html`, a
|
|
231
237
|
`package.json` naming a browser framework, a `docs/ux/screens.md`, or a deploy target
|
|
232
238
|
that serves pages. **A CLI, a library or a backend service does not flag either** —
|
|
@@ -237,18 +243,20 @@ Rules:
|
|
|
237
243
|
`mcp__chrome-devtools__list_pages` (either one under whatever prefix the host uses).
|
|
238
244
|
Present → `✓ ready`. Absent → print its install lines **once** and continue; neither
|
|
239
245
|
is a gate.
|
|
240
|
-
- **They are two channels for one look, and the run needs one of them, not both
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
**`
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
246
|
+
- **They are two channels for one look, and the run needs one of them, not both —
|
|
247
|
+
on WebKit first** (`DEC-0007`, [`browser.md`](browser.md) → *Engine order*). Both open
|
|
248
|
+
the page, snapshot it and read the console and the network log, so the look is taken
|
|
249
|
+
once: **`playwright` with `--browser webkit`** (on macOS, Safari itself through
|
|
250
|
+
`safaridriver` is the same engine) — running the same look twice is a cost with no
|
|
251
|
+
second fact. **`chrome-devtools` is the stated Chromium exception**: it drives Chrome
|
|
252
|
+
only, so it is reached for when the question needs Chrome — a Lighthouse category or a
|
|
253
|
+
heap snapshot, neither of which the Playwright channel has, a performance trace you
|
|
254
|
+
want *analysed* rather than only recorded, or a Chrome-only API — and the verdict says
|
|
255
|
+
which and why. Where only `chrome-devtools` is present, the look is reported as
|
|
256
|
+
*checked in Chromium*, never as *tested in a browser*; where neither is, say the
|
|
257
|
+
surface was verified **by reading the diff**. The rank is of the **engine**, not of the
|
|
258
|
+
tools' quality: neither channel is *the better browser*, and a run that claims one is
|
|
259
|
+
has invented a fact this matrix does not carry.
|
|
252
260
|
- **graphify**: detect via `graphify-out/graph.json` (built → `✓ ready`, query it in
|
|
253
261
|
the harvest) or a resolving `graphify` binary with no `graphify-out/` (installed,
|
|
254
262
|
not built → offer the one-line `/graphify .`). Absent → print the install lines
|
|
@@ -97,7 +97,8 @@ This spans the whole run, not one stage:
|
|
|
97
97
|
finished.
|
|
98
98
|
|
|
99
99
|
It stops for exactly four things: an unmet `manual` gate, a block it cannot resolve, a
|
|
100
|
-
genuine ambiguity the brief does not answer, and completion
|
|
100
|
+
genuine ambiguity the brief does not answer, and completion — the iteration's finish line
|
|
101
|
+
reached ([`finish-line.md`](finish-line.md)), never a search that ran dry.
|
|
101
102
|
|
|
102
103
|
**A block or an ambiguity stops its node, not the run.** An ambiguity whose answer is
|
|
103
104
|
internal and reversible is not a stop at all: the run takes the recommended answer, records
|
|
@@ -112,6 +113,11 @@ recorded reasons: external waits go on watchers, human decisions go into the que
|
|
|
112
113
|
batch. Exit 4 does not prove a human gate or completion. A watcher keeps the recorded
|
|
113
114
|
next action alive while no independent node is runnable. **When the board is empty, say so once**, and do not invent work to fill it.
|
|
114
115
|
|
|
116
|
+
**Stop is not idle.** A finish line reached closes that iteration — stages 9–10, the
|
|
117
|
+
hand-back, the retro — and on an armed loop the highest-priority board row starts a new
|
|
118
|
+
iteration with its own contract. Re-opening the closed one to polish it is not continuing
|
|
119
|
+
([`finish-line.md`](finish-line.md) → *Stop is not idle*).
|
|
120
|
+
|
|
115
121
|
**This extends [`build.md`](build.md); it does not replace it.** That file's
|
|
116
122
|
*Continuous execution* rule governs the inside of a stage-5 execution — do not
|
|
117
123
|
check in between the tasks of a plan you were told to execute. It is unconditional
|
|
@@ -59,6 +59,7 @@ Custom profiles use their own declared stages and doctrine, with the kernel inta
|
|
|
59
59
|
| **first run in a project** (new or existing) | `references/adoption.md` |
|
|
60
60
|
| **first run · the entry audit** (offered once) | `references/setup.md` |
|
|
61
61
|
| **what travels with the bundle vs stays in a project** | `references/portability.md` |
|
|
62
|
+
| 0–10 · when an iteration stops — the contract fixed at intake, triage at discovery, the round budget | `references/finish-line.md` |
|
|
62
63
|
| any repeating loop | `references/loop-guard.md` |
|
|
63
64
|
| run-wide · what the run **leaves running and leaves behind** — every gate, and stage 10 | `references/residue.md` |
|
|
64
65
|
| run-wide · what the run **prints about itself** — the rail, the iteration line | `references/progress.md` |
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# The finish line — when an iteration stops
|
|
2
|
+
|
|
3
|
+
An iteration stops when the work it promised is done **on the artefact the operator uses**.
|
|
4
|
+
It does not stop when a search runs dry, because a search never does: every reading finds
|
|
5
|
+
something, every fix is new surface for the next reading, and find → fix → find has no end of
|
|
6
|
+
its own. This file is that end. The verdict is computed by `scripts/waves.py finish`.
|
|
7
|
+
|
|
8
|
+
## Contents
|
|
9
|
+
|
|
10
|
+
- The contract, fixed at intake
|
|
11
|
+
- Triage at discovery
|
|
12
|
+
- Rounds and the stop
|
|
13
|
+
- Computing the verdict
|
|
14
|
+
- Stop is not idle
|
|
15
|
+
- The finish block
|
|
16
|
+
- Rationalizations
|
|
17
|
+
|
|
18
|
+
## The contract, fixed at intake
|
|
19
|
+
|
|
20
|
+
The brief's `## Finish line` ([`../templates/brief.md`](../templates/brief.md)) carries five
|
|
21
|
+
fields, written at stage 0 and confirmed with the brief:
|
|
22
|
+
|
|
23
|
+
- **Objective** — one sentence: what is true when this iteration is done.
|
|
24
|
+
- **Exit checks** — REQ ids, each with its command, run on the artefact the operator uses:
|
|
25
|
+
released, installed or deployed. A branch is not that artefact.
|
|
26
|
+
- **Scope** — the modules, paths and REQ ids this iteration may change, as a list.
|
|
27
|
+
- **Budget** — `run.finish.maxRounds` (default 3) and `run.finish.maxReleases` (default 2),
|
|
28
|
+
from `pipeline.json` ([`../pipeline.schema.json`](../pipeline.schema.json)).
|
|
29
|
+
- **Base** — the commit the iteration started from.
|
|
30
|
+
|
|
31
|
+
Widening the scope is a recorded revision of the brief, with the operator's go. A finding is
|
|
32
|
+
not one.
|
|
33
|
+
|
|
34
|
+
## Triage at discovery
|
|
35
|
+
|
|
36
|
+
Every finding that reaches a round is classed when it is found, before anyone fixes it. First
|
|
37
|
+
match wins. A defect in a node's own diff, caught before the node closes, follows
|
|
38
|
+
[`review.md`](review.md) instead: Critical and Important block that node.
|
|
39
|
+
|
|
40
|
+
**Blocking**, when:
|
|
41
|
+
- **B1** — an exit check is red.
|
|
42
|
+
- **B2** — it is, or once released would be, a hotfix-lane entry. The list's single home is [`iteration.md`](iteration.md)
|
|
43
|
+
→ *No fix travels alone*; restated here, kept equal by the validator:
|
|
44
|
+
- production is down
|
|
45
|
+
- data is being lost or corrupted
|
|
46
|
+
- a credential has leaked
|
|
47
|
+
- a security hole is open to someone outside
|
|
48
|
+
- money or a legal obligation is failing
|
|
49
|
+
- **B3** — the failing scenario passes at Base: this iteration broke it.
|
|
50
|
+
- **B4** — a REQ marked `verified`, or a claim this iteration publishes, is false on the
|
|
51
|
+
artefact. A published claim beyond the REQs may instead be narrowed in the same change.
|
|
52
|
+
|
|
53
|
+
**Deferred** — real, with a receipt, and no B test matches. It becomes a board row with its
|
|
54
|
+
evidence, its priority inputs ([`prioritisation.md`](prioritisation.md)) and
|
|
55
|
+
`found-in: <iteration>`. It is not fixed now.
|
|
56
|
+
|
|
57
|
+
**Noise** — no reproducible receipt; a duplicate (append its evidence to the existing row); a
|
|
58
|
+
Minor with no behavioural consequence; or an environment transient named by its cause. One
|
|
59
|
+
ledger line, nothing else.
|
|
60
|
+
|
|
61
|
+
Severity words, effort and "it is a one-line fix" never change the class. Each finding leaves
|
|
62
|
+
one line in the run ledger ([`../templates/run.md`](../templates/run.md)):
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
finding: <id> — blocking:B<n> | deferred:B-NNN | noise — round <N> — base-repro yes|no|n/a
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Rounds and the stop
|
|
69
|
+
|
|
70
|
+
A **round** is every exit check run once, plus one independent reading over the Scope: an
|
|
71
|
+
audit axis, an observer, or the post-release readback. Rotating the axis
|
|
72
|
+
([`audit.md`](audit.md)) never adds a round. Only new blocking findings count.
|
|
73
|
+
|
|
74
|
+
- **Done** — every exit check green on the artefact, and two consecutive rounds with no new
|
|
75
|
+
blocking finding. The second of them may read only the last fix's diff.
|
|
76
|
+
- **Diverging** — new blocking findings did not fall from one round to the next, or
|
|
77
|
+
self-inflicted ≥ new. Run [`loop-guard.md`](loop-guard.md)'s break protocol.
|
|
78
|
+
- **Budget spent** — `maxRounds` or `maxReleases` reached before done: a blocker open, or the
|
|
79
|
+
second clean round still owed. Stop and hand the iteration back: each open blocker becomes a
|
|
80
|
+
top board row marked `needs-operator`. No round runs past the budget without the operator's
|
|
81
|
+
go, given with the numbers; a done reached past it without that go is still `budget`.
|
|
82
|
+
|
|
83
|
+
The finish word is one of three: `done`; `budget`, the budget reached before done; `blocked`,
|
|
84
|
+
the rounds diverging, handed to the loop guard. Deferred findings never extend an iteration.
|
|
85
|
+
|
|
86
|
+
Each round leaves one ledger line, clean rounds included, because a clean round leaves no
|
|
87
|
+
finding to count:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
round: <N> — <reading> — new blocking <k>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Computing the verdict
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
python3 scripts/waves.py finish --inventory <inventory.json> --ledger .task-pipeline/run.md \
|
|
97
|
+
--max-rounds 3 --max-releases 2 --releases <n> --checks <k>/<m> --artefact <name>@<sha>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`--rounds N` may stand in for `--ledger`; with neither the count is unknown and the script
|
|
101
|
+
refuses. Exit codes:
|
|
102
|
+
|
|
103
|
+
- `0` — done: the last two rounds found no new blocking item, none is open, and every exit
|
|
104
|
+
check is green on the artefact.
|
|
105
|
+
- `3` — continue: a blocker open, a second clean round owed, or no `--checks` given.
|
|
106
|
+
- `5` — budget: reached before done, or done past it without `--operator-go`.
|
|
107
|
+
- `6` — blocked: diverging; run the loop guard's break protocol.
|
|
108
|
+
- `1` — malformed: the inventory, the ledger or the arguments, each reason named.
|
|
109
|
+
|
|
110
|
+
## Stop is not idle
|
|
111
|
+
|
|
112
|
+
Reaching the finish line closes the iteration. It does not end the work.
|
|
113
|
+
|
|
114
|
+
1. Close it: stages 9–10, the hand-back ([`progress.md`](progress.md) → *The hand-back*), the
|
|
115
|
+
retrospective.
|
|
116
|
+
2. On an armed loop ([`continuity.md`](continuity.md)), take the highest-priority board row as a
|
|
117
|
+
**new** iteration with its own contract. Choose by priority, not recency: the row found last
|
|
118
|
+
is not next because it is fresh.
|
|
119
|
+
3. Re-opening a closed iteration to polish it is the loop this rule ends.
|
|
120
|
+
|
|
121
|
+
## The finish block
|
|
122
|
+
|
|
123
|
+
Printed at stage 10, beside the verdict, and in the hand-back's `FINISH` field:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
finish: done | budget | blocked — rounds <n>/<max> — releases <n>/<max>
|
|
127
|
+
exit checks: <k>/<m> green on <artefact>@<sha>
|
|
128
|
+
blocking: <n> open · <n> fixed
|
|
129
|
+
deferred: <n> → <ids, top priority first>
|
|
130
|
+
noise: <n>
|
|
131
|
+
known risks: <deferred rows at blast 3 or rung I4+, or none>
|
|
132
|
+
next: B-NNN (new iteration) | board empty
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Rationalizations
|
|
136
|
+
|
|
137
|
+
| Excuse | Reality |
|
|
138
|
+
|---|---|
|
|
139
|
+
| "One more pass, it keeps finding things" | Every reading finds something. Only a new blocking finding argues for another round |
|
|
140
|
+
| "It is a one-line fix, do it now" | Effort never changes the class. A deferred finding is a board row |
|
|
141
|
+
| "This one is critical" | A severity word is not a B test. Name B1–B4, or defer it |
|
|
142
|
+
| "Rotate the axis and keep going" | Rotation happens inside the round budget, never on top of it |
|
|
143
|
+
| "The budget is nearly enough, one more round" | A round past the budget needs the operator's go, with the numbers |
|
|
144
|
+
| "The deferred list is long, so we are not done" | Deferred findings never extend an iteration |
|
|
145
|
+
| "Re-open the last iteration, it is nearly perfect" | That is the loop this rule ends. Take the top board row as a new iteration |
|
|
@@ -36,7 +36,8 @@ A fix designed against today's state is the intermediate state that
|
|
|
36
36
|
seam, and the fix is then paid for twice. The finding gets an id in its owning register
|
|
37
37
|
and lands on a canvas node. Its wave decides when it is built.
|
|
38
38
|
|
|
39
|
-
**The hotfix lane is the only exception, and it is closed.**
|
|
39
|
+
**The hotfix lane is the only exception, and it is closed.** This list is its single home;
|
|
40
|
+
[`finish-line.md`](finish-line.md)'s blocking test B2 cites it. It has five entries:
|
|
40
41
|
- production is down;
|
|
41
42
|
- data is being lost or corrupted;
|
|
42
43
|
- a credential has leaked;
|
|
@@ -57,12 +58,12 @@ reason. "It is quick" is not one of the five entries.
|
|
|
57
58
|
| 4 | Question round | answers from the sources, then one batch to the operator | every question is answered, assumed, or blocks a named node |
|
|
58
59
|
| 5 | Plan | the work graph with waves and risk classes — `scripts/waves.py sync-graph` writes each node's `wave` and `risk` from the plan, so `graph.py close` enforces the rounds it owes — and one packet per node | every REQ lands on a node; [`planning.md`](planning.md)'s set comparison holds |
|
|
59
60
|
| 6 | Build | parallel agents, each owning disjoint files | each node is committed on its branch, with its own checks green |
|
|
60
|
-
| 7 | Verify | rounds per node, starting as each node lands | each node passes its risk class's rounds |
|
|
61
|
+
| 7 | Verify | rounds per node, starting as each node lands; each finding triaged at discovery ([`finish-line.md`](finish-line.md)) | each node passes its risk class's rounds |
|
|
61
62
|
| 8 | Seam check | cross-module checks per seam group | every seam the canvas names is exercised end to end |
|
|
62
63
|
| 9 | Docs | stage 9 over everything the release iteration shipped | the doc gate passes and the docs match the code |
|
|
63
64
|
| 10 | Release | versions, tags, pins, changelogs, in dependency order | the published artefacts resolve |
|
|
64
|
-
| 11 | Post-release check | the stage-8 trio on what was released | every item the release claims closed is checked on the released artefact |
|
|
65
|
-
| 12 | Next pool | the re-measured inventory and the proposal | the hand-back is sent |
|
|
65
|
+
| 11 | Post-release check | the stage-8 trio on what was released, read as a finish-line round | every item the release claims closed is checked on the released artefact, and `finish:` is computed |
|
|
66
|
+
| 12 | Next pool | the re-measured inventory and the proposal | the hand-back, with its `finish:` line, is sent |
|
|
66
67
|
| 13 | Retrospective | the project retro, plus the shared lesson store where one exists | written last ([`retrospective.md`](retrospective.md)) |
|
|
67
68
|
|
|
68
69
|
Steps 1–4 are stages 0–4 run once. Steps 6–8 are stages 5–8 per wave, and a wave's
|
|
@@ -218,7 +219,10 @@ actually published, installed or deployed — never on the branch. Each item the
|
|
|
218
219
|
claims closed is re-checked against the released artefact. For installed packages and
|
|
219
220
|
skills, follow [`deploy-targets.md`](deploy-targets.md) → *The verification trio*: update
|
|
220
221
|
within the authorized rollout and read back each claimed installed channel. A failure goes to the hotfix
|
|
221
|
-
lane if it is one of its five entries.
|
|
222
|
+
lane if it is one of its five entries. Every post-release failure is triaged at the finish
|
|
223
|
+
line ([`finish-line.md`](finish-line.md) → *Triage at discovery*): a blocking one is fixed in
|
|
224
|
+
this release iteration, and the corrective release counts against `run.finish.maxReleases`; a
|
|
225
|
+
deferred one goes to the next pool, with an id.
|
|
222
226
|
|
|
223
227
|
## The next pool
|
|
224
228
|
|
|
@@ -101,6 +101,11 @@ review cap reached — 3 rounds — artifact: test/validate.py
|
|
|
101
101
|
- **New > self-inflicted** — the reader is still paying. Continuing is then the
|
|
102
102
|
operator's call, made with the numbers in hand rather than out of fatigue.
|
|
103
103
|
|
|
104
|
+
At the level of a whole iteration only new **blocking** findings argue for continuing; a
|
|
105
|
+
deferred or noise finding is paid for on the board, not with another round
|
|
106
|
+
([`finish-line.md`](finish-line.md) → *Rounds and the stop*). The class is read from the
|
|
107
|
+
run ledger's `finding:` lines and the rounds from its `round:` lines, never from memory.
|
|
108
|
+
|
|
104
109
|
**The pair is the whole point.** A round count alone says how tired everyone is; the
|
|
105
110
|
pair says whether the loop still produces anything. Measured on one file once, the
|
|
106
111
|
guard's shapes and the run's own prose disagreed — one still paying, one exhausted —
|
|
@@ -64,6 +64,7 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
64
64
|
| The entry audit and what it inspects | `references/setup.md` |
|
|
65
65
|
| The ladder, seams, axis rotation, ratchets | `references/audit.md` |
|
|
66
66
|
| Loop detection and its caps | `references/loop-guard.md` |
|
|
67
|
+
| **The finish line** — when an iteration stops: the contract, triage at discovery, the round budget | `references/finish-line.md` |
|
|
67
68
|
| **What the run prints about itself** — the header block, the rail, the iteration line | `references/progress.md` |
|
|
68
69
|
| **What the run leaves running and leaves behind** — the eight classes, the `holds:` field, the teardown | `references/residue.md` |
|
|
69
70
|
| **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
|
|
@@ -169,6 +169,9 @@ SCOPE what this claim covers: the commit, the environment, the REQ
|
|
|
169
169
|
NOT VERIFIED what was built and NOT checked, or could not be. The literal
|
|
170
170
|
`none within the stated scope` is a valid answer; an empty
|
|
171
171
|
field is not
|
|
172
|
+
FINISH finish: done | budget | blocked — the finish block, as
|
|
173
|
+
finish-line.md prints it; mid-iteration, the round and
|
|
174
|
+
the open blocking count
|
|
172
175
|
|
|
173
176
|
DECISIONS WAITING <n> each as a question with options, asked HERE
|
|
174
177
|
AMBIGUITIES <n> computed, below
|
|
@@ -189,6 +192,11 @@ And `none within the stated scope` is a claim with a subject — it says *nothin
|
|
|
189
192
|
what SCOPE names is unverified*. Leaving the field empty says nothing at all, which reads
|
|
190
193
|
as the same thing and is not: canon 9a, one artifact over.
|
|
191
194
|
|
|
195
|
+
**`FINISH` says why the iteration stopped** ([`finish-line.md`](finish-line.md) → *The
|
|
196
|
+
finish block*): `done` with its exit checks green on the artefact, `budget` with each open
|
|
197
|
+
blocker a `needs-operator` board row, or `blocked`. A hand-back that cannot fill it has not
|
|
198
|
+
reached a finish line, and says which round it is in.
|
|
199
|
+
|
|
192
200
|
**Where there is no brief** — `checkup`, `setup`, a short path — TASK quotes the
|
|
193
201
|
operator's own sentence instead, marked as such. An unquotable TASK is a run that cannot
|
|
194
202
|
say what it was asked, which is worth its own line.
|