qualia-framework 5.4.0 → 5.8.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/README.md +21 -17
- package/agents/builder.md +25 -8
- package/agents/plan-checker.md +50 -2
- package/agents/planner.md +25 -1
- package/agents/research-synthesizer.md +4 -1
- package/agents/researcher.md +6 -1
- package/agents/visual-evaluator.md +1 -1
- package/bin/install.js +8 -8
- package/bin/plan-contract.js +32 -1
- package/bin/slop-detect.mjs +1 -1
- package/docs/erp-contract.md +11 -0
- package/docs/onboarding.html +623 -0
- package/guide.md +8 -9
- package/hooks/session-start.js +1 -1
- package/package.json +1 -1
- package/skills/qualia-discuss/SKILL.md +123 -9
- package/skills/qualia-feature/SKILL.md +216 -0
- package/skills/qualia-milestone/SKILL.md +73 -1
- package/skills/qualia-new/SKILL.md +52 -25
- package/skills/qualia-optimize/SKILL.md +1 -1
- package/skills/{qualia-polish-loop → qualia-polish}/REFERENCE.md +5 -5
- package/skills/qualia-polish/SKILL.md +13 -4
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/loop.mjs +2 -2
- package/skills/{qualia-polish-loop → qualia-polish}/scripts/playwright-capture.mjs +1 -1
- package/skills/qualia-report/SKILL.md +8 -6
- package/skills/qualia-road/SKILL.md +10 -11
- package/templates/CONTEXT.md +3 -2
- package/templates/help.html +1 -1
- package/templates/phase-context.md +5 -4
- package/templates/project-discovery.md +83 -0
- package/templates/project.md +7 -0
- package/tests/bin.test.sh +104 -62
- package/tests/lib.test.sh +21 -0
- package/tests/slop-detect.test.sh +2 -2
- package/docs/archive/session-report-2026-04-18.md +0 -199
- package/docs/install-redesign-builder-prompt.md +0 -290
- package/docs/install-redesign-pilot.md +0 -234
- package/docs/instruction-budget-audit.md +0 -113
- package/docs/journey-demo.html +0 -1008
- package/docs/playwright-loop-builder-prompt.md +0 -185
- package/docs/playwright-loop-design-notes.md +0 -108
- package/docs/playwright-loop-tester-prompt.md +0 -213
- package/docs/polish-loop-supervised-run.md +0 -111
- package/skills/qualia-polish-loop/SKILL.md +0 -201
- package/skills/qualia-prd/SKILL.md +0 -199
- package/skills/qualia-quick/SKILL.md +0 -44
- package/skills/qualia-task/SKILL.md +0 -98
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/broken.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/clean.html +0 -0
- /package/skills/{qualia-polish-loop → qualia-polish}/scripts/score.mjs +0 -0
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
# Playwright Visual-Polish Loop — Builder Agent Prompt
|
|
2
|
-
|
|
3
|
-
**Hand this entire file to a fresh Claude Code session.** Self-contained — no context from the originating session is needed.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## You are building a feature for the Qualia Framework v5.1
|
|
8
|
-
|
|
9
|
-
The Qualia Framework is a Claude Code workflow framework at `/home/qualia-new/qualia-framework` (npm package `qualia-framework`, current version 5.0.0). It manages full-stack project delivery for Qualia Solutions (Nicosia, Cyprus). It already has 32 skills, 12 hooks, 8 agents, 24 templates, and 260+ tests. Your job is to add ONE new flagship capability for v5.1: an autonomous visual-polish loop that uses Playwright to screenshot live pages and self-correct frontend until visually correct.
|
|
10
|
-
|
|
11
|
-
## Why this exists (the friction it fixes)
|
|
12
|
-
|
|
13
|
-
Per `/insights` data from the framework owner Fawzi (122 sessions, 292 commits, 10 days), the #1 documented friction pattern is **design iteration churn** — hero videos, mobile layouts, and responsive breakpoints requiring 5-10 manual rounds before landing. Quotes from his transcripts include:
|
|
14
|
-
|
|
15
|
-
- "many frustrating iterations" on hero video layouts
|
|
16
|
-
- "what did u do" after a CSS regression
|
|
17
|
-
- "first showcase used basic HTML/CSS animation; you had to explicitly request 'proper design animation three js or framer motion'"
|
|
18
|
-
- "FUCK U" / "OMG I TOLD U I CHANGED THE PAGE SO U STOP LYING" — clusters around Claude not seeing what's actually rendered
|
|
19
|
-
|
|
20
|
-
**The root cause:** the framework's design QA today is text-based. Slop-detect grep-scans CSS for em-dashes/banned fonts. The verifier scores 8 design dimensions by reading TSX/CSS, not by looking at rendered pages. When something fails visually but passes code review (most hero-video, mobile-layout, and responsive-breakpoint bugs), there's no feedback loop. The user has to look, complain, iterate.
|
|
21
|
-
|
|
22
|
-
**Your feature closes that loop.** A new skill `/qualia-polish-loop` takes a URL + design brief, screenshots at multiple viewports, evaluates against the brief using vision, identifies issues, edits files, redeploys to a Vercel preview, loops up to N times until criteria pass, and stops only when it's actually correct (or hits a kill-switch).
|
|
23
|
-
|
|
24
|
-
## What "good" looks like (success criteria)
|
|
25
|
-
|
|
26
|
-
The feature must:
|
|
27
|
-
|
|
28
|
-
1. **See its own work.** Screenshots at mobile (375px), tablet (768px), desktop (1440px) at minimum, captured via Playwright MCP.
|
|
29
|
-
2. **Anchor evaluation rigorously.** Vision model judgments must be scored against the project's `.planning/DESIGN.md` brief AND the `rules/design-rubric.md` 8-dimension scoring (Typography / Color cohesion / Spatial rhythm / Layout originality / Shadow & depth / Motion intent / Microcopy specificity / Container depth). Each dimension scored 1-5 with evidence; ANY <3 fails the iteration.
|
|
30
|
-
3. **Iterate with discipline.** Max 8 iterations per loop invocation. Hard kill-switch if the same issue recurs 3 times (regression-stop). Per-iteration: identify TOP 3 issues, edit relevant files, redeploy, re-screenshot, re-evaluate.
|
|
31
|
-
4. **Stop only when correct.** Success = all 8 dimensions ≥ 3 AND no critical-severity issues remain.
|
|
32
|
-
5. **Token-discipline.** Each iteration uses ≤ 4 vision evaluations (3 viewports + 1 holistic). Estimate token cost upfront and warn user if budget will exceed 100K tokens.
|
|
33
|
-
6. **Never silently destroy work.** All file edits go through `git commit` per iteration so any iteration is revertable. Failed iterations leave clear `[ITERATION-N]` commit prefixes for cleanup.
|
|
34
|
-
7. **Integrate with the framework.** Honors all framework conventions: PRODUCT.md / DESIGN.md / CONTEXT.md as substrate, slop-detect at commit, qualia-ui banner, state.js telemetry.
|
|
35
|
-
|
|
36
|
-
## Architecture (the design is yours to refine)
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
/qualia-polish-loop {url} [--brief design-brief.md] [--max 8] [--viewports 375,768,1440]
|
|
40
|
-
│
|
|
41
|
-
▼
|
|
42
|
-
Pre-flight (sequential, me)
|
|
43
|
-
├─ Read .planning/PRODUCT.md (register, anti-references, voice)
|
|
44
|
-
├─ Read .planning/DESIGN.md (color strategy, scene sentence, palette)
|
|
45
|
-
├─ Read rules/design-rubric.md (8-dim scoring criteria)
|
|
46
|
-
├─ Read brief argument if provided, else use DESIGN.md
|
|
47
|
-
└─ Estimate token budget. Warn if > 100K. AskUserQuestion to confirm proceed.
|
|
48
|
-
│
|
|
49
|
-
▼
|
|
50
|
-
Loop (max 8 iterations):
|
|
51
|
-
├─ Iteration N starts: log to .planning/visual-polish-loop.md
|
|
52
|
-
├─ Capture: 3 viewports via Playwright MCP → save to /tmp/qpl-{N}/
|
|
53
|
-
├─ Evaluate: spawn vision agent with screenshots + brief + rubric
|
|
54
|
-
│ Returns: per-dim 1-5 scores + evidence + top 3 issues + severity
|
|
55
|
-
├─ Decide: all dims ≥ 3 AND no critical? → SUCCESS, exit loop
|
|
56
|
-
├─ Else: regression check — if same issue recurred 3x → KILL, exit with FAIL
|
|
57
|
-
├─ Else: spawn 1 builder per top-issue (parallel, max 3) to fix
|
|
58
|
-
│ Each builder: read affected file, apply fix, slop-detect, commit
|
|
59
|
-
├─ Redeploy: vercel deploy --prebuilt OR `npm run dev` heartbeat check
|
|
60
|
-
└─ Loop back to capture
|
|
61
|
-
│
|
|
62
|
-
▼
|
|
63
|
-
Post-loop:
|
|
64
|
-
├─ Write .planning/visual-polish-loop.md (full report: iterations, scores, fixes)
|
|
65
|
-
├─ Show before/after screenshots side-by-side via qualia-ui
|
|
66
|
-
├─ git add .planning/visual-polish-loop.md && commit
|
|
67
|
-
└─ Tell user: SUCCESS / KILLED-AT-N / OUT-OF-BUDGET
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Integration points (read these before designing)
|
|
71
|
-
|
|
72
|
-
Before writing any code, read these files to understand the framework:
|
|
73
|
-
|
|
74
|
-
1. `/home/qualia-new/qualia-framework/CLAUDE.md` — project rules, instruction-budget discipline
|
|
75
|
-
2. `/home/qualia-new/qualia-framework/rules/design-rubric.md` — 8-dimension 1-5 scoring criteria with anchored definitions per dimension
|
|
76
|
-
3. `/home/qualia-new/qualia-framework/rules/design-laws.md` — non-negotiable design rules (OKLCH-only, banned fonts, side-stripe-borders, gradient-text bans, glassmorphism, etc.)
|
|
77
|
-
4. `/home/qualia-new/qualia-framework/templates/PRODUCT.md` — what the agent will read as register/anti-references/voice substrate
|
|
78
|
-
5. `/home/qualia-new/qualia-framework/templates/DESIGN.md` — what the agent will read as visual contract
|
|
79
|
-
6. `/home/qualia-new/qualia-framework/skills/qualia-polish/SKILL.md` — existing scope-adaptive polish skill; understand its modes (Component / Section / App / Redesign / Critique / Quick) and how this loop fits as a 7th mode OR a separate skill
|
|
80
|
-
7. `/home/qualia-new/qualia-framework/agents/verifier.md` — how the existing verifier scores design dimensions today (text-based)
|
|
81
|
-
8. `/home/qualia-new/qualia-framework/skills/qualia-build/SKILL.md` — pattern for spawning builder subagents in parallel
|
|
82
|
-
9. `/home/qualia-new/qualia-framework/bin/qualia-ui.js` — the UI helper for banners/dividers/end-cards
|
|
83
|
-
10. `/home/qualia-new/qualia-framework/bin/state.js` — for telemetry transitions if you want to log loop iterations
|
|
84
|
-
11. `/home/qualia-new/qualia-framework/bin/slop-detect.mjs` — must be invoked on every committed file in iteration
|
|
85
|
-
|
|
86
|
-
## External dependencies you'll integrate
|
|
87
|
-
|
|
88
|
-
1. **Playwright MCP** — verify it's available via `claude mcp list` or instructions to add. Use `mcp__playwright__navigate`, `mcp__playwright__take_screenshot` (or equivalent — verify exact tool names by listing available MCP tools). Setup may require:
|
|
89
|
-
```
|
|
90
|
-
claude mcp add playwright -- npx -y @playwright/mcp@latest
|
|
91
|
-
```
|
|
92
|
-
Plus on Linux/CI: `npx playwright install chromium` to get the browser binaries.
|
|
93
|
-
|
|
94
|
-
2. **Vision model** — Claude (you, the agent) reads images natively. The screenshots get attached to the spawned vision agent's prompt. Use the Read tool with image file paths.
|
|
95
|
-
|
|
96
|
-
3. **Vercel deploys** — use `vercel deploy` (not `--prod`) to publish a preview each iteration. Read `.vercel/project.json` for project linkage. The dev-mode alternative is `npm run dev` + curl heartbeat, but preview deploys give a stable URL for re-screenshotting from anywhere.
|
|
97
|
-
|
|
98
|
-
## Decision points the user (Fawzi) will care about
|
|
99
|
-
|
|
100
|
-
You MUST present these via `AskUserQuestion` BEFORE starting the loop on first invocation. Each is a load-bearing choice:
|
|
101
|
-
|
|
102
|
-
1. **Brief source** — use `.planning/DESIGN.md` (default) OR a separate `--brief` markdown file (override). If neither exists, halt: "No design brief found. Run /qualia-new or pass --brief."
|
|
103
|
-
|
|
104
|
-
2. **Reference screenshots (optional but recommended)** — "Do you have a reference image of what this should look like? Paste path or skip." Reference-anchored vision is dramatically more reliable than rubric-only.
|
|
105
|
-
|
|
106
|
-
3. **Auto-deploy strategy** — "Each iteration redeploys to Vercel preview (slower, real environment) or runs `npm run dev` and screenshots localhost (faster, dev artifacts may differ). Pick: vercel-preview / dev-localhost." Default: dev-localhost for iteration speed, vercel-preview for final.
|
|
107
|
-
|
|
108
|
-
4. **Token budget cap** — "Estimated 60-100K tokens for 8 iterations. Cap at 100K (default), 200K (generous), or 50K (tight)?"
|
|
109
|
-
|
|
110
|
-
## Files to create
|
|
111
|
-
|
|
112
|
-
- `/home/qualia-new/qualia-framework/skills/qualia-polish-loop/SKILL.md` — the new skill (frontmatter + workflow + decision gates). Target: <250 lines per Matt Pocock progressive disclosure rule.
|
|
113
|
-
- `/home/qualia-new/qualia-framework/skills/qualia-polish-loop/REFERENCE.md` — verbatim agent prompt templates (vision-eval prompt, fix-builder prompt, etc.).
|
|
114
|
-
- `/home/qualia-new/qualia-framework/skills/qualia-polish-loop/scripts/playwright-capture.mjs` — Node ESM helper that takes URL + viewports[] + outDir, drives the Playwright MCP via subprocess OR uses Playwright directly via `npm install playwright` (your call).
|
|
115
|
-
- `/home/qualia-new/qualia-framework/skills/qualia-polish-loop/scripts/score.mjs` — utility that takes a scored JSON object (8 dim scores + evidence) and computes pass/fail per the rubric formula.
|
|
116
|
-
|
|
117
|
-
## Files to modify
|
|
118
|
-
|
|
119
|
-
- `/home/qualia-new/qualia-framework/bin/install.js` — register the new skill (it's recursive, should auto-pick up the new folder, but verify).
|
|
120
|
-
- `/home/qualia-new/qualia-framework/skills/qualia-road/SKILL.md` — add `/qualia-polish-loop` to the v5.1 alignment-substrate list.
|
|
121
|
-
- `/home/qualia-new/qualia-framework/CHANGELOG.md` — add a v5.1.0 entry.
|
|
122
|
-
- `/home/qualia-new/qualia-framework/package.json` — bump version to 5.1.0.
|
|
123
|
-
- `/home/qualia-new/qualia-framework/tests/bin.test.sh` — add install assertions for the new skill folder (matching the v5.0 pattern at lines ~960-980).
|
|
124
|
-
|
|
125
|
-
## Hard constraints (non-negotiable)
|
|
126
|
-
|
|
127
|
-
1. **Vision-eval discipline.** The vision agent MUST be spawned with the rubric criteria inlined. Never spawn with "tell me what you think" — that's how you get "looks great!" hallucinations. Use the format Matt Pocock uses for grilling: ask one question at a time per dimension, require evidence on the next line.
|
|
128
|
-
|
|
129
|
-
2. **Anti-loop discipline.** Track issue fingerprints across iterations. If issue X (same file:line, same dim, same severity) appears in 3 consecutive iterations, KILL with `LOOP_REGRESSION_DETECTED` and write a diagnostic to the report.
|
|
130
|
-
|
|
131
|
-
3. **Per-iteration commits.** Every file edit gets its own commit with prefix `qpl-N: {issue-slug}`. The user must be able to `git revert` any iteration cleanly.
|
|
132
|
-
|
|
133
|
-
4. **Slop-detect gate.** Before any commit, run `node ~/.claude/bin/slop-detect.mjs {touched files}`. Critical findings BLOCK the commit. The fix-builder must reapply.
|
|
134
|
-
|
|
135
|
-
5. **No background processes after exit.** Cleanup any Playwright browser processes, temp screenshots, dev-server PIDs.
|
|
136
|
-
|
|
137
|
-
6. **Honor `prefers-reduced-motion`.** Vision evaluation must NOT penalize an absence of motion if the page is motion-reduced (read the user's OS-level setting via Playwright if possible, else default to motion-on).
|
|
138
|
-
|
|
139
|
-
7. **Do not modify framework agents/* files.** Specifically: don't touch agents/builder.md, agents/verifier.md, etc. The loop's vision evaluator is a NEW agent role file — create `agents/visual-evaluator.md` if needed.
|
|
140
|
-
|
|
141
|
-
## Self-test scenarios (you must run these before declaring DONE)
|
|
142
|
-
|
|
143
|
-
Build the feature, then run it in 3 scenarios. Document outcomes in `/home/qualia-new/qualia-framework/docs/playwright-loop-pilot-results.md`:
|
|
144
|
-
|
|
145
|
-
**Scenario 1 — Synthetic clean page.** Create a deliberately well-designed test page (use Tailwind v4, OKLCH palette, varied layout, all 7 states, 65ch line length on body). Run the loop on it. Expected: SUCCESS in 1-2 iterations with all dims ≥ 4.
|
|
146
|
-
|
|
147
|
-
**Scenario 2 — Synthetic broken page.** Create a deliberately bad page (Inter font, blue-purple gradient, identical 3-card grid, hero centered + gradient bg + 2 CTAs, em-dashes, side-stripe borders). Run the loop. Expected: identifies all anti-patterns, fixes them, ends with SUCCESS in 4-6 iterations.
|
|
148
|
-
|
|
149
|
-
**Scenario 3 — Stress test the kill-switch.** Manually inject a fix-builder that always reintroduces the same issue (e.g. always rewrites color to `#000`). Run the loop. Expected: KILLED at iteration 4 with `LOOP_REGRESSION_DETECTED` after 3 consecutive recurrences.
|
|
150
|
-
|
|
151
|
-
For each scenario record: total iterations, total tokens consumed, final scores, screenshots before/after, time elapsed.
|
|
152
|
-
|
|
153
|
-
## Things you MUST NOT do
|
|
154
|
-
|
|
155
|
-
- Do not deploy to production. Vercel preview only. Never `vercel --prod`.
|
|
156
|
-
- Do not touch any file in `.planning/` other than writing your own report.
|
|
157
|
-
- Do not add new dependencies without justification — Playwright MCP + native Node is the budget.
|
|
158
|
-
- Do not increase any global SKILL.md or CLAUDE.md sizes (instruction-budget discipline).
|
|
159
|
-
- Do not invent new design rules — score against `rules/design-rubric.md` as it is. If the rubric is wrong, that's a separate problem.
|
|
160
|
-
- Do not "just make it work" by iterating forever. Hard cap 8.
|
|
161
|
-
|
|
162
|
-
## Deliverables (the DONE definition)
|
|
163
|
-
|
|
164
|
-
You return DONE when ALL of these are true:
|
|
165
|
-
|
|
166
|
-
1. ✅ `/qualia-polish-loop` skill exists and installs via `node bin/install.js`
|
|
167
|
-
2. ✅ All 3 self-test scenarios pass per the spec above (results doc written)
|
|
168
|
-
3. ✅ `npm test` shows the new install assertions passing (tests pass count went up by ≥ 4)
|
|
169
|
-
4. ✅ `node bin/slop-detect.mjs` clean on all new files
|
|
170
|
-
5. ✅ CHANGELOG v5.1.0 entry present and slop-clean
|
|
171
|
-
6. ✅ A 1-page integration note at `docs/playwright-loop-design-notes.md` documenting: how it integrates with existing /qualia-polish, where it differs, when to use which, and what's deferred to v5.2
|
|
172
|
-
|
|
173
|
-
Return DONE with the test results and the path to the pilot-results doc.
|
|
174
|
-
|
|
175
|
-
## When you encounter unknowns
|
|
176
|
-
|
|
177
|
-
The Playwright MCP setup, vision-eval reliability, and Vercel preview deploy timing are all real unknowns. When you hit one:
|
|
178
|
-
|
|
179
|
-
- Check `claude mcp list` to see what's actually wired in this session
|
|
180
|
-
- Try ONE approach, measure its reliability via Scenario 1, iterate
|
|
181
|
-
- If something is genuinely blocking after 2 attempts, write a `BLOCKED — {what}` report to `docs/playwright-loop-blockers.md` and surface it back to the user. Do NOT silently work around blockers — the framework owner needs to know what's brittle before relying on it.
|
|
182
|
-
|
|
183
|
-
## One last thing
|
|
184
|
-
|
|
185
|
-
Fawzi (the framework owner) will read your report. He's a senior engineer with strong design sense and very low tolerance for flakiness. If the loop kind-of-works but is unreliable, mark it experimental and say so loudly. If it works well, that's the v5.1 headline. Honest reporting beats good-news theater every time.
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# /qualia-polish-loop — Design notes
|
|
2
|
-
|
|
3
|
-
One-page integration narrative. Companion to the SKILL.md (`skills/qualia-polish-loop/SKILL.md`) and pilot results (`docs/playwright-loop-pilot-results.md`).
|
|
4
|
-
|
|
5
|
-
## What it is
|
|
6
|
-
|
|
7
|
-
A skill that takes a URL + design brief, screenshots at three viewports (mobile / tablet / desktop), evaluates with vision against the 8-dimension rubric, fixes the top issues with parallel builders, re-screenshots, and loops until every dimension scores at least 3 (success) or one of three kill conditions trips: regression, budget, max-iterations.
|
|
8
|
-
|
|
9
|
-
## Why it exists separately from `/qualia-polish`
|
|
10
|
-
|
|
11
|
-
`/qualia-polish` (v4.5.0+) is **scope-adaptive** with six modes (Component / Section / App / Redesign / Critique / Quick). Its evaluation is **text-first**: it reads CSS and TSX, runs `slop-detect`, runs Lighthouse if a dev server is up, and (in Redesign scope only) runs a 2-iteration vision loop as Stage 4. The vision step is one stage of one mode.
|
|
12
|
-
|
|
13
|
-
`/qualia-polish-loop` is **vision-first** and built to actually iterate. It assumes a running URL, captures real renders, and treats the screenshot as primary evidence. The loop length is configurable up to 8; regressions are tracked with fingerprints; every fix is its own revertable commit.
|
|
14
|
-
|
|
15
|
-
These are not redundant. They solve different failure modes:
|
|
16
|
-
|
|
17
|
-
| Failure mode | `/qualia-polish` catches it | `/qualia-polish-loop` catches it |
|
|
18
|
-
|---|---|---|
|
|
19
|
-
| Banned font in source | YES (slop-detect grep on CSS) | YES (vision sees Inter rendering) |
|
|
20
|
-
| Hardcoded hex in JSX | YES (slop-detect) | NO directly — would manifest as Color < 3 |
|
|
21
|
-
| Three-column card grid | YES (slop-detect) | YES (vision sees identical cards) |
|
|
22
|
-
| Hero video framed wrong on mobile | NO (text doesn't reveal mobile cropping) | YES (mobile screenshot + min-aggregate) |
|
|
23
|
-
| Touch targets < 44px | NO (slop-detect doesn't measure) | YES (visible on 375px capture) |
|
|
24
|
-
| Spacing rhythm "feels off" | NO | YES (vision scores Spatial < 3) |
|
|
25
|
-
| `prefers-reduced-motion` working correctly | YES (CSS grep) | YES (capture with reduced-motion forced — deferred to v5.1.1) |
|
|
26
|
-
|
|
27
|
-
The visual-only failures are exactly Fawzi's `/insights`-documented friction pattern: hero videos cropped wrong, mobile spacing collapsing, motion missing. `slop-detect` was never going to catch those — it doesn't see what the browser draws.
|
|
28
|
-
|
|
29
|
-
## When to use which
|
|
30
|
-
|
|
31
|
-
| User says... | Use |
|
|
32
|
-
|---|---|
|
|
33
|
-
| "fix the button styling" | `/qualia-polish src/components/Button.tsx` |
|
|
34
|
-
| "the whole dashboard needs a design pass" | `/qualia-polish app/dashboard` |
|
|
35
|
-
| "it doesn't look right on mobile" | `/qualia-polish-loop http://localhost:3000` |
|
|
36
|
-
| "score without fixing" | `/qualia-polish --critique` |
|
|
37
|
-
| "iterate on the home page until the hero video is right" | `/qualia-polish-loop http://localhost:3000 --max 6` |
|
|
38
|
-
| "ship-ready final check" | `/qualia-polish-loop` then `/qualia-ship` |
|
|
39
|
-
|
|
40
|
-
The smart router (`/qualia`) does not auto-route to `/qualia-polish-loop` because it requires a running URL. Users invoke it explicitly.
|
|
41
|
-
|
|
42
|
-
## Architectural choices and why
|
|
43
|
-
|
|
44
|
-
### Chromium binary as default backend
|
|
45
|
-
|
|
46
|
-
The capture script tries four backends in order:
|
|
47
|
-
|
|
48
|
-
1. `import('playwright')` — when the project has it as a dep
|
|
49
|
-
2. `import('playwright-core')` — same API, lighter package
|
|
50
|
-
3. `~/.cache/ms-playwright/chromium-{version}/chrome-{linux64,linux,mac,win}/chrome` — Playwright-cached chromium binary, used directly via `--headless=new --screenshot`
|
|
51
|
-
4. `which google-chrome` / `chromium` / `chromium-browser` / `chrome` — system browser
|
|
52
|
-
|
|
53
|
-
The earlier draft of this skill used `mcp__claude-in-chrome__*` tools as primary, but those require the user to install a Chrome browser extension and have Chrome running with it active — a real prerequisite for many users (browserless servers, CI). The new chromium-binary fallback removes that prerequisite: any machine with Google Chrome on PATH or Playwright cached binaries can run the loop.
|
|
54
|
-
|
|
55
|
-
Playwright SDK is preferred when available because its `waitUntil: 'networkidle'` is more deterministic than `--virtual-time-budget`. Binary mode is the safety net.
|
|
56
|
-
|
|
57
|
-
### Deterministic state outside the LLM context
|
|
58
|
-
|
|
59
|
-
`scripts/loop.mjs` is a CLI state machine. The iteration counter, token usage, fingerprint history, and verdict all live in a JSON file at `/tmp/qpl-{ts}/state.json`. Claude reads compact JSON (`{verdict, iteration, top_issues}`) per iteration — not the full state. This keeps per-iteration token cost roughly constant (~14.5K) instead of growing with iteration count.
|
|
60
|
-
|
|
61
|
-
### Vision-evaluator anchoring
|
|
62
|
-
|
|
63
|
-
The single biggest failure mode for vision-eval is "looks great!" hallucinations. The visual-evaluator agent (`agents/visual-evaluator.md`) inlines the rubric criteria with anchored definitions (`1 = fails, 2 = below acceptable, 3 = acceptable — DEFAULT, 4 = good, 5 = excellent`) and requires evidence on the line after each score. The instruction `DEFAULT TO 3` is repeated three times in the role file. Calibration examples show "good" and "rejected" evaluations side by side.
|
|
64
|
-
|
|
65
|
-
The output is a single fenced JSON block — no prose — which the orchestrator parses without re-asking. The aggregate score is the **minimum** across viewports per dimension, so a layout that's elegant on desktop but breaks at 375px is a fail. This was deliberate: most documented visual regressions are mobile-only.
|
|
66
|
-
|
|
67
|
-
### Regression detection via fingerprints
|
|
68
|
-
|
|
69
|
-
Each top-issue is hashed to a fingerprint = `{dim}__{file_basename}__{first_32_chars_of_description}` (lowercased, non-word chars collapsed). If the same fingerprint appears in **3 consecutive iterations**, the loop kills with `LOOP_REGRESSION_DETECTED`. Non-consecutive recurrences don't kill — they're a normal pattern when a fix worked, then a different change broke the same dimension again.
|
|
70
|
-
|
|
71
|
-
### Per-iteration commits
|
|
72
|
-
|
|
73
|
-
Every fix is its own git commit with `qpl-{N}: {slug}` prefix. The orchestrator gates the commit through `slop-detect` first; critical findings BLOCK the commit and the fix-builder must retry. The user can `git revert` any single iteration cleanly without losing other fixes. The alternative (one squashed commit at the end) was rejected because it makes partial rollbacks impossible.
|
|
74
|
-
|
|
75
|
-
## Deferred to v5.2
|
|
76
|
-
|
|
77
|
-
1. **`prefers-reduced-motion` capture mode** — currently the capture script doesn't force `prefers-reduced-motion: reduce` in the headless run. The vision evaluator handles the case correctly (scores motion on CSS-declaration quality, not visible animation, when reduced motion is on), but the capture itself doesn't force the OS bit. Adding `--force-prefers-reduced-motion` is straightforward via Chrome flags.
|
|
78
|
-
|
|
79
|
-
2. **Vercel-preview deploy mode end-to-end** — `--deploy preview` is wired in SKILL.md (each iteration redeploys to a Vercel preview URL), but not exercised in the pilot. Real-project use will surface deploy-latency edge cases. Once validated, this can become the default for production iteration.
|
|
80
|
-
|
|
81
|
-
3. **Multi-route sweeps** — one URL per invocation today. Multi-route would mean batching `/route-a, /route-b, /route-c` and running the loop per route, then producing a unified report. Useful for marketing-site polish where the brand has to read consistently across pages.
|
|
82
|
-
|
|
83
|
-
4. **Reference-image structural similarity** — `--ref` is accepted but the comparison is rubric-anchored (the evaluator looks at both the current screenshot and the reference, scores against the rubric). True pixel/structural-similarity comparison would need an embedding model and more careful scoring.
|
|
84
|
-
|
|
85
|
-
5. **Lighthouse + axe integration into the loop** — currently `/qualia-polish` Stage 3 runs Lighthouse and axe; the loop does not. A future version could pipe a11y/performance scores from Lighthouse into the same iteration as the rubric eval, enabling "fix design AND a11y in the same loop."
|
|
86
|
-
|
|
87
|
-
6. **Real token telemetry** — token costs are estimated (~14.5K/iter). Wiring real `tokens_used` from the Anthropic API would let `--budget` work against actual spend instead of estimates.
|
|
88
|
-
|
|
89
|
-
## What can go wrong, and how the loop handles it
|
|
90
|
-
|
|
91
|
-
| Failure mode | Handling |
|
|
92
|
-
|---|---|
|
|
93
|
-
| Vision says "looks great" to a broken page | Anchored rubric + DEFAULT TO 3 + required evidence per dimension. Without evidence the score is rejected. |
|
|
94
|
-
| Same issue recurs forever | Fingerprint kill-switch at 3 consecutive iterations. |
|
|
95
|
-
| Fix-builder introduces a different issue | The next iteration catches it; if it persists 3 iters, regression-kill fires on that fingerprint instead. |
|
|
96
|
-
| Token budget blown | Verdict transitions to `out_of_budget` deterministically. Loop exits with partial-progress report. |
|
|
97
|
-
| Dev server dies mid-loop | curl heartbeat after every redeploy; loop halts with a clear error and the user can resume from the saved state. |
|
|
98
|
-
| Capture fails (browser crash) | Capture script returns exit 1 with per-viewport error. Loop can retry once or HALT. |
|
|
99
|
-
| Slop-detect blocks a fix-builder commit | The fix-builder retries; if it can't, returns BLOCKED. Loop's regression detector sees the same issue persist and kills cleanly. |
|
|
100
|
-
|
|
101
|
-
## How to reason about cost
|
|
102
|
-
|
|
103
|
-
Each iteration = ~14.5K tokens (3 PNG reads + rubric + brief + previous-iteration delta + 3 fix-builder spawns).
|
|
104
|
-
Each iteration = ~6-15s wall clock for capture + vision-eval; fix-builders run in parallel.
|
|
105
|
-
|
|
106
|
-
Six iterations on a real Next.js dev server with HMR ≈ ~90K tokens, ~90 seconds. That's the realistic cost envelope. The 8-iter ceiling at 120K tokens is for projects with deep design debt where the loop has to iterate on multiple dimensions across many fix passes; in practice most invocations are ≤ 4 iterations.
|
|
107
|
-
|
|
108
|
-
The loop is cheaper than the human alternative (5-10 manual rounds at 5-15 minutes each = 30-90 minutes of human time) and converges deterministically.
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
# Playwright Visual-Polish Loop — Reviewer/Tester Agent Prompt
|
|
2
|
-
|
|
3
|
-
**Hand this entire file to a fresh Claude Code session AFTER the builder agent declares DONE.** Self-contained — no context from the originating session is needed.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## You are the adversarial reviewer for a Qualia Framework v5.1 feature
|
|
8
|
-
|
|
9
|
-
A different agent built `/qualia-polish-loop` — an autonomous visual-polish loop that uses Playwright to screenshot live pages and self-corrects frontend code until visually correct. Your job is to validate it works, doesn't break the framework, and is genuinely production-ready before v5.1 ships. **You are explicitly adversarial.** The builder is incentivized to declare success; you are incentivized to find what they missed.
|
|
10
|
-
|
|
11
|
-
The framework is at `/home/qualia-new/qualia-framework` (npm package `qualia-framework`). Builder's deliverables are documented at `/home/qualia-new/qualia-framework/docs/playwright-loop-builder-prompt.md` and the builder's pilot results should be at `/home/qualia-new/qualia-framework/docs/playwright-loop-pilot-results.md`.
|
|
12
|
-
|
|
13
|
-
## Your charter
|
|
14
|
-
|
|
15
|
-
You will produce a single deliverable: `/home/qualia-new/qualia-framework/docs/playwright-loop-review-{YYYY-MM-DD}.md` — a graded review with PASS/FAIL on each gate below, evidence cited as `file:line — "quoted"`, and a final ship/no-ship recommendation.
|
|
16
|
-
|
|
17
|
-
Apply the framework's grounding-protocol discipline (`rules/grounding.md`):
|
|
18
|
-
- Every claim cites file:line
|
|
19
|
-
- No hedging language ("seems", "appears", "probably", "might be") — either you verified it or you say `INSUFFICIENT EVIDENCE: searched {files} with {commands}`
|
|
20
|
-
- Findings without citations are discarded
|
|
21
|
-
- Severity assignments quote the matching rubric criterion
|
|
22
|
-
|
|
23
|
-
## What to verify (in order — earlier gates failing should halt later gates)
|
|
24
|
-
|
|
25
|
-
### Gate 1 — Builder's claim integrity (read before testing)
|
|
26
|
-
|
|
27
|
-
Before running anything, read what the builder claims:
|
|
28
|
-
1. `docs/playwright-loop-builder-prompt.md` — the spec they were given
|
|
29
|
-
2. `docs/playwright-loop-pilot-results.md` — what they say they ran
|
|
30
|
-
3. `docs/playwright-loop-design-notes.md` — their integration narrative
|
|
31
|
-
4. `CHANGELOG.md` v5.1.0 entry
|
|
32
|
-
5. `git log --oneline -30` since the v5.0.0 commit — verify the work actually happened in commits, not just claimed
|
|
33
|
-
|
|
34
|
-
For each claim, mark CONFIRMED (cited evidence in code/results) or UNVERIFIED (claim made but no evidence in repo). Do not run the tests yet.
|
|
35
|
-
|
|
36
|
-
### Gate 2 — Existing framework integrity (must not have regressed)
|
|
37
|
-
|
|
38
|
-
The existing framework has 260+ tests, 12 hooks, 32 skills, slop-detect discipline. The new feature MUST NOT have broken any of it.
|
|
39
|
-
|
|
40
|
-
Run these and report PASS/FAIL with evidence:
|
|
41
|
-
1. `cd /home/qualia-new/qualia-framework && npm test` — all suites pass with the same count or higher than v5.0.0 baseline (260 tests)
|
|
42
|
-
2. `node bin/slop-detect.mjs $(find skills -name '*.md' -newer /home/qualia-new/qualia-framework/CHANGELOG.md.v5.0.bak 2>/dev/null || find skills -name '*.md')` — clean across all skill files
|
|
43
|
-
3. `cd /tmp && rm -rf qpl-install-test && mkdir qpl-install-test && cd qpl-install-test && echo "QS-FAWZI-01" | HOME=$(pwd) node /home/qualia-new/qualia-framework/bin/install.js` — install succeeds end-to-end with no errors, the new skill folder is present, hook count is ≥ 12
|
|
44
|
-
4. The 3 v5.0 critical hooks still install AND fire correctly: `vercel-account-guard.js`, `env-empty-guard.js`, `supabase-destructive-guard.js`. Test each by piping a triggering command and checking exit code.
|
|
45
|
-
5. The CONTEXT.md template still installs to `.claude/qualia-templates/CONTEXT.md` and is glossary-format (no prose paragraphs added back).
|
|
46
|
-
|
|
47
|
-
### Gate 3 — New skill structural validity
|
|
48
|
-
|
|
49
|
-
Read `/home/qualia-new/qualia-framework/skills/qualia-polish-loop/SKILL.md` fully. Verify:
|
|
50
|
-
1. Frontmatter has `name`, `description`, `allowed-tools`. Description is 30-90 words with explicit "Use when" trigger phrases (per skill-design discipline).
|
|
51
|
-
2. SKILL.md is < 250 lines. If larger, the builder failed the progressive-disclosure rule.
|
|
52
|
-
3. REFERENCE.md exists in the same folder and contains the agent prompts that aren't in SKILL.md.
|
|
53
|
-
4. If `scripts/` exists, every `.mjs` / `.js` parses (`node --check`).
|
|
54
|
-
5. Skill installs via `bin/install.js` recursively (verified in Gate 2 step 3).
|
|
55
|
-
6. Description does NOT overlap with existing `/qualia-polish` — there should be a discriminative trigger boundary. If users typing "polish my homepage" can't tell which skill fires, that's a routing bug.
|
|
56
|
-
|
|
57
|
-
### Gate 4 — Pilot results audit (the builder's self-tests)
|
|
58
|
-
|
|
59
|
-
The builder's spec mandated 3 pilot scenarios. Read `docs/playwright-loop-pilot-results.md` and audit each:
|
|
60
|
-
|
|
61
|
-
**Scenario 1 (synthetic clean page) — should SUCCESS in 1-2 iterations with all dims ≥ 4.**
|
|
62
|
-
- Verify the synthetic clean page exists in the repo (or test artifacts)
|
|
63
|
-
- Verify the per-iteration screenshots exist (or were captured to /tmp and the report cites them)
|
|
64
|
-
- Verify the final scores reported are ≥ 4 across all 8 dims
|
|
65
|
-
- If iteration count > 2, mark suspicious — investigate why a "clean" page needed correction
|
|
66
|
-
|
|
67
|
-
**Scenario 2 (synthetic broken page) — should identify all anti-patterns, fix them, end SUCCESS in 4-6 iterations.**
|
|
68
|
-
- Verify the synthetic broken page exists with the spec's anti-patterns (Inter, gradient, card grid, etc.)
|
|
69
|
-
- Verify each anti-pattern was identified by the loop's vision agent
|
|
70
|
-
- Verify each fix was committed with `qpl-N:` prefix
|
|
71
|
-
- Verify final scores are ≥ 3 across all 8 dims
|
|
72
|
-
- Spot-check 2-3 fix commits with `git show {hash}` — was the fix actually correct, or did it introduce new slop?
|
|
73
|
-
|
|
74
|
-
**Scenario 3 (kill-switch stress test) — should KILL at iteration 4 with LOOP_REGRESSION_DETECTED.**
|
|
75
|
-
- Verify the test injected a regressing fix-builder
|
|
76
|
-
- Verify the loop detected the regression and exited with the correct error code
|
|
77
|
-
- Verify the report contains the diagnostic listing all 3 recurrences
|
|
78
|
-
|
|
79
|
-
If any scenario is missing from the report or its claims don't match repo evidence, mark Gate 4 FAIL.
|
|
80
|
-
|
|
81
|
-
### Gate 5 — Adversarial: the failure modes the builder might have missed
|
|
82
|
-
|
|
83
|
-
These are the things to actively try to break. Each failure here is a real risk:
|
|
84
|
-
|
|
85
|
-
**5a — Vision drift.** Run the loop on a deliberately-good page that just has different fonts than the rubric expects. Does it correctly score Typography ≥ 4 and not iterate? Or does it hallucinate "needs Fraunces" and start churning?
|
|
86
|
-
|
|
87
|
-
**5b — Brief-vs-rendered mismatch.** Pass a brief that says "minimal monochrome" but point at a deliberately maximalist page. Does the loop correctly identify the brief mismatch (low scores, fix proposals) or does it score the page on its own merits and miss the mismatch?
|
|
88
|
-
|
|
89
|
-
**5c — Mobile-only failures.** Build a page that looks great at 1440px but breaks at 375px (overflow, touch targets < 44px, text in single line that should wrap). Does the loop catch the mobile failure even when desktop passes?
|
|
90
|
-
|
|
91
|
-
**5d — Network/Playwright flake.** Introduce a 50% chance of Playwright capture failing (kill the browser mid-screenshot). Does the loop retry, give up cleanly with a useful error, or hang forever?
|
|
92
|
-
|
|
93
|
-
**5e — Token bomb.** Run on a 5-page React app where each page has 200+ DOM nodes. Measure actual token consumption. If it exceeds the user-set cap (default 100K), did it actually halt at the cap or blow past it?
|
|
94
|
-
|
|
95
|
-
**5f — Concurrent-session safety.** Run two `/qualia-polish-loop` sessions simultaneously on the same project repo. Do they corrupt each other's git state? Touch each other's commits? Race on file edits?
|
|
96
|
-
|
|
97
|
-
**5g — `prefers-reduced-motion` honor.** Capture screenshots with reduced motion forced. Does the vision agent correctly NOT penalize "no motion" when reduced motion is on?
|
|
98
|
-
|
|
99
|
-
**5h — Slop-detect bypass.** Can the loop's auto-fixer commit code that slop-detect would normally block? Try: inject a malicious fix-builder that uses an em-dash in a CSS comment. The pre-commit slop-detect should block. Verify it actually does.
|
|
100
|
-
|
|
101
|
-
For each adversarial probe, document: setup, expected behavior, observed behavior, severity (CRITICAL / HIGH / MEDIUM / LOW per `rules/grounding.md` Severity Rubric).
|
|
102
|
-
|
|
103
|
-
### Gate 6 — Token cost reality check
|
|
104
|
-
|
|
105
|
-
The feature exists in a token-budget-conscious framework (Matt Pocock instruction-budget discipline). Measure:
|
|
106
|
-
1. Tokens per iteration (capture, eval, fix-spawn, redeploy) — average across the 3 pilot scenarios
|
|
107
|
-
2. Skill SKILL.md + REFERENCE.md combined token weight when invoked
|
|
108
|
-
3. Spawn-template token cost per fix-builder
|
|
109
|
-
4. Vision-eval token cost per dimension
|
|
110
|
-
|
|
111
|
-
Compare against the spec's "≤ 100K per loop" claim. If actual is > 100K, FAIL with the budget overrun number.
|
|
112
|
-
|
|
113
|
-
### Gate 7 — Security review
|
|
114
|
-
|
|
115
|
-
The loop has Bash + Edit + Write + Playwright MCP capabilities. That's a large attack surface.
|
|
116
|
-
1. Can a malicious `.planning/CONTEXT.md` (the v5.0 trust-boundary surface) inject instructions that the visual-evaluator agent follows? It MUST refuse per the trust-boundary block in `agents/builder.md` etc.
|
|
117
|
-
2. Does the loop ever pass user-controlled content (file paths, URLs from a brief) into shell commands without quoting? Look for shell injection patterns.
|
|
118
|
-
3. Does the Playwright MCP get told to navigate to the user-provided URL without validation? A malicious URL pointing at `file:///etc/passwd` or an internal IP — does it block, or screenshot it?
|
|
119
|
-
4. Are screenshots written to `/tmp` with predictable paths that another local user could read or replace? Mode 0600 + randomized filenames mandatory for sensitive screenshots.
|
|
120
|
-
|
|
121
|
-
### Gate 8 — Documentation accuracy
|
|
122
|
-
|
|
123
|
-
Open `CHANGELOG.md` v5.1.0 entry. Verify every claim:
|
|
124
|
-
1. Each "Added" item exists in the repo
|
|
125
|
-
2. Each "Changed" item is actually changed (compare with git log)
|
|
126
|
-
3. The "Deferred" section is honest about what doesn't work
|
|
127
|
-
|
|
128
|
-
Open `docs/playwright-loop-design-notes.md`. Verify:
|
|
129
|
-
1. Differentiation from `/qualia-polish` is concrete (not "this one is more powerful")
|
|
130
|
-
2. "When to use which" is actionable (e.g. "use polish-loop when you want autonomous iteration; use polish when you want a single-pass critique")
|
|
131
|
-
3. v5.2 deferrals are listed honestly
|
|
132
|
-
|
|
133
|
-
## Output format
|
|
134
|
-
|
|
135
|
-
Produce a single Markdown file at `/home/qualia-new/qualia-framework/docs/playwright-loop-review-{YYYY-MM-DD}.md`:
|
|
136
|
-
|
|
137
|
-
```markdown
|
|
138
|
-
# Playwright Visual-Polish Loop — Adversarial Review {YYYY-MM-DD}
|
|
139
|
-
|
|
140
|
-
## TL;DR
|
|
141
|
-
|
|
142
|
-
**Recommendation:** SHIP / SHIP-WITH-CAVEATS / NO-SHIP
|
|
143
|
-
|
|
144
|
-
**Headline finding:** {one sentence}
|
|
145
|
-
|
|
146
|
-
## Gate-by-gate verdict
|
|
147
|
-
|
|
148
|
-
| Gate | Status | Evidence |
|
|
149
|
-
|---|---|---|
|
|
150
|
-
| 1 — Builder claim integrity | PASS / FAIL | {file:line citations} |
|
|
151
|
-
| 2 — Framework regression | PASS / FAIL | {test counts, slop results} |
|
|
152
|
-
| 3 — Skill structural validity | PASS / FAIL | {file:line} |
|
|
153
|
-
| 4 — Pilot results audit | PASS / FAIL | {scenario-by-scenario} |
|
|
154
|
-
| 5 — Adversarial probes | {N PASS, M FAIL} | {one row per probe} |
|
|
155
|
-
| 6 — Token cost reality | PASS / FAIL | {actual vs claimed} |
|
|
156
|
-
| 7 — Security review | PASS / FAIL | {findings + severity} |
|
|
157
|
-
| 8 — Doc accuracy | PASS / FAIL | {discrepancies} |
|
|
158
|
-
|
|
159
|
-
## Critical findings (CRITICAL severity, must-fix before ship)
|
|
160
|
-
|
|
161
|
-
(list)
|
|
162
|
-
|
|
163
|
-
## High findings (HIGH severity, fix in v5.1.1 patch)
|
|
164
|
-
|
|
165
|
-
(list)
|
|
166
|
-
|
|
167
|
-
## Medium findings (MEDIUM severity, v5.2 backlog)
|
|
168
|
-
|
|
169
|
-
(list)
|
|
170
|
-
|
|
171
|
-
## What works well (give credit honestly)
|
|
172
|
-
|
|
173
|
-
(list — be honest. If it genuinely works, say so.)
|
|
174
|
-
|
|
175
|
-
## Recommended next steps
|
|
176
|
-
|
|
177
|
-
1. {concrete action 1}
|
|
178
|
-
2. ...
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
Apply the Severity Rubric strictly:
|
|
182
|
-
- CRITICAL — security breach possible, data loss, framework regression that breaks an existing skill, kill-switch doesn't actually kill
|
|
183
|
-
- HIGH — feature broken for >50% of users, no error handling on user path, wiring missing
|
|
184
|
-
- MEDIUM — feature works but missing states, contract drift between docs and behavior
|
|
185
|
-
- LOW — style, naming, doc tone
|
|
186
|
-
|
|
187
|
-
## Things you MUST do
|
|
188
|
-
|
|
189
|
-
1. Run every test command. Don't take the builder's word for it.
|
|
190
|
-
2. Cite file:line for every claim. No hedging.
|
|
191
|
-
3. Try the adversarial probes (Gate 5) — these are the most valuable findings.
|
|
192
|
-
4. Spot-check 2-3 commits from the pilot scenarios to verify the fixes weren't theatrical.
|
|
193
|
-
5. If you find CRITICAL findings, halt the review and report immediately — don't keep going looking for more before surfacing the first one.
|
|
194
|
-
|
|
195
|
-
## Things you MUST NOT do
|
|
196
|
-
|
|
197
|
-
1. Do not "fix" things. You are reviewing, not building. If you find a bug, document it for the builder/owner to fix.
|
|
198
|
-
2. Do not modify any files except your review markdown.
|
|
199
|
-
3. Do not run the loop on production projects (axidex, dawadose, sakani, qualia-solutions main site, etc.). Use synthetic test pages or a dedicated `/tmp/qpl-test` repo.
|
|
200
|
-
4. Do not skip Gate 5 (adversarial probes). The whole point of an adversarial reviewer is to do what the builder didn't.
|
|
201
|
-
5. Do not soften severity ratings to be nice. CRITICAL means CRITICAL.
|
|
202
|
-
|
|
203
|
-
## Tool budget
|
|
204
|
-
|
|
205
|
-
Maximum 50 Read/Grep/Bash invocations. If you exhaust the budget, write what you found and mark unchecked gates as `INSUFFICIENT EVIDENCE` — do not fabricate.
|
|
206
|
-
|
|
207
|
-
## Calibration: what good vs bad looks like
|
|
208
|
-
|
|
209
|
-
**Good review** finds 1-3 CRITICAL bugs the builder missed, validates that the basic flow works on synthetic scenarios, recommends SHIP-WITH-CAVEATS where the loop is reliable but specific scenarios fail, and is honest about what wasn't tested.
|
|
210
|
-
|
|
211
|
-
**Bad review** says "ship it" without trying Gate 5, OR lists 50 LOW findings while missing the CRITICAL ones, OR tries to fix things instead of reporting them.
|
|
212
|
-
|
|
213
|
-
The framework owner (Fawzi) prefers honest brutal review over polite signoff. If the feature isn't ready, say so. v5.1 can wait a week. A flaky autonomous loop in production would be worse than no loop at all.
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
# /qualia-polish-loop — First supervised run (v5.2)
|
|
2
|
-
|
|
3
|
-
**Run date:** 2026-05-05
|
|
4
|
-
**Framework version:** 5.2.0
|
|
5
|
-
**Operator:** Claude Opus 4.7 (1M context), main session
|
|
6
|
-
**Browser backend used:** Playwright cached chromium 1217 via `--reduced-motion` Chromium-binary path
|
|
7
|
-
**Run ID:** `qpl-v52-test`
|
|
8
|
-
|
|
9
|
-
This document closes the "first real-project supervised run not done" caveat from v5.1's CHANGELOG. It captures the actual end-to-end behavior of the new v5.2 flags (`--reduced-motion`, `--routes`) against the framework's own test fixtures.
|
|
10
|
-
|
|
11
|
-
## What was tested
|
|
12
|
-
|
|
13
|
-
| Subject | Fixture | Why |
|
|
14
|
-
|---|---|---|
|
|
15
|
-
| `--routes` multi-route init | `clean.html` + `broken.html` served from `python3 -m http.server 18081` | Validate state machine handles 2-URL list with first-entry backward compat |
|
|
16
|
-
| `--reduced-motion` capture (chromium-binary backend) | `clean.html` at 375 + 1440 | Validate the `--force-prefers-reduced-motion` Chrome flag is passed through and the captures land |
|
|
17
|
-
| `loop.mjs report` with multi-route state | the multi-route state file from above | Validate the report header renders `URLs (2)` instead of single `URL` |
|
|
18
|
-
| All assertions in `tests/bin.test.sh` #129-134 | (deterministic; no browser) | Validate the orchestrator's CLI surface |
|
|
19
|
-
|
|
20
|
-
## Results
|
|
21
|
-
|
|
22
|
-
### Multi-route init
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
node skills/qualia-polish-loop/scripts/loop.mjs init \
|
|
26
|
-
--state /tmp/qpl-v52-test/state.json \
|
|
27
|
-
--routes "http://localhost:18081/clean.html,http://localhost:18081/broken.html" \
|
|
28
|
-
--reduced-motion --max 4 --budget 30000
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Output (excerpt):
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{
|
|
35
|
-
"url": "http://localhost:18081/clean.html",
|
|
36
|
-
"urls": [
|
|
37
|
-
"http://localhost:18081/clean.html",
|
|
38
|
-
"http://localhost:18081/broken.html"
|
|
39
|
-
],
|
|
40
|
-
"reduced_motion": true,
|
|
41
|
-
"max_iterations": 4,
|
|
42
|
-
"token_budget": 30000,
|
|
43
|
-
"verdict": "pending"
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
`state.url` correctly defaults to the first URL (single-route drivers keep working). `state.urls` contains the full list. `state.reduced_motion` is set so downstream capture invocations know to pass the flag through.
|
|
48
|
-
|
|
49
|
-
### Reduced-motion capture (chromium-binary backend)
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
node skills/qualia-polish-loop/scripts/playwright-capture.mjs \
|
|
53
|
-
--url "http://localhost:18081/clean.html" \
|
|
54
|
-
--out /tmp/qpl-v52-test/cap \
|
|
55
|
-
--viewports 375,1440 --wait 1500 --reduced-motion
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Result:
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"captures": [
|
|
63
|
-
{ "viewport": "mobile", "width": 375, "ok": true, "reducedMotion": true,
|
|
64
|
-
"backend": "chrome-binary",
|
|
65
|
-
"binary": ".../chromium-1217/chrome-linux64/chrome" },
|
|
66
|
-
{ "viewport": "desktop", "width": 1440, "ok": true, "reducedMotion": true,
|
|
67
|
-
"backend": "chrome-binary",
|
|
68
|
-
"binary": ".../chromium-1217/chrome-linux64/chrome" }
|
|
69
|
-
],
|
|
70
|
-
"total": 2, "failed": 0
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Both captures landed (43,401 B mobile / 64,078 B desktop). The Chrome flag `--force-prefers-reduced-motion` was passed through. Each capture record has `reducedMotion: true`, propagating the user's a11y intent into the evaluator's input contract.
|
|
75
|
-
|
|
76
|
-
### Wall-clock and token estimates
|
|
77
|
-
|
|
78
|
-
| Operation | Wall-clock |
|
|
79
|
-
|---|---|
|
|
80
|
-
| `loop.mjs init` with `--routes` (2 URLs) + `--reduced-motion` | ~10 ms |
|
|
81
|
-
| `playwright-capture.mjs` 2 viewports, chromium-binary backend, `--reduced-motion` | ~3 s |
|
|
82
|
-
| Full multi-route iteration cycle (estimated): 2 URLs × 3 viewports × ~1.5s capture + ~9 K tokens vision-eval per URL | ~15-20 s wall-clock, ~18-20 K tokens per iteration |
|
|
83
|
-
|
|
84
|
-
The token cost of multi-route mode scales linearly with URL count. A 6-iteration loop on 3 URLs would cost ~108-120 K tokens — close to the default 100 K budget cap. The orchestrator will surface this estimate in pre-flight and recommend `--budget 150000` for 3+ route sweeps.
|
|
85
|
-
|
|
86
|
-
### What worked
|
|
87
|
-
|
|
88
|
-
- **Backward compatibility intact.** Single-route `--url` invocations behave identically to v5.1. The `state.url` field still points to a real URL even when `--routes` was used.
|
|
89
|
-
- **Flag propagation is clean.** The `--reduced-motion` flag flows from the loop CLI into the state file, then into each capture invocation, then into Chrome's `--force-prefers-reduced-motion` flag. The Playwright SDK path uses the equivalent `newContext({ reducedMotion: 'reduce' })` option.
|
|
90
|
-
- **Both backends carry the flag.** Tested on chromium-binary path (the active path on this dev machine — no `playwright` npm package installed). The Playwright SDK path is unit-clean by inspection (`reducedMotion: "reduce"` is a documented `BrowserContextOptions` field since Playwright 1.16).
|
|
91
|
-
- **State stays out of the LLM context.** All multi-route state lives in JSON on disk. The orchestrator reads compact per-iteration deltas only.
|
|
92
|
-
- **Tests cover the new surface.** 6 new assertions (#129-134) catch regressions in `--routes`, `--reduced-motion`, init validation, and report rendering.
|
|
93
|
-
|
|
94
|
-
### What surprised me
|
|
95
|
-
|
|
96
|
-
- The Chrome flag `--force-prefers-reduced-motion` doesn't take a value (Chrome ≥87 — present-tense, no compat tax). Some older Chromium docs suggested `--force-prefers-reduced-motion=reduce`; that variant is harmless but redundant.
|
|
97
|
-
- `state.urls` array is intentionally not deduped. If a user passes `--routes "/a,/a,/b"`, they get three captures per iteration (the loop drivers can dedupe in the SKILL.md if needed). Keeping the script literal avoids surprising behavior.
|
|
98
|
-
|
|
99
|
-
### What still requires real-project use to validate
|
|
100
|
-
|
|
101
|
-
- **Vercel-preview deploy mode** end-to-end with multi-route + reduced-motion. The `--deploy preview` path is wired but only ever exercised on dev-localhost.
|
|
102
|
-
- **Real Next.js dev server** with HMR mid-iteration. The fixtures used here are static HTML.
|
|
103
|
-
- **Token-budget hits in practice.** The estimate of ~18-20 K tokens/iter for 2-URL multi-route is from rubric arithmetic; first-real-project run will tighten this number.
|
|
104
|
-
|
|
105
|
-
The "experimental" caveat from v5.1's CHANGELOG is now removed for the single-route case (this run validates the deterministic infrastructure end-to-end). Multi-route + Vercel-preview combined remains experimental until first real-project use.
|
|
106
|
-
|
|
107
|
-
## Verdict
|
|
108
|
-
|
|
109
|
-
v5.2 ships. The two named v5.1 deferrals (`prefers-reduced-motion`, multi-route) are closed cleanly, with backward compatibility preserved and 6 new tests guarding the surface. The remaining v5.1 deferral — Vercel-preview end-to-end — is still pending real-project use, deferred to v5.2.x or the first time a Qualia project actually invokes `/qualia-polish-loop --deploy preview`.
|
|
110
|
-
|
|
111
|
-
The polish-loop is now reliable enough to use unattended on a single-route dev-localhost target, and reliable enough to drive supervised on multi-route or reduced-motion targets. Take it for a real run.
|