qualia-framework 6.2.9 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/AGENTS.md +1 -0
  2. package/CLAUDE.md +1 -0
  3. package/README.md +26 -30
  4. package/agents/builder.md +7 -7
  5. package/agents/planner.md +39 -3
  6. package/agents/research-synthesizer.md +1 -1
  7. package/agents/researcher.md +3 -3
  8. package/agents/roadmapper.md +7 -7
  9. package/agents/verifier.md +18 -6
  10. package/agents/visual-evaluator.md +8 -7
  11. package/bin/cli.js +160 -16
  12. package/bin/command-surface.js +71 -0
  13. package/bin/contract-runner.js +219 -0
  14. package/bin/harness-eval.js +296 -0
  15. package/bin/host-adapters.js +66 -0
  16. package/bin/install.js +116 -172
  17. package/bin/knowledge-flush.js +21 -10
  18. package/bin/knowledge.js +1 -1
  19. package/bin/plan-contract.js +99 -2
  20. package/bin/planning-hygiene.js +262 -0
  21. package/bin/project-snapshot.js +20 -0
  22. package/bin/report-payload.js +18 -0
  23. package/bin/runtime-manifest.js +35 -0
  24. package/bin/state-ledger.js +184 -0
  25. package/bin/state.js +330 -20
  26. package/bin/trust-score.js +268 -0
  27. package/bin/work-packet.js +228 -0
  28. package/docs/erp-contract.md +81 -1
  29. package/docs/onboarding.html +4 -14
  30. package/guide.md +16 -16
  31. package/hooks/fawzi-approval-guard.js +143 -0
  32. package/hooks/pre-deploy-gate.js +74 -1
  33. package/hooks/session-start.js +29 -1
  34. package/package.json +1 -1
  35. package/qualia-design/design-rubric.md +17 -5
  36. package/qualia-design/frontend.md +6 -2
  37. package/qualia-design/graphics.md +47 -0
  38. package/rules/codex-goal.md +1 -1
  39. package/rules/command-output.md +35 -0
  40. package/rules/one-opinion.md +2 -2
  41. package/rules/speed.md +0 -1
  42. package/skills/qualia/SKILL.md +12 -12
  43. package/skills/qualia-build/SKILL.md +20 -14
  44. package/skills/qualia-discuss/SKILL.md +10 -10
  45. package/skills/qualia-doctor/SKILL.md +140 -0
  46. package/skills/qualia-feature/SKILL.md +24 -22
  47. package/skills/qualia-fix/SKILL.md +216 -0
  48. package/skills/qualia-handoff/SKILL.md +9 -9
  49. package/skills/qualia-learn/SKILL.md +11 -11
  50. package/skills/qualia-map/SKILL.md +2 -2
  51. package/skills/qualia-milestone/SKILL.md +15 -15
  52. package/skills/qualia-new/REFERENCE.md +9 -9
  53. package/skills/qualia-new/SKILL.md +14 -14
  54. package/skills/qualia-optimize/REFERENCE.md +1 -1
  55. package/skills/qualia-optimize/SKILL.md +23 -16
  56. package/skills/qualia-plan/SKILL.md +23 -13
  57. package/skills/qualia-polish/REFERENCE.md +15 -15
  58. package/skills/qualia-polish/SKILL.md +81 -21
  59. package/skills/qualia-polish/scripts/loop.mjs +3 -3
  60. package/skills/qualia-polish/scripts/score.mjs +9 -3
  61. package/skills/{qualia-vibe/scripts/extract.mjs → qualia-polish/scripts/vibe-extract.mjs} +5 -5
  62. package/skills/{qualia-vibe/scripts/tokens.mjs → qualia-polish/scripts/vibe-tokens.mjs} +6 -6
  63. package/skills/qualia-postmortem/SKILL.md +9 -9
  64. package/skills/qualia-report/SKILL.md +23 -23
  65. package/skills/qualia-research/SKILL.md +5 -5
  66. package/skills/qualia-review/SKILL.md +28 -12
  67. package/skills/qualia-road/SKILL.md +30 -22
  68. package/skills/qualia-ship/SKILL.md +31 -24
  69. package/skills/qualia-test/SKILL.md +5 -5
  70. package/skills/qualia-verify/SKILL.md +45 -23
  71. package/skills/zoho-workflow/SKILL.md +1 -1
  72. package/templates/help.html +11 -20
  73. package/tests/bin.test.sh +178 -76
  74. package/tests/hooks.test.sh +81 -1
  75. package/tests/install-smoke.test.sh +35 -5
  76. package/tests/lib.test.sh +432 -0
  77. package/tests/published-install-smoke.test.sh +4 -3
  78. package/tests/refs.test.sh +9 -4
  79. package/tests/runner.js +32 -28
  80. package/tests/skills.test.sh +4 -4
  81. package/tests/state.test.sh +133 -3
  82. package/skills/qualia-debug/SKILL.md +0 -185
  83. package/skills/qualia-flush/SKILL.md +0 -198
  84. package/skills/qualia-help/SKILL.md +0 -74
  85. package/skills/qualia-hook-gen/SKILL.md +0 -206
  86. package/skills/qualia-idk/SKILL.md +0 -166
  87. package/skills/qualia-issues/SKILL.md +0 -151
  88. package/skills/qualia-pause/SKILL.md +0 -68
  89. package/skills/qualia-resume/SKILL.md +0 -52
  90. package/skills/qualia-skill-new/SKILL.md +0 -173
  91. package/skills/qualia-triage/SKILL.md +0 -152
  92. package/skills/qualia-vibe/SKILL.md +0 -226
  93. package/skills/qualia-zoom/SKILL.md +0 -51
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-optimize
3
- description: "Deep optimization pass — reads .planning/ AND codebase to find performance, design, UI, backend, frontend, AND architecture-deepening opportunities. Spawns parallel specialist agents. Use whenever the user says 'optimize', 'optimization pass', 'find issues', 'qualia-optimize', 'deep optimize', 'performance audit', 'design alignment check', 'speed up', 'slow', 'bundle size', 'refactor architecture', 'shallow modules', 'simplify', or wants a comprehensive quality sweep. Supports --perf, --ui, --backend, --alignment, --deepen, --fix flags."
3
+ description: "Deep improvement discovery pass — reads .planning/ AND codebase to find performance, design, UI, backend, frontend, alignment, and architecture-deepening opportunities. Spawns parallel specialist agents and writes OPTIMIZE.md/RFCs; practical repair work routes to /qualia-fix or /qualia-polish. Use when the user says 'optimize', 'optimization pass', 'find issues', 'deep improve', 'performance audit', 'design alignment check', 'speed up', 'bundle size', 'refactor architecture', 'shallow modules', 'simplify', or wants a comprehensive quality sweep. Supports --perf, --ui, --backend, --alignment, --deepen, --fix flags."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -21,6 +21,8 @@ Detailed agent-prompt templates live in `REFERENCE.md` (in this same skill folde
21
21
 
22
22
  Reads `.planning/` docs AND codebase. Never analyze one without the other.
23
23
 
24
+ Optimize is discovery-first, not a hotfix lane. If the user has one broken behavior, route to `/qualia-fix`. If the user has visual quality problems, route to `/qualia-polish`. Use optimize when the question is "where can this system get better?"
25
+
24
26
  ## Usage
25
27
 
26
28
  - `/qualia-optimize` — Full (all 7 dimensions + architecture deepening)
@@ -29,7 +31,7 @@ Reads `.planning/` docs AND codebase. Never analyze one without the other.
29
31
  - `/qualia-optimize --backend` — Backend only (RLS, auth, queries, edge fns)
30
32
  - `/qualia-optimize --alignment` — Planning-code alignment only
31
33
  - `/qualia-optimize --deepen` — Architecture deepening only (Ousterhout: shallow modules, deeper interfaces)
32
- - `/qualia-optimize --fix` — Auto-fix LOW/MEDIUM from existing OPTIMIZE.md
34
+ - `/qualia-optimize --fix` — Compatibility mode: convert LOW/MEDIUM `.planning/reports/optimize/OPTIMIZE.md` findings into safe repairs, using `/qualia-fix` rules for any code mutation
33
35
 
34
36
  ## Process
35
37
 
@@ -37,7 +39,7 @@ Reads `.planning/` docs AND codebase. Never analyze one without the other.
37
39
 
38
40
  Mode from $ARGUMENTS. Default: `full`.
39
41
  Modes: `full`, `perf`, `ui`, `backend`, `alignment`, `deepen`, `fix`.
40
- `--fix` skips to Step 9 (requires `.planning/OPTIMIZE.md`).
42
+ `--fix` skips to Step 9 (requires `.planning/reports/optimize/OPTIMIZE.md`, with fallback to legacy `.planning/OPTIMIZE.md`) and follows `/qualia-fix` mutation rules.
41
43
 
42
44
  ### Step 2: Load Planning Context (MANDATORY)
43
45
 
@@ -73,8 +75,8 @@ ls .planning/decisions/ 2>/dev/null && cat .planning/decisions/*.md 2>/dev/null
73
75
 
74
76
  Also read rules:
75
77
  ```bash
76
- cat ~/.claude/qualia-design/frontend.md 2>/dev/null
77
- cat ~/.claude/rules/security.md 2>/dev/null
78
+ cat ${QUALIA_DESIGN}/frontend.md 2>/dev/null
79
+ cat ${QUALIA_RULES}/security.md 2>/dev/null
78
80
  ```
79
81
 
80
82
  Store all; inline into agent prompts.
@@ -146,7 +148,7 @@ Collect all 3 proposals. Present to the user as a side-by-side table:
146
148
  | 2 | ... | ... | ... | ... |
147
149
  | 3 | ... | ... | ... | ... |
148
150
 
149
- User picks `1`, `2`, `3`, or `hybrid` (with notes on which elements from which proposals to combine). The synthesizer then writes a "Refactor RFC" to `.planning/REFACTOR-{slug}.md` and optionally opens a GH issue.
151
+ User picks `1`, `2`, `3`, or `hybrid` (with notes on which elements from which proposals to combine). The synthesizer then writes a "Refactor RFC" to `.planning/reports/refactor/REFACTOR-{slug}.md` and optionally opens a GH issue.
150
152
 
151
153
  **Why parallel + radically different**: a single deepening proposal anchors on the first idea the LLM has. Three parallel proposals with diverse design constraints surface trade-offs the user can see at a glance — and the human's "taste" dominates the choice rather than the agent's first instinct. Empirically (Matt Pocock + Qualia internal testing) this produces dramatically better refactor RFCs than a single-pass proposal.
152
154
 
@@ -187,7 +189,11 @@ All agents done:
187
189
 
188
190
  ### Step 8: Write OPTIMIZE.md and Present Results
189
191
 
190
- Write to `.planning/OPTIMIZE.md`:
192
+ Create the report directory and write to `.planning/reports/optimize/OPTIMIZE.md`:
193
+
194
+ ```bash
195
+ mkdir -p .planning/reports/optimize
196
+ ```
191
197
 
192
198
  ```markdown
193
199
  ---
@@ -237,7 +243,7 @@ status: {clean|needs_attention|critical_issues}
237
243
 
238
244
  Commit:
239
245
  ```bash
240
- git add .planning/OPTIMIZE.md && git commit -m "docs: optimization report ({mode} mode, {critical} critical)"
246
+ git add .planning/reports/optimize/OPTIMIZE.md && git commit -m "docs: optimization report ({mode} mode, {critical} critical)"
241
247
  ```
242
248
 
243
249
  **Present results:**
@@ -247,25 +253,26 @@ If CRITICAL findings exist:
247
253
  {critical} critical issues found. Options:
248
254
 
249
255
  1. Create a fix phase in ROADMAP.md for critical + high findings
250
- 2. Auto-fix LOW/MEDIUM findings: /qualia-optimize --fix
251
- 3. Review full report: cat .planning/OPTIMIZE.md
256
+ 2. Repair a specific blocker: /qualia-fix {finding}
257
+ 3. Convert LOW/MEDIUM findings into safe repairs: /qualia-optimize --fix
258
+ 4. Review full report: cat .planning/reports/optimize/OPTIMIZE.md
252
259
  ```
253
260
 
254
261
  If no CRITICAL:
255
262
  ```
256
263
  Optimization complete. {total} findings ({high} high, {medium} medium, {low} low).
257
- Report: .planning/OPTIMIZE.md
264
+ Report: .planning/reports/optimize/OPTIMIZE.md
258
265
 
259
- Run /qualia-optimize --fix to auto-fix LOW/MEDIUM findings.
266
+ Run /qualia-fix for a specific defect, or /qualia-optimize --fix only for safe LOW/MEDIUM cleanup from this report.
260
267
  ```
261
268
 
262
269
  ### Step 9: --fix Mode
263
270
 
264
- `--fix` mode:
271
+ `--fix` mode is a compatibility cleanup lane, not a replacement for `/qualia-fix`.
265
272
 
266
- 1. Read `.planning/OPTIMIZE.md`; missing: "Run /qualia-optimize first"
273
+ 1. Read `.planning/reports/optimize/OPTIMIZE.md` (fallback: `.planning/OPTIMIZE.md` for older projects); missing: "Run /qualia-optimize first"
267
274
  2. Filter to LOW + MEDIUM only
268
- 3. Per finding with clear, safe fix:
275
+ 3. Per finding with clear, safe fix, apply `/qualia-fix` mutation rules:
269
276
  - Read target file
270
277
  - Apply fix
271
278
  - Verify (npx tsc --noEmit if TS)
@@ -273,7 +280,7 @@ Run /qualia-optimize --fix to auto-fix LOW/MEDIUM findings.
273
280
  5. Commit
274
281
  6. Report fixed vs remaining
275
282
 
276
- **Never auto-fix CRITICAL/HIGH.** Require human judgment.
283
+ **Never auto-fix CRITICAL/HIGH.** Require human judgment. If a finding is an actual broken behavior, use `/qualia-fix {finding}` instead of burying it in optimize.
277
284
 
278
285
  ### Step 10: Gap Phase Creation (user picks option 1)
279
286
 
@@ -37,9 +37,9 @@ Per `rules/codex-goal.md` — set the thread goal at plan start with scope `phas
37
37
  cat .planning/STATE.md 2>/dev/null
38
38
  cat .planning/ROADMAP.md 2>/dev/null
39
39
  cat .planning/PROJECT.md 2>/dev/null
40
- node ~/.claude/bin/knowledge.js
41
- node ~/.claude/bin/knowledge.js load patterns
42
- node ~/.claude/bin/knowledge.js load client
40
+ node ${QUALIA_BIN}/knowledge.js
41
+ node ${QUALIA_BIN}/knowledge.js load patterns
42
+ node ${QUALIA_BIN}/knowledge.js load client
43
43
  ```
44
44
 
45
45
  No phase number → current phase from STATE.md.
@@ -67,13 +67,13 @@ Suggest: *"Run /qualia-discuss {N} first to lock decisions? Optional."*
67
67
  ### 3. Spawn Planner (Fresh Context)
68
68
 
69
69
  ```bash
70
- node ~/.claude/bin/qualia-ui.js banner plan {N} "{phase name from ROADMAP.md}"
71
- node ~/.claude/bin/qualia-ui.js spawn planner "Breaking phase into tasks..."
70
+ node ${QUALIA_BIN}/qualia-ui.js banner plan {N} "{phase name from ROADMAP.md}"
71
+ node ${QUALIA_BIN}/qualia-ui.js spawn planner "Breaking phase into tasks..."
72
72
  ```
73
73
 
74
74
  ```
75
75
  Agent(prompt="
76
- Role: @~/.claude/agents/planner.md
76
+ Role: @${QUALIA_AGENTS}/planner.md
77
77
 
78
78
  <project_context>
79
79
  @.planning/PROJECT.md
@@ -116,7 +116,7 @@ Read generated plan. Spawn checker:
116
116
 
117
117
  ```
118
118
  Agent(prompt="
119
- Role: @~/.claude/agents/plan-checker.md
119
+ Role: @${QUALIA_AGENTS}/plan-checker.md
120
120
 
121
121
  <plan_path>.planning/phase-{N}-plan.md</plan_path>
122
122
  <phase_goal>{goal from ROADMAP.md}</phase_goal>
@@ -138,7 +138,7 @@ Per revision:
138
138
 
139
139
  ```
140
140
  Agent(prompt="
141
- Role: @~/.claude/agents/planner.md
141
+ Role: @${QUALIA_AGENTS}/planner.md
142
142
 
143
143
  <revision_mode>true</revision_mode>
144
144
  <current_plan>@.planning/phase-{N}-plan.md</current_plan>
@@ -155,7 +155,7 @@ After revision, re-spawn checker. Max 2 total cycles.
155
155
  **BLOCKED after 2 cycles:**
156
156
 
157
157
  ```bash
158
- node ~/.claude/bin/qualia-ui.js fail "Plan failed validation after 2 revisions"
158
+ node ${QUALIA_BIN}/qualia-ui.js fail "Plan failed validation after 2 revisions"
159
159
  ```
160
160
 
161
161
  Show remaining issues. Options:
@@ -165,10 +165,19 @@ Show remaining issues. Options:
165
165
 
166
166
  ### 5. Present Final Plan
167
167
 
168
+ Before presenting, write the machine-readable contract:
169
+
170
+ ```bash
171
+ node ${QUALIA_BIN}/plan-contract.js validate .planning/phase-{N}-contract.json
172
+ node ${QUALIA_BIN}/state.js validate-plan --phase {N} --require-contract
173
+ ```
174
+
175
+ The planner must create `.planning/phase-{N}-contract.json` from the final plan. This JSON contract is the authority for build and verification; Markdown contracts are explanatory only. If validation fails, revise the plan/contract pair before asking for approval.
176
+
168
177
  Render story-file dashboard:
169
178
 
170
179
  ```bash
171
- node ~/.claude/bin/qualia-ui.js plan-summary .planning/phase-{N}-plan.md
180
+ node ${QUALIA_BIN}/qualia-ui.js plan-summary .planning/phase-{N}-plan.md
172
181
  ```
173
182
 
174
183
  End with plain text: *"Approve? (yes / adjust)"*
@@ -178,7 +187,8 @@ If "adjust" — get feedback, re-spawn planner with revision context, re-validat
178
187
  ### 6. Update State
179
188
 
180
189
  ```bash
181
- node ~/.claude/bin/state.js transition --to planned --phase {N}
190
+ node ${QUALIA_BIN}/state.js validate-plan --phase {N} --require-contract
191
+ node ${QUALIA_BIN}/state.js transition --to planned --phase {N}
182
192
  ```
183
193
 
184
194
  Error → show, stop. Do NOT edit STATE.md or tracking.json manually.
@@ -188,7 +198,7 @@ Error → show, stop. Do NOT edit STATE.md or tracking.json manually.
188
198
  **`--auto`:** invoke `/qualia-build {N} --auto` inline. User approved at `/qualia-new`; no per-phase gate.
189
199
 
190
200
  ```bash
191
- node ~/.claude/bin/qualia-ui.js info "Auto mode — chaining into /qualia-build {N}"
201
+ node ${QUALIA_BIN}/qualia-ui.js info "Auto mode — chaining into /qualia-build {N}"
192
202
  ```
193
203
 
194
204
  Then invoke `qualia-build` inline with `--auto`.
@@ -196,7 +206,7 @@ Then invoke `qualia-build` inline with `--auto`.
196
206
  **Guided mode:** stop, show next step:
197
207
 
198
208
  ```bash
199
- node ~/.claude/bin/qualia-ui.js end "PHASE {N} PLANNED" "/qualia-build {N}"
209
+ node ${QUALIA_BIN}/qualia-ui.js end "PHASE {N} PLANNED" "/qualia-build {N}"
200
210
  ```
201
211
 
202
212
  ## Gap Closure Mode (`--gaps`)
@@ -55,10 +55,10 @@ Agent({
55
55
  subagent_type: "qualia-visual-evaluator",
56
56
  description: "Score iteration {N} screenshots against rubric",
57
57
  prompt: `
58
- Role: @~/.claude/agents/visual-evaluator.md
58
+ Role: @${QUALIA_AGENTS}/visual-evaluator.md
59
59
 
60
60
  <rubric>
61
- {INLINE qualia-design/design-rubric.md §"The 8 dimensions" through §"Aggregate score"}
61
+ {INLINE qualia-design/design-rubric.md §"The 9 dimensions" through §"Aggregate score"}
62
62
  </rubric>
63
63
 
64
64
  <brief>
@@ -101,7 +101,7 @@ Agent({
101
101
  subagent_type: "qualia-builder",
102
102
  description: "Fix {dim} issue: {short description}",
103
103
  prompt: `
104
- Role: @~/.claude/agents/builder.md
104
+ Role: @${QUALIA_AGENTS}/builder.md
105
105
 
106
106
  <phase_context>
107
107
  You are inside /qualia-polish --loop iteration {N}. The vision evaluator scored
@@ -133,7 +133,7 @@ the {dim} dimension at {score}. Your single task: fix that one dimension.
133
133
  2. Make the MINIMUM edit to fix this one dimension. Do not refactor. Do not change logic. Do not touch state management. Do not change copy unless this is a microcopy issue.
134
134
  3. Use design tokens from DESIGN.md. Do not invent new color values, font names, or spacing.
135
135
  4. After the edit, commit via the orchestrator (slop-detect-gated):
136
- node ~/.claude/skills/qualia-polish/scripts/loop.mjs commit-fix --state {STATE} --file {file} --slug {dim}-{short-keyword}
136
+ node ${QUALIA_SKILLS}/qualia-polish/scripts/loop.mjs commit-fix --state {STATE} --file {file} --slug {dim}-{short-keyword}
137
137
  If slop-detect blocks (exit 2), READ the slop output and re-edit. If you cannot fix without violating slop-detect, return BLOCKED with the conflict.
138
138
  5. Return DONE with: file modified, lines changed, slop-detect: pass, commit: {sha}.
139
139
  </task>
@@ -153,10 +153,10 @@ the {dim} dimension at {score}. Your single task: fix that one dimension.
153
153
  ```json
154
154
  {
155
155
  "iteration": 1,
156
- "scores": { "typography": 1, "color": 1, "spatial": 3, "layout": 1, "shadow": 3, "motion": 3, "microcopy": 1, "container": 1 },
157
- "aggregate": 14,
156
+ "scores": { "typography": 1, "color": 1, "spatial": 3, "layout": 1, "shadow": 3, "motion": 3, "microcopy": 1, "container": 1, "graphics": 1 },
157
+ "aggregate": 15,
158
158
  "pass": false,
159
- "failing_dims": ["typography", "color", "layout", "microcopy", "container"],
159
+ "failing_dims": ["typography", "color", "layout", "microcopy", "container", "graphics"],
160
160
  "top_issues": [
161
161
  { "dim": "color", "severity": "critical", "description": "blue→purple gradient on hero", "likely_file": "src/styles/globals.css", "fix": "replace linear-gradient with single accent var(--accent)" },
162
162
  { "dim": "typography", "severity": "critical", "description": "Inter as primary font-family", "likely_file": "src/styles/globals.css", "fix": "swap to Fraunces + JetBrains Mono per DESIGN.md §3" },
@@ -222,23 +222,23 @@ The pilot-results doc at `docs/playwright-loop-pilot-results.md` records the act
222
222
  ## Iteration log
223
223
 
224
224
  ### Iteration 1
225
- - Scores: typo=1 colo=1 spat=3 layo=1 shad=3 moti=3 micr=1 cont=1
226
- - Aggregate: 14/40 (avg 1.75)
227
- - Pass: NO (failing: typography, color, layout, microcopy, container)
225
+ - Scores: typo=1 colo=1 spat=3 layo=1 shad=3 moti=3 micr=1 cont=1 grap=1
226
+ - Aggregate: 15/45 (avg 1.67)
227
+ - Pass: NO (failing: typography, color, layout, microcopy, container, graphics)
228
228
  - Top issues:
229
229
  - **color** [critical] blue→purple gradient on hero → src/styles/globals.css
230
230
  - **typography** [critical] Inter as primary → src/styles/globals.css
231
231
  - **layout** [high] three identical cards → src/pages/index.tsx
232
232
 
233
233
  ### Iteration 2
234
- - Scores: typo=3 colo=3 spat=3 layo=2 shad=3 moti=3 micr=2 cont=2
235
- - Aggregate: 21/40 (avg 2.62)
234
+ - Scores: typo=3 colo=3 spat=3 layo=2 shad=3 moti=3 micr=2 cont=2 grap=2
235
+ - Aggregate: 23/45 (avg 2.56)
236
236
  - Pass: NO (failing: layout, microcopy, container)
237
237
  - ...
238
238
 
239
239
  ### Iteration 3
240
- - Scores: typo=4 colo=3 spat=3 layo=3 shad=3 moti=3 micr=3 cont=3
241
- - Aggregate: 25/40 (avg 3.13)
240
+ - Scores: typo=4 colo=3 spat=3 layo=3 shad=3 moti=3 micr=3 cont=3 grap=4
241
+ - Aggregate: 29/45 (avg 3.22)
242
242
  - Pass: YES
243
243
 
244
244
  ## Fix commits (revertable)
@@ -262,6 +262,6 @@ This is intentional. Most visual regressions Fawzi has documented in `/insights`
262
262
  - Accessibility audits beyond what the rubric scores — use `/qualia-polish` Stage 3 (Lighthouse + axe) for that.
263
263
  - Performance regressions — use `/qualia-polish --loop` only after Lighthouse score passes.
264
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.
265
+ - Aesthetic pivots — if the issue is "the whole vibe is wrong", `/qualia-polish --vibe` swaps the aesthetic in minutes instead of grinding the loop against a vibe that doesn't fit.
266
266
 
267
267
  Implemented as of v5.2: `--routes a,b,c` for multi-route sweeps, `--reduced-motion` for `prefers-reduced-motion: reduce` capture.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-polish
3
- description: "Scope-adaptive design pass. Works on a single component, a route, the whole app, a ground-up redesign, or an autonomous visual loop. Trigger on 'polish', 'design pass', 'fix the design', 'redesign', 'critique', 'audit design', 'looks ugly', 'make it look better', 'polish loop', 'visual loop', 'fix what I see', 'iterate on the design until it's correct'. Replaces /qualia-polish-loop (now /qualia-polish --loop) and /qualia-design from earlier versions."
3
+ description: "Scope-adaptive visual quality pass. Works on a single component, a route, the whole app, a ground-up redesign, an aesthetic token pivot, or an autonomous visual loop, but does not repair business logic or broken data flow. Trigger on 'polish', 'design pass', 'fix the design', 'redesign', 'critique', 'audit design', 'looks ugly', 'make it look better', 'different vibe', 'polish loop', 'visual loop', 'fix what I see', 'iterate on the design until it's correct'. Route functional bugs to /qualia-fix."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -9,12 +9,16 @@ allowed-tools:
9
9
  - Grep
10
10
  - Glob
11
11
  - Agent
12
+ - WebSearch
13
+ - WebFetch
12
14
  argument-hint: "[file|route|--redesign|--critique|--quick|--loop] [--register=brand|product] [--brief PATH] [--max 8] [--viewports 375,768,1440]"
13
15
  ---
14
16
 
15
17
  # /qualia-polish — Scope-Adaptive Design Pass
16
18
 
17
- One command. Seven scopes. Use it whenever you need design work, from a 30-second component touch-up to a 30-minute ground-up redesign to a fully autonomous see-fix-verify loop.
19
+ One command. Seven scopes. Use it whenever you need design work, from a 30-second component touch-up to a ground-up redesign with current design research, complex visuals, and a fully transparent see-fix-verify loop.
20
+
21
+ Polish fixes visual quality only. Broken behavior, failing tests, API bugs, state bugs, and config errors go to `/qualia-fix`. Whole-site aesthetic token pivots stay inside `/qualia-polish --vibe` so the design surface is one command.
18
22
 
19
23
  ## Scopes
20
24
 
@@ -28,25 +32,54 @@ The first argument selects the scope. Stage selection follows from scope.
28
32
  | `/qualia-polish --redesign` | **Redesign** | ~30m | all + Stage 1 mandatory + 2 vision iterations |
29
33
  | `/qualia-polish --critique` | **Critique** | read-only | 0, 4, 5 (no edits) |
30
34
  | `/qualia-polish --quick` | **Quick** | ~1m | 0, 2, 7 (gates only, no vision loop) |
35
+ | `/qualia-polish --vibe` | **Aesthetic pivot** | ~3m | token-only direction swap |
31
36
  | `/qualia-polish --loop {url}` | **Loop** | ~5-15m | autonomous see/fix/verify, max 8 iterations |
32
37
 
33
- Other flags: `--register=brand|product` overrides register inference. Loop-specific flags: `--brief PATH`, `--max N`, `--viewports 375,768,1440`, `--ref PATH`, `--budget 100000`.
38
+ Other flags: `--register=brand|product` overrides register inference. Vibe-specific flags: `--variants N`, `--extract URL|image`, `--sync`, `--write`. Loop-specific flags: `--brief PATH`, `--max N`, `--viewports 375,768,1440`, `--ref PATH`, `--budget 100000`.
39
+
40
+ ## Transparent Command Output
41
+
42
+ Follow `rules/command-output.md`. At minimum, show:
43
+
44
+ ```text
45
+ Command: /qualia-polish {scope}
46
+ Scope: {target files/routes}
47
+ Intent: visual quality | redesign | critique | loop
48
+ Mutation: none | planned | active | blocked
49
+ Evidence: DESIGN.md, PRODUCT.md, qualia-design files, screenshots, online sources when used
50
+ Output: changed files, screenshots, report, commit
51
+ Next: {next command or done}
52
+ ```
34
53
 
35
54
  ## --loop mode (autonomous visual loop)
36
55
 
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).
56
+ When `--loop` is the first flag, the polish run is fully autonomous: screenshot a live URL at three viewports, score 9 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
57
 
39
58
  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
59
 
41
60
  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
61
 
62
+ ## --vibe mode (aesthetic token pivot)
63
+
64
+ When `--vibe` is detected, do not restructure JSX, routes, data flow, navigation, or layout grids. Change only aesthetic tokens and matching DESIGN.md sections: color, typography, depth, motion, brand accents, and short visual-direction copy.
65
+
66
+ Supporting scripts ship inside this skill:
67
+
68
+ ```bash
69
+ node ${QUALIA_SKILLS}/qualia-polish/scripts/vibe-tokens.mjs sync --design .planning/DESIGN.md
70
+ node ${QUALIA_SKILLS}/qualia-polish/scripts/vibe-tokens.mjs propose-variants --product .planning/PRODUCT.md --design .planning/DESIGN.md --count 3
71
+ node ${QUALIA_SKILLS}/qualia-polish/scripts/vibe-extract.mjs --source https://example.com
72
+ ```
73
+
74
+ Default flow proposes one opinionated direction per `rules/one-opinion.md`. `--variants` is opt-in only. `--extract` stages a reference screenshot for the visual evaluator to reverse-engineer into DESIGN.md tokens; the user must review low-confidence extracted values before application. `--sync --write` patches DESIGN.md to reflect tokens already present in code.
75
+
43
76
  ## Setup gates (non-optional, every scope)
44
77
 
45
78
  Before any work — design or otherwise — pass these gates. Skipping them produces generic output that ignores the project.
46
79
 
47
80
  | Gate | Required check | If fail |
48
81
  |---|---|---|
49
- | Substrate | `qualia-design/design-laws.md`, `design-brand.md`, `design-product.md`, `design-rubric.md` exist and have been read | Read them. |
82
+ | Substrate | `qualia-design/design-laws.md`, `design-brand.md`, `design-product.md`, `design-rubric.md`, `design-reference.md`, `frontend.md`, `graphics.md` exist and have been read when scope requires them | Read them. |
50
83
  | PRODUCT | `PRODUCT.md` exists at project root, has `register:` field, and is not placeholder (`[TODO]` markers, &lt; 200 chars) | Run setup: ask 5 questions and generate it. Never synthesize from prompt alone. |
51
84
  | DESIGN | `DESIGN.md` exists. If missing on App / Redesign scope, BLOCK and run setup. If missing on Component / Section / Critique / Quick scope, NUDGE and proceed. | Generate from PRODUCT.md + 3 questions. |
52
85
  | Slop-detect | `bin/slop-detect.mjs` is callable | Install or pull from framework. |
@@ -55,13 +88,13 @@ Before any work — design or otherwise — pass these gates. Skipping them prod
55
88
  State this preflight explicitly before editing:
56
89
 
57
90
  ```
58
- POLISH_PREFLIGHT: substrate=pass product=pass design=pass|nudged slop_detect=pass mutation=open
91
+ POLISH_PREFLIGHT: substrate=pass product=pass design=pass|nudged graphics=loaded|skipped slop_detect=pass mutation=open
59
92
  ```
60
93
 
61
94
  ## Process
62
95
 
63
96
  ```bash
64
- node ~/.claude/bin/qualia-ui.js banner polish
97
+ node ${QUALIA_BIN}/qualia-ui.js banner polish
65
98
  ```
66
99
 
67
100
  ### Stage 0 — Direction commit (mandatory; light on small scopes)
@@ -79,9 +112,19 @@ Aesthetic direction: {ONE concrete direction — e.g. "editorial broadsheet, iv
79
112
  Color strategy: {ONE choice — Restrained / Committed / Full palette / Drenched — with one-line justification}
80
113
  Scene sentence: {who uses this, where, ambient light, mood — concrete}
81
114
  Differentiation: {what someone remembers 24 hours later}
115
+ Complex visual: {hero/product/data/diagram/3D/canvas concept, or "none because..."}
116
+ Research anchors: {2-4 sources checked, or "local only" for component/quick}
82
117
  ```
83
118
 
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.
119
+ For Redesign scope, run a short online best-practices check before the brief unless the user explicitly says offline. Prefer primary sources:
120
+ - W3C WCAG 2.2 / WAI for accessibility, focus, target size, contrast: https://www.w3.org/TR/WCAG22/
121
+ - Apple Human Interface Guidelines for motion/accessibility restraint: https://developer.apple.com/design/human-interface-guidelines/motion
122
+ - Material Design motion guidance for spatial continuity and state transitions: https://m3.material.io/styles/motion/overview
123
+ - Nielsen Norman Group for visual hierarchy, scannability, and usability evidence: https://www.nngroup.com/articles/visual-hierarchy-ux-definition/
124
+
125
+ Use the sources as constraints, not as a style to copy. Cite links in the report/summary when they shaped the redesign.
126
+
127
+ If the user pushes back on the proposed direction, switch to `/qualia-polish --vibe` mode — do not start enumerating alternatives in the brief.
85
128
 
86
129
  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.
87
130
 
@@ -112,7 +155,9 @@ For App / Redesign / Section scope on multi-file work:
112
155
 
113
156
  Each agent receives:
114
157
  - `qualia-design/design-laws.md` + the matching register file
158
+ - `qualia-design/frontend.md`, `design-reference.md`, and `graphics.md` for App / Redesign / Loop scopes
115
159
  - `PRODUCT.md` + `DESIGN.md` (inlined)
160
+ - Online research anchors for Redesign scope, summarized in 3-6 bullets with links
116
161
  - Its 5 files (paths + contents)
117
162
  - Instruction: apply the Design Quality Rubric per file. Fix every dimension scoring &lt; 3. Make literal edits. Do NOT change logic — only styling.
118
163
 
@@ -130,6 +175,21 @@ For Component scope: do the work in main context. Read, fix, verify.
130
175
  | Motion intent | DESIGN.md §7 — easing, stagger, signature motion |
131
176
  | Microcopy | rename "Get Started" / "Learn More" to action-named CTAs |
132
177
  | Container depth | flatten card-on-card; remove side-stripe borders |
178
+ | Complex graphics | graphics.md — add meaningful product/data/process visuals, not decoration |
179
+
180
+ ### Stage 2b — Complex Visual Layer (App / Redesign / Loop)
181
+
182
+ For whole-app, redesign, and loop scopes, decide whether the page needs a stronger visual system.
183
+
184
+ 1. Read `qualia-design/graphics.md`.
185
+ 2. Inspect the product/domain from PRODUCT.md and CONTEXT.md.
186
+ 3. Choose one:
187
+ - **No complex visual**: explain why typography/layout alone is stronger.
188
+ - **Bitmap/media**: real/generative/search asset that reveals product/place/person/state.
189
+ - **Diagram/data**: custom SVG/canvas/chart that explains relationships.
190
+ - **3D/canvas**: Three.js or canvas scene for spatial/product/system experience.
191
+ 4. If adding a visual, implement it as a first-viewport or primary-section signal, not a tiny decoration.
192
+ 5. Verify mobile framing, reduced-motion fallback, contrast, and nonblank rendering.
133
193
 
134
194
  ### Stage 3 — Runtime gates (App / Section / Redesign only — needs dev server)
135
195
 
@@ -170,7 +230,7 @@ For each iteration:
170
230
 
171
231
  1. Capture all 3 viewports
172
232
  2. Pass to a vision-model agent with `qualia-design/design-rubric.md` as the prompt anchor + DESIGN.md as the spec
173
- 3. The agent scores 8 dimensions, anchored 1-5, with evidence per dimension
233
+ 3. The agent scores 9 dimensions, anchored 1-5, with evidence per dimension
174
234
  4. Apply fixes ONLY to dimensions scored 1 or 2 (don't nitpick 3s; prevents oscillation)
175
235
  5. STOP if: all dimensions ≥ 3 (success), OR any dimension regressed from previous iteration (regression-stop), OR 2 iterations reached (hard cap)
176
236
 
@@ -208,7 +268,7 @@ npx tsc --noEmit 2>&1 | tail -10
208
268
 
209
269
  ### Stage 7 — Commit & state
210
270
 
211
- For Critique scope: write the report to `.planning/polish-critique-{timestamp}.md` and STOP. Do not edit, do not commit.
271
+ For Critique scope: create `.planning/reports/polish/`, write the report to `.planning/reports/polish/polish-critique-{timestamp}.md`, and STOP. Do not edit, do not commit.
212
272
 
213
273
  For all other scopes:
214
274
 
@@ -219,7 +279,7 @@ polish({scope}): {brief summary}
219
279
 
220
280
  - {key change 1}
221
281
  - {key change 2}
222
- - rubric scores: typography {N}, color {N}, ..., aggregate {N}/40
282
+ - rubric scores: typography {N}, color {N}, graphics {N}, ..., aggregate {N}/45
223
283
 
224
284
  Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
225
285
  EOF
@@ -229,7 +289,7 @@ EOF
229
289
  If this is the FINAL polish before deploy (Handoff milestone, last phase):
230
290
 
231
291
  ```bash
232
- node ~/.claude/bin/state.js transition --to polished
292
+ node ${QUALIA_BIN}/state.js transition --to polished
233
293
  ```
234
294
 
235
295
  Otherwise, no state transition (polish is now a normal verb, not a phase boundary).
@@ -237,21 +297,21 @@ Otherwise, no state transition (polish is now a normal verb, not a phase boundar
237
297
  ### Output
238
298
 
239
299
  ```bash
240
- node ~/.claude/bin/qualia-ui.js divider
241
- node ~/.claude/bin/qualia-ui.js ok "Scope: {component|section|app|redesign|critique|quick}"
242
- node ~/.claude/bin/qualia-ui.js ok "Files: {N}"
243
- node ~/.claude/bin/qualia-ui.js ok "Slop-detect: {N critical, M high, K medium}"
244
- node ~/.claude/bin/qualia-ui.js ok "Rubric aggregate: {N}/40 (avg {N})"
245
- node ~/.claude/bin/qualia-ui.js ok "Vision iterations: {0|1|2}"
246
- node ~/.claude/bin/qualia-ui.js ok "Drift findings: {N}"
247
- node ~/.claude/bin/qualia-ui.js end "POLISHED" "{next command — depends on context}"
300
+ node ${QUALIA_BIN}/qualia-ui.js divider
301
+ node ${QUALIA_BIN}/qualia-ui.js ok "Scope: {component|section|app|redesign|critique|quick}"
302
+ node ${QUALIA_BIN}/qualia-ui.js ok "Files: {N}"
303
+ node ${QUALIA_BIN}/qualia-ui.js ok "Slop-detect: {N critical, M high, K medium}"
304
+ node ${QUALIA_BIN}/qualia-ui.js ok "Rubric aggregate: {N}/45 (avg {N})"
305
+ node ${QUALIA_BIN}/qualia-ui.js ok "Vision iterations: {0|1|2}"
306
+ node ${QUALIA_BIN}/qualia-ui.js ok "Drift findings: {N}"
307
+ node ${QUALIA_BIN}/qualia-ui.js end "POLISHED" "{next command — depends on context}"
248
308
  ```
249
309
 
250
310
  ## Rules
251
311
 
252
312
  1. **Read before write.** Understand every file before changing it.
253
313
  2. **DESIGN.md is law.** If a project decision exists, follow it. Don't override.
254
- 3. **Don't break functionality.** Only change styling, never logic.
314
+ 3. **Don't repair functionality here.** Only change styling, layout, copy polish, accessibility attributes, and design tokens already authorized by DESIGN.md. Route logic/data/config bugs to `/qualia-fix`.
255
315
  4. **Slop is a bug.** Critical-severity findings block commit. No overriding the script.
256
316
  5. **TypeScript must pass** after every change.
257
317
  6. **One commit per polish run** — not per category, not per file.
@@ -16,7 +16,7 @@
16
16
  * {
17
17
  * "iteration": 1,
18
18
  * "viewport_results": [{ viewport, scores, top_issues }],
19
- * "aggregate_scores": { typography, color, spatial, layout, shadow, motion, microcopy, container },
19
+ * "aggregate_scores": { typography, color, spatial, layout, shadow, motion, microcopy, container, graphics },
20
20
  * "top_issues": [{ dim, severity, description, likely_file, fix }],
21
21
  * "tokens_used": 14500
22
22
  * }
@@ -33,7 +33,7 @@ import path, { dirname } from "node:path";
33
33
  import { argv, exit } from "node:process";
34
34
  import { spawnSync } from "node:child_process";
35
35
 
36
- const DIMS = ["typography", "color", "spatial", "layout", "shadow", "motion", "microcopy", "container"];
36
+ const DIMS = ["typography", "color", "spatial", "layout", "shadow", "motion", "microcopy", "container", "graphics"];
37
37
 
38
38
  // ── helpers ──────────────────────────────────────────────────────────────
39
39
  function loadState(p) {
@@ -271,7 +271,7 @@ function cmdReport() {
271
271
  lines.push(`### Iteration ${it.iteration}`);
272
272
  const dims = DIMS.map((d) => `${d.slice(0, 4)}=${it.scores[d] ?? "?"}`).join(" ");
273
273
  lines.push(`- Scores: ${dims}`);
274
- lines.push(`- Aggregate: ${it.aggregate}/40 (avg ${(it.aggregate / 8).toFixed(2)})`);
274
+ lines.push(`- Aggregate: ${it.aggregate}/${DIMS.length * 5} (avg ${(it.aggregate / DIMS.length).toFixed(2)})`);
275
275
  lines.push(`- Pass: ${it.pass ? "YES" : "NO"} ${it.failing_dims.length ? `(failing: ${it.failing_dims.join(", ")})` : ""}`);
276
276
  if (it.top_issues && it.top_issues.length) {
277
277
  lines.push(`- Top issues:`);
@@ -2,11 +2,11 @@
2
2
  /**
3
3
  * score.mjs -- Qualia visual-polish loop scoring utility.
4
4
  *
5
- * Takes a JSON object with 8 dimension scores and computes pass/fail
5
+ * Takes a JSON object with 9 dimension scores and computes pass/fail
6
6
  * per the design rubric formula from qualia-design/design-rubric.md.
7
7
  *
8
8
  * Usage:
9
- * echo '{"typography":3,"color":2,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | node score.mjs
9
+ * echo '{"typography":3,"color":2,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3,"graphics":3}' | node score.mjs
10
10
  * node score.mjs --file scores.json
11
11
  * node score.mjs --scores '{"typography":4,"color":3,...}'
12
12
  *
@@ -31,6 +31,7 @@ const DIMENSIONS = [
31
31
  "motion",
32
32
  "microcopy",
33
33
  "container",
34
+ "graphics",
34
35
  ];
35
36
 
36
37
  const DIMENSION_ALIASES = {
@@ -50,6 +51,11 @@ const DIMENSION_ALIASES = {
50
51
  "container depth": "container",
51
52
  "container_depth": "container",
52
53
  "container depth & nesting": "container",
54
+ "visual system": "graphics",
55
+ "visual_system": "graphics",
56
+ "visual system & graphics": "graphics",
57
+ "visual_system_graphics": "graphics",
58
+ "complex graphics": "graphics",
53
59
  };
54
60
 
55
61
  function normalizeKey(key) {
@@ -112,7 +118,7 @@ function computeResult(scores) {
112
118
  return {
113
119
  scores,
114
120
  total,
115
- max: 40,
121
+ max: 45,
116
122
  avg,
117
123
  pass,
118
124
  failing,
@@ -6,11 +6,11 @@
6
6
  * 1. If source is a URL → capture screenshot at 1440 via playwright-capture.mjs.
7
7
  * If source is a local image path → use it directly.
8
8
  * 2. Emit a JSON scaffold the LLM uses to generate the extracted token bundle.
9
- * 3. The skill (qualia-vibe) reads the scaffold, runs the vision evaluator in
9
+ * 3. The skill (qualia-polish --vibe) reads the scaffold, runs the vision evaluator in
10
10
  * extract mode, gets the bundle back, renders it as a DESIGN.md draft.
11
11
  *
12
12
  * This script does NOT call any LLM directly — it stages the inputs and emits
13
- * a deterministic JSON contract. The /qualia-vibe skill orchestrates the LLM
13
+ * a deterministic JSON contract. The /qualia-polish --vibe skill orchestrates the LLM
14
14
  * call.
15
15
  *
16
16
  * Usage:
@@ -35,7 +35,7 @@ function flag(name, fallback) {
35
35
  }
36
36
 
37
37
  const source = flag("--source");
38
- const outDraft = flag("--out", ".planning/DESIGN-extracted.md");
38
+ const outDraft = flag("--out", ".planning/design/DESIGN-extracted.md");
39
39
 
40
40
  if (!source) {
41
41
  console.error("--source required (URL or local image path)");
@@ -49,7 +49,7 @@ let screenshotPath;
49
49
  const isUrl = /^https?:\/\//i.test(source);
50
50
  if (isUrl) {
51
51
  const stamp = Date.now().toString(36);
52
- const outDir = join(tmpdir(), `qualia-vibe-extract-${stamp}`);
52
+ const outDir = join(tmpdir(), `qualia-polish-vibe-extract-${stamp}`);
53
53
  mkdirSync(outDir, { recursive: true });
54
54
  screenshotPath = join(outDir, "ref-1440.png");
55
55
 
@@ -132,7 +132,7 @@ const scaffold = {
132
132
  rules: [
133
133
  "Banned fonts: Inter, Roboto, Arial, Helvetica, system-ui, Space Grotesk, Montserrat, Poppins, Lato, Open Sans. If you see one of these, name it AND flag it so the user can decide whether to ban or accept.",
134
134
  "Banned patterns: purple-blue gradient, gradient text, bounce/elastic easing. Flag the same way.",
135
- "Confidence < high → user must review before /qualia-vibe applies.",
135
+ "Confidence < high → user must review before /qualia-polish --vibe applies.",
136
136
  ],
137
137
  next_step: `After producing the bundle, write a DESIGN.md draft to ${outDraft} using the bundle to populate sections 1 (Direction), 2 (Color), 3 (Typography), 4 (Spacing), 6 (Depth), 7 (Motion). Leave sections that depend on PRODUCT.md or anti-references empty — the user will fill them.`,
138
138
  };