qualia-framework 5.5.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.
Files changed (31) hide show
  1. package/README.md +17 -13
  2. package/agents/research-synthesizer.md +4 -1
  3. package/agents/researcher.md +6 -1
  4. package/agents/visual-evaluator.md +1 -1
  5. package/bin/install.js +6 -6
  6. package/bin/slop-detect.mjs +1 -1
  7. package/docs/onboarding.html +623 -0
  8. package/guide.md +5 -6
  9. package/hooks/session-start.js +1 -1
  10. package/package.json +1 -1
  11. package/skills/qualia-discuss/SKILL.md +106 -6
  12. package/skills/qualia-feature/SKILL.md +216 -0
  13. package/skills/qualia-milestone/SKILL.md +73 -1
  14. package/skills/qualia-new/SKILL.md +52 -25
  15. package/skills/qualia-optimize/SKILL.md +1 -1
  16. package/skills/{qualia-polish-loop → qualia-polish}/REFERENCE.md +5 -5
  17. package/skills/qualia-polish/SKILL.md +13 -4
  18. package/skills/{qualia-polish-loop → qualia-polish}/scripts/loop.mjs +2 -2
  19. package/skills/{qualia-polish-loop → qualia-polish}/scripts/playwright-capture.mjs +1 -1
  20. package/skills/qualia-road/SKILL.md +10 -11
  21. package/templates/project-discovery.md +83 -0
  22. package/templates/project.md +7 -0
  23. package/tests/bin.test.sh +74 -62
  24. package/tests/slop-detect.test.sh +2 -2
  25. package/skills/qualia-polish-loop/SKILL.md +0 -201
  26. package/skills/qualia-prd/SKILL.md +0 -199
  27. package/skills/qualia-quick/SKILL.md +0 -44
  28. package/skills/qualia-task/SKILL.md +0 -98
  29. /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/broken.html +0 -0
  30. /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/clean.html +0 -0
  31. /package/skills/{qualia-polish-loop → qualia-polish}/scripts/score.mjs +0 -0
@@ -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, or a ground-up redesign. Trigger on 'polish', 'design pass', 'fix the design', 'redesign', 'critique', 'audit design', 'looks ugly', 'make it look better'. Replaces both /qualia-polish and /qualia-design from earlier versions."
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."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -9,12 +9,12 @@ allowed-tools:
9
9
  - Grep
10
10
  - Glob
11
11
  - Agent
12
- argument-hint: "[file|route|--redesign|--critique|--quick] [--register=brand|product]"
12
+ argument-hint: "[file|route|--redesign|--critique|--quick|--loop] [--register=brand|product] [--brief PATH] [--max 8] [--viewports 375,768,1440]"
13
13
  ---
14
14
 
15
15
  # /qualia-polish — Scope-Adaptive Design Pass
16
16
 
17
- One command. Six scopes. Use it whenever you need design work from a 30-second component touch-up to a 30-minute ground-up redesign.
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.
18
18
 
19
19
  ## Scopes
20
20
 
@@ -28,8 +28,17 @@ The first argument selects the scope. Stage selection follows from scope.
28
28
  | `/qualia-polish --redesign` | **Redesign** | ~30m | all + Stage 1 mandatory + 2 vision iterations |
29
29
  | `/qualia-polish --critique` | **Critique** | read-only | 0, 4, 5 (no edits) |
30
30
  | `/qualia-polish --quick` | **Quick** | ~1m | 0, 2, 7 (gates only, no vision loop) |
31
+ | `/qualia-polish --loop {url}` | **Loop** | ~5-15m | autonomous see/fix/verify, max 8 iterations |
31
32
 
32
- Other flags: `--register=brand|product` to override register inference.
33
+ Other flags: `--register=brand|product` overrides register inference. Loop-specific flags: `--brief PATH`, `--max N`, `--viewports 375,768,1440`, `--ref PATH`, `--budget 100000`.
34
+
35
+ ## --loop mode (autonomous visual loop)
36
+
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
+
39
+ This is the surface formerly known as `/qualia-polish-loop` (consolidated into a flag in v5.8.0). The scripts ship at `skills/qualia-polish/scripts/{loop,playwright-capture,score}.mjs`; vision evaluator is `agents/visual-evaluator.md`; full loop spec lives in this skill's `REFERENCE.md`.
40
+
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.
33
42
 
34
43
  ## Setup gates (non-optional, every scope)
35
44
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * loop.mjs — orchestrator state-machine for /qualia-polish-loop.
3
+ * loop.mjs — orchestrator state-machine for /qualia-polish --loop.
4
4
  *
5
5
  * Claude (the parent session) drives the loop by issuing CLI commands. This
6
6
  * script keeps the deterministic state — iteration counter, regression
@@ -294,7 +294,7 @@ switch (cmd) {
294
294
  case "--help":
295
295
  case "-h":
296
296
  case undefined:
297
- console.log(`loop.mjs — orchestrator for /qualia-polish-loop
297
+ console.log(`loop.mjs — orchestrator for /qualia-polish --loop
298
298
 
299
299
  Commands:
300
300
  init --state PATH (--url URL | --routes URL1,URL2,...) [--brief PATH] [--ref PATH] [--max 8] [--budget 100000] [--reduced-motion]
@@ -36,7 +36,7 @@ function parseArgs() {
36
36
  } else if (a === "--wait" && argv[i + 1]) args.wait = parseInt(argv[++i], 10);
37
37
  else if (a === "--reduced-motion") args.reducedMotion = true;
38
38
  else if (a === "--help" || a === "-h") {
39
- console.log(`playwright-capture.mjs — Screenshot capture for /qualia-polish-loop
39
+ console.log(`playwright-capture.mjs — Screenshot capture for /qualia-polish --loop
40
40
 
41
41
  Usage:
42
42
  node playwright-capture.mjs --url <url> --out <dir> [--viewports 375,768,1440] [--wait 1500] [--reduced-motion]
@@ -45,23 +45,22 @@ 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
- ## /qualia-polish-loop -- autonomous visual QA (v5.1+, hardened in v5.2)
48
+ ## /qualia-polish --loop -- autonomous visual QA (v5.1+, consolidated into /qualia-polish in v5.8)
49
49
  ```
50
- /qualia-polish-loop http://localhost:3000 screenshot + eval + fix loop
51
- /qualia-polish-loop {url} --max 4 cap iterations
52
- /qualia-polish-loop {url} --ref design.png anchor to reference image
53
- /qualia-polish-loop {url} --reduced-motion force prefers-reduced-motion (v5.2+)
54
- /qualia-polish-loop --routes /a,/b,/c multi-route sweep (v5.2+)
50
+ /qualia-polish --loop http://localhost:3000 screenshot + eval + fix loop
51
+ /qualia-polish --loop {url} --max 4 cap iterations
52
+ /qualia-polish --loop {url} --ref design.png anchor to reference image
53
+ /qualia-polish --loop {url} --reduced-motion force prefers-reduced-motion
54
+ /qualia-polish --loop --routes /a,/b,/c multi-route sweep
55
55
  ```
56
56
  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
57
 
58
- ## v5.3+ skills (Matt Pocock gaps closed)
58
+ ## v5.3+ skills
59
59
  ```
60
- /qualia-prd synthesize current conversation → .planning/PRD-{slug}.md (durable feature spec)
61
60
  /qualia-hook-gen convert a CLAUDE.md/rules instruction into a deterministic pre-tool-use hook
62
- /qualia-optimize --deepen now spawns 3 parallel interface-design variants per candidate (Step 5b)
61
+ /qualia-optimize --deepen spawns 3 parallel interface-design variants per candidate (Step 5b)
63
62
  ```
64
- `/qualia-prd` pairs with `/qualia-issues` to form the PRD → vertical-slice → execute loop. `/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.
63
+ `/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.
65
64
 
66
65
  ## Alignment substrate (v5.0+)
67
66
  Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (domain glossary) and `.planning/decisions/` (ADRs):
@@ -80,7 +79,7 @@ Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (
80
79
  ```
81
80
  Lost? → /qualia (state router — tells you the next command)
82
81
  Stuck/weird? → /qualia-idk (diagnostic — spawns plan-view + code-view agents in parallel)
83
- Quick fix? → /qualia-quick (skip planning for small tasks)
82
+ Single feature? → /qualia-feature (auto-scoped: inline for trivia, fresh spawn for 1-5 files)
84
83
  Paused? → /qualia-resume (restore from .continue-here.md or STATE.md)
85
84
  End of day? → /qualia-report (mandatory before clock-out; writes ERP payload)
86
85
  Debug bug? → /qualia-debug (feedback-loop-first investigation)
@@ -0,0 +1,83 @@
1
+ ---
2
+ project_type: {demo or full}
3
+ discovered_at: {YYYY-MM-DD}
4
+ discovery_mode: project
5
+ ---
6
+
7
+ # Project Discovery, {Project Name}
8
+
9
+ The non-technical kickoff interview output. `/qualia-discuss` writes this in PROJECT MODE before `/qualia-new` generates JOURNEY.md. Captures intent, audience, brand, and constraints in the user's own words.
10
+
11
+ Demo path: 8 questions. Full-project path: 14 questions.
12
+
13
+ ## 1. The one-line pitch
14
+
15
+ > {What is this thing, in one sentence a stranger would understand?}
16
+
17
+ ## 2. Who is it for
18
+
19
+ > {Name three real humans who will use this. Not personas, real names plus their scenario.}
20
+
21
+ ## 3. The "remember 24 hours later" sentence
22
+
23
+ > {What does someone remember 24 hours after first using this?}
24
+
25
+ ## 4. Three anti-references
26
+
27
+ > {Three sites or apps this should NOT look like, with one-line reasons each.}
28
+
29
+ ## 5. Brand voice
30
+
31
+ > {Three adjectives, then one paragraph of voice in motion — an error message, a confirmation, an empty state.}
32
+
33
+ ## 6. Success criterion
34
+
35
+ > {How does the client know this worked? One observable outcome.}
36
+
37
+ ## 7. Hard constraints
38
+
39
+ > {Anything that is non-negotiable: stack, deadline, compliance, integrations, budget.}
40
+
41
+ ## 8. Out of scope
42
+
43
+ > {What is intentionally NOT in this project, even if it would be obvious to add.}
44
+
45
+ ---
46
+
47
+ The remaining six questions only run for `project_type: full`. Demo mode stops here.
48
+
49
+ ## 9. Milestone arc, in the client's words
50
+
51
+ > {After the demo, what's the next chapter? After that, what's the chapter after? Stop at three to five chapters total. The last chapter is always Handoff.}
52
+
53
+ ## 10. Compliance and legal
54
+
55
+ > {Anything regulated: payments, medical, legal, finance, accessibility commitments, data residency.}
56
+
57
+ ## 11. Integrations
58
+
59
+ > {Third-party systems this must talk to, in priority order.}
60
+
61
+ ## 12. Content and copy
62
+
63
+ > {Who writes the copy and where does it live, today and after handoff?}
64
+
65
+ ## 13. Team and roles after handoff
66
+
67
+ > {Who maintains this after we ship? What can they do, what can't they do?}
68
+
69
+ ## 14. Budget and timeline shape
70
+
71
+ > {Fixed deadline, fixed scope, or fixed budget? Pick one — the other two flex.}
72
+
73
+ ---
74
+
75
+ ## How this feeds `/qualia-new`
76
+
77
+ - §1-§5 seed PROJECT.md (one-line pitch, what we're building) and PRODUCT.md (users, register, voice, anti-references).
78
+ - §6 becomes the first row of the success-criteria table in ROADMAP.md.
79
+ - §7-§8 populate PROJECT.md's "Out of Scope" and the constraints section.
80
+ - §9 (full only) seeds JOURNEY.md milestone names + "why now" lines.
81
+ - §10-§14 (full only) feed research scoping and the Handoff milestone checklist.
82
+
83
+ Demo projects skip §9-§14 because they ARE one milestone — the journey is just that milestone plus an implicit "client signs, we extend" branch handled by `/qualia-milestone`.
@@ -1,8 +1,15 @@
1
+ ---
2
+ project_type: full
3
+ ---
4
+
1
5
  # {Project Name}
2
6
 
3
7
  ## Client
4
8
  {client name}
5
9
 
10
+ ## Project Type
11
+ {demo or full — demo is a single shippable milestone for a sales conversation; full is the multi-milestone arc to Handoff}
12
+
6
13
  ## What We're Building
7
14
  {description}
8
15
 
package/tests/bin.test.sh CHANGED
@@ -1131,52 +1131,59 @@ fi
1131
1131
  echo ""
1132
1132
  echo "--- v5.0.0 (visual-polish loop addendum) ---"
1133
1133
 
1134
- # 99. qualia-polish-loop SKILL.md installs
1134
+ # 99. qualia-polish SKILL.md installs (v5.8: polish-loop consolidated into --loop flag)
1135
1135
  TMP=$(mktmp)
1136
1136
  echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
1137
- if [ -f "$TMP/.claude/skills/qualia-polish-loop/SKILL.md" ]; then
1138
- pass "qualia-polish-loop SKILL.md installs"
1137
+ if [ -f "$TMP/.claude/skills/qualia-polish/SKILL.md" ]; then
1138
+ pass "qualia-polish SKILL.md installs"
1139
1139
  else
1140
- fail_case "qualia-polish-loop SKILL.md missing after install"
1140
+ fail_case "qualia-polish SKILL.md missing after install"
1141
1141
  fi
1142
1142
 
1143
- # 100. qualia-polish-loop REFERENCE.md installs
1144
- if [ -f "$TMP/.claude/skills/qualia-polish-loop/REFERENCE.md" ]; then
1145
- pass "qualia-polish-loop REFERENCE.md installs"
1143
+ # 100. qualia-polish REFERENCE.md installs (carries the loop spec)
1144
+ if [ -f "$TMP/.claude/skills/qualia-polish/REFERENCE.md" ]; then
1145
+ pass "qualia-polish REFERENCE.md installs"
1146
1146
  else
1147
- fail_case "qualia-polish-loop REFERENCE.md missing after install"
1147
+ fail_case "qualia-polish REFERENCE.md missing after install"
1148
1148
  fi
1149
1149
 
1150
- # 101. qualia-polish-loop SKILL.md references the design rubric
1151
- if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish-loop/SKILL.md"; then
1152
- pass "qualia-polish-loop references design-rubric.md"
1150
+ # 101. qualia-polish SKILL.md references the design rubric
1151
+ if grep -q "design-rubric.md" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
1152
+ pass "qualia-polish references design-rubric.md"
1153
1153
  else
1154
- fail_case "qualia-polish-loop missing rubric reference"
1154
+ fail_case "qualia-polish missing rubric reference"
1155
1155
  fi
1156
1156
 
1157
- # 102. qualia-polish-loop REFERENCE.md has the anchored vision eval prompt
1158
- if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish-loop/REFERENCE.md"; then
1159
- pass "qualia-polish-loop REFERENCE.md has anchored rubric prompt"
1157
+ # 102. qualia-polish REFERENCE.md has the anchored vision eval prompt
1158
+ if grep -q "DEFAULT TO 3" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
1159
+ pass "qualia-polish REFERENCE.md has anchored rubric prompt"
1160
1160
  else
1161
- fail_case "qualia-polish-loop REFERENCE.md missing anchored rubric"
1161
+ fail_case "qualia-polish REFERENCE.md missing anchored rubric"
1162
1162
  fi
1163
1163
 
1164
- # 103. qualia-polish-loop SKILL.md has regression detection (LOOP_REGRESSION_DETECTED)
1165
- if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish-loop/SKILL.md"; then
1166
- pass "qualia-polish-loop has regression kill-switch"
1164
+ # 103. qualia-polish REFERENCE.md has regression detection (LOOP_REGRESSION_DETECTED)
1165
+ if grep -q "LOOP_REGRESSION_DETECTED" "$TMP/.claude/skills/qualia-polish/REFERENCE.md"; then
1166
+ pass "qualia-polish has regression kill-switch"
1167
1167
  else
1168
- fail_case "qualia-polish-loop missing regression kill-switch"
1168
+ fail_case "qualia-polish missing regression kill-switch"
1169
+ fi
1170
+
1171
+ # 103b. qualia-polish SKILL.md documents the --loop flag
1172
+ if grep -q -- "--loop" "$TMP/.claude/skills/qualia-polish/SKILL.md"; then
1173
+ pass "qualia-polish SKILL.md documents --loop flag"
1174
+ else
1175
+ fail_case "qualia-polish SKILL.md missing --loop documentation"
1169
1176
  fi
1170
1177
 
1171
1178
  # 104. score.mjs exists in the framework skill scripts
1172
- if [ -f "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/score.mjs" ]; then
1179
+ if [ -f "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" ]; then
1173
1180
  pass "score.mjs exists in skill scripts"
1174
1181
  else
1175
1182
  fail_case "score.mjs missing from skill scripts"
1176
1183
  fi
1177
1184
 
1178
1185
  # 105. score.mjs computes pass correctly (all dims >= 3)
1179
- SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/score.mjs" 2>&1)
1186
+ SCORE_OUT=$(echo '{"typography":3,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
1180
1187
  EXIT=$?
1181
1188
  if [ "$EXIT" -eq 0 ] && echo "$SCORE_OUT" | grep -q '"pass": true'; then
1182
1189
  pass "score.mjs pass on all-3 scores"
@@ -1185,7 +1192,7 @@ else
1185
1192
  fi
1186
1193
 
1187
1194
  # 106. score.mjs computes fail correctly (one dim < 3)
1188
- SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/score.mjs" 2>&1)
1195
+ SCORE_OUT=$(echo '{"typography":2,"color":3,"spatial":3,"layout":3,"shadow":3,"motion":3,"microcopy":3,"container":3}' | $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/score.mjs" 2>&1)
1189
1196
  EXIT=$?
1190
1197
  if [ "$EXIT" -eq 1 ] && echo "$SCORE_OUT" | grep -q '"pass": false'; then
1191
1198
  pass "score.mjs fail on dim < 3"
@@ -1193,38 +1200,38 @@ else
1193
1200
  fail_case "score.mjs fail computation" "exit=$EXIT"
1194
1201
  fi
1195
1202
 
1196
- # 107. qualia-road references qualia-polish-loop
1197
- if grep -q "qualia-polish-loop" "$TMP/.claude/skills/qualia-road/SKILL.md"; then
1198
- pass "qualia-road references qualia-polish-loop"
1203
+ # 107. qualia-road references the polish loop (now via --loop flag)
1204
+ if grep -qE "qualia-polish --loop|/qualia-polish --loop" "$TMP/.claude/skills/qualia-road/SKILL.md"; then
1205
+ pass "qualia-road references /qualia-polish --loop"
1199
1206
  else
1200
- fail_case "qualia-road missing qualia-polish-loop reference"
1207
+ fail_case "qualia-road missing /qualia-polish --loop reference"
1201
1208
  fi
1202
1209
 
1203
1210
  # 108. package.json version is 5.x (5.1+ accepted; v5.1 / v5.2 share the v5 line)
1204
- if grep -qE '"5\.[1234]\.' "$FRAMEWORK_DIR/package.json"; then
1211
+ if grep -qE '"5\.([1-9]|[1-9][0-9])\.' "$FRAMEWORK_DIR/package.json"; then
1205
1212
  pass "package.json version is 5.x"
1206
1213
  else
1207
1214
  fail_case "package.json version not 5.x"
1208
1215
  fi
1209
1216
 
1210
1217
  # 109. loop.mjs installs (orchestrator)
1211
- if [ -f "$TMP/.claude/skills/qualia-polish-loop/scripts/loop.mjs" ]; then
1212
- pass "qualia-polish-loop scripts/loop.mjs installs"
1218
+ if [ -f "$TMP/.claude/skills/qualia-polish/scripts/loop.mjs" ]; then
1219
+ pass "qualia-polish scripts/loop.mjs installs"
1213
1220
  else
1214
1221
  fail_case "scripts/loop.mjs missing — install.js scripts/ subfolder copy broken"
1215
1222
  fi
1216
1223
 
1217
1224
  # 110. playwright-capture.mjs installs (capture helper)
1218
- if [ -f "$TMP/.claude/skills/qualia-polish-loop/scripts/playwright-capture.mjs" ]; then
1219
- pass "qualia-polish-loop scripts/playwright-capture.mjs installs"
1225
+ if [ -f "$TMP/.claude/skills/qualia-polish/scripts/playwright-capture.mjs" ]; then
1226
+ pass "qualia-polish scripts/playwright-capture.mjs installs"
1220
1227
  else
1221
1228
  fail_case "scripts/playwright-capture.mjs missing"
1222
1229
  fi
1223
1230
 
1224
1231
  # 111. fixtures/ subfolder installs (self-test pages)
1225
- if [ -f "$TMP/.claude/skills/qualia-polish-loop/fixtures/clean.html" ] && \
1226
- [ -f "$TMP/.claude/skills/qualia-polish-loop/fixtures/broken.html" ]; then
1227
- pass "qualia-polish-loop fixtures/ installs (clean.html + broken.html)"
1232
+ if [ -f "$TMP/.claude/skills/qualia-polish/fixtures/clean.html" ] && \
1233
+ [ -f "$TMP/.claude/skills/qualia-polish/fixtures/broken.html" ]; then
1234
+ pass "qualia-polish fixtures/ installs (clean.html + broken.html)"
1228
1235
  else
1229
1236
  fail_case "fixtures/ subfolder not copied by install.js"
1230
1237
  fi
@@ -1237,7 +1244,7 @@ else
1237
1244
  fi
1238
1245
 
1239
1246
  # 113. loop.mjs parses as valid Node ESM
1240
- EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" 2>/dev/null || EXIT=$?
1247
+ EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" 2>/dev/null || EXIT=$?
1241
1248
  if [ "$EXIT" -eq 0 ]; then
1242
1249
  pass "loop.mjs parses as valid Node ESM"
1243
1250
  else
@@ -1245,7 +1252,7 @@ else
1245
1252
  fi
1246
1253
 
1247
1254
  # 114. playwright-capture.mjs parses as valid Node ESM
1248
- EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/playwright-capture.mjs" 2>/dev/null || EXIT=$?
1255
+ EXIT=0; $NODE --check "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" 2>/dev/null || EXIT=$?
1249
1256
  if [ "$EXIT" -eq 0 ]; then
1250
1257
  pass "playwright-capture.mjs parses as valid Node ESM"
1251
1258
  else
@@ -1255,7 +1262,7 @@ fi
1255
1262
  # 115. loop.mjs init creates a valid state file
1256
1263
  TMP_STATE=$(mktmp)/qpl-state.json
1257
1264
  mkdir -p "$(dirname "$TMP_STATE")"
1258
- EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1265
+ EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1259
1266
  --state "$TMP_STATE" --url "http://localhost:3000" --max 4 --budget 50000 >/dev/null 2>&1 || EXIT=$?
1260
1267
  if [ "$EXIT" -eq 0 ] && [ -f "$TMP_STATE" ] && grep -q '"verdict": "pending"' "$TMP_STATE"; then
1261
1268
  pass "loop.mjs init creates valid state.json"
@@ -1267,7 +1274,7 @@ fi
1267
1274
  TMP_STATE2=$(mktmp)/qpl-kill.json
1268
1275
  TMP_EVAL=$(mktmp)/qpl-eval.json
1269
1276
  mkdir -p "$(dirname "$TMP_STATE2")" "$(dirname "$TMP_EVAL")"
1270
- $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1277
+ $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1271
1278
  --state "$TMP_STATE2" --url "http://localhost:3000" --max 8 >/dev/null 2>&1
1272
1279
  # write 3 identical evals
1273
1280
  KILL_OK=true
@@ -1282,7 +1289,7 @@ for ITER in 1 2 3; do
1282
1289
  "pass": false
1283
1290
  }
1284
1291
  EOF
1285
- EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" record \
1292
+ EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" record \
1286
1293
  --state "$TMP_STATE2" --eval "$TMP_EVAL" >/dev/null 2>&1 || EXIT=$?
1287
1294
  if [ "$ITER" -lt 3 ] && [ "$EXIT" -ne 1 ]; then KILL_OK=false; fi
1288
1295
  if [ "$ITER" -eq 3 ] && [ "$EXIT" -ne 3 ]; then KILL_OK=false; fi
@@ -1430,7 +1437,7 @@ fi
1430
1437
 
1431
1438
  # 128. package.json bumped to 5.x (5.1+ accepted; 5.2 is the v5.2 release)
1432
1439
  PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
1433
- if echo "$PKG_V" | grep -qE "^5\.[1234]\."; then
1440
+ if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
1434
1441
  pass "package.json version bumped to 5.x ($PKG_V)"
1435
1442
  else
1436
1443
  fail_case "package.json version not 5.x" "got=$PKG_V"
@@ -1442,7 +1449,7 @@ echo "--- v5.2.0 (polish-loop reliability) ---"
1442
1449
  # 129. loop.mjs init accepts --routes and stores the URL list
1443
1450
  TMP_S=$(mktmp)/qpl-routes.json
1444
1451
  mkdir -p "$(dirname "$TMP_S")"
1445
- EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1452
+ EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1446
1453
  --state "$TMP_S" \
1447
1454
  --routes "http://x.test/a,http://x.test/b,http://x.test/c" \
1448
1455
  --max 4 >/dev/null 2>&1 || EXIT=$?
@@ -1466,7 +1473,7 @@ fi
1466
1473
  # 131. loop.mjs init accepts --reduced-motion and records it in state
1467
1474
  TMP_S2=$(mktmp)/qpl-rm.json
1468
1475
  mkdir -p "$(dirname "$TMP_S2")"
1469
- EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1476
+ EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1470
1477
  --state "$TMP_S2" --url "http://x.test/" --reduced-motion >/dev/null 2>&1 || EXIT=$?
1471
1478
  if [ "$EXIT" -eq 0 ] && grep -q '"reduced_motion": true' "$TMP_S2"; then
1472
1479
  pass "loop.mjs init --reduced-motion records state.reduced_motion=true"
@@ -1475,7 +1482,7 @@ else
1475
1482
  fi
1476
1483
 
1477
1484
  # 132. playwright-capture.mjs accepts --reduced-motion (parses without error)
1478
- EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/playwright-capture.mjs" --help 2>&1) || EXIT=$?
1485
+ EXIT=0; OUT=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/playwright-capture.mjs" --help 2>&1) || EXIT=$?
1479
1486
  if [ "$EXIT" -eq 0 ] && echo "$OUT" | grep -q -- "--reduced-motion"; then
1480
1487
  pass "playwright-capture.mjs --help documents --reduced-motion"
1481
1488
  else
@@ -1485,7 +1492,7 @@ fi
1485
1492
  # 133. loop.mjs init rejects when neither --url nor --routes given
1486
1493
  TMP_S3=$(mktmp)/qpl-nourl.json
1487
1494
  mkdir -p "$(dirname "$TMP_S3")"
1488
- EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1495
+ EXIT=0; $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1489
1496
  --state "$TMP_S3" --max 4 >/dev/null 2>&1 || EXIT=$?
1490
1497
  if [ "$EXIT" -eq 2 ]; then
1491
1498
  pass "loop.mjs init rejects missing --url/--routes (exit 2)"
@@ -1496,9 +1503,9 @@ fi
1496
1503
  # 134. loop.mjs report mentions multi-route when state.urls > 1
1497
1504
  TMP_S4=$(mktmp)/qpl-rep.json
1498
1505
  mkdir -p "$(dirname "$TMP_S4")"
1499
- $NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" init \
1506
+ $NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" init \
1500
1507
  --state "$TMP_S4" --routes "http://a/,http://b/" >/dev/null 2>&1
1501
- REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish-loop/scripts/loop.mjs" report --state "$TMP_S4" 2>&1)
1508
+ REP=$($NODE "$FRAMEWORK_DIR/skills/qualia-polish/scripts/loop.mjs" report --state "$TMP_S4" 2>&1)
1502
1509
  if echo "$REP" | grep -q "URLs (2)"; then
1503
1510
  pass "loop.mjs report renders multi-route header"
1504
1511
  else
@@ -1512,27 +1519,32 @@ echo "--- v5.3.0 (Matt Pocock gaps: prd, hook-gen, parallel-interface) ---"
1512
1519
  TMP=$(mktmp)
1513
1520
  echo "QS-FAWZI-01" | HOME="$TMP" $NODE "$INSTALL_JS" >/dev/null 2>&1
1514
1521
 
1515
- # 135. qualia-prd skill installs
1516
- if [ -f "$TMP/.claude/skills/qualia-prd/SKILL.md" ]; then
1517
- pass "qualia-prd skill installs"
1522
+ # 135-137. /qualia-prd removed in v5.8.0 (was deprecated, overlapped /qualia-discuss).
1523
+ # Assert non-existence so the framework cannot accidentally re-ship it.
1524
+ if [ ! -f "$TMP/.claude/skills/qualia-prd/SKILL.md" ]; then
1525
+ pass "qualia-prd removed (v5.8.0 cleanup)"
1526
+ else
1527
+ fail_case "qualia-prd unexpectedly present after v5.8.0 removal"
1528
+ fi
1529
+
1530
+ # v5.8.0: assert /qualia-quick + /qualia-task also removed (were deprecated in v5.7).
1531
+ if [ ! -f "$TMP/.claude/skills/qualia-quick/SKILL.md" ]; then
1532
+ pass "qualia-quick removed (v5.8.0 cleanup)"
1518
1533
  else
1519
- fail_case "qualia-prd SKILL.md missing after install"
1534
+ fail_case "qualia-quick unexpectedly present after v5.8.0 removal"
1520
1535
  fi
1521
1536
 
1522
- # 136. qualia-prd description mentions PRD synthesis from conversation
1523
- if grep -q "synthesize\|Synthesize" "$TMP/.claude/skills/qualia-prd/SKILL.md" \
1524
- && grep -q "/qualia-issues" "$TMP/.claude/skills/qualia-prd/SKILL.md"; then
1525
- pass "qualia-prd describes synthesis flow + pairs with /qualia-issues"
1537
+ if [ ! -f "$TMP/.claude/skills/qualia-task/SKILL.md" ]; then
1538
+ pass "qualia-task removed (v5.8.0 cleanup)"
1526
1539
  else
1527
- fail_case "qualia-prd missing synthesis or /qualia-issues link"
1540
+ fail_case "qualia-task unexpectedly present after v5.8.0 removal"
1528
1541
  fi
1529
1542
 
1530
- # 137. qualia-prd documents fork-based token discipline
1531
- if grep -qE "[Ff]orked subagent|fork.*subagent" "$TMP/.claude/skills/qualia-prd/SKILL.md" \
1532
- && grep -q "Token discipline" "$TMP/.claude/skills/qualia-prd/SKILL.md"; then
1533
- pass "qualia-prd documents fork-based synthesis (token discipline)"
1543
+ # v5.8.0: assert /qualia-feature is the canonical single-feature surface.
1544
+ if [ -f "$TMP/.claude/skills/qualia-feature/SKILL.md" ]; then
1545
+ pass "qualia-feature installed (canonical single-feature surface)"
1534
1546
  else
1535
- fail_case "qualia-prd missing fork/token-discipline section"
1547
+ fail_case "qualia-feature missing after install"
1536
1548
  fi
1537
1549
 
1538
1550
  # 138. qualia-hook-gen skill installs
@@ -1577,7 +1589,7 @@ fi
1577
1589
 
1578
1590
  # 143. package.json version is 5.x (5.1+ accepted; v5.3 is the v5.3 release)
1579
1591
  PKG_V=$($NODE -e 'console.log(require("'"$FRAMEWORK_DIR"'/package.json").version)')
1580
- if echo "$PKG_V" | grep -qE "^5\.[1234]\."; then
1592
+ if echo "$PKG_V" | grep -qE "^5\.([1-9]|[1-9][0-9])\."; then
1581
1593
  pass "package.json version is 5.x ($PKG_V) — v5.3 accepted"
1582
1594
  else
1583
1595
  fail_case "package.json version not 5.x" "got=$PKG_V"
@@ -121,8 +121,8 @@ else
121
121
  fail_case "gradient detection" "expected exit 1, got $EXIT_CODE"
122
122
  fi
123
123
 
124
- # ── Existing fixture: skills/qualia-polish-loop/fixtures/broken.html ──
125
- FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish-loop/fixtures/broken.html"
124
+ # ── Existing fixture: skills/qualia-polish/fixtures/broken.html ──
125
+ FIXTURE="$(cd "$(dirname "$0")/.." && pwd)/skills/qualia-polish/fixtures/broken.html"
126
126
  if [ -f "$FIXTURE" ]; then
127
127
  EXIT_CODE=0
128
128
  $NODE "$SLOP_DETECT" "$FIXTURE" >/dev/null 2>&1 || EXIT_CODE=$?