task-pipeline-skill 1.54.0 → 1.56.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 +173 -0
- package/CONTRIBUTING.md +41 -0
- package/README.md +16 -5
- package/SKILL-CARD.md +3 -3
- package/cursor/rules/task-pipeline.mdc +13 -6
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +3 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +278 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +38 -10
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +30 -6
- package/plugins/task-pipeline/skills/task-pipeline/references/tdd.md +14 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,178 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.56.0 — the stages demanded a look and named no way to take one
|
|
4
|
+
|
|
5
|
+
Since v1.36.0 three stages have required the rendered surface to be checked in a
|
|
6
|
+
browser, and v1.55.0 gave that requirement a second channel. Neither release said
|
|
7
|
+
**how a look is taken**. An agent reading this bundle learned which plugin to install
|
|
8
|
+
and nothing about what to do with it — which is precisely how a run reports *checked in
|
|
9
|
+
a browser* and means *ran the unit tests*.
|
|
10
|
+
|
|
11
|
+
`references/browser.md` is that mechanism, and stages 5, 6 and 8, `tdd.md` and both
|
|
12
|
+
gate rows in `SKILL.md` now point at it.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **The one model both channels share.** A snapshot returns the accessibility tree with
|
|
17
|
+
a **ref** per element, and you act on the ref — not on pixels, not on coordinates. Three
|
|
18
|
+
consequences the doctrine already rested on and had never stated: a look costs a page of
|
|
19
|
+
text and no vision model, a ref is deterministic where a coordinate is not, and **a ref
|
|
20
|
+
that stops resolving is a finding rather than an error to retry past**.
|
|
21
|
+
- **The look as four runnable commands** — `open`, `snapshot`, `console`, `requests` —
|
|
22
|
+
with the MCP and `chrome-devtools` names beside them, because the look is the same look
|
|
23
|
+
and that is why the matrix ranks neither.
|
|
24
|
+
- **Sessions and the daemon.** The browser lives between commands, which is the whole
|
|
25
|
+
reason the four compose; `-s=<session>` isolates, `list` is the evidence the environment
|
|
26
|
+
is clean, `kill-all` is for the zombie left by a crash.
|
|
27
|
+
- **`--json` / `--raw`.** The difference between output a reader reads and output a check
|
|
28
|
+
can gate on. A gate that regexes prose breaks on the release that rewords it.
|
|
29
|
+
- **"Tested in a browser" separated into the three claims it conflates** — the look, the
|
|
30
|
+
spec suite (`playwright test`, the runner) and the **library** (`class Playwright`),
|
|
31
|
+
which is an automation API and not a test framework at all. Choosing the library where a
|
|
32
|
+
runner was wanted is how a project grows a half-runner nobody trusts.
|
|
33
|
+
- **Auth and mocking as solved steps rather than exemptions.** `state-save` / `state-load`
|
|
34
|
+
(`--storage-state` on the MCP) for a surface behind a login — the state file is a
|
|
35
|
+
credential and goes where credentials go; `route` / `route-list` / `unroute` for the
|
|
36
|
+
failure paths a mocked unit test can never show rendering.
|
|
37
|
+
- **The loop that turns a look into a test that keeps it found:** `generate-locator` on
|
|
38
|
+
the element the look caught, then `pause-at` / `step-over` / `resume` to watch the new
|
|
39
|
+
spec see what you saw. A browser finding fixed with no test behind it is a finding
|
|
40
|
+
scheduled to return.
|
|
41
|
+
- **What the channel can reach**, because recommending a real browser is the widest
|
|
42
|
+
capability in the matrix: the MCP confines file access to the workspace roots until
|
|
43
|
+
`--allow-unrestricted-file-access` says otherwise, `--isolated` keeps nothing,
|
|
44
|
+
`--secrets` exists so a password reaches the browser and not the transcript — and
|
|
45
|
+
`--allowed-origins` is **not** a security boundary, which is upstream's own wording.
|
|
46
|
+
|
|
47
|
+
### Measured rather than restated
|
|
48
|
+
|
|
49
|
+
- **The MCP's tool list is capability-gated: 24 tools by default, 42 with
|
|
50
|
+
`--caps vision,pdf,devtools`** — counted by starting the server and calling `tools/list`,
|
|
51
|
+
not read off a page. `browser_start_tracing`, `browser_start_video` and
|
|
52
|
+
`browser_pdf_save` are **absent** from a default server. A doctrine naming them without
|
|
53
|
+
`--caps` sends an agent to a tool that is not there, and the agent concludes the doctrine
|
|
54
|
+
is stale rather than the server narrow. The page current at the time also listed route,
|
|
55
|
+
cookie and localStorage tools this version does not ship at all — which is why the CLI is
|
|
56
|
+
what this file names for state and mocking.
|
|
57
|
+
- Every CLI command and flag in the new file was checked against `playwright-cli --help`
|
|
58
|
+
before it shipped, `--persistent` included, which lives on `open` rather than at the top
|
|
59
|
+
level.
|
|
60
|
+
|
|
61
|
+
### Corrected before merge, by the reader
|
|
62
|
+
|
|
63
|
+
- **`npx playwright-cli --help` — this file's own re-derivation command — did not run.**
|
|
64
|
+
Outside a project that has already installed it, npm resolves the bare `playwright-cli`
|
|
65
|
+
to **somebody else's package**: Microsoft's, deprecated in favour of this one, latest
|
|
66
|
+
`0.262.0` against `@playwright/cli`'s `0.1.18`. The line sat inside the sentence that is
|
|
67
|
+
the whole file's evidentiary warrant. It now says `npx @playwright/cli@latest --help`
|
|
68
|
+
and explains the trap.
|
|
69
|
+
- **`state-save .auth/state.json` fails on a directory that does not exist** — real exit 1,
|
|
70
|
+
`ENOENT`. The recipe gained the `mkdir -p` it always needed.
|
|
71
|
+
- **The prescribed verdict quoted a filtered number as the page's request count.**
|
|
72
|
+
`requests` hides successful static resources by default and says so in its own footer.
|
|
73
|
+
Failures are listed either way, so *no status ≥ 400* survives and *"14 requests"* is
|
|
74
|
+
gone.
|
|
75
|
+
|
|
76
|
+
### Guards
|
|
77
|
+
|
|
78
|
+
Guards: 318 → **322**. Property checks: 9 → 9. Two checks: a stage that asks for a browser
|
|
79
|
+
channel must **link** the mechanism, and the mechanism must keep the whole look in one
|
|
80
|
+
runnable fence inside the section the stages point at.
|
|
81
|
+
|
|
82
|
+
**Both shipped weaker first, and the independent reader `R-005` requires broke both.**
|
|
83
|
+
The pointer check tested the substring `browser.md`, so `<!-- browser.md -->` — invisible
|
|
84
|
+
once rendered — satisfied it while the stage named no reachable mechanism. The recipe
|
|
85
|
+
check searched the whole file, so the four commands could be parked in a fence captioned
|
|
86
|
+
*"the ones this file tells you never to run"*, every needle intact and the recipe deleted;
|
|
87
|
+
it also accepted `open` off an incidental mention in the session table. An earlier draft
|
|
88
|
+
had already been caught by a `\b` that let `console-messages` satisfy `console`, and
|
|
89
|
+
`tdd.md` could drop both its pointers because only `stages.md` was read.
|
|
90
|
+
|
|
91
|
+
**The scope is now written down rather than implied.** An anti-recipe *inside* the right
|
|
92
|
+
section still passes: no text check separates *run these four* from *never run these four*,
|
|
93
|
+
because the difference is the prose. Three drafts were spent proving that; the fourth
|
|
94
|
+
stopped and filed `B-073`. `B-074` carries the other hole the reader found — a stage can
|
|
95
|
+
demand the look while naming no channel, and nothing looks at it.
|
|
96
|
+
|
|
97
|
+
## v1.55.0 — the browser step gets a second channel, and the table that names it stops truncating itself
|
|
98
|
+
|
|
99
|
+
The bundle has told every web project to check the rendered surface since v1.36.0, and
|
|
100
|
+
it named exactly one way to do it: the `chrome-devtools` MCP, behind a plugin install.
|
|
101
|
+
One channel is a single point of failure for a step the pipeline asks for at three
|
|
102
|
+
stages, and the operator's report was the ordinary one — it lags.
|
|
103
|
+
|
|
104
|
+
Playwright now sits beside it, and **neither is ranked**. They do the same look; the
|
|
105
|
+
difference is stated as capability rather than quality, so a run picks by need instead of
|
|
106
|
+
by taste. `playwright` costs the least per look — its own upstream sells the CLI on not
|
|
107
|
+
loading large tool schemas and verbose accessibility trees into the model context, and
|
|
108
|
+
both of its channels snapshot the accessibility tree rather than pixels.
|
|
109
|
+
`chrome-devtools` is the one that reaches past the page: `lighthouse_audit`, performance
|
|
110
|
+
traces and heap snapshots have no Playwright equivalent, and `seo-aeo-audit` builds on
|
|
111
|
+
the first of them.
|
|
112
|
+
|
|
113
|
+
### Added
|
|
114
|
+
|
|
115
|
+
- **`playwright` as a companion**, with two install paths that need no plugin:
|
|
116
|
+
`npm install -D @playwright/cli@latest` (then `npx playwright-cli`) and
|
|
117
|
+
`claude mcp add playwright npx @playwright/mcp@latest`. Verified against the registry
|
|
118
|
+
at release time: `@playwright/cli` 0.1.18, `@playwright/mcp` 0.0.79.
|
|
119
|
+
- **One detection rule for both channels instead of two that drift**, with the
|
|
120
|
+
tie-breaker written down: `playwright` where the project already runs it or context
|
|
121
|
+
budget is tight, `chrome-devtools` where the question is Lighthouse, a trace or a
|
|
122
|
+
heap snapshot. A run that ranks them has invented a fact the matrix does not carry.
|
|
123
|
+
- **Stop at the first channel that answers.** Both open the page and read the console
|
|
124
|
+
and the network log; running the look twice is a cost with no second fact.
|
|
125
|
+
- **A browser test suite is the other half of the gate, never a substitute for the
|
|
126
|
+
look** (stages 6, `tdd.md`, `SKILL.md`). `playwright test` in CI is a suite whose
|
|
127
|
+
runner happens to be a browser: it proves what someone thought to assert, and cannot
|
|
128
|
+
report the console error nobody asserted on or the element that moved under a header.
|
|
129
|
+
The suite is counted as coverage; the look is still a page opened and read. This
|
|
130
|
+
closes `OQ-0003` as `DEC-0004`.
|
|
131
|
+
- **What the look finds is fixed in the stage that found it** (stages 5 and 6). A
|
|
132
|
+
browser finding parked for later is the diff-review verdict wearing a screenshot.
|
|
133
|
+
|
|
134
|
+
### Fixed
|
|
135
|
+
|
|
136
|
+
- **Three claims this release shipped as facts, corrected against the tool's own
|
|
137
|
+
`--help`.** The independent reader measured them. *"Costs the least per look"* was
|
|
138
|
+
upstream's CLI-against-MCP comparison restated as this repo's CLI-against-`chrome-devtools`
|
|
139
|
+
fact — now attributed and scoped. *"Both channels snapshot the accessibility tree rather
|
|
140
|
+
than pixels"* was true of the default and denied a `screenshot` both channels ship —
|
|
141
|
+
now says which is the default and what the other costs. *"`chrome-devtools` alone
|
|
142
|
+
reaches performance traces"* was simply false: `playwright-cli tracing-start` records
|
|
143
|
+
one. Only the Lighthouse and heap-snapshot legs are exclusive, and the honest
|
|
144
|
+
difference on traces is that one channel **analyses** what the other only records.
|
|
145
|
+
- **The look was called a half of the gate in the same file that calls it never a gate.**
|
|
146
|
+
Stage 6's new paragraph made the browser look sound like gate membership while the
|
|
147
|
+
GATE bullet above it, both matrix rows and `SKILL.md` all keep it recommended and
|
|
148
|
+
degradable. Stage 5 had the mirror defect: *fixed in this task, not filed* against a
|
|
149
|
+
GATE bullet that explicitly permits parking with a ruling. Both now say the thing the
|
|
150
|
+
gate actually enforces.
|
|
151
|
+
|
|
152
|
+
- **A pipe inside a matrix cell silently disabled the guard that reads it.** Both
|
|
153
|
+
readers of `companion-skills.md`'s table split cells on `|` and do not decode `\|`,
|
|
154
|
+
so an escaped pipe ends its cell early and hands the next check a different column.
|
|
155
|
+
The `graphify` row had carried `graphify query\|affected\|god-nodes` since it was
|
|
156
|
+
added: the matrix→stages check has been reading that row's second cell as `affected`,
|
|
157
|
+
parsing no stage numbers out of it, and passing **without comparing anything** — a
|
|
158
|
+
guard quiet because its input was truncated, which reads exactly like a guard that
|
|
159
|
+
looked and agreed. Found while planting a defect into the new `playwright` row and
|
|
160
|
+
watching the check stay silent. There is now a guard for the class, probed both ways,
|
|
161
|
+
and the `graphify` row is comma-separated. The umbrella hit the same class from the
|
|
162
|
+
other side in `B-40` (an *un*escaped pipe adding a column), which is the second
|
|
163
|
+
sighting that makes it a check rather than a third ledger row.
|
|
164
|
+
|
|
165
|
+
### Guards
|
|
166
|
+
|
|
167
|
+
Guards: 315 → **318**. Property checks: 9 → 9. Two new checks over the companion matrix,
|
|
168
|
+
each watched failing against a plant: the row's cell count against the header (which
|
|
169
|
+
catches a bare pipe and an escaped one alike), and a row that derives no stage at all.
|
|
170
|
+
The first draft of the first check tested `\|` only, and the independent reader `R-005`
|
|
171
|
+
requires broke it with a bare pipe in one move — with a control proving the hole masked
|
|
172
|
+
real matrix→stages drift. The second check exists because the same reader measured every
|
|
173
|
+
row and found `agent-sync` deriving nothing from `stage-10`, one row below the `graphify`
|
|
174
|
+
row this release set out to fix.
|
|
175
|
+
|
|
3
176
|
## v1.54.0 — a run cannot reach acceptance with a stage it never stamped
|
|
4
177
|
|
|
5
178
|
The 2026-08-13 artifact-root run closed at stage 10 with `0,1,2,5,6,7,8,9,10` recorded
|
package/CONTRIBUTING.md
CHANGED
|
@@ -464,6 +464,47 @@ VISUAL — each with its owning skill, because the first reads matrix **row name
|
|
|
464
464
|
the copy half lives inside super-ux's own cell, exactly where it was invisible.
|
|
465
465
|
*(guard: `has not heard of it` and `names no owner`)*
|
|
466
466
|
|
|
467
|
+
**54. The companion matrix's own cells must be readable, and every row must derive a
|
|
468
|
+
stage.** Every check that reads that table splits a cell on `|`, and none of them decodes
|
|
469
|
+
the escaped form. So one extra pipe anywhere in a row — `\|` or bare — ends its cell early
|
|
470
|
+
and hands the next check a different column, which is how the `graphify` row spent every
|
|
471
|
+
release since it was added with its stage pointers **never compared**: the check derived
|
|
472
|
+
an empty set and reported agreement. The cell count is now compared against the header,
|
|
473
|
+
because that is blind to how the pipe was written, and the first draft of this guard was
|
|
474
|
+
not — it tested `\|` only and an independent reader broke it with a bare one in a single
|
|
475
|
+
move. Separately, the outcome is asserted directly: a row whose *"needed for"* cell
|
|
476
|
+
derives **no** stage fails, because a pipe is only one road to an empty set and
|
|
477
|
+
`agent-sync` took another, writing `stage-10` where the stage pattern wanted `stage 10`.
|
|
478
|
+
The two checks share one compiled pattern for that reason — two copies would drift, and
|
|
479
|
+
the drift is silent in precisely the direction that hurts.
|
|
480
|
+
*(guard: `pipes where the header has` and `names no stage its second cell`)*
|
|
481
|
+
|
|
482
|
+
**55. A stage that demands a look at the rendered surface LINKS the mechanism, and the
|
|
483
|
+
mechanism keeps the whole look in one runnable block.** From v1.36.0 to v1.55.0 stages 5,
|
|
484
|
+
6 and 8 required the browser and pointed only at which companion to install, so the
|
|
485
|
+
requirement had no *how* anywhere in the bundle — the shape that lets a run report
|
|
486
|
+
*checked in a browser* while meaning *ran the unit tests*. Every stage naming a browser
|
|
487
|
+
channel, and `tdd.md` too, must **link** `references/browser.md`, and that file must keep
|
|
488
|
+
one fenced block showing `open`, `snapshot`, `console` and `requests` together.
|
|
489
|
+
|
|
490
|
+
Both halves are stated that precisely because the first draft of each was weaker and an
|
|
491
|
+
independent reader broke both. The stage check tested the substring `browser.md`, and
|
|
492
|
+
`<!-- browser.md -->` — invisible once rendered — satisfied it. The mechanism check
|
|
493
|
+
searched the whole file, so the four commands could be parked in a fence captioned *"the
|
|
494
|
+
ones this file tells you never to run"* with every needle intact and the recipe deleted;
|
|
495
|
+
it also accepted `open` off an incidental mention in the session table. Requiring *one
|
|
496
|
+
fence with all four* was the second draft and fell to the same reader: a fence captioned
|
|
497
|
+
*"never run these"* holds all four. No text check separates a recipe from an anti-recipe,
|
|
498
|
+
so the check is **scoped to the section** — the recipe must live under *The look, as
|
|
499
|
+
commands you can run*, and renaming that heading fails the build, which is correct: the
|
|
500
|
+
section is the contract. **What it does not claim:** an anti-recipe written inside that
|
|
501
|
+
same section still passes. Three drafts were spent trying to close that with a pattern;
|
|
502
|
+
the fourth wrote the limit down instead (`B-073`), because the difference between *run
|
|
503
|
+
these* and *never run these* is prose, and prose is R-005's job. The move needle allows the `--json`, `--raw` and `-s=` prefixes,
|
|
504
|
+
because this same file recommends them and a check that fails its own advice gets edited
|
|
505
|
+
out rather than satisfied.
|
|
506
|
+
*(guard: `does not LINK references/browser.md` and `has no single fenced block showing the whole`)*
|
|
507
|
+
|
|
467
508
|
**53. Publishing a retro insight is opt-in, enumerated, and its own example obeys its
|
|
468
509
|
own rules.** `retro.publish` is off when absent — opening an issue in another repository
|
|
469
510
|
is an outward act, and a generic flag is not a specific authorization. The redaction
|
package/README.md
CHANGED
|
@@ -131,6 +131,7 @@ until it is installed.
|
|
|
131
131
|
| 4 Plan | [`planning.md`](plugins/task-pipeline/skills/task-pipeline/references/planning.md) — zero-context tasks, parallel groups, no placeholders |
|
|
132
132
|
| 5 Build | [`build.md`](plugins/task-pipeline/skills/task-pipeline/references/build.md) + [`review.md`](plugins/task-pipeline/skills/task-pipeline/references/review.md) — isolation, ledger, subagent loop, review rubric, fix loop |
|
|
133
133
|
| 5–6 TDD | [`tdd.md`](plugins/task-pipeline/skills/task-pipeline/references/tdd.md) — the iron law, red/green/refactor, the suite gate |
|
|
134
|
+
| 5, 6, 8 The browser | [`browser.md`](plugins/task-pipeline/skills/task-pipeline/references/browser.md) — the ref model both channels share, the four commands the look is made of, sessions, and the three different things *"tested in a browser"* means |
|
|
134
135
|
| 10 Acceptance | [`acceptance.md`](plugins/task-pipeline/skills/task-pipeline/references/acceptance.md) — REQ coverage table, evidence rules, the closing question |
|
|
135
136
|
| 10 + any audit | [`audit.md`](plugins/task-pipeline/skills/task-pipeline/references/audit.md) — the L0→L7 ladder and its seams, axis rotation, ratchets, proven checks |
|
|
136
137
|
| any loop | [`loop-guard.md`](plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md) — churn detection, caps, the break protocol |
|
|
@@ -210,14 +211,24 @@ run proved stale is already in the ledger with what's wrong, so "docs updated" m
|
|
|
210
211
|
the sources the next run will trust — not just the files this change happened to
|
|
211
212
|
touch.
|
|
212
213
|
|
|
213
|
-
**A web front end gets a browser, not a diff.** Where
|
|
214
|
+
**A web front end gets a browser, not a diff.** Where a browser channel is connected,
|
|
214
215
|
stages 5–6 load the surface and read the console and the network log before calling it
|
|
215
216
|
green, and stage 8 opens the deployed page instead of trusting a `200`. A green suite
|
|
216
217
|
cannot see a component that renders correctly and lands under a fixed header, a request
|
|
217
|
-
that 404s while every unit test mocks it, or an error that costs nothing at test time
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
that 404s while every unit test mocks it, or an error that costs nothing at test time —
|
|
219
|
+
and neither can a **browser test suite**, which asserts what someone wrote down and is
|
|
220
|
+
counted as coverage rather than as the look. Absent, the run says *"verified by reading
|
|
221
|
+
the diff"* — a weaker claim, recorded as one.
|
|
222
|
+
|
|
223
|
+
There are **two channels and either is enough**, ranked by nothing: `playwright`
|
|
224
|
+
(`npm install -D @playwright/cli@latest`, or
|
|
225
|
+
`claude mcp add playwright npx @playwright/mcp@latest`) needs no plugin and is already
|
|
226
|
+
there on a project that runs Playwright, and its CLI half puts no tool schema in the
|
|
227
|
+
context window; `chrome-devtools`
|
|
228
|
+
(`/plugin install chrome-devtools-mcp@claude-plugins-official`) is the one that reaches
|
|
229
|
+
past the page to Lighthouse and heap snapshots, and analyses a performance trace rather
|
|
230
|
+
than only recording one. Neither is a gate,
|
|
231
|
+
and a CLI, a library or a backend service is never offered either.
|
|
221
232
|
|
|
222
233
|
**The wiki is [obsidian-wiki](https://github.com/ar9av/obsidian-wiki)** (Karpathy's
|
|
223
234
|
LLM-wiki pattern), and it's the one source that carries *why* across projects and
|
package/SKILL-CARD.md
CHANGED
|
@@ -12,9 +12,9 @@ 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.56.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
|
-
| **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
|
|
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` |
|
|
19
19
|
|
|
20
20
|
## Risk-tier disclosure
|
|
@@ -25,7 +25,7 @@ apply.
|
|
|
25
25
|
| Indicator | Applies? | What exactly |
|
|
26
26
|
|---|---|---|
|
|
27
27
|
| **Code execution** | **Yes — High** | Ships `templates/docgate.sh` (seeded into the host project as its documentation gate), `bin/task-pipeline.js` and `install.sh` (installers), `test/*.py` and `evals/run.py` (repo checks). None run automatically; the gate is seeded and run by the host project |
|
|
28
|
-
| **MCP server references** | **Yes — High** | Instructions name `context7`, `figma`, `graphify`, `wiki-query`, `wiki-update` and
|
|
28
|
+
| **MCP server references** | **Yes — High** | Instructions name `context7`, `figma`, `graphify`, `wiki-query`, `wiki-update` and **two browser channels — `playwright` (CLI `@playwright/cli` or MCP `@playwright/mcp`) and `chrome-devtools`** — the last two **drive a real browser**: they open pages, run scripts in them and read their console and network traffic, which is a wider capability than the others and is recommended only for projects that have a web front end. Either one satisfies the browser step; neither is required. All optional; absence degrades a stage, never blocks one, except super-ux on a UI task |
|
|
29
29
|
| **Tool invocations** | **Yes — Medium** | Instructs bash (git, test runners, the host's lint/deploy commands), file reads and writes, and a `PreToolUse` hook example that runs the docs gate before a commit |
|
|
30
30
|
| **Filesystem access scope** | **Yes — Medium** | Reads and writes inside the host project: `docs/`, `scripts/check-docs.sh`, `.task-pipeline/` scratch, `CONTEXT.md`. Stage 5 creates and removes git worktrees. Writing to **another repository** is treated as outward and requires an explicit go |
|
|
31
31
|
| **Instruction manipulation** | No | Nothing instructs Claude to bypass safety rules, hide actions, or behave conditionally on hidden inputs. Outward and irreversible actions (deploy, publish, PR, editing a shared design file) explicitly require operator authorization |
|
|
@@ -253,12 +253,19 @@ not authorize an outward, irreversible action — stage 7 stops and asks.
|
|
|
253
253
|
behavior, never mock behavior. **Web front end? Check the surface in a browser,
|
|
254
254
|
not in the diff.** A green suite cannot see a component that renders correctly and
|
|
255
255
|
lands under a fixed header, a request that 404s while every unit test mocks it, or
|
|
256
|
-
a console error that costs nothing at test time
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
256
|
+
a console error that costs nothing at test time — and neither can a browser test
|
|
257
|
+
suite, which asserts what someone wrote down and counts as coverage, not as the
|
|
258
|
+
look. With a browser channel connected: load the surface, snapshot it, read the
|
|
259
|
+
console and the network log, and quote what you read. Fix what the look finds
|
|
260
|
+
before calling the stage green. Without one, say "verified by reading the diff" and
|
|
261
|
+
treat that as the weaker claim it is. Two channels, either is enough, ranked by
|
|
262
|
+
nothing: `npm install -D @playwright/cli@latest` (or
|
|
263
|
+
`claude mcp add playwright npx @playwright/mcp@latest`) needs no plugin, and its CLI
|
|
264
|
+
half puts no tool schema in the context window;
|
|
265
|
+
`/plugin install chrome-devtools-mcp@claude-plugins-official` is the one that
|
|
266
|
+
reaches Lighthouse and heap snapshots, and analyses a trace rather than only
|
|
267
|
+
recording one. Never a gate. A CLI, a
|
|
268
|
+
library or a backend service is never offered either.
|
|
262
269
|
7. **Lint + deploy** (manual) — lint clean AND suite green before deploy; deploy is
|
|
263
270
|
outward → explicit user go, or the specific standing authorization recorded in
|
|
264
271
|
the stage-0 brief.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.56.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.56.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -60,6 +60,7 @@ gate stops until it is installed.
|
|
|
60
60
|
| 4 Plan | `references/planning.md` |
|
|
61
61
|
| 5 Build (worktree, subagents, fix loop) | `references/build.md` + `references/review.md` |
|
|
62
62
|
| 5–6 TDD + suite gate | `references/tdd.md` |
|
|
63
|
+
| 5, 6, 8 The browser — the look, the spec suite, and the difference | `references/browser.md` |
|
|
63
64
|
| 10 Acceptance (REQ close-out) | `references/acceptance.md` |
|
|
64
65
|
| 10 Retrospective (the run's last act) | `references/retrospective.md` |
|
|
65
66
|
| 10 + any audit (what's *missing*) | `references/audit.md` |
|
|
@@ -253,9 +254,9 @@ capable available — see `references/model-tiering.md`).
|
|
|
253
254
|
| 3 | Spec | committed + reviewed; UI: chain validated, linter green, scenarios/`SCR-` traced | manual |
|
|
254
255
|
| 4 | Plan | parallel-ready, DoD per task | auto |
|
|
255
256
|
| 5 | Dev | tasks DONE, TDD green per task, branch integrated per the brief; **anything generated passes its own checks, and local infrastructure does not publish the host's default ports** ([`references/learned.md`](references/learned.md)) | auto |
|
|
256
|
-
| 6 | Tests | full suite green; new/changed code covered; **every new check probed both ways and asserted on its exit code**, and the suite run once against a cold environment ; **on a web front end the surface is checked in a browser, not in the diff** — a green suite cannot see a component that renders under a fixed header, a request that 404s past its mock, or a console error (`chrome-devtools`, [`references/companion-skills.md`](references/companion-skills.md); absent → say *verified by reading the diff* and record it as the weaker claim it is) | auto |
|
|
257
|
+
| 6 | Tests | full suite green; new/changed code covered; **every new check probed both ways and asserted on its exit code**, and the suite run once against a cold environment ; **on a web front end the surface is checked in a browser, not in the diff** — a green suite cannot see a component that renders under a fixed header, a request that 404s past its mock, or a console error — and a browser **test suite** is the other half of the pair, never a substitute for the look (`playwright` or `chrome-devtools`, either one — **how**: [`references/browser.md`](references/browser.md), which channel: [`references/companion-skills.md`](references/companion-skills.md); absent → say *verified by reading the diff* and record it as the weaker claim it is) | auto |
|
|
257
258
|
| 7 | Lint + deploy | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
|
|
258
|
-
| 8 | Post-deploy | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and says nothing about a 404'd bundle or a console full of errors on load (`chrome-devtools
|
|
259
|
+
| 8 | Post-deploy | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and says nothing about a 404'd bundle or a console full of errors on load (`playwright` or `chrome-devtools`, either one, [`references/browser.md`](references/browser.md); absent → call it an HTTP response, which is its honest name) | auto |
|
|
259
260
|
| 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 ledger names what you read, the matrix names what you owe — every settled thing recorded with an id, every answered question resolved, and **the documentation gate green with its ratchet counts printed**; docs synced; wiki synced; **the code graph refreshed where one exists** and checked against the docs (a hub no doc names, a doc naming a node the graph lost); **every number computed rather than restated, every named command or file resolvable** ([`references/learned.md`](references/learned.md)); the carry-over count printed beside the verdict | auto |
|
|
260
261
|
| 10 | **Acceptance** | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); **the hand-back is written** — the request quoted as given, progress against it, what was solved, what surfaced unasked, waiting decisions asked here, and the ambiguity count computed ([`references/progress.md`](references/progress.md)); **the environment is given back** — all eight classes enumerated, what this run started ended and verified by re-enumerating rather than by the teardown's reply, an earlier run of this project ended only when **provably spent**, anything this project does not own reported rather than ended, written as a `holds:` line (`references/residue.md`); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **every disclosure printed beside the verdict** — `abstained` (what the run declined to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither with a floor, neither ever a target ([`references/gates.md`](references/gates.md) → *Disclosures*) | manual |
|
|
261
262
|
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# The browser — how the look is actually taken, and how a suite is run beside it
|
|
2
|
+
|
|
3
|
+
[`companion-skills.md`](companion-skills.md) decides **which** channel a project has
|
|
4
|
+
and how to install it. This file is **how to use one**: the model both channels share,
|
|
5
|
+
the commands the look is made of, and the three different things people mean when they
|
|
6
|
+
say *"tested in a browser"*.
|
|
7
|
+
|
|
8
|
+
Stages 5, 6 and 8 ([`stages.md`](stages.md)) and [`tdd.md`](tdd.md) demand a look at the
|
|
9
|
+
rendered surface. Until this file existed, they demanded it and named no mechanism —
|
|
10
|
+
which is how a run says *I checked the browser* and means *I ran the unit tests*.
|
|
11
|
+
|
|
12
|
+
> **Every command and flag below was read from the tool's own `--help`**, not from a
|
|
13
|
+
> vendor page. Where the two disagreed, `--help` won and the page was wrong — see
|
|
14
|
+
> *Rationalizations*. Re-derive before quoting:
|
|
15
|
+
> `npx @playwright/cli@latest --help` and `npx @playwright/mcp@latest --help`.
|
|
16
|
+
>
|
|
17
|
+
> **Use the scoped name with `npx`.** `npx playwright-cli --help` fails outside a project
|
|
18
|
+
> that has already installed it (`could not determine executable to run`), and the bare
|
|
19
|
+
> `playwright-cli` on npm is **somebody else's package** — Microsoft's, deprecated in
|
|
20
|
+
> favour of this one. The binary is called `playwright-cli`; the package is
|
|
21
|
+
> `@playwright/cli`. Every `playwright-cli …` line below assumes it is installed and on
|
|
22
|
+
> PATH, which is what the matrix's install line does.
|
|
23
|
+
|
|
24
|
+
## Contents
|
|
25
|
+
|
|
26
|
+
- The one model: a tree, and a ref
|
|
27
|
+
- The look, as commands you can run
|
|
28
|
+
- Sessions, and why an agent needs them
|
|
29
|
+
- Reading a look vs gating on one
|
|
30
|
+
- "Tested in a browser" is three different claims
|
|
31
|
+
- Getting past a login, and past a backend
|
|
32
|
+
- When the look finds something: debugging the spec that missed it
|
|
33
|
+
- Evidence a reader can open
|
|
34
|
+
- What the channel can reach — the part a recommendation owes you
|
|
35
|
+
- Rationalizations
|
|
36
|
+
|
|
37
|
+
## The one model: a tree, and a ref
|
|
38
|
+
|
|
39
|
+
**Both channels drive the page through its accessibility tree, not its pixels.** You ask
|
|
40
|
+
for a snapshot, you get structured text — roles, names, and a **ref** per interactive
|
|
41
|
+
element (`e5`, `e12`) — and you act on the ref.
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
snapshot -> button "Checkout" [ref=e12] -> click e12
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Three consequences the doctrine rests on:
|
|
48
|
+
|
|
49
|
+
- **A look costs a page of text and no vision model.** This is why the pipeline can ask
|
|
50
|
+
for one at three stages without the cost being an argument. A `screenshot` exists in
|
|
51
|
+
both channels and *is* pixels — take one for a human to look at, not for you to read.
|
|
52
|
+
- **The ref is a fact about the page as rendered**, so `click e12` after a snapshot is
|
|
53
|
+
deterministic in a way a coordinate never is.
|
|
54
|
+
- **A ref that no longer resolves is a finding, not an error to retry past.** The element
|
|
55
|
+
moved, or never rendered. That is exactly the class stage 6 says a green suite cannot
|
|
56
|
+
see. Re-snapshot, read what changed, and report it — do not hunt for a selector that
|
|
57
|
+
makes the command succeed.
|
|
58
|
+
|
|
59
|
+
Refs come from the **latest** snapshot. Act, then snapshot again before using a ref from
|
|
60
|
+
before the act.
|
|
61
|
+
|
|
62
|
+
## The look, as commands you can run
|
|
63
|
+
|
|
64
|
+
The pipeline asks for the same four things every time: **open it, snapshot it, read the
|
|
65
|
+
console, read the network.** In the CLI that is literally four commands:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
playwright-cli open http://localhost:3000/checkout
|
|
69
|
+
playwright-cli snapshot
|
|
70
|
+
playwright-cli console warning # min-level: only warnings and errors
|
|
71
|
+
playwright-cli requests # then: request <n> for headers, body, response
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The MCP is the same four moves under different names: `browser_navigate`,
|
|
75
|
+
`browser_snapshot`, `browser_console_messages`, `browser_network_requests`.
|
|
76
|
+
|
|
77
|
+
**Quote what you read, not that you looked.** *"Console clean, all requests fine"* is a
|
|
78
|
+
claim. *"`console warning` → empty; `requests` → no status ≥ 400"* is the same claim with
|
|
79
|
+
its command attached, and it is the one that belongs in a gate verdict.
|
|
80
|
+
|
|
81
|
+
**Do not quote the request count as the page's count.** `requests` hides successful static
|
|
82
|
+
resources by default and says so in its own footer (*"N static request(s) not shown"*);
|
|
83
|
+
`requests --static` includes them. Failures are listed either way — a 404'd stylesheet
|
|
84
|
+
appears without the flag — so *no status ≥ 400* is a safe claim and *14 requests* is not.
|
|
85
|
+
|
|
86
|
+
`chrome-devtools` takes the identical four moves — `navigate_page`, `take_snapshot`,
|
|
87
|
+
`list_console_messages`, `list_network_requests` — which is why the matrix ranks neither:
|
|
88
|
+
the look is the same look.
|
|
89
|
+
|
|
90
|
+
## Sessions, and why an agent needs them
|
|
91
|
+
|
|
92
|
+
**The CLI keeps a browser alive between commands.** That is the whole reason the four
|
|
93
|
+
commands above compose: `snapshot` sees the page `open` navigated to, and `click e12`
|
|
94
|
+
acts on the element that snapshot named. A tool that launched a browser per invocation
|
|
95
|
+
would lose the page, and every ref with it.
|
|
96
|
+
|
|
97
|
+
| Need | Command |
|
|
98
|
+
|---|---|
|
|
99
|
+
| Two surfaces at once without shared cookies | `playwright-cli -s=checkout open …` and `-s=admin open …` |
|
|
100
|
+
| See what is still running | `playwright-cli list` |
|
|
101
|
+
| Tidy up at the end of a stage | `playwright-cli close-all` |
|
|
102
|
+
| A stale or zombie process after a crash | `playwright-cli kill-all` |
|
|
103
|
+
|
|
104
|
+
**A run that opened a browser closes it**, the same rule the pipeline applies to every
|
|
105
|
+
other resource it starts ([`residue.md`](residue.md)). `list` before you claim the
|
|
106
|
+
environment is clean — the reply is the evidence, not the `close-all` you typed.
|
|
107
|
+
|
|
108
|
+
## Reading a look vs gating on one
|
|
109
|
+
|
|
110
|
+
Two global flags change what the output is for:
|
|
111
|
+
|
|
112
|
+
- **`--json`** — the full response as JSON. This is what a script parses, and therefore
|
|
113
|
+
what a *check* can be built on.
|
|
114
|
+
- **`--raw`** — the result value alone, no status wrapper. For one value in a shell
|
|
115
|
+
variable.
|
|
116
|
+
|
|
117
|
+
Default output is for a reader. If you find yourself regexing the default output in a
|
|
118
|
+
gate, you wanted `--json`; a check that parses prose breaks on the release that reworded
|
|
119
|
+
it ([`gates.md`](gates.md)).
|
|
120
|
+
|
|
121
|
+
## "Tested in a browser" is three different claims
|
|
122
|
+
|
|
123
|
+
Keeping these apart is the entire point of the stage-6 pair, and conflating them is the
|
|
124
|
+
commonest way a run reports a green it does not have.
|
|
125
|
+
|
|
126
|
+
| | What it is | What it proves | Where it counts |
|
|
127
|
+
|---|---|---|---|
|
|
128
|
+
| **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 **look**, stage 6 — recommended, never a gate |
|
|
129
|
+
| **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 |
|
|
130
|
+
| **The library** | `require('playwright')` — `chromium`/`firefox`/`webkit`, `devices`, `request`, `selectors` | whatever your own script asserts; it is an automation API, not a test framework | wherever the project already runs it |
|
|
131
|
+
|
|
132
|
+
The library and the runner are **separate APIs** — a script built on `chromium.launch()`
|
|
133
|
+
has no `expect`, no fixtures, no reporter, and no retry. Choosing the library where a
|
|
134
|
+
runner was wanted is how a project ends up with a bespoke half-runner nobody trusts.
|
|
135
|
+
|
|
136
|
+
The minimal library shape, for reading a script that already exists:
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
const { chromium } = require('playwright');
|
|
140
|
+
const browser = await chromium.launch();
|
|
141
|
+
const page = await browser.newPage();
|
|
142
|
+
await page.goto('http://example.com');
|
|
143
|
+
await browser.close();
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**A green spec suite never discharges the look.** It asserts what was written down; the
|
|
147
|
+
console error nobody asserted on is precisely what the look is for. This is `DEC-0004`
|
|
148
|
+
and it is the reason both halves exist.
|
|
149
|
+
|
|
150
|
+
## Getting past a login, and past a backend
|
|
151
|
+
|
|
152
|
+
A surface behind auth is the usual reason a run skips the look. Both channels solve it,
|
|
153
|
+
and neither needs a password in a transcript.
|
|
154
|
+
|
|
155
|
+
**Storage state — log in once, replay it.**
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
mkdir -p .auth # state-save does not create it
|
|
159
|
+
playwright-cli open https://app.example.com/login
|
|
160
|
+
# … sign in by hand, or drive the form …
|
|
161
|
+
playwright-cli state-save .auth/state.json # cookies + localStorage
|
|
162
|
+
playwright-cli state-load .auth/state.json # every later look starts signed in
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The MCP takes the same file at startup: `--storage-state <path>`. Point the spec suite
|
|
166
|
+
at it too and the suite and the look agree about who is signed in.
|
|
167
|
+
**The state file is a credential.** It goes where credentials go, never into the
|
|
168
|
+
repository.
|
|
169
|
+
|
|
170
|
+
**Routes — make the backend say what you need it to.**
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
playwright-cli route '**/api/quote' --status 500 # then look at the error state
|
|
174
|
+
playwright-cli route-list
|
|
175
|
+
playwright-cli unroute '**/api/quote'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This is how a failure path gets a look at all. `route` is also the honest way to check
|
|
179
|
+
that a 404'd bundle or a 500'd call *renders* as something a user can act on — which no
|
|
180
|
+
unit test with a mocked fetch will ever tell you.
|
|
181
|
+
|
|
182
|
+
Storage families exist per layer when you need to reach past the whole state file:
|
|
183
|
+
`cookie-list|get|set|delete|clear`, and the same verbs for `localstorage-` and
|
|
184
|
+
`sessionstorage-`.
|
|
185
|
+
|
|
186
|
+
## When the look finds something: debugging the spec that missed it
|
|
187
|
+
|
|
188
|
+
The look found a defect the suite did not. Stage 6 says fix it here — and the fix has two
|
|
189
|
+
halves: the code, and the assertion that should have caught it.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
playwright-cli generate-locator e12 # a locator for the element the look found
|
|
193
|
+
playwright-cli highlight e12 # show it on the page (--hide to clear)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Drop that locator into a new spec, then drive the spec itself:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
playwright-cli pause-at src/checkout.spec.ts:42 # run up to this line and stop
|
|
200
|
+
playwright-cli snapshot # the page as the test sees it there
|
|
201
|
+
playwright-cli step-over
|
|
202
|
+
playwright-cli resume
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
That loop is what turns *"the look caught it"* into *"the suite catches it next time"* —
|
|
206
|
+
which is the only reason the look's finding stops recurring. `run-code` and `eval` are
|
|
207
|
+
there for the case a question is faster answered in the page than through a command.
|
|
208
|
+
|
|
209
|
+
## Evidence a reader can open
|
|
210
|
+
|
|
211
|
+
A verdict that says *the surface renders* is worth what its attachment is worth.
|
|
212
|
+
|
|
213
|
+
| Artefact | Command | Use it for |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| Screenshot | `screenshot [ref]` | one state, for a human |
|
|
216
|
+
| Trace | `tracing-start` … `tracing-stop` | a failure someone else has to reproduce |
|
|
217
|
+
| Video | `video-start [file]`, `video-chapter <title>`, `video-stop` | a flow, or a regression that only appears in motion |
|
|
218
|
+
| PDF | `pdf` | a printable surface that is itself the deliverable |
|
|
219
|
+
|
|
220
|
+
`video-show-actions` annotates each action on the page with a callout naming it, which is
|
|
221
|
+
what makes a recording readable by someone who did not run it.
|
|
222
|
+
|
|
223
|
+
The MCP's equivalents are `browser_take_screenshot`, `browser_start_tracing` /
|
|
224
|
+
`browser_stop_tracing`, `browser_start_video` / `browser_stop_video`, `browser_pdf_save`,
|
|
225
|
+
written under `--output-dir` — **and all but the screenshot are behind `--caps`.** See
|
|
226
|
+
below: the tool list you read about is not the tool list you get.
|
|
227
|
+
|
|
228
|
+
**Attach the artefact or drop the claim.** A trace nobody can open is prose.
|
|
229
|
+
|
|
230
|
+
## What the channel can reach — the part a recommendation owes you
|
|
231
|
+
|
|
232
|
+
This bundle recommends handing an agent a real browser. That is a wider capability than
|
|
233
|
+
anything else in the matrix, and the boundary is worth stating rather than discovering.
|
|
234
|
+
|
|
235
|
+
- **The MCP restricts file access to the workspace roots** (cwd when no roots are
|
|
236
|
+
configured) and blocks navigation to `file://` by default. `--allow-unrestricted-file-access`
|
|
237
|
+
removes both. Read that flag as what it says.
|
|
238
|
+
- **`--allowed-origins` / `--blocked-origins` are not a security boundary**, and upstream
|
|
239
|
+
says so in its own help: they do not survive redirects. Do not use them as one.
|
|
240
|
+
- **`--isolated` keeps the profile in memory**, so nothing persists past the session —
|
|
241
|
+
the right default for a look at someone else's site. The opposite is deliberate and
|
|
242
|
+
spelled differently per channel: `--user-data-dir <path>` on the MCP,
|
|
243
|
+
`open --persistent` (or `open --profile <path>`) on the CLI.
|
|
244
|
+
- **`--secrets <path>`** exists so a credential reaches the browser without reaching the
|
|
245
|
+
transcript. Use it rather than typing the password into a `fill`.
|
|
246
|
+
- **`--extension` / `attach`** connect to a browser **you are already using**, with your
|
|
247
|
+
sessions in it. That is occasionally exactly what you want and is never the default
|
|
248
|
+
for an unattended run.
|
|
249
|
+
|
|
250
|
+
**The MCP's tool list is capability-gated, and the default is the small one.** Asking
|
|
251
|
+
the running server rather than a page: **24 tools by default, 42 with
|
|
252
|
+
`--caps vision,pdf,devtools`.** Tracing, video and PDF — `browser_start_tracing`,
|
|
253
|
+
`browser_start_video`, `browser_video_chapter`, `browser_pdf_save` — are **not present**
|
|
254
|
+
until `--caps` names them, and neither are the coordinate-mouse tools. A doctrine that
|
|
255
|
+
sends an agent to `browser_start_tracing` on a default server sends it to a tool that is
|
|
256
|
+
not there, and the agent concludes the doctrine is stale rather than the server narrow.
|
|
257
|
+
Re-derive rather than trust this paragraph: start the server and call `tools/list`.
|
|
258
|
+
|
|
259
|
+
Both counts above were measured on `@playwright/mcp` 0.0.79 by listing the server's own
|
|
260
|
+
tools. The vendor page current at the time listed tool groups this version does not ship
|
|
261
|
+
at all — routes, cookies and localStorage among them — which is why the CLI is what this
|
|
262
|
+
file names for state and mocking.
|
|
263
|
+
|
|
264
|
+
The MCP runs **headed** by default; the CLI is headless unless you pass `open --headed`.
|
|
265
|
+
On a CI box, headed is the failure you will spend an hour on.
|
|
266
|
+
|
|
267
|
+
## Rationalizations
|
|
268
|
+
|
|
269
|
+
| The excuse | Why it fails |
|
|
270
|
+
|---|---|
|
|
271
|
+
| *"`playwright test` is green, the surface is checked."* | The suite asserts what someone wrote down. `DEC-0004`: it is the coverage half, never the look. |
|
|
272
|
+
| *"I took a screenshot, so I looked."* | A screenshot is pixels you did not read. The look is `snapshot` + `console` + `requests`, and the verdict quotes them. |
|
|
273
|
+
| *"The click failed, I'll find a better selector."* | A ref that stopped resolving **is the finding**. Re-snapshot and report what moved. |
|
|
274
|
+
| *"The docs say the CLI has no `tracing`."* | A vendor page is a claim; `--help` is the tool. This file was written against `--help` **because** a page-derived claim shipped here and was wrong. |
|
|
275
|
+
| *"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. |
|
|
276
|
+
| *"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. |
|
|
277
|
+
| *"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. |
|
|
278
|
+
| *"I closed the browser."* | `list` is the evidence. The command you typed is not the state you left ([`residue.md`](residue.md)). |
|
|
@@ -48,8 +48,9 @@ better, plus one that is required only for user-facing work.
|
|
|
48
48
|
| **context7** (MCP — call tools fully qualified: `context7:resolve-library-id`, `context7:query-docs`) | stage 1 docs study | Recommended (web-search fallback) | connect the context7 MCP server |
|
|
49
49
|
| **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) |
|
|
50
50
|
| **[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` |
|
|
51
|
-
| **[graphify](https://github.com/Graphify-Labs/graphify)** (`/graphify`, `graphify query
|
|
52
|
-
| **
|
|
51
|
+
| **[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 .` |
|
|
52
|
+
| **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`) | **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). MCP: `claude mcp add playwright npx @playwright/mcp@latest` |
|
|
53
|
+
| **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`) | **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) |
|
|
53
54
|
| **[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` |
|
|
54
55
|
| ~~superpowers~~ | — | **Not a dependency.** Stages 2/4/5/6 run on the built-in doctrine above. See *Optional bridge* | — |
|
|
55
56
|
| ~~grill-me / grilling~~ | — | **Not a dependency.** The stage-0 grill is built in (`references/grill.md`) | — |
|
|
@@ -112,9 +113,20 @@ Pipeline companions (stage doctrine is built in — nothing to install for it):
|
|
|
112
113
|
/graphify . (once, in this project)
|
|
113
114
|
(running without it — no reach queries, no graph↔docs
|
|
114
115
|
divergence check)
|
|
116
|
+
✗ playwright — recommended when this project has a web front end.
|
|
117
|
+
One of TWO channels that do the same look; either is
|
|
118
|
+
enough, and a project that already runs Playwright has
|
|
119
|
+
this one for free:
|
|
120
|
+
npm install -D @playwright/cli@latest (then npx playwright-cli)
|
|
121
|
+
claude mcp add playwright npx @playwright/mcp@latest
|
|
122
|
+
(running without it — see the line below; without BOTH,
|
|
123
|
+
the surface is verified by reading the diff)
|
|
115
124
|
✗ chrome-devtools — recommended when this project has a web front end:
|
|
116
125
|
stages 5-6 check the RENDERED surface instead of the
|
|
117
|
-
diff, stage 8 reads what the browser did after a deploy
|
|
126
|
+
diff, stage 8 reads what the browser did after a deploy.
|
|
127
|
+
The other channel; it alone reaches lighthouse_audit
|
|
128
|
+
and heap snapshots, and analyses a trace rather than
|
|
129
|
+
only recording one:
|
|
118
130
|
/plugin install chrome-devtools-mcp@claude-plugins-official
|
|
119
131
|
(running without it — the surface is verified by reading
|
|
120
132
|
the diff, and the close-out says so in those words)
|
|
@@ -147,13 +159,29 @@ Rules:
|
|
|
147
159
|
`wiki-query`/`wiki-update`. Present → say `✓ ready` and use it in the harvest.
|
|
148
160
|
Absent → print the two install lines **once** and continue; never ask twice in a
|
|
149
161
|
run and never block a stage on it ([`knowledge-sources.md`](knowledge-sources.md)).
|
|
150
|
-
- **
|
|
151
|
-
|
|
152
|
-
a
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
162
|
+
- **The browser channels — `playwright` and `chrome-devtools`, one rule for both.**
|
|
163
|
+
Flag them only when the project **has a web front end** — an `index.html`, a
|
|
164
|
+
`package.json` naming a browser framework, a `docs/ux/screens.md`, or a deploy target
|
|
165
|
+
that serves pages. **A CLI, a library or a backend service does not flag either** —
|
|
166
|
+
offering a browser to a project with no browser is how a recommendation is taught to
|
|
167
|
+
be noise. Detect `playwright` via a resolving `playwright-cli` binary, a
|
|
168
|
+
`@playwright/cli` or `@playwright/mcp` dependency, a `playwright.config.*`, or
|
|
169
|
+
`mcp__playwright__browser_navigate`; detect `chrome-devtools` via a resolving
|
|
170
|
+
`mcp__chrome-devtools__list_pages` (either one under whatever prefix the host uses).
|
|
171
|
+
Present → `✓ ready`. Absent → print its install lines **once** and continue; neither
|
|
172
|
+
is a gate.
|
|
173
|
+
- **They are two channels for one look, and the run needs one of them, not both.**
|
|
174
|
+
Both open the page, snapshot it and read the console and the network log, so **stop
|
|
175
|
+
at the first one that answers** — running the same look twice is a cost with no
|
|
176
|
+
second fact. Where neither is present, say the surface was verified **by reading the
|
|
177
|
+
diff**; where both are, the tie-breakers are stated rather than left to taste:
|
|
178
|
+
**`playwright` when the project already runs it**, or when context budget is tight —
|
|
179
|
+
its own upstream sells the CLI on not loading large tool schemas and verbose
|
|
180
|
+
accessibility trees into the model context. **`chrome-devtools` when the question is
|
|
181
|
+
past the page** — a Lighthouse category or a heap snapshot, neither of which the
|
|
182
|
+
Playwright channel has, or a performance trace you want *analysed* rather than only
|
|
183
|
+
recorded. Neither is *the better
|
|
184
|
+
browser*, and a run that ranks them has invented a fact this matrix does not carry.
|
|
157
185
|
- **graphify**: detect via `graphify-out/graph.json` (built → `✓ ready`, query it in
|
|
158
186
|
the harvest) or a resolving `graphify` binary with no `graphify-out/` (installed,
|
|
159
187
|
not built → offer the one-line `/graphify .`). Absent → print the install lines
|
|
@@ -76,6 +76,7 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
76
76
|
| **The canons** — what makes a claim documentation, and the index that routes to each | `references/documentation.md`, `../evidence-docs/SKILL.md` |
|
|
77
77
|
| **Effect verification** — the `verified-by:` contract and the rubric item that blocks | `references/build.md`, `references/review.md` |
|
|
78
78
|
| The TDD iron law and the suite gate | `references/tdd.md` |
|
|
79
|
+
| How the browser look is taken, and how a spec suite sits beside it | `references/browser.md` |
|
|
79
80
|
| The REQ coverage table, evidence rules, the closing question | `references/acceptance.md` |
|
|
80
81
|
| How the host project's own conventions are read | `references/conventions.md` |
|
|
81
82
|
| Which companions exist, what is required, self-currency | `references/companion-skills.md` |
|
|
@@ -395,12 +395,17 @@ never that the work was skipped quietly.
|
|
|
395
395
|
run's confirmed model (`model-tiering.md`). The plan's parallel groups fan out
|
|
396
396
|
**only** when each implementer gets its own worktree; otherwise sequential.
|
|
397
397
|
- **Web front end? The task's own surface is checked in a browser, not in the diff.**
|
|
398
|
-
Where
|
|
399
|
-
|
|
398
|
+
Where a browser channel is connected — `playwright` **or** `chrome-devtools`, either
|
|
399
|
+
one, whichever answers first (**how**: [`browser.md`](browser.md); which:
|
|
400
|
+
[`companion-skills.md`](companion-skills.md)): after a
|
|
401
|
+
task that changes a rendered surface, load it, take a snapshot and read the
|
|
400
402
|
console and the network log **before the task is marked DONE** — a component can be
|
|
401
403
|
correct and land under a fixed header, and a review of the diff cannot see that.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
+
**What the look finds is fixed in this task, or parked with the ruling the GATE below
|
|
405
|
+
requires — never parked silently** — a browser finding filed without a ruling is the
|
|
406
|
+
diff-review verdict wearing a screenshot; the look was worth taking only if it can
|
|
407
|
+
still change the code or is on record as deliberately not doing so. Absent, say the surface was verified by reading
|
|
408
|
+
the diff and treat it as the weaker claim it is. Stage 6 repeats this over the whole tree; this one catches it while the
|
|
404
409
|
implementer that wrote it is still dispatched. The matrix pointed this companion at
|
|
405
410
|
stages 5–6 from the day it was added and **this stage had never named it** — found by
|
|
406
411
|
the guard comparing the two, not by a reader.
|
|
@@ -438,12 +443,30 @@ never that the work was skipped quietly.
|
|
|
438
443
|
A passing suite proves the code does what its assertions say. It does not prove the
|
|
439
444
|
page rendered — a component can be correct and land under a fixed header, a request
|
|
440
445
|
can 404 while every unit test mocks it, and a console error costs nothing at test
|
|
441
|
-
time. Where
|
|
446
|
+
time. Where a browser channel is connected — `playwright` **or** `chrome-devtools`,
|
|
447
|
+
either one ([`browser.md`](browser.md) is the four commands this sentence means;
|
|
448
|
+
[`companion-skills.md`](companion-skills.md) is which channel):
|
|
442
449
|
load the surface, take a snapshot, and read **the console and the network log**
|
|
443
450
|
before calling it green. Absent, say the surface was verified **by reading the
|
|
444
451
|
diff** — that is a weaker claim and the close-out records it as one, rather than
|
|
445
452
|
letting "tests pass" stand in for "it renders". This is the `L6→L7` seam of
|
|
446
453
|
[`audit.md`](audit.md)'s ladder: *is there an executed observable a user reaches?*
|
|
454
|
+
- **A browser test suite does not discharge the look, and does not become it.** A
|
|
455
|
+
project whose CI runs `playwright test` has an *asserted* browser — it proves what
|
|
456
|
+
someone thought to assert, on the paths someone thought to write. It cannot report
|
|
457
|
+
the console error nobody asserted on, the bundle that 404s past a route nobody
|
|
458
|
+
visits, or the element that moved four pixels under a header. So a green spec suite
|
|
459
|
+
counts where every other test counts, inside **the suite half of the GATE above**;
|
|
460
|
+
the look stays what it already is here — **recommended, never a gate**, and reported
|
|
461
|
+
in the words the gate gives it. What the pair buys is that they fail differently: a
|
|
462
|
+
run that answers *the surface was checked* by pointing at its spec suite has answered
|
|
463
|
+
a different question. Where the suite is the thing that changed, the look is what
|
|
464
|
+
proves it runs against a page that renders.
|
|
465
|
+
- **What the look finds is fixed here.** A rendering defect found at stage 6 is a
|
|
466
|
+
stage-6 finding: fix it, look again, then call the stage green. Filing it to the
|
|
467
|
+
board and advancing is how a run reports *checked in a browser* for a page it has
|
|
468
|
+
seen to be broken — so if it does leave unfixed, the reason is on record and the
|
|
469
|
+
close-out carries it, exactly as a parked finding does.
|
|
447
470
|
|
|
448
471
|
## 7 — Lint + deploy
|
|
449
472
|
- **Freedom: low** — outward and irreversible — the authorization floor is exact or the stage stops ([`gates.md`](gates.md) → *Axis C*).
|
|
@@ -496,7 +519,8 @@ never that the work was skipped quietly.
|
|
|
496
519
|
- **A deployed web target is opened, not curled.** A `200` proves the server
|
|
497
520
|
answered; it says nothing about whether the page rendered, whether a bundle 404'd,
|
|
498
521
|
or whether the console filled with errors on load — all three ship green past a
|
|
499
|
-
health check. Where
|
|
522
|
+
health check. Where a browser channel is connected — `playwright` **or**
|
|
523
|
+
`chrome-devtools`, either one ([`browser.md`](browser.md)) — load the deployed URL and read
|
|
500
524
|
the console and the network log; quote what you read, not that you looked
|
|
501
525
|
([`companion-skills.md`](companion-skills.md)). Absent → say the check was an HTTP
|
|
502
526
|
response only, which is the honest name for it.
|
|
@@ -101,13 +101,25 @@ database created ten seconds ago" are different claims, and only the second one
|
|
|
101
101
|
- **A green suite is not a rendered page.** On a web front end the suite proves the
|
|
102
102
|
code does what its assertions say; it cannot see a component that renders correctly
|
|
103
103
|
and lands under a fixed header, a request that 404s while every unit test mocks it,
|
|
104
|
-
or a console error that costs nothing at test time. Where
|
|
105
|
-
connected
|
|
104
|
+
or a console error that costs nothing at test time. Where a browser channel is
|
|
105
|
+
connected — `playwright` **or** `chrome-devtools`, either one
|
|
106
|
+
([`companion-skills.md`](companion-skills.md)) — open the surface and read
|
|
106
107
|
the console and the network log before calling it done — and **quote what you read**,
|
|
107
108
|
not that you looked. Absent, the honest sentence is *"verified by reading the diff"*,
|
|
108
109
|
which is a weaker claim and is recorded as one. Same family as a test that passes
|
|
109
110
|
regardless of the production code: the assertion is real and it is pointed at
|
|
110
111
|
something other than what a user reaches.
|
|
112
|
+
- **A browser test suite does not close this, either.** `playwright test` in CI is a
|
|
113
|
+
suite whose runner happens to be a browser: it still asserts only what someone wrote
|
|
114
|
+
down. It belongs to the coverage half of the gate, and the sentence above still needs
|
|
115
|
+
a page that was opened and read. The two fail differently, which is the entire reason
|
|
116
|
+
to keep both — and [`browser.md`](browser.md) separates them from a third thing they
|
|
117
|
+
are both confused with, the Playwright **library**, which is an automation API and not
|
|
118
|
+
a test framework at all.
|
|
119
|
+
- **The look that found it writes the assertion that keeps it found.** `generate-locator`
|
|
120
|
+
on the element the look caught, then a spec around it, then `pause-at` to watch the
|
|
121
|
+
new spec see what you saw ([`browser.md`](browser.md)). A browser finding fixed with
|
|
122
|
+
no test behind it is a finding scheduled to return.
|
|
111
123
|
|
|
112
124
|
## Stage 6 — consolidation and the suite gate
|
|
113
125
|
|