task-pipeline-skill 1.88.1 → 1.90.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.
Files changed (31) hide show
  1. package/CHANGELOG.md +109 -0
  2. package/README.md +2 -2
  3. package/SKILL-CARD.md +1 -1
  4. package/package.json +3 -3
  5. package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
  6. package/plugins/task-pipeline/agents/verifier-product.md +3 -1
  7. package/plugins/task-pipeline/agents/verifier-visual.md +115 -0
  8. package/plugins/task-pipeline/agents/verifier.md +2 -1
  9. package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +5 -5
  10. package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +22 -1
  11. package/plugins/task-pipeline/skills/task-pipeline/pipeline.example.json +4 -4
  12. package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +12 -0
  13. package/plugins/task-pipeline/skills/task-pipeline/references/audit.md +14 -8
  14. package/plugins/task-pipeline/skills/task-pipeline/references/browser.md +107 -3
  15. package/plugins/task-pipeline/skills/task-pipeline/references/build.md +41 -2
  16. package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +46 -5
  17. package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +29 -0
  18. package/plugins/task-pipeline/skills/task-pipeline/references/conventions.md +3 -3
  19. package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -1
  20. package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +15 -9
  21. package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +23 -0
  22. package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -1
  23. package/plugins/task-pipeline/skills/task-pipeline/references/spec.md +27 -3
  24. package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +83 -13
  25. package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +2 -2
  26. package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +45 -16
  27. package/plugins/task-pipeline/skills/task-pipeline/scripts/stage_checkpoint.py +21 -1
  28. package/plugins/task-pipeline/skills/task-pipeline/scripts/visual_gate.py +728 -0
  29. package/plugins/task-pipeline/skills/task-pipeline/templates/brief.md +5 -2
  30. package/plugins/task-pipeline/skills/task-pipeline/templates/browser-claims.json +223 -1
  31. package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +10 -0
@@ -8,6 +8,9 @@
8
8
  - **Task (one line):** <what the operator asked for, restated>
9
9
  - **UI verdict:** yes / no — does this touch a user-facing surface (web/mobile/CLI/TUI)?
10
10
  If yes, the stage-3 super-ux UX track is armed.
11
+ - **surface_class:** flagship / product / internal / ad — UI tasks only. Selects the
12
+ visual gate profile: the director record's fields at stage 3, whether the visual half
13
+ of the look gates stage 6, and whether stage 10 needs the approved contact sheet.
11
14
 
12
15
  ## Contents
13
16
 
@@ -129,9 +132,9 @@ is not neutral — it is a scheduled interruption.
129
132
  | 0 Docs regime | Where settled things live (register or ADR set — one home, never both); who may write it; lease mechanism present, or is this run `ungated`? Gate command + ratchet floors; may this run raise a floor? | … |
130
133
  | 1 Docs | External libs/APIs/SDKs in play; any context7 can't resolve → where their docs live | … |
131
134
  | 2 Decompose | Platform (several capabilities/surfaces) or one module? If platform — deploy cadence: per module, or once at the end | … |
132
- | 2–3 Spec | UI verdict (arms super-ux); scenario-tracing waiver, if any | … |
135
+ | 2–3 Spec | UI verdict (arms super-ux) and `surface_class`; scenario-tracing waiver, if any | … |
133
136
  | 3 Design surface | UI only: Figma on or text-only (check `docs/ux/foundation.md` → Design tooling first); Figma MCP connected? **If not — ship text-only, or stop and connect it?** | … (super-ux never blocks on a missing MCP, so an unanswered row here ships the feature without mockups) |
134
- | 3 Design file | Figma on only: **which team/org + which file** — existing URL, or "create one in team `<name>`" **with creation authorized**. Canonical record: `docs/ux/foundation.md` → Design tooling | … (team: `<name>` · file: `<url>` \| `create in <team>, authorized` — never create when a recorded file resolves) |
137
+ | 3 Design file | Figma on only: **which team/org + which file per surface** (App, Web, ASO) — existing URL, or "create one in team `<name>`" **with creation authorized**. Canonical record: `docs/ux/foundation.md` → Design tooling | … (team: `<name>` · App: `<url>` · Web: `<url>` · ASO: `<url>` \| `create in <team>, authorized` — never create when a recorded file resolves) |
135
138
  | 4–5 Dev | Base branch; worktree/branch policy; is `main` off-limits; commit convention; task tracker | … |
136
139
  | 5 Integration | How the branch lands — direct merge, PR (who approves), or "leave it, I'll merge"; is parallel fan-out (one worktree per implementer) wanted? | … |
137
140
  | 6 Tests | Test command; what "green" means; known-red baseline; coverage expectation | … |
@@ -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)