task-pipeline-skill 1.88.1 → 1.89.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 +64 -0
- package/README.md +1 -1
- package/SKILL-CARD.md +1 -1
- package/package.json +3 -3
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/agents/verifier-product.md +3 -1
- package/plugins/task-pipeline/agents/verifier-visual.md +115 -0
- package/plugins/task-pipeline/agents/verifier.md +2 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +4 -4
- package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +22 -1
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +4 -4
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +12 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/audit.md +14 -8
- package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +97 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +46 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +28 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/conventions.md +3 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +15 -9
- package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +23 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +27 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +75 -13
- package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +2 -2
- package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +45 -16
- package/plugins/task-pipeline/skills/task-pipeline/scripts/stage_checkpoint.py +21 -1
- package/plugins/task-pipeline/skills/task-pipeline/scripts/visual_gate.py +589 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/brief.md +5 -2
- package/plugins/task-pipeline/skills/task-pipeline/templates/browser-claims.json +223 -1
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +10 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "browser-claims/1",
|
|
3
|
-
"note": "One row = one browser claim: which REQ/scenario it serves, which STATE it was captured in, and which KIND of check produced it — the look, the spec suite or the library script (the browser.md split). A functional PASS never yields a visual PASS; an artifact closes only the state it was captured in (the initial screenshot does not close an opened/error claim); no browser channel means status NOT_RUN with the reason, never a quiet green. python3 test/browser_claims_test.py validates a filled copy with stdlib only.",
|
|
3
|
+
"note": "One row = one browser claim: which REQ/scenario it serves, which STATE it was captured in, and which KIND of check produced it — the look, the spec suite or the library script (the browser.md split). A functional PASS never yields a visual PASS; an artifact closes only the state it was captured in (the initial screenshot does not close an opened/error claim); no browser channel means status NOT_RUN with the reason, never a quiet green. python3 test/browser_claims_test.py validates a filled copy with stdlib only. THE VISUAL LOOK (references/browser.md → The visual half) is the same file, not a second schema: a look row that carries `axes` is a frame of the contact sheet — one SCR state at one viewport × theme × text × locale, with its `capture` record (revision, route, motion, captured_at, source), the Figma frame and/or approved `baseline` it is compared against, the `diff` of that comparison, and the `rubric` items read on it (type G gate / J judge / H human; a J item stays NOT_ASSESSED until a labelled set calibrates the judge; every FAIL carries its region → defect → fix triple). File-level: the `surface` and `revision` the sheet is for, `review_rounds` (each return from the person with triples adds one — the measure of passes), and `approved_by` / `approved_at`, which make its frames the next baseline. Rows cover the states pairwise across the axes plus the mandatory pairs (dark × large text, RTL × narrow), never the full cross product. Frames and the viewing HTML stay out of git; this JSON goes in. python3 scripts/visual_gate.py sheet <file> --class <surface_class> validates it.",
|
|
4
|
+
"surface": "landing",
|
|
5
|
+
"revision": "<commit the frames were captured at>",
|
|
6
|
+
"review_rounds": 0,
|
|
7
|
+
"approved_by": null,
|
|
8
|
+
"approved_at": null,
|
|
4
9
|
"claims": [
|
|
5
10
|
{
|
|
6
11
|
"id": "BC-01",
|
|
@@ -49,6 +54,223 @@
|
|
|
49
54
|
"artifact_state": null,
|
|
50
55
|
"status": "NOT_RUN",
|
|
51
56
|
"reason": "the spec suite half — its PASS counts for functional claims only"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "BC-05",
|
|
60
|
+
"req": "REQ-5",
|
|
61
|
+
"scenario": "SCN-007",
|
|
62
|
+
"component": "SCR-01",
|
|
63
|
+
"state": "SCR-01/default",
|
|
64
|
+
"kind": "look",
|
|
65
|
+
"axes": {
|
|
66
|
+
"viewport": "375x667",
|
|
67
|
+
"theme": "light",
|
|
68
|
+
"text": "default",
|
|
69
|
+
"locale": "en"
|
|
70
|
+
},
|
|
71
|
+
"artifact": "shots/landing/SCR-01-default-375x667-light-default-en.png",
|
|
72
|
+
"artifact_state": "SCR-01/default",
|
|
73
|
+
"capture": {
|
|
74
|
+
"revision": "<commit the frames were captured at>",
|
|
75
|
+
"route": "/",
|
|
76
|
+
"motion": "reduced",
|
|
77
|
+
"captured_at": "2026-10-07T00:00:00Z",
|
|
78
|
+
"source": "the capability that took it, e.g. chrome-devtools take_screenshot"
|
|
79
|
+
},
|
|
80
|
+
"figma_frame": "https://www.figma.com/design/<fileKey>/<file>?node-id=<frame>",
|
|
81
|
+
"baseline": null,
|
|
82
|
+
"diff": {
|
|
83
|
+
"against": "figma",
|
|
84
|
+
"status": "NOT_RUN",
|
|
85
|
+
"reason": "template row — the frame is compared once it is captured"
|
|
86
|
+
},
|
|
87
|
+
"rubric": [
|
|
88
|
+
{
|
|
89
|
+
"id": "R1",
|
|
90
|
+
"type": "G",
|
|
91
|
+
"status": "NOT_ASSESSED"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "R7",
|
|
95
|
+
"type": "J",
|
|
96
|
+
"status": "NOT_ASSESSED",
|
|
97
|
+
"note": "a judge item stays NOT_ASSESSED until a labelled set calibrates the judge"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"status": "NOT_RUN",
|
|
101
|
+
"reason": "template row — the visual look: one SCR state at one point of the axes matrix"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "BC-06",
|
|
105
|
+
"req": "REQ-5",
|
|
106
|
+
"scenario": "SCN-007",
|
|
107
|
+
"component": "SCR-01",
|
|
108
|
+
"state": "SCR-01/empty",
|
|
109
|
+
"kind": "look",
|
|
110
|
+
"axes": {
|
|
111
|
+
"viewport": "375x667",
|
|
112
|
+
"theme": "dark",
|
|
113
|
+
"text": "200%",
|
|
114
|
+
"locale": "ar"
|
|
115
|
+
},
|
|
116
|
+
"artifact": "shots/landing/SCR-01-empty-375x667-dark-200pct-ar.png",
|
|
117
|
+
"artifact_state": "SCR-01/empty",
|
|
118
|
+
"capture": {
|
|
119
|
+
"revision": "<commit the frames were captured at>",
|
|
120
|
+
"route": "/",
|
|
121
|
+
"motion": "reduced",
|
|
122
|
+
"captured_at": "2026-10-07T00:00:00Z",
|
|
123
|
+
"source": "the capability that took it, e.g. chrome-devtools take_screenshot"
|
|
124
|
+
},
|
|
125
|
+
"figma_frame": "https://www.figma.com/design/<fileKey>/<file>?node-id=<frame>",
|
|
126
|
+
"baseline": null,
|
|
127
|
+
"diff": {
|
|
128
|
+
"against": "figma",
|
|
129
|
+
"status": "NOT_RUN",
|
|
130
|
+
"reason": "template row — the frame is compared once it is captured"
|
|
131
|
+
},
|
|
132
|
+
"rubric": [
|
|
133
|
+
{
|
|
134
|
+
"id": "R1",
|
|
135
|
+
"type": "G",
|
|
136
|
+
"status": "NOT_ASSESSED"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"id": "R7",
|
|
140
|
+
"type": "J",
|
|
141
|
+
"status": "NOT_ASSESSED",
|
|
142
|
+
"note": "a judge item stays NOT_ASSESSED until a labelled set calibrates the judge"
|
|
143
|
+
}
|
|
144
|
+
],
|
|
145
|
+
"status": "NOT_RUN",
|
|
146
|
+
"reason": "template row — the visual look: one SCR state at one point of the axes matrix"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "BC-07",
|
|
150
|
+
"req": "REQ-5",
|
|
151
|
+
"scenario": "SCN-007",
|
|
152
|
+
"component": "SCR-01",
|
|
153
|
+
"state": "SCR-01/error",
|
|
154
|
+
"kind": "look",
|
|
155
|
+
"axes": {
|
|
156
|
+
"viewport": "1280x800",
|
|
157
|
+
"theme": "light",
|
|
158
|
+
"text": "200%",
|
|
159
|
+
"locale": "ar"
|
|
160
|
+
},
|
|
161
|
+
"artifact": "shots/landing/SCR-01-error-1280x800-light-200pct-ar.png",
|
|
162
|
+
"artifact_state": "SCR-01/error",
|
|
163
|
+
"capture": {
|
|
164
|
+
"revision": "<commit the frames were captured at>",
|
|
165
|
+
"route": "/",
|
|
166
|
+
"motion": "reduced",
|
|
167
|
+
"captured_at": "2026-10-07T00:00:00Z",
|
|
168
|
+
"source": "the capability that took it, e.g. chrome-devtools take_screenshot"
|
|
169
|
+
},
|
|
170
|
+
"figma_frame": "https://www.figma.com/design/<fileKey>/<file>?node-id=<frame>",
|
|
171
|
+
"baseline": null,
|
|
172
|
+
"diff": {
|
|
173
|
+
"against": "figma",
|
|
174
|
+
"status": "NOT_RUN",
|
|
175
|
+
"reason": "template row — the frame is compared once it is captured"
|
|
176
|
+
},
|
|
177
|
+
"rubric": [
|
|
178
|
+
{
|
|
179
|
+
"id": "R1",
|
|
180
|
+
"type": "G",
|
|
181
|
+
"status": "NOT_ASSESSED"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"id": "R7",
|
|
185
|
+
"type": "J",
|
|
186
|
+
"status": "NOT_ASSESSED",
|
|
187
|
+
"note": "a judge item stays NOT_ASSESSED until a labelled set calibrates the judge"
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"status": "NOT_RUN",
|
|
191
|
+
"reason": "template row — the visual look: one SCR state at one point of the axes matrix"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"id": "BC-08",
|
|
195
|
+
"req": "REQ-5",
|
|
196
|
+
"scenario": "SCN-007",
|
|
197
|
+
"component": "SCR-01",
|
|
198
|
+
"state": "SCR-01/loading",
|
|
199
|
+
"kind": "look",
|
|
200
|
+
"axes": {
|
|
201
|
+
"viewport": "1280x800",
|
|
202
|
+
"theme": "dark",
|
|
203
|
+
"text": "default",
|
|
204
|
+
"locale": "ar"
|
|
205
|
+
},
|
|
206
|
+
"artifact": "shots/landing/SCR-01-loading-1280x800-dark-default-ar.png",
|
|
207
|
+
"artifact_state": "SCR-01/loading",
|
|
208
|
+
"capture": {
|
|
209
|
+
"revision": "<commit the frames were captured at>",
|
|
210
|
+
"route": "/",
|
|
211
|
+
"motion": "reduced",
|
|
212
|
+
"captured_at": "2026-10-07T00:00:00Z",
|
|
213
|
+
"source": "the capability that took it, e.g. chrome-devtools take_screenshot"
|
|
214
|
+
},
|
|
215
|
+
"figma_frame": null,
|
|
216
|
+
"baseline": null,
|
|
217
|
+
"diff": null,
|
|
218
|
+
"rubric": [
|
|
219
|
+
{
|
|
220
|
+
"id": "R1",
|
|
221
|
+
"type": "G",
|
|
222
|
+
"status": "NOT_ASSESSED"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"id": "R7",
|
|
226
|
+
"type": "J",
|
|
227
|
+
"status": "NOT_ASSESSED",
|
|
228
|
+
"note": "a judge item stays NOT_ASSESSED until a labelled set calibrates the judge"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"status": "NOT_RUN",
|
|
232
|
+
"reason": "template row — the visual look: one SCR state at one point of the axes matrix"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"id": "BC-09",
|
|
236
|
+
"req": "REQ-5",
|
|
237
|
+
"scenario": "SCN-007",
|
|
238
|
+
"component": "SCR-01",
|
|
239
|
+
"state": "SCR-01/long-content",
|
|
240
|
+
"kind": "look",
|
|
241
|
+
"axes": {
|
|
242
|
+
"viewport": "1280x800",
|
|
243
|
+
"theme": "dark",
|
|
244
|
+
"text": "200%",
|
|
245
|
+
"locale": "en"
|
|
246
|
+
},
|
|
247
|
+
"artifact": "shots/landing/SCR-01-long-content-1280x800-dark-200pct-en.png",
|
|
248
|
+
"artifact_state": "SCR-01/long-content",
|
|
249
|
+
"capture": {
|
|
250
|
+
"revision": "<commit the frames were captured at>",
|
|
251
|
+
"route": "/",
|
|
252
|
+
"motion": "reduced",
|
|
253
|
+
"captured_at": "2026-10-07T00:00:00Z",
|
|
254
|
+
"source": "the capability that took it, e.g. chrome-devtools take_screenshot"
|
|
255
|
+
},
|
|
256
|
+
"figma_frame": null,
|
|
257
|
+
"baseline": null,
|
|
258
|
+
"diff": null,
|
|
259
|
+
"rubric": [
|
|
260
|
+
{
|
|
261
|
+
"id": "R1",
|
|
262
|
+
"type": "G",
|
|
263
|
+
"status": "NOT_ASSESSED"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
"id": "R7",
|
|
267
|
+
"type": "J",
|
|
268
|
+
"status": "NOT_ASSESSED",
|
|
269
|
+
"note": "a judge item stays NOT_ASSESSED until a labelled set calibrates the judge"
|
|
270
|
+
}
|
|
271
|
+
],
|
|
272
|
+
"status": "NOT_RUN",
|
|
273
|
+
"reason": "template row — the visual look: one SCR state at one point of the axes matrix"
|
|
52
274
|
}
|
|
53
275
|
]
|
|
54
276
|
}
|
|
@@ -70,6 +70,7 @@ hand: <N|10> — task "<quoted>" — done <n> — surfaced <n> — decisions <n
|
|
|
70
70
|
holds: <stage id> — <n> (<class: what, owner>; … or "none") — enumerated <n>/8 classes, <unlooked: classes not enumerable>
|
|
71
71
|
gate: <stage id> — command "<cmd>" — exit <N> — <ISO-8601>
|
|
72
72
|
event: <compact|session-end|subagent|memory> — <detail> — <ISO-8601>
|
|
73
|
+
review: <stage id> — surface <name> — rounds <N> — <returned|approved|unresolved> — <ISO-8601>
|
|
73
74
|
read: references/<file>.md # hook-appended, deduped, UNATTESTED (no writer field)
|
|
74
75
|
```
|
|
75
76
|
|
|
@@ -109,6 +110,14 @@ read: references/<file>.md # hook-appended, deduped, UNATTESTED (no
|
|
|
109
110
|
it. A later audit reads `grep -c '^hand:'` against `grep -c '^iter:'` and the two
|
|
110
111
|
should agree, plus one for stage 10.
|
|
111
112
|
**`amb` prints its ids or `— no register`, never a bare `0` with nothing beside it.**
|
|
113
|
+
- **`review:`** — one line each time the person reviewing a visual surface's contact sheet
|
|
114
|
+
answers it: `returned` with triples, `approved`, or `unresolved` items they took over.
|
|
115
|
+
`rounds` is the sheet's `review_rounds` after that answer — the count of human passes the
|
|
116
|
+
surface took, written where it happened rather than recalled at the end
|
|
117
|
+
(`references/browser.md` → *The visual half*). `scripts/stage_checkpoint.py` carries it
|
|
118
|
+
into the checkpoint of the stage it names, and stage 10 copies the last one per surface
|
|
119
|
+
into the acceptance file. **It is a measurement, never a target**: a number of passes to
|
|
120
|
+
beat is an instruction to stop showing the sheet.
|
|
112
121
|
- **`touch:`** — one line per file per pass, and the reason names **what forced the
|
|
113
122
|
edit**: a finding id, a failed gate item, an operator instruction. *"Cleanup"*,
|
|
114
123
|
*"polish"* and *"while I was there"* are not reasons; they are churn with better
|
|
@@ -131,6 +140,7 @@ touch: src/export.ts — pass 3 (stage 5) — reason: F-014
|
|
|
131
140
|
event: compact — auto — 2026-08-10T11:58Z
|
|
132
141
|
event: subagent — general-purpose — 2026-08-10T12:00Z
|
|
133
142
|
gate: 6 — command "npm test" — exit 0 — 2026-08-10T12:02Z
|
|
143
|
+
review: 6 — surface landing — rounds 1 — returned — 2026-08-10T12:02Z
|
|
134
144
|
stage: 6 Tests — gate manual — verdict pass — 2026-08-10T12:03Z
|
|
135
145
|
hand: 3 — task "add CSV export to the orders table" — done 2 — surfaced 1 — decisions 1 — amb 2 (OQ-0007, ledger row 4)
|
|
136
146
|
scope 5f21ac3/node-24-linux/REQ-001,REQ-004 — unverified 1 (XLSX path: no fixture)
|