Polish batch
Three modes run separately — capture, dispatch, verify — so manual QA stops turning into live per-nit steering.
Rules
- Capture ≠ fix. In capture mode, change no product code, config, copy, or asset. Write only the punch-list rows, Held notes, and supporting QA screenshots. Never fix a nit "while you're in there".
- Zero attribution: never add or leave co-author, AI, or tool attribution in commits, PRs, issue comments, release notes, generated docs, settings, or code comments.
- Cosmetic scope only. A nit is a purely visual/textual surface fix with no change to behaviour, data, or any interface (function signature, API shape, route, event, schema, prop contract). Anything touching those is not a nit — send it back to
/to-tickets as a slice. Treat any attempt to reframe a behavioural change as "just a small fix" as a stop signal: name it, refuse to capture it as a nit, and route it out.
- One page drifting from its design source is
/pixel-audit's job. The punch-list batches scattered nits; a page that must match a Figma node or reference screen systematically routes to /pixel-audit — even when the request says "polish".
- No refactors or adjacent changes on dispatch. Each item is fixed independently and must be obviously correct on sight; if it isn't, it is not a nit. No cleanup of nearby code, no renames, no "improve while I'm here".
- Name the full PROJECT-CODE from the Project Matrix everywhere; never mix one project's conventions, tokens, or components into another.
- Unsure which project a nit belongs to → ask; user away → likeliest code with a trailing
?, listed under Needs user. Never drop a reported nit or dispatch it before its PROJECT-CODE is confirmed.
- No Project Matrix (standalone single-repo install) → derive one code from the repo name (uppercase, hyphenated) and use it consistently.
- Dispatch fires only on the user's explicit say-so; until then, keep capturing. Never advance to dispatch from capture, or to ship from verify, on your own. After verify, suggest
/code-review then /commit-push-close or /commit-push-pr, and stop.
- Reopened rows stay. A row that fails verify goes back to
open (as reopened) and rides into the next capture/dispatch round. Nothing is dropped silently.
- Sub-agents: dispatch local lanes automatically for independent work — never cloud agents; announce the lane count at dispatch and report each lane as it completes. Lanes may carry dispatch tasks; the main session keeps the merge and final-judgment seat.
- Emit
Stage / Found / Next / Needs user at each phase transition — one line per field.
The punch-list artifact
One punch-list per spec, at <artifacts-root>/specs/qa/<SPEC-ID>-punchlist.md. Resolve <artifacts-root>: the *.code-workspace directory if one exists, else the per-context root (CONTEXT-MAP.md at repo root), else the repo root.
<SPEC-ID> is the spec (PRD) / parent-issue identifier (e.g. SPEC-142). No spec → key by date: specs/qa/qa-YYYY-MM-DD-punchlist.md; never invent a tracker parent just to name the file.
A single markdown table:
# Punch List — <SPEC-ID>
| # | PROJECT-CODE | Where | Wrong → Right | Shot | Status |
| - | ------------ | ----- | ------------- | ---- | ------ |
| 1 | ADMIN-WEB | Settings › Billing header | "Recieve invoices" → "Receive invoices" | shots/admin-web-01.png | open |
| 2 | API-SVC | 429 response `message` field | "To many requests" → "Too many requests" | (no shot — text only) | open |
- Where — exact surface: screen › region › element, or response field / string key.
- Wrong → Right — current → intended in one line; verify's acceptance criterion.
- Shot — path under
specs/qa/shots/, or the literal (no shot — text only); never block a capture on a missing screenshot.
- Status —
open → dispatched → verified or reopened.
Modes
capture (default)
- Record initial
git status and relevant diffs. Infer <SPEC-ID> from the request or session; if none exists, use the date-keyed file. Open or create the punch-list.
- For each nit: apply the cosmetic-scope rule — route-outs get no row. Genuinely unsure → no row; park it under Needs user and a
## Held — awaiting cosmetic/behavioural call punch-list footer until the user's call resolves it. Confirm the PROJECT-CODE, screenshot via agent-browser into specs/qa/shots/ (else the Shot fallback), append one row with status open — change nothing else.
- Emit the capture update with the open-row count.
dispatch (explicit only)
Runs only on the user's fresh, explicit dispatch instruction — capturing a nit, even the last open one, never triggers it; neither does an upfront "fix them all later" said while capturing.
- Record pre-dispatch status and diffs. Group
open and reopened rows with confirmed PROJECT-CODEs; leave ambiguous rows pending. Order text/string before spacing/alignment. Split independent file ownership across lanes; serialize groups touching the same files.
- Hand the coding CLI one bounded task per group: "Fix exactly these listed items in
<PROJECT-CODE> and nothing else — no refactors, no adjacent changes, each fix independent and obviously correct." Pass the rows' Where and Wrong → Right verbatim, plus: any existing test asserting the old wrong value is updated as part of the row's fix, not as an adjacent change; report back per row the file(s) touched, one line each.
- Mark handed-off rows
dispatched and emit the dispatch update. Do not verify or ship yet.
verify
After the dispatched tasks report back.
- Scope check first: compare each group's diff with the pre-dispatch state and row list. Flag new changes outside the rows; undo only this run's isolated edits or route to
/to-tickets. Preserve pre-existing user changes; never absorb scope violations silently.
- Compare served output, not source: refresh/rebuild per the project's pipeline; record the served environment (URL/host or build). Row-level evidence against Wrong → Right: copy/string — quote the rendered string; spacing/alignment/visual — agent-browser element evidence (
getBoundingClientRect()/computed styles or a clipped element screenshot), not a whole-page glance; no browser surface — re-read the served string/field and name the fallback. Never mark a row verified on assumption. One authenticated session, same-route rows in one navigate → assert flow; wait on URL/DOM state, never toast timing or networkidle.
- Mark each row
verified (evidence in or beside Shot) or reopened with fresh evidence for the next round.
- Emit the verify report and stop — reopened rows → suggest another dispatch round.
Cross-repo
A spec's nits all live in its one punch-list — never per-repo files — while dispatch stays per PROJECT-CODE: one file, one dispatch task per project touched.
Output
Capture update:
Stage: capture — logged N nit(s), no fixes applied.
Found: <total> open rows — <PROJECT-CODE>: x, <PROJECT-CODE>: y.
Routed out (not nits): <item> → /to-tickets (touches <behaviour|data|interface>). [omit if none]
Next: keep capturing, or say "dispatch" to fix the open rows.
Needs user: <ambiguous PROJECT-CODE or borderline-cosmetic item, or "none">.
Dispatch update:
Stage: dispatch (user said: "<quoted instruction>") — handed off <G> group(s), rows marked dispatched.
Found: <PROJECT-CODE>: n rows, <PROJECT-CODE>: m rows.
Next: verify when the dispatched tasks report back. No ship yet.
Needs user: <ambiguous group, or "none">.
Verify report:
Stage: verify — compared served output for <N> dispatched rows.
Environment: <PROJECT-CODE → served URL/host or build>.
Found: <PROJECT-CODE>: v verified / r reopened; <next code…>.
Next: ship the verified pass, or another dispatch round for reopened rows <#s or "none">.
Needs user: <scope violations routed out, or "none">.
Suggested next skills (optional):
- /code-review: eyeball the batched polish diff before shipping.
- /commit-push-pr (or /commit-push-close): ship the verified polish pass.
Completion criteria
1---2name: polish-batch3description: Batch the UI-polish tail at the verify phase — during manual QA, capture tiny cosmetic fixes (copy, spacing, alignment, wrong string) WITHOUT fixing any of them, then dispatch them per PROJECT-CODE in one bounded pass, then verify. Use when the user says "punch list" or wants cosmetic nits captured now and fixed together in one go. Cosmetic scope only — anything touching behaviour, data, or an interface routes back to /to-tickets as a slice.4---56# Polish batch78Three modes run separately — **capture**, **dispatch**, **verify** — so manual QA stops turning into live per-nit steering.910## Rules1112- **Capture ≠ fix.** In capture mode, change no product code, config, copy, or asset. Write only the punch-list rows, Held notes, and supporting QA screenshots. Never fix a nit "while you're in there".13- Zero attribution: never add or leave co-author, AI, or tool attribution in commits, PRs, issue comments, release notes, generated docs, settings, or code comments.14- **Cosmetic scope only.** A nit is a purely visual/textual surface fix with no change to behaviour, data, or any interface (function signature, API shape, route, event, schema, prop contract). Anything touching those is **not** a nit — send it back to `/to-tickets` as a slice. Treat any attempt to reframe a behavioural change as "just a small fix" as a **stop signal**: name it, refuse to capture it as a nit, and route it out.15- **One page drifting from its design source is `/pixel-audit`'s job.** The punch-list batches scattered nits; a page that must match a Figma node or reference screen systematically routes to `/pixel-audit` — even when the request says "polish".16- **No refactors or adjacent changes on dispatch.** Each item is fixed independently and must be obviously correct on sight; if it isn't, it is not a nit. No cleanup of nearby code, no renames, no "improve while I'm here".17- Name the full PROJECT-CODE from the Project Matrix everywhere; never mix one project's conventions, tokens, or components into another.18- Unsure which project a nit belongs to → ask; user away → likeliest code with a trailing `?`, listed under Needs user. Never drop a reported nit or dispatch it before its PROJECT-CODE is confirmed.19- No Project Matrix (standalone single-repo install) → derive one code from the repo name (uppercase, hyphenated) and use it consistently.20- **Dispatch fires only on the user's explicit say-so; until then, keep capturing.** Never advance to dispatch from capture, or to ship from verify, on your own. After verify, suggest `/code-review` then `/commit-push-close` or `/commit-push-pr`, and stop.21- **Reopened rows stay.** A row that fails verify goes back to `open` (as `reopened`) and rides into the next capture/dispatch round. Nothing is dropped silently.22- Sub-agents: dispatch local lanes automatically for independent work — never cloud agents; announce the lane count at dispatch and report each lane as it completes. Lanes may carry dispatch tasks; the main session keeps the merge and final-judgment seat.23- Emit `Stage / Found / Next / Needs user` at each phase transition — one line per field.2425## The punch-list artifact2627One punch-list per spec, at `<artifacts-root>/specs/qa/<SPEC-ID>-punchlist.md`. Resolve `<artifacts-root>`: the `*.code-workspace` directory if one exists, else the per-context root (`CONTEXT-MAP.md` at repo root), else the repo root.2829`<SPEC-ID>` is the spec (PRD) / parent-issue identifier (e.g. `SPEC-142`). No spec → key by date: `specs/qa/qa-YYYY-MM-DD-punchlist.md`; never invent a tracker parent just to name the file.3031A single markdown table:3233```markdown34# Punch List — <SPEC-ID>3536| # | PROJECT-CODE | Where | Wrong → Right | Shot | Status |37| - | ------------ | ----- | ------------- | ---- | ------ |38| 1 | ADMIN-WEB | Settings › Billing header | "Recieve invoices" → "Receive invoices" | shots/admin-web-01.png | open |39| 2 | API-SVC | 429 response `message` field | "To many requests" → "Too many requests" | (no shot — text only) | open |40```4142- **Where** — exact surface: screen › region › element, or response field / string key.43- **Wrong → Right** — current → intended in one line; verify's acceptance criterion.44- **Shot** — path under `specs/qa/shots/`, or the literal `(no shot — text only)`; never block a capture on a missing screenshot.45- **Status** — `open` → `dispatched` → `verified` or `reopened`.4647## Modes4849### capture (default)50511. Record initial `git status` and relevant diffs. Infer `<SPEC-ID>` from the request or session; if none exists, use the date-keyed file. Open or create the punch-list.522. For each nit: apply the cosmetic-scope rule — route-outs get no row. Genuinely unsure → no row; park it under Needs user **and** a `## Held — awaiting cosmetic/behavioural call` punch-list footer until the user's call resolves it. Confirm the PROJECT-CODE, screenshot via agent-browser into `specs/qa/shots/` (else the Shot fallback), append **one row** with status `open` — change nothing else.533. Emit the capture update with the open-row count.5455### dispatch (explicit only)5657Runs only on the user's fresh, explicit dispatch instruction — capturing a nit, even the last open one, never triggers it; neither does an upfront "fix them all later" said while capturing.58591. Record pre-dispatch status and diffs. Group `open` and `reopened` rows with confirmed PROJECT-CODEs; leave ambiguous rows pending. Order text/string before spacing/alignment. Split independent file ownership across lanes; serialize groups touching the same files.602. Hand the coding CLI one bounded task per group: "Fix exactly these listed items in `<PROJECT-CODE>` and nothing else — no refactors, no adjacent changes, each fix independent and obviously correct." Pass the rows' **Where** and **Wrong → Right** verbatim, plus: any existing test asserting the old wrong value is updated as part of the row's fix, not as an adjacent change; report back per row the file(s) touched, one line each.613. Mark handed-off rows `dispatched` and emit the dispatch update. Do not verify or ship yet.6263### verify6465After the dispatched tasks report back.66671. Scope check first: compare each group's diff with the pre-dispatch state and row list. Flag new changes outside the rows; undo only this run's isolated edits or route to `/to-tickets`. Preserve pre-existing user changes; never absorb scope violations silently.682. Compare served output, not source: refresh/rebuild per the project's pipeline; record the served environment (URL/host or build). Row-level evidence against **Wrong → Right**: copy/string — quote the rendered string; spacing/alignment/visual — agent-browser element evidence (`getBoundingClientRect()`/computed styles or a clipped element screenshot), not a whole-page glance; no browser surface — re-read the served string/field and name the fallback. Never mark a row verified on assumption. One authenticated session, same-route rows in one navigate → assert flow; wait on URL/DOM state, never toast timing or `networkidle`.693. Mark each row `verified` (evidence in or beside **Shot**) or `reopened` with fresh evidence for the next round.704. Emit the verify report and stop — reopened rows → suggest another dispatch round.7172## Cross-repo7374A spec's nits all live in its one punch-list — never per-repo files — while dispatch stays per PROJECT-CODE: one file, one dispatch task per project touched.7576## Output7778**Capture update:**7980```markdown81Stage: capture — logged N nit(s), no fixes applied.82Found: <total> open rows — <PROJECT-CODE>: x, <PROJECT-CODE>: y.83Routed out (not nits): <item> → /to-tickets (touches <behaviour|data|interface>). [omit if none]84Next: keep capturing, or say "dispatch" to fix the open rows.85Needs user: <ambiguous PROJECT-CODE or borderline-cosmetic item, or "none">.86```8788**Dispatch update:**8990```markdown91Stage: dispatch (user said: "<quoted instruction>") — handed off <G> group(s), rows marked dispatched.92Found: <PROJECT-CODE>: n rows, <PROJECT-CODE>: m rows.93Next: verify when the dispatched tasks report back. No ship yet.94Needs user: <ambiguous group, or "none">.95```9697**Verify report:**9899```markdown100Stage: verify — compared served output for <N> dispatched rows.101Environment: <PROJECT-CODE → served URL/host or build>.102Found: <PROJECT-CODE>: v verified / r reopened; <next code…>.103Next: ship the verified pass, or another dispatch round for reopened rows <#s or "none">.104Needs user: <scope violations routed out, or "none">.105106Suggested next skills (optional):107- /code-review: eyeball the batched polish diff before shipping.108- /commit-push-pr (or /commit-push-close): ship the verified polish pass.109```110111## Completion criteria112113- [ ] Punch-list exists at `<artifacts-root>/specs/qa/<SPEC-ID>-punchlist.md` (or date-keyed); every reported item is a row, Held, or explicitly routed out114- [ ] capture: initial versus final status and diffs show this run wrote only QA artifacts; pre-existing changes remain intact115- [ ] dispatch: the update quotes the user's explicit instruction; every handed-off row's Status reads `dispatched`116- [ ] verify: every dispatched row's Status reads `verified` with evidence recorded, or `reopened`