qualia-framework 5.9.0 → 6.1.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/AGENTS.md +2 -1
- package/CLAUDE.md +2 -1
- package/README.md +14 -7
- package/agents/builder.md +1 -5
- package/agents/plan-checker.md +1 -1
- package/agents/planner.md +2 -6
- package/agents/qa-browser.md +3 -3
- package/agents/roadmapper.md +1 -1
- package/agents/verifier.md +7 -9
- package/agents/visual-evaluator.md +1 -3
- package/bin/cli.js +32 -6
- package/bin/slop-detect.mjs +81 -9
- package/docs/archive/CHANGELOG-pre-v4.md +855 -0
- package/docs/onboarding.html +2 -2
- package/guide.md +15 -2
- package/hooks/auto-update.js +6 -3
- package/hooks/env-empty-guard.js +5 -4
- package/hooks/pre-compact.js +5 -3
- package/hooks/pre-push.js +57 -0
- package/package.json +2 -2
- package/qualia-design/design-reference.md +2 -1
- package/qualia-design/frontend.md +4 -4
- package/rules/one-opinion.md +59 -0
- package/rules/trust-boundary.md +35 -0
- package/skills/qualia-discuss/SKILL.md +4 -2
- package/skills/qualia-feature/SKILL.md +5 -5
- package/skills/qualia-flush/SKILL.md +5 -7
- package/skills/qualia-hook-gen/SKILL.md +1 -1
- package/skills/qualia-learn/SKILL.md +1 -0
- package/skills/qualia-map/SKILL.md +1 -0
- package/skills/qualia-milestone/SKILL.md +1 -1
- package/skills/qualia-new/SKILL.md +73 -45
- package/skills/qualia-plan/SKILL.md +1 -1
- package/skills/qualia-polish/REFERENCE.md +8 -6
- package/skills/qualia-polish/SKILL.md +9 -7
- package/skills/qualia-polish/scripts/loop.mjs +18 -6
- package/skills/qualia-postmortem/SKILL.md +1 -1
- package/skills/qualia-report/SKILL.md +2 -1
- package/skills/qualia-road/SKILL.md +16 -4
- package/skills/qualia-verify/SKILL.md +2 -2
- package/skills/qualia-vibe/SKILL.md +226 -0
- package/skills/qualia-vibe/scripts/extract.mjs +141 -0
- package/skills/qualia-vibe/scripts/tokens.mjs +342 -0
- package/templates/help.html +9 -2
- package/tests/bin.test.sh +12 -12
- package/tests/refs.test.sh +1 -1
- package/tests/run-all.sh +48 -0
- package/tests/slop-detect.test.sh +11 -5
|
@@ -46,11 +46,33 @@ Initialize a project with the **entire arc mapped from kickoff to handoff**. All
|
|
|
46
46
|
node ~/.claude/bin/qualia-ui.js banner new
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Banner only. Do NOT ask anything yet. The next thing the user sees is the project-shape gate — not a free-text "tell me what to build". Shape gate first, content second, because the shape drives the question set.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
### Step 1. Project Type Gate (Demo vs Full vs Quick) — FIRST QUESTION
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
The single most important fork. Demo and Full produce different journeys, different research depth, different milestone counts. This is the literal first interaction with the user.
|
|
54
|
+
|
|
55
|
+
Use **AskUserQuestion** (interactive UI — never a plain-text prompt):
|
|
56
|
+
|
|
57
|
+
- header: "Project shape"
|
|
58
|
+
- question: "What kind of project is this? Pick one — it drives everything else."
|
|
59
|
+
- options:
|
|
60
|
+
- "Demo" — one shippable milestone, real backend, no mocks. Built to win a client conversation, extensible via `/qualia-milestone` if they sign. 8-question discovery.
|
|
61
|
+
- "Full project" — the multi-milestone arc to Handoff. 2-5 milestones planned upfront. 14-question discovery.
|
|
62
|
+
- "Quick prototype" — landing page, throwaway, ≤1 day. Skips research and journey. (Equivalent to `--quick` flag.)
|
|
63
|
+
|
|
64
|
+
Store the answer as `PROJECT_TYPE=demo` | `PROJECT_TYPE=full` | `PROJECT_TYPE=quick`. It drives every downstream step.
|
|
65
|
+
|
|
66
|
+
**Demo design philosophy is non-negotiable (do NOT compromise on these regardless of speed pressure):**
|
|
67
|
+
- **1 milestone only.** No multi-milestone arc, no Handoff phase. The demo IS the artifact.
|
|
68
|
+
- **NO mock data.** Real backend, real database, real auth. Hardcoded JSON in components is a hard-block. If the data needs Supabase, ship Supabase.
|
|
69
|
+
- **Real agent/platform functionality.** The thing actually works end-to-end. A demo with broken flows is not a Qualia demo.
|
|
70
|
+
- **DESIGN.md mandatory.** OKLCH palette, distinctive typography, full token system. Slop-detect runs hard-block.
|
|
71
|
+
- **Focus = design + functionality.** No sales decks, no placeholder copy, no "lorem ipsum" anywhere.
|
|
72
|
+
|
|
73
|
+
Speed in a demo comes from skipping multi-milestone planning, NEVER from skipping design quality, mocking the backend, or cutting corners on the core flow.
|
|
74
|
+
|
|
75
|
+
### Step 2. Brownfield Check
|
|
54
76
|
|
|
55
77
|
```bash
|
|
56
78
|
test -f package.json && echo "HAS_PACKAGE"
|
|
@@ -58,23 +80,27 @@ test -d .git && echo "HAS_GIT"
|
|
|
58
80
|
test -f .planning/codebase/README.md && echo "ALREADY_MAPPED"
|
|
59
81
|
```
|
|
60
82
|
|
|
61
|
-
If existing code is detected AND not already mapped,
|
|
83
|
+
If existing code is detected AND not already mapped, **AskUserQuestion**:
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
- header: "Existing code detected"
|
|
86
|
+
- question: "Run `/qualia-map` to scan the repo first?"
|
|
87
|
+
- options: ["Yes — map it", "No — proceed without mapping"]
|
|
64
88
|
|
|
65
|
-
|
|
89
|
+
If yes, invoke the `qualia-map` skill inline, wait for completion, then continue. If quick prototype + brownfield, skip the map (quick is for greenfield trivial work; brownfield + quick is contradictory — route to `/qualia-feature` instead).
|
|
66
90
|
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
### Step 3. One-line Pitch (free-text — minimal, no clarification round)
|
|
92
|
+
|
|
93
|
+
The shape is locked, now capture the content in one sentence:
|
|
94
|
+
|
|
95
|
+
> **"What are you building? One sentence — a stranger should understand it."**
|
|
96
|
+
|
|
97
|
+
Accept whatever the user says, even if broad. **Do NOT start an ad-hoc clarification round here.** Depth comes from the structured discovery interview in Step 4, not from free-form questioning. If the answer is "a SaaS platform" — that's fine, write it down, move on. `/qualia-discuss` will refine it through its 8 or 14 structured questions.
|
|
72
98
|
|
|
73
|
-
|
|
99
|
+
This is the ONLY free-text question in the kickoff flow. Everything else is `AskUserQuestion`.
|
|
74
100
|
|
|
75
|
-
|
|
101
|
+
### Step 4. Mandatory Discovery Interview (PROJECT MODE)
|
|
76
102
|
|
|
77
|
-
|
|
103
|
+
**Hard rule:** This is the next tool call after Step 3. No ad-hoc clarification, no free-form follow-up, no "let me ask a few quick things first." If the one-line pitch was "a SaaS platform", you invoke `/qualia-discuss` NOW — that skill's structured questions are how breadth gets refined into depth.
|
|
78
104
|
|
|
79
105
|
Invoke `/qualia-discuss` inline in PROJECT MODE — non-technical kickoff interview. 8 questions for demo, 14 for full project. Pass `PROJECT_TYPE` so the discuss skill skips the type question.
|
|
80
106
|
|
|
@@ -94,11 +120,11 @@ After the interview returns, `.planning/project-discovery.md` exists with the us
|
|
|
94
120
|
|
|
95
121
|
If "More questions": re-invoke `/qualia-discuss` for additional rounds. Otherwise continue.
|
|
96
122
|
|
|
97
|
-
### Step
|
|
123
|
+
### Step 5. Detect Project Type
|
|
98
124
|
|
|
99
|
-
From questioning answers, infer type → `website` | `ai-agent` | `voice-agent` | `mobile-app` | `null`. If matched, `cat ~/.claude/qualia-templates/projects/{type}.md` gives suggested milestone arc. Store `template_type` for Step
|
|
125
|
+
From questioning answers, infer type → `website` | `ai-agent` | `voice-agent` | `mobile-app` | `null`. If matched, `cat ~/.claude/qualia-templates/projects/{type}.md` gives suggested milestone arc. Store `template_type` for Step 13.
|
|
100
126
|
|
|
101
|
-
### Step
|
|
127
|
+
### Step 6. Design Direction (frontend only)
|
|
102
128
|
|
|
103
129
|
- header: "Design"
|
|
104
130
|
- question: "What's the design vibe?"
|
|
@@ -106,7 +132,7 @@ From questioning answers, infer type → `website` | `ai-agent` | `voice-agent`
|
|
|
106
132
|
|
|
107
133
|
Plus free-text: "Any brand colors or reference sites I should look at?"
|
|
108
134
|
|
|
109
|
-
### Step
|
|
135
|
+
### Step 7. Client Context
|
|
110
136
|
|
|
111
137
|
- header: "Client"
|
|
112
138
|
- question: "Client project or internal?"
|
|
@@ -117,7 +143,7 @@ If client, ask name. Check saved prefs:
|
|
|
117
143
|
node ~/.claude/bin/knowledge.js search "{client name}"
|
|
118
144
|
```
|
|
119
145
|
|
|
120
|
-
### Step
|
|
146
|
+
### Step 8. Write PROJECT.md
|
|
121
147
|
|
|
122
148
|
Create `.planning/PROJECT.md` from the template. Include: client, what we're building, core value, validated + active requirements (empty for greenfield), out of scope, stack, design direction, decisions table.
|
|
123
149
|
|
|
@@ -127,7 +153,7 @@ git add .planning/PROJECT.md
|
|
|
127
153
|
git commit -m "docs: initialize project"
|
|
128
154
|
```
|
|
129
155
|
|
|
130
|
-
### Step
|
|
156
|
+
### Step 8a. Seed CONTEXT.md and decisions/ (REQUIRED)
|
|
131
157
|
|
|
132
158
|
The domain glossary is the single highest-leverage piece of substrate — every road agent loads it BEFORE PROJECT.md/DESIGN.md. Misalignment is the #1 failure mode in AI coding; CONTEXT.md kills it.
|
|
133
159
|
|
|
@@ -140,7 +166,7 @@ mkdir -p .planning/decisions
|
|
|
140
166
|
cp ~/.claude/qualia-templates/decisions/ADR-template.md .planning/decisions/_template.md
|
|
141
167
|
```
|
|
142
168
|
|
|
143
|
-
Then **seed the glossary from the questioning answers**. For each domain term that came up during Step
|
|
169
|
+
Then **seed the glossary from the questioning answers**. For each domain term that came up during the Step 4 `/qualia-discuss` interview — entities, actions, statuses, key nouns the user repeatedly said — add an entry to `.planning/CONTEXT.md` under `## Language` with:
|
|
144
170
|
- the term
|
|
145
171
|
- a one-sentence definition
|
|
146
172
|
- an `Avoid:` line listing rejected synonyms (terms the team should NOT use for this concept)
|
|
@@ -156,7 +182,7 @@ git commit -m "docs: seed CONTEXT.md domain glossary + decisions/ folder"
|
|
|
156
182
|
|
|
157
183
|
The glossary stays terse — one sentence per entry. It's loaded into every agent spawn; bloat costs tokens. `/qualia-discuss` will grow it inline as decisions crystallize during phase planning.
|
|
158
184
|
|
|
159
|
-
### Step
|
|
185
|
+
### Step 8b. Write PRODUCT.md (REQUIRED)
|
|
160
186
|
|
|
161
187
|
`PRODUCT.md` is the "who and why" every road agent reads before designing or building. It is **required** — the planner, builder, and verifier all load it as substrate.
|
|
162
188
|
|
|
@@ -175,7 +201,7 @@ git add .planning/PRODUCT.md
|
|
|
175
201
|
git commit -m "docs: PRODUCT.md — register, users, voice, anti-references"
|
|
176
202
|
```
|
|
177
203
|
|
|
178
|
-
### Step
|
|
204
|
+
### Step 9. Create config.json
|
|
179
205
|
|
|
180
206
|
```json
|
|
181
207
|
{
|
|
@@ -190,9 +216,9 @@ git commit -m "docs: PRODUCT.md — register, users, voice, anti-references"
|
|
|
190
216
|
}
|
|
191
217
|
```
|
|
192
218
|
|
|
193
|
-
**Note:** `workflow.research` is
|
|
219
|
+
**Note:** `workflow.research` is always `true`. It exists for telemetry but is no longer read as a gate.
|
|
194
220
|
|
|
195
|
-
### Step
|
|
221
|
+
### Step 10. Create DESIGN.md (frontend projects — OKLCH-first)
|
|
196
222
|
|
|
197
223
|
If frontend work is involved, generate `.planning/DESIGN.md` from `templates/DESIGN.md`. The generation MUST commit to four things upfront (these go in §1 of DESIGN.md):
|
|
198
224
|
|
|
@@ -219,7 +245,7 @@ git add .planning/DESIGN.md .planning/config.json
|
|
|
219
245
|
git commit -m "docs: DESIGN.md — direction commit + OKLCH palette + tokens"
|
|
220
246
|
```
|
|
221
247
|
|
|
222
|
-
### Step
|
|
248
|
+
### Step 11. Run Research (ALWAYS, no permission ask)
|
|
223
249
|
|
|
224
250
|
**In v4, research runs unconditionally.** The previous `workflow.research` gate is gone. Skipping research leads to generic roadmaps and surprises late in the project — the 4-agent cost is worth it.
|
|
225
251
|
|
|
@@ -253,7 +279,7 @@ node ~/.claude/bin/qualia-ui.js ok "Research complete"
|
|
|
253
279
|
```
|
|
254
280
|
Display top 3 from SUMMARY.md (stack recommendation, table stakes, top pitfall).
|
|
255
281
|
|
|
256
|
-
### Step
|
|
282
|
+
### Step 12. Feature Scoping (Multi-Milestone)
|
|
257
283
|
|
|
258
284
|
Read `.planning/research/FEATURES.md` and present the feature landscape. Features are scoped **to milestones** — you'll decide per-feature which milestone owns it.
|
|
259
285
|
|
|
@@ -271,7 +297,7 @@ Track selections:
|
|
|
271
297
|
|
|
272
298
|
Gather any additional requirements the user wants that research missed.
|
|
273
299
|
|
|
274
|
-
### Step
|
|
300
|
+
### Step 13. Run Roadmapper
|
|
275
301
|
|
|
276
302
|
```bash
|
|
277
303
|
node ~/.claude/bin/qualia-ui.js banner roadmap
|
|
@@ -279,12 +305,12 @@ node ~/.claude/bin/qualia-ui.js banner roadmap
|
|
|
279
305
|
|
|
280
306
|
**Roadmapper output branches on `PROJECT_TYPE`:**
|
|
281
307
|
|
|
282
|
-
- **Demo** (`PROJECT_TYPE=demo`): roadmapper produces a 1-milestone JOURNEY.md (the demo milestone, 2-4 phases) plus a matching REQUIREMENTS.md and a fully-detailed ROADMAP.md. No "Handoff" milestone is appended — the demo is its own complete artifact. The journey-tree at Step
|
|
308
|
+
- **Demo** (`PROJECT_TYPE=demo`): roadmapper produces a 1-milestone JOURNEY.md (the demo milestone, 2-4 phases) plus a matching REQUIREMENTS.md and a fully-detailed ROADMAP.md. No "Handoff" milestone is appended — the demo is its own complete artifact. The journey-tree at Step 14 shows a single rung; the "extend to full project" branch is handled later by `/qualia-milestone` if the client signs.
|
|
283
309
|
- **Full project** (`PROJECT_TYPE=full`): roadmapper produces the standard 2-5 milestone arc ending in Handoff. Milestone 1 fully detailed, M2..M{N-1} sketched (unless `--full-detail`).
|
|
284
310
|
|
|
285
311
|
Spawn the roadmapper with `<project_type>$PROJECT_TYPE</project_type>` in the prompt. If the user passed `--full-detail`, include `<full_detail>true</full_detail>` so the roadmapper writes complete phase detail for ALL milestones (full project only; demo always has full detail because there's only one milestone). See REFERENCE.md section "Roadmapper prompt" for the verbatim prompt template.
|
|
286
312
|
|
|
287
|
-
### Step
|
|
313
|
+
### Step 14. Present the Journey (single view)
|
|
288
314
|
|
|
289
315
|
Render the branded journey ladder:
|
|
290
316
|
|
|
@@ -296,7 +322,7 @@ This shows M1..M{N} as a vertical ladder: shipped milestones get a green dot, cu
|
|
|
296
322
|
|
|
297
323
|
Also narrate the one-glance summary. See REFERENCE.md section "Journey ladder format" for the ASCII template.
|
|
298
324
|
|
|
299
|
-
### Step
|
|
325
|
+
### Step 15. Approval Gate (single — for the whole journey)
|
|
300
326
|
|
|
301
327
|
- header: "Journey"
|
|
302
328
|
- question: "Does this journey work for you?"
|
|
@@ -326,7 +352,7 @@ node ~/.claude/bin/qualia-ui.js info "Full phase detail for each later milestone
|
|
|
326
352
|
|
|
327
353
|
(Skip this block when `--full-detail` was used — all milestones are already fully planned in that case.)
|
|
328
354
|
|
|
329
|
-
### Step
|
|
355
|
+
### Step 16. Environment Setup
|
|
330
356
|
|
|
331
357
|
Supabase project? `supabase link` or create. Vercel project? `vercel link`. Env vars? `.env.local` with placeholders from PROJECT.md stack.
|
|
332
358
|
|
|
@@ -337,7 +363,7 @@ git add .gitignore
|
|
|
337
363
|
git commit -m "chore: environment setup" 2>/dev/null
|
|
338
364
|
```
|
|
339
365
|
|
|
340
|
-
### Step
|
|
366
|
+
### Step 17. Auto-Apply Gate (or stop here)
|
|
341
367
|
|
|
342
368
|
If invoked with `--auto`, skip straight into building Milestone 1:
|
|
343
369
|
|
|
@@ -390,15 +416,17 @@ Do NOT use `--quick` for: client projects, anything with compliance stakes, anyt
|
|
|
390
416
|
|
|
391
417
|
## Rules
|
|
392
418
|
|
|
393
|
-
1. **Project type is the first
|
|
394
|
-
2. **
|
|
395
|
-
3. **
|
|
396
|
-
4. **
|
|
397
|
-
5. **
|
|
398
|
-
6. **
|
|
399
|
-
7. **
|
|
400
|
-
8. **
|
|
401
|
-
9. **
|
|
402
|
-
10. **
|
|
403
|
-
11. **
|
|
404
|
-
12. **
|
|
419
|
+
1. **Project type is the first question, period.** Step 1 (Demo / Full / Quick) is the literal first interaction with the user — even before "what are you building". Every downstream step branches on the answer. Don't skip it, don't infer it, don't ask anything before it.
|
|
420
|
+
2. **AskUserQuestion for every discrete-choice question.** Project type, brownfield gate, design vibe, client type, approval gate, auto-chain — all use the interactive UI. The ONLY free-text question in the kickoff flow is the Step 3 one-line pitch. No plain-text prompts for anything that has a closed set of answers.
|
|
421
|
+
3. **No ad-hoc clarification questioning.** After Step 3 (one-line pitch), the next tool call is `/qualia-discuss`. No "let me ask a few quick things first", no "that's too broad, can you clarify". Depth is the discuss skill's job — not yours.
|
|
422
|
+
4. **Discovery interview is mandatory.** Step 4 always invokes `/qualia-discuss` in PROJECT MODE. No free-form questioning loop, no "I'll just sketch PROJECT.md from the user's first message." The interview is 8 questions for demo, 14 for full project.
|
|
423
|
+
5. **Research runs automatically.** No permission ask. Only `--quick` skips it. Demo path uses `<scope>quick</scope>` (3-call budget per researcher); full project uses standard 8-call budget.
|
|
424
|
+
6. **Demo design philosophy is non-negotiable.** Real backend always (Supabase, real auth), DESIGN.md mandatory, slop-detect hard-block, 1 milestone, focus on real agent/platform functionality + design quality. No mock data, no lorem ipsum, no broken flows. Speed comes from skipping multi-milestone planning, never from skipping design quality, mocking the backend, or cutting corners on the core flow. A demo that uses mock data is not a Qualia demo.
|
|
425
|
+
7. **Demos are 1 milestone, full projects are 2-5.** Demo journeys have no "Handoff" — the demo IS the artifact. Full projects always end in Handoff (fixed 4 phases). The journey-tree adapts to both shapes.
|
|
426
|
+
8. **The full-project journey includes Handoff.** Every full project's final milestone is literally named "Handoff" with 4 standard phases. The roadmapper enforces this.
|
|
427
|
+
9. **Single approval gate.** One gate for the whole journey. Not per-milestone, not per-phase.
|
|
428
|
+
10. **Milestone 1 is fully detailed (full projects).** M2..M{N-1} are sketched. Detail fills in when each milestone opens. Demos are always fully detailed because they're 1 milestone.
|
|
429
|
+
11. **STATE.md through state.js.** Never edit STATE.md or tracking.json by hand.
|
|
430
|
+
12. **Inline skill invocation.** When Step 2 offers `/qualia-map` or Step 4 invokes `/qualia-discuss`, invoke it inline — don't exit.
|
|
431
|
+
13. **CONTEXT.md is mandatory.** Every project gets a domain glossary at `.planning/CONTEXT.md`. Seeded from the discovery interview answers. Loaded by every road agent. Kept terse.
|
|
432
|
+
14. **ADRs are scarce.** `.planning/decisions/` exists from day one but only fills with hard-to-reverse, surprising-without-context, real-tradeoff decisions. Cargo-culting ADRs ruins the signal.
|
|
@@ -212,7 +212,7 @@ With `--gaps`, planner enters gap-closure mode:
|
|
|
212
212
|
## Rules
|
|
213
213
|
|
|
214
214
|
1. **Plan-checker mandatory by default.** Skip only with `--skip-check`.
|
|
215
|
-
2. **Max
|
|
215
|
+
2. **Max 2 revision cycles.** 2 fails → escalate; scope probably wrong.
|
|
216
216
|
3. **Honor locked decisions.** phase-{N}-context.md locked decisions non-negotiable.
|
|
217
217
|
4. **One plan file per phase.** No phase-1-plan-v2.md. Edit in place.
|
|
218
218
|
5. **Revision is surgical.** Fix only what checker flagged; no scope creep.
|
|
@@ -256,10 +256,12 @@ Per the spec's hard constraint (§5g `prefers-reduced-motion` and §5c mobile-on
|
|
|
256
256
|
|
|
257
257
|
This is intentional. Most visual regressions Fawzi has documented in `/insights` (hero videos cropped wrong on mobile, touch targets < 44px on mobile, navigation collapse misbehaving) only show up below 768. Scoring on desktop alone is how we got "looks great in dev" → "looks broken on the user's phone."
|
|
258
258
|
|
|
259
|
-
## What the loop does NOT do
|
|
259
|
+
## What the loop does NOT do
|
|
260
260
|
|
|
261
|
-
- Cross-browser rendering checks (Firefox / WebKit) — Chromium-only, per `qualia-polish` Stage 4 precedent
|
|
262
|
-
- Accessibility audits beyond what the rubric scores — use `/qualia-polish` Stage 3 (Lighthouse + axe) for that
|
|
263
|
-
- Performance regressions — use `/qualia-polish --loop` only after Lighthouse score passes
|
|
264
|
-
- Reference-image-only mode (compare to a target screenshot without a brief) —
|
|
265
|
-
-
|
|
261
|
+
- Cross-browser rendering checks (Firefox / WebKit) — Chromium-only, per `qualia-polish` Stage 4 precedent.
|
|
262
|
+
- Accessibility audits beyond what the rubric scores — use `/qualia-polish` Stage 3 (Lighthouse + axe) for that.
|
|
263
|
+
- Performance regressions — use `/qualia-polish --loop` only after Lighthouse score passes.
|
|
264
|
+
- Reference-image-only mode (compare to a target screenshot without a brief) — the brief is required; reference is supplemental.
|
|
265
|
+
- Aesthetic pivots — if the issue is "the whole vibe is wrong", `/qualia-vibe` swaps the aesthetic in minutes instead of grinding the loop against a vibe that doesn't fit.
|
|
266
|
+
|
|
267
|
+
Implemented as of v5.2: `--routes a,b,c` for multi-route sweeps, `--reduced-motion` for `prefers-reduced-motion: reduce` capture.
|
|
@@ -36,7 +36,7 @@ Other flags: `--register=brand|product` overrides register inference. Loop-speci
|
|
|
36
36
|
|
|
37
37
|
When `--loop` is the first flag, the polish run is fully autonomous: screenshot a live URL at three viewports, score 8 design dimensions of `qualia-design/design-rubric.md` against the brief using vision, fix top issues in the codebase, re-screenshot, repeat until every dimension scores ≥ 3 or the kill-switch fires (regression, budget cap, max iterations).
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
Scripts ship at `skills/qualia-polish/scripts/{loop,playwright-capture,score}.mjs`; the vision evaluator is `agents/visual-evaluator.md`; the full loop spec lives in this skill's `REFERENCE.md`.
|
|
40
40
|
|
|
41
41
|
When `--loop` is detected on entry, route to the loop process documented in `REFERENCE.md` and stop executing the standard stages below. The two paths share Stage 0 substrate gates and the rubric, but diverge from Stage 1 onward.
|
|
42
42
|
|
|
@@ -72,15 +72,17 @@ Read PRODUCT.md and DESIGN.md. Identify the **register** — Brand (marketing/la
|
|
|
72
72
|
2. `register:` field in PRODUCT.md
|
|
73
73
|
3. `--register` flag override
|
|
74
74
|
|
|
75
|
-
For App / Redesign scope, write the brief BEFORE any code (use `ultrathink`):
|
|
75
|
+
For App / Redesign scope, write the brief BEFORE any code (use `ultrathink`). Per `rules/one-opinion.md` — **propose one direction, do NOT list a menu of aesthetic options to the user.** Infer the one direction from `PRODUCT.md` register + anti-references + scene sentence, then commit to it in writing:
|
|
76
76
|
|
|
77
77
|
```
|
|
78
|
-
Aesthetic direction: {
|
|
79
|
-
Color strategy: {Restrained
|
|
78
|
+
Aesthetic direction: {ONE concrete direction — e.g. "editorial broadsheet, ivory ground, deep navy ink, italic accents"}
|
|
79
|
+
Color strategy: {ONE choice — Restrained / Committed / Full palette / Drenched — with one-line justification}
|
|
80
80
|
Scene sentence: {who uses this, where, ambient light, mood — concrete}
|
|
81
81
|
Differentiation: {what someone remembers 24 hours later}
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
If the user pushes back on the proposed direction, that is a `/qualia-vibe` trigger — switch surfaces, do not start enumerating alternatives in the brief.
|
|
85
|
+
|
|
84
86
|
For Component / Section / Quick scope, the brief is implicit (loaded from DESIGN.md). Skip the ultrathink step but cite the relevant DESIGN.md tokens you'll touch.
|
|
85
87
|
|
|
86
88
|
For Critique scope, no commit needed — you're scoring, not editing.
|
|
@@ -154,13 +156,13 @@ If a11y < 90 OR axe critical/serious violations: **fix programmatically** (th
|
|
|
154
156
|
|
|
155
157
|
### Stage 4 — Vision loop (Redesign scope only — max 2 iterations)
|
|
156
158
|
|
|
157
|
-
Use
|
|
159
|
+
Use `skills/qualia-polish/scripts/playwright-capture.mjs` (Playwright backend, with Chrome-binary fallback). Capture screenshots at 3 viewports: 375 / 768 / 1440 — these match what `agents/visual-evaluator.md` expects, and what the `--loop` mode captures. Single browser (Chromium) is fine in 2026 — cross-browser CSS rendering differences are vanishingly rare.
|
|
158
160
|
|
|
159
161
|
```
|
|
160
162
|
viewports: [
|
|
161
163
|
{ width: 375, height: 812, name: 'mobile' },
|
|
162
164
|
{ width: 768, height: 1024, name: 'tablet' },
|
|
163
|
-
{ width:
|
|
165
|
+
{ width: 1440, height: 900, name: 'desktop' }
|
|
164
166
|
]
|
|
165
167
|
```
|
|
166
168
|
|
|
@@ -261,7 +263,7 @@ node ~/.claude/bin/qualia-ui.js end "POLISHED" "{next command — depends on con
|
|
|
261
263
|
| Symptom | Likely cause | Action |
|
|
262
264
|
|---|---|---|
|
|
263
265
|
| `bin/slop-detect.mjs not found` | Framework not installed in project | Run `npx qualia install` or pull script from framework repo |
|
|
264
|
-
| `PRODUCT.md missing` |
|
|
266
|
+
| `PRODUCT.md missing` | Project predates the PRODUCT.md substrate | Run setup (ask 5 questions, generate). For Component scope, can proceed with nudge. |
|
|
265
267
|
| `Lighthouse not installed` | Optional tool | Skip Stage 3 numeric gates, note in report. Don't fail. |
|
|
266
268
|
| `webapp-testing skill not present` | Optional Anthropic skill | Skip Stage 4 vision loop on Redesign scope. Note in report. Recommend installing. |
|
|
267
269
|
| Vision loop oscillates between iterations | Rubric not anchored properly | Verify rubric prompt instructs "default to 3, only 1-2 = fix". Hard cap at 2 iterations. |
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
32
|
-
import { dirname } from "node:path";
|
|
32
|
+
import path, { dirname } from "node:path";
|
|
33
33
|
import { argv, exit } from "node:process";
|
|
34
34
|
import { spawnSync } from "node:child_process";
|
|
35
35
|
|
|
@@ -202,10 +202,17 @@ function cmdCommitFix() {
|
|
|
202
202
|
if (!statePath || !file) { console.error("--state and --file required"); exit(2); }
|
|
203
203
|
const state = loadState(statePath);
|
|
204
204
|
|
|
205
|
-
// slop-detect gate — block on critical findings
|
|
205
|
+
// slop-detect gate — block on critical findings. Resolve the script path with
|
|
206
|
+
// a search order so installs that put slop-detect in non-default locations
|
|
207
|
+
// still gate. Silent skip is reserved for genuinely missing installs.
|
|
206
208
|
const slopBin = process.env.SLOP_DETECT_BIN || "node";
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
+
const slopCandidates = [
|
|
210
|
+
process.env.SLOP_DETECT_SCRIPT,
|
|
211
|
+
`${process.env.HOME}/.claude/bin/slop-detect.mjs`,
|
|
212
|
+
path.join(path.dirname(new URL(import.meta.url).pathname), "..", "..", "..", "bin", "slop-detect.mjs"),
|
|
213
|
+
].filter(Boolean);
|
|
214
|
+
const slopScript = slopCandidates.find((p) => existsSync(p));
|
|
215
|
+
if (slopScript) {
|
|
209
216
|
const r = spawnSync(slopBin, [slopScript, file], { encoding: "utf8" });
|
|
210
217
|
if (r.status === 1) {
|
|
211
218
|
console.log(JSON.stringify({ ok: false, gate: "slop-detect", file, output: r.stdout }, null, 2));
|
|
@@ -213,12 +220,17 @@ function cmdCommitFix() {
|
|
|
213
220
|
}
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
// Stage + commit
|
|
223
|
+
// Stage + commit. Set a bot identity inline so the commit works on fresh
|
|
224
|
+
// clones where git user.name / user.email aren't configured yet.
|
|
217
225
|
const safeSlug = String(slug).toLowerCase().replace(/[^a-z0-9-]+/g, "-").slice(0, 48);
|
|
218
226
|
const msg = `qpl-${state.iteration}: ${safeSlug}`;
|
|
219
227
|
const add = spawnSync("git", ["add", file], { encoding: "utf8" });
|
|
220
228
|
if (add.status !== 0) { console.error(add.stderr); exit(2); }
|
|
221
|
-
const commit = spawnSync("git", [
|
|
229
|
+
const commit = spawnSync("git", [
|
|
230
|
+
"-c", "user.name=Qualia Polish Loop",
|
|
231
|
+
"-c", "user.email=polish-loop@qualia.solutions",
|
|
232
|
+
"commit", "-m", msg,
|
|
233
|
+
], { encoding: "utf8" });
|
|
222
234
|
if (commit.status !== 0) {
|
|
223
235
|
// empty diff → nothing to commit; not fatal
|
|
224
236
|
if (/nothing to commit/i.test(commit.stdout + commit.stderr)) {
|
|
@@ -95,7 +95,7 @@ matches the failure. Use this lookup:
|
|
|
95
95
|
| Wave 2 task ran before wave 1 committed | `agents/planner.md` (dependency graph) |
|
|
96
96
|
| Build passed locally, broke in CI | `rules/deployment.md` or a missing pre-deploy-gate scan |
|
|
97
97
|
| RLS missing on new table | `rules/security.md` + `agents/builder.md` (security persona handling) |
|
|
98
|
-
| Design regression — fonts off, contrast fail | `qualia-design/frontend.md` + `skills/qualia-
|
|
98
|
+
| Design regression — fonts off, contrast fail | `qualia-design/frontend.md` + `qualia-design/design-laws.md` + `skills/qualia-polish/SKILL.md` |
|
|
99
99
|
| Migration unsafe (DROP without IF EXISTS, etc.) | `hooks/migration-guard.js` |
|
|
100
100
|
| Verifier missed it | `agents/verifier.md` — most embarrassing case, address with extra care |
|
|
101
101
|
|
|
@@ -221,7 +221,8 @@ PAYLOAD=$(
|
|
|
221
221
|
tasks_done:t.tasks_done||0,tasks_total:t.tasks_total||0,verification:t.verification||'pending',
|
|
222
222
|
gap_cycles:(t.gap_cycles||{})[String(t.phase)]||0,build_count:t.build_count||0,
|
|
223
223
|
deploy_count:t.deploy_count||0,deployed_url:t.deployed_url||'',
|
|
224
|
-
session_started_at:t.session_started_at
|
|
224
|
+
...(t.session_started_at?{session_started_at:t.session_started_at}:{}),
|
|
225
|
+
...(t.last_pushed_at?{last_pushed_at:t.last_pushed_at}:{}),
|
|
225
226
|
session_duration_minutes:sessionDurationMinutes,
|
|
226
227
|
lifetime:t.lifetime||{},commits:commits,notes:notes,
|
|
227
228
|
submitted_by:process.env.SUBMITTED_BY||'unknown',submitted_at:process.env.SUBMITTED_AT
|
|
@@ -32,7 +32,7 @@ Final milestone = Handoff:
|
|
|
32
32
|
Done.
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
## Design as a thread
|
|
35
|
+
## Design as a thread
|
|
36
36
|
Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Builders run `slop-detect` on every frontend commit. Verifiers score 8 design dimensions per phase.
|
|
37
37
|
|
|
38
38
|
## /qualia-polish is scope-adaptive
|
|
@@ -45,7 +45,19 @@ Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Buil
|
|
|
45
45
|
/qualia-polish --quick ~1m gates only
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
##
|
|
48
|
+
## Design pivots — /qualia-vibe (v6.1+)
|
|
49
|
+
```
|
|
50
|
+
/qualia-vibe fast aesthetic pivot: ONE proposed direction, swap tokens, keep layout (~3 min)
|
|
51
|
+
/qualia-vibe brutalist explicit pivot to named direction
|
|
52
|
+
/qualia-vibe --variants 3 opt-in menu (uses AskUserQuestion; default flow is one-opinion)
|
|
53
|
+
/qualia-vibe --extract https://stripe.com reverse-engineer DESIGN.md from a reference URL
|
|
54
|
+
/qualia-vibe --extract ./inspo.png same, from a local screenshot
|
|
55
|
+
/qualia-vibe --sync show drift between code (CSS vars, Tailwind config) and DESIGN.md
|
|
56
|
+
/qualia-vibe --sync --write patch DESIGN.md to match code, commit
|
|
57
|
+
```
|
|
58
|
+
`/qualia-vibe` is for the WHOLE-SITE aesthetic. For surgical component-level fixes use `/qualia-polish` (component or section scope). For ground-up structural redesign use `/qualia-polish --redesign`.
|
|
59
|
+
|
|
60
|
+
## /qualia-polish --loop — autonomous visual QA
|
|
49
61
|
```
|
|
50
62
|
/qualia-polish --loop http://localhost:3000 screenshot + eval + fix loop
|
|
51
63
|
/qualia-polish --loop {url} --max 4 cap iterations
|
|
@@ -55,14 +67,14 @@ Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Buil
|
|
|
55
67
|
```
|
|
56
68
|
Screenshots at 3 viewports (375/768/1440), scores 8 design dimensions using vision, fixes issues, re-screenshots, loops until all dims >= 3 or kill-switch triggers. Per-iteration git commits for clean revert.
|
|
57
69
|
|
|
58
|
-
##
|
|
70
|
+
## Deterministic-enforcement skills
|
|
59
71
|
```
|
|
60
72
|
/qualia-hook-gen convert a CLAUDE.md/rules instruction into a deterministic pre-tool-use hook
|
|
61
73
|
/qualia-optimize --deepen spawns 3 parallel interface-design variants per candidate (Step 5b)
|
|
62
74
|
```
|
|
63
75
|
`/qualia-hook-gen` reduces lifetime token cost (each migrated rule frees ~50-200 tokens per request). `/qualia-optimize --deepen` produces dramatically better refactor RFCs because 3 radically-different interfaces are surfaced and the human picks/hybridizes.
|
|
64
76
|
|
|
65
|
-
## Alignment substrate
|
|
77
|
+
## Alignment substrate
|
|
66
78
|
Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (domain glossary) and `.planning/decisions/` (ADRs):
|
|
67
79
|
|
|
68
80
|
```
|
|
@@ -19,7 +19,7 @@ Spawn verifier to check phase goal. Does NOT trust build summaries; greps codeba
|
|
|
19
19
|
`/qualia-verify` — verify current built phase
|
|
20
20
|
`/qualia-verify {N}` — verify specific phase
|
|
21
21
|
`/qualia-verify {N} --auto` — verify + auto-chain: PASS → next phase/milestone; FAIL → gap closure; gap limit → halt
|
|
22
|
-
`/qualia-verify {N} --adversarial` — second verifier in fresh context with adversarial prompt. Union findings. Recommended for high-stakes phases (Handoff, payment/auth/migration).
|
|
22
|
+
`/qualia-verify {N} --adversarial` — second verifier in fresh context with adversarial prompt. Union findings. Recommended for high-stakes phases (Handoff, payment/auth/migration).
|
|
23
23
|
|
|
24
24
|
## Process
|
|
25
25
|
|
|
@@ -142,7 +142,7 @@ Per gap:
|
|
|
142
142
|
node ~/.claude/bin/qualia-ui.js fail "{gap description}"
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
**Self-healing
|
|
145
|
+
**Self-healing:** before re-planning gaps, run postmortem so the framework learns from the miss. Writes `.planning/phase-{N}-postmortem.md`. Does NOT auto-apply deltas unless user runs `/qualia-postmortem --apply`.
|
|
146
146
|
|
|
147
147
|
```
|
|
148
148
|
/qualia-postmortem --phase {N}
|