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
  #!/usr/bin/env node
2
2
  /**
3
- * tokens.mjs — read/write design tokens for /qualia-vibe.
3
+ * tokens.mjs — read/write design tokens for /qualia-polish --vibe.
4
4
  *
5
5
  * Commands:
6
6
  * tokens.mjs sync --design .planning/DESIGN.md [--write]
@@ -36,13 +36,13 @@ function hasFlag(name) {
36
36
  const CMD = argv[2];
37
37
 
38
38
  if (!CMD || CMD === "--help" || CMD === "-h") {
39
- console.log(`tokens.mjs — design-token utility for /qualia-vibe
39
+ console.log(`tokens.mjs — design-token utility for /qualia-polish --vibe
40
40
 
41
41
  Usage:
42
42
  tokens.mjs sync --design <path> [--write]
43
43
  tokens.mjs propose-variants --product <path> --design <path> --count <N>
44
44
 
45
- See skills/qualia-vibe/SKILL.md.
45
+ See skills/qualia-polish/SKILL.md.
46
46
  `);
47
47
  exit(0);
48
48
  }
@@ -268,7 +268,7 @@ function cmdSync() {
268
268
  ``,
269
269
  `## §sync — auto-synced from code (${stamp})`,
270
270
  ``,
271
- `<!-- Generated by /qualia-vibe --sync --write. Reflects values actually present in code at sync time. -->`,
271
+ `<!-- Generated by /qualia-polish --vibe --sync --write. Reflects values actually present in code at sync time. -->`,
272
272
  ``,
273
273
  "```css",
274
274
  `:root {`,
@@ -307,7 +307,7 @@ function cmdProposeVariants() {
307
307
 
308
308
  // Emit a structured scaffold the LLM uses to generate variants.
309
309
  const scaffold = {
310
- instruction: `Generate exactly ${count} aesthetic-direction variants for /qualia-vibe --variants. Each variant must be opinionated and concrete — no "modern minimal" hedging. Variants must be meaningfully different from each other AND from the current direction.`,
310
+ instruction: `Generate exactly ${count} aesthetic-direction variants for /qualia-polish --vibe --variants. Each variant must be opinionated and concrete — no "modern minimal" hedging. Variants must be meaningfully different from each other AND from the current direction.`,
311
311
  context: {
312
312
  product_md: product.slice(0, 4000),
313
313
  current_direction_lines: design
@@ -323,7 +323,7 @@ function cmdProposeVariants() {
323
323
  "No purple-blue gradients.",
324
324
  "No bounce/elastic easing.",
325
325
  `Respect anti-references from PRODUCT.md if present.`,
326
- "Each variant should be commit-able as-is — concrete enough that /qualia-vibe can apply it without further questions.",
326
+ "Each variant should be commit-able as-is — concrete enough that /qualia-polish --vibe can apply it without further questions.",
327
327
  ],
328
328
  };
329
329
 
@@ -53,9 +53,9 @@ or applies manually.
53
53
  ### 1. Load the failure
54
54
 
55
55
  ```bash
56
- node ~/.claude/bin/qualia-ui.js banner postmortem 2>/dev/null || true
56
+ node ${QUALIA_BIN}/qualia-ui.js banner postmortem 2>/dev/null || true
57
57
 
58
- PHASE="${PHASE:-$(node ~/.claude/bin/state.js check 2>/dev/null | node -e 'let s=""; process.stdin.on("data",d=>s+=d).on("end",()=>{try{console.log(JSON.parse(s).phase)}catch{console.log("")}})')}"
58
+ PHASE="${PHASE:-$(node ${QUALIA_BIN}/state.js check 2>/dev/null | node -e 'let s=""; process.stdin.on("data",d=>s+=d).on("end",()=>{try{console.log(JSON.parse(s).phase)}catch{console.log("")}})')}"
59
59
  [ -z "$PHASE" ] && { echo "QUALIA: Could not resolve current phase. Pass --phase N explicitly."; exit 1; }
60
60
 
61
61
  VERIFY_FILE=".planning/phase-${PHASE}-verification.md"
@@ -76,13 +76,13 @@ match a finding to the file most likely responsible:
76
76
 
77
77
  ```bash
78
78
  # Agent prompts (planner, builder, plan-checker, verifier, etc.)
79
- ls ~/.claude/agents/
79
+ ls ${QUALIA_AGENTS}/
80
80
  # Skill descriptions (qualia-plan, qualia-build, qualia-verify, etc.)
81
- ls ~/.claude/skills/
81
+ ls ${QUALIA_SKILLS}/
82
82
  # Project rules + grounding
83
- ls ~/.claude/rules/
83
+ ls ${QUALIA_RULES}/
84
84
  # Already-curated knowledge
85
- node ~/.claude/bin/knowledge.js
85
+ node ${QUALIA_BIN}/knowledge.js
86
86
  ```
87
87
 
88
88
  You don't read all of them — you read the ones whose job description
@@ -163,7 +163,7 @@ the framework's own type/test gates (`node --test tests/runner.js` if you
163
163
  modified anything in `bin/`, `agents/`, or `rules/`) to confirm no
164
164
  regression.
165
165
 
166
- If a proposed delta is to a `~/.claude/agents/X.md` file (the installed
166
+ If a proposed delta is to a `${QUALIA_AGENTS}/X.md` file (the installed
167
167
  copy), edit that copy directly — the user re-running the installer will
168
168
  overwrite it next release, so also flag a TODO in the postmortem report
169
169
  saying "this delta should be PR'd back to the framework repo at
@@ -177,7 +177,7 @@ where data is unprotected"), append to the curated tier so future
177
177
  builders pick it up:
178
178
 
179
179
  ```bash
180
- node ~/.claude/bin/knowledge.js append \
180
+ node ${QUALIA_BIN}/knowledge.js append \
181
181
  --type pattern \
182
182
  --title "{lesson title}" \
183
183
  --body "{lesson body}" \
@@ -220,7 +220,7 @@ node ~/.claude/bin/knowledge.js append \
220
220
  AI layer, not the codebase. The gap-closure loop (`/qualia-plan
221
221
  {N} --gaps`) handles the code. Postmortem only touches `agents/`,
222
222
  `rules/`, `skills/`, and the knowledge layer.
223
- - **Auto-applying deltas to `~/.claude/agents/X.md` without flagging a
223
+ - **Auto-applying deltas to `${QUALIA_AGENTS}/X.md` without flagging a
224
224
  framework PR TODO.** That edit lasts until the next reinstall. Always
225
225
  note the TODO so the lesson reaches the framework repo.
226
226
  - **Promoting every postmortem finding to knowledge.** Most are
@@ -24,11 +24,11 @@ This is not a task-completion ceremony. The report records what happened during
24
24
  ### Step 0 — Pre-flight (graceful)
25
25
 
26
26
  ```bash
27
- node ~/.claude/bin/qualia-ui.js banner report
27
+ node ${QUALIA_BIN}/qualia-ui.js banner report
28
28
 
29
29
  # Sanity checks — soft failures only, never block the report
30
- test -d .git || node ~/.claude/bin/qualia-ui.js warn "Not a git repo — local commit will be skipped, ERP upload will still try"
31
- test -f .planning/tracking.json || node ~/.claude/bin/qualia-ui.js warn "No tracking.json yet — ERP payload will use defaults"
30
+ test -d .git || node ${QUALIA_BIN}/qualia-ui.js warn "Not a git repo — local commit will be skipped, ERP upload will still try"
31
+ test -f .planning/tracking.json || node ${QUALIA_BIN}/qualia-ui.js warn "No tracking.json yet — ERP payload will use defaults"
32
32
 
33
33
  DRY_RUN="${DRY_RUN:-false}"
34
34
  echo "$ARGUMENTS" | grep -q -- '--dry-run' && DRY_RUN="true"
@@ -101,11 +101,11 @@ Per-project sequential ID (QS-REPORT-01, 02, ...). State.js owns the counter —
101
101
  ```bash
102
102
  PEEK=""
103
103
  [ "$DRY_RUN" = "true" ] && PEEK="--peek"
104
- CLIENT_REPORT_ID=$(node ~/.claude/bin/state.js next-report-id $PEEK 2>/dev/null \
104
+ CLIENT_REPORT_ID=$(node ${QUALIA_BIN}/state.js next-report-id $PEEK 2>/dev/null \
105
105
  | node -e "try{const j=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(j.report_id||'')}catch{}")
106
106
 
107
107
  if [ -z "$CLIENT_REPORT_ID" ]; then
108
- node ~/.claude/bin/qualia-ui.js fail "Could not allocate report ID. Try: cat .planning/tracking.json (is it valid JSON?)"
108
+ node ${QUALIA_BIN}/qualia-ui.js fail "Could not allocate report ID. Try: cat .planning/tracking.json (is it valid JSON?)"
109
109
  exit 1
110
110
  fi
111
111
  ```
@@ -116,10 +116,10 @@ fi
116
116
  if [ "$DRY_RUN" != "true" ] && [ -d .git ]; then
117
117
  mkdir -p .planning/reports
118
118
  git add .planning/reports/report-{date}.md .planning/tracking.json
119
- git commit -m "report: $CLIENT_REPORT_ID session {YYYY-MM-DD}" || node ~/.claude/bin/qualia-ui.js warn "Nothing to commit (clean tree?)"
119
+ git commit -m "report: $CLIENT_REPORT_ID session {YYYY-MM-DD}" || node ${QUALIA_BIN}/qualia-ui.js warn "Nothing to commit (clean tree?)"
120
120
  git push 2>&1 | tail -3
121
121
  PUSH_EXIT=${PIPESTATUS[0]}
122
- [ "$PUSH_EXIT" != "0" ] && node ~/.claude/bin/qualia-ui.js warn "git push failed — report committed locally but not pushed. ERP upload will still try."
122
+ [ "$PUSH_EXIT" != "0" ] && node ${QUALIA_BIN}/qualia-ui.js warn "git push failed — report committed locally but not pushed. ERP upload will still try."
123
123
  fi
124
124
  ```
125
125
 
@@ -136,12 +136,12 @@ The full payload-builder + 3-attempt-retry logic lives unchanged from v4 — see
136
136
 
137
137
  ```bash
138
138
  if [ "$DRY_RUN" != "true" ]; then
139
- node ~/.claude/bin/state.js transition --to activity --notes "Session report $CLIENT_REPORT_ID generated" 2>/dev/null
139
+ node ${QUALIA_BIN}/state.js transition --to activity --notes "Session report $CLIENT_REPORT_ID generated" 2>/dev/null
140
140
  fi
141
141
 
142
- node ~/.claude/bin/qualia-ui.js divider
143
- node ~/.claude/bin/qualia-ui.js ok "Report $CLIENT_REPORT_ID complete."
144
- node ~/.claude/bin/qualia-ui.js info "Shift report submitted. You can clock out now."
142
+ node ${QUALIA_BIN}/qualia-ui.js divider
143
+ node ${QUALIA_BIN}/qualia-ui.js ok "Report $CLIENT_REPORT_ID complete."
144
+ node ${QUALIA_BIN}/qualia-ui.js info "Shift report submitted. You can clock out now."
145
145
  ```
146
146
 
147
147
  ## Common errors (read this when something goes wrong)
@@ -149,7 +149,7 @@ node ~/.claude/bin/qualia-ui.js info "Shift report submitted. You can clock out
149
149
  | Symptom | Likely cause | Self-service fix |
150
150
  |---|---|---|
151
151
  | "Could not allocate report ID" | tracking.json missing/corrupt | `cat .planning/tracking.json` to inspect, or restore from `git checkout HEAD -- .planning/tracking.json` |
152
- | "ERP API key missing" | `~/.claude/.erp-api-key` empty | `printf '%s' "$QUALIA_ERP_KEY" \| qualia-framework set-erp-key` (ask Fawzi for the key) |
152
+ | "ERP API key missing" | `${QUALIA_HOME}/.erp-api-key` empty | `printf '%s' "$QUALIA_ERP_KEY" \| qualia-framework set-erp-key` (ask Fawzi for the key) |
153
153
  | "ERP auth failed (401)" | Key revoked or wrong | Ask Fawzi for a fresh key |
154
154
  | "ERP upload failed after 3 attempts" | ERP down or network issue | Local commit is safe. Re-run `/qualia-report` later. |
155
155
  | "git push failed" | Auth or network or upstream issue | `git push` manually, see the error, fix, re-run |
@@ -163,7 +163,7 @@ The Step 6 payload + retry logic. Inlined to avoid a script-file fetch on every
163
163
  ERP_URL=$(node -e "try{const c=JSON.parse(require('fs').readFileSync(require('os').homedir()+'/.claude/.qualia-config.json','utf8'));console.log(c.erp?.url||'https://portal.qualiasolutions.net')}catch{console.log('https://portal.qualiasolutions.net')}")
164
164
  ERP_ENABLED=$(node -e "try{const c=JSON.parse(require('fs').readFileSync(require('os').homedir()+'/.claude/.qualia-config.json','utf8'));console.log(c.erp?.enabled!==false)}catch{console.log('true')}")
165
165
 
166
- API_KEY=$(cat ~/.claude/.erp-api-key 2>/dev/null)
166
+ API_KEY=$(cat ${QUALIA_HOME}/.erp-api-key 2>/dev/null)
167
167
  REPORT_FILE=".planning/reports/report-{date}.md"
168
168
  SUBMITTED_BY=$(git config user.name || echo "unknown")
169
169
  SUBMITTED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
@@ -181,7 +181,7 @@ IDEMPOTENCY_KEY=$(node -e "
181
181
 
182
182
  # Guard: API key required for upload (otherwise curl posts an empty bearer)
183
183
  if [ "$ERP_ENABLED" = "true" ] && [ -z "$API_KEY" ] && [ "$DRY_RUN" != "true" ]; then
184
- node ~/.claude/bin/qualia-ui.js warn "ERP API key missing (~/.claude/.erp-api-key). Run: printf '%s' \"\$QUALIA_ERP_KEY\" | qualia-framework set-erp-key"
184
+ node ${QUALIA_BIN}/qualia-ui.js warn "ERP API key missing (${QUALIA_HOME}/.erp-api-key). Run: printf '%s' \"\$QUALIA_ERP_KEY\" | qualia-framework set-erp-key"
185
185
  ERP_ENABLED="false"
186
186
  fi
187
187
 
@@ -190,7 +190,7 @@ fi
190
190
  PAYLOAD=$(
191
191
  SUBMITTED_BY="$SUBMITTED_BY" SUBMITTED_AT="$SUBMITTED_AT" \
192
192
  CLIENT_REPORT_ID="$CLIENT_REPORT_ID" REPORT_FILE="$REPORT_FILE" \
193
- node ~/.claude/bin/report-payload.js
193
+ node ${QUALIA_BIN}/report-payload.js
194
194
  )
195
195
 
196
196
  # --dry-run: print and stop
@@ -216,19 +216,19 @@ if [ "$ERP_ENABLED" = "true" ]; then
216
216
 
217
217
  if [ "$HTTP_CODE" = "200" ]; then
218
218
  ERP_REPORT_ID=$(echo "$BODY" | node -e "try{process.stdout.write(JSON.parse(require('fs').readFileSync(0,'utf8')).report_id||'')}catch{}")
219
- node ~/.claude/bin/qualia-ui.js ok "Uploaded as $CLIENT_REPORT_ID (ERP: ${ERP_REPORT_ID:-none})"
219
+ node ${QUALIA_BIN}/qualia-ui.js ok "Uploaded as $CLIENT_REPORT_ID (ERP: ${ERP_REPORT_ID:-none})"
220
220
  break
221
221
  fi
222
222
  if [ "$HTTP_CODE" = "401" ] || [ "$HTTP_CODE" = "422" ]; then
223
- node ~/.claude/bin/qualia-ui.js warn "ERP rejected ($HTTP_CODE) — $([ "$HTTP_CODE" = "401" ] && echo "API key invalid, ask Fawzi" || echo "schema mismatch:")"
223
+ node ${QUALIA_BIN}/qualia-ui.js warn "ERP rejected ($HTTP_CODE) — $([ "$HTTP_CODE" = "401" ] && echo "API key invalid, ask Fawzi" || echo "schema mismatch:")"
224
224
  [ "$HTTP_CODE" = "422" ] && echo "$BODY" | head -3
225
225
  break
226
226
  fi
227
- [ $ATTEMPT -lt 3 ] && { SLEEP=$((1 * 3 ** (ATTEMPT - 1))); node ~/.claude/bin/qualia-ui.js warn "Attempt $ATTEMPT failed (HTTP ${HTTP_CODE:-timeout}), retrying in ${SLEEP}s..."; sleep $SLEEP; }
227
+ [ $ATTEMPT -lt 3 ] && { SLEEP=$((1 * 3 ** (ATTEMPT - 1))); node ${QUALIA_BIN}/qualia-ui.js warn "Attempt $ATTEMPT failed (HTTP ${HTTP_CODE:-timeout}), retrying in ${SLEEP}s..."; sleep $SLEEP; }
228
228
  done
229
229
 
230
230
  # If all 3 in-process attempts failed, enqueue the report into the persistent
231
- # retry queue (~/.claude/.erp-retry-queue.json). session-start.js drains it on
231
+ # retry queue (${QUALIA_HOME}/.erp-retry-queue.json). session-start.js drains it on
232
232
  # the next Claude Code launch; `qualia-framework erp-flush` drains it on demand.
233
233
  # This replaces the prior "will appear after retry" message which was a lie —
234
234
  # no retry mechanism existed before v5.9.
@@ -256,13 +256,13 @@ if [ "$ERP_ENABLED" = "true" ]; then
256
256
  process.exit(1);
257
257
  }
258
258
  " 2>/dev/null && {
259
- node ~/.claude/bin/qualia-ui.js warn "ERP upload failed after 3 attempts — $CLIENT_REPORT_ID enqueued for auto-retry on next session"
260
- node ~/.claude/bin/qualia-ui.js info "Drain manually with: qualia-framework erp-flush"
259
+ node ${QUALIA_BIN}/qualia-ui.js warn "ERP upload failed after 3 attempts — $CLIENT_REPORT_ID enqueued for auto-retry on next session"
260
+ node ${QUALIA_BIN}/qualia-ui.js info "Drain manually with: qualia-framework erp-flush"
261
261
  } || {
262
- node ~/.claude/bin/qualia-ui.js warn "ERP upload failed after 3 attempts AND queue enqueue failed. $CLIENT_REPORT_ID is committed locally — re-run /qualia-report later to retry."
262
+ node ${QUALIA_BIN}/qualia-ui.js warn "ERP upload failed after 3 attempts AND queue enqueue failed. $CLIENT_REPORT_ID is committed locally — re-run /qualia-report later to retry."
263
263
  }
264
264
  fi
265
265
  fi
266
266
 
267
- [ "$ERP_ENABLED" != "true" ] && node ~/.claude/bin/qualia-ui.js info "ERP upload skipped (disabled). $CLIENT_REPORT_ID committed locally."
267
+ [ "$ERP_ENABLED" != "true" ] && node ${QUALIA_BIN}/qualia-ui.js info "ERP upload skipped (disabled). $CLIENT_REPORT_ID committed locally."
268
268
  ```
@@ -30,7 +30,7 @@ Targeted research on domain, library, or integration for a specific phase. Narro
30
30
  ### 1. Determine Phase
31
31
 
32
32
  ```bash
33
- node ~/.claude/bin/state.js check 2>/dev/null
33
+ node ${QUALIA_BIN}/state.js check 2>/dev/null
34
34
  ```
35
35
 
36
36
  Phase N from args, or current phase from STATE.md.
@@ -55,7 +55,7 @@ Wait for answer. Answer defines research question.
55
55
 
56
56
  ```
57
57
  Agent(prompt="
58
- Role: @~/.claude/agents/researcher.md
58
+ Role: @${QUALIA_AGENTS}/researcher.md
59
59
 
60
60
  <dimension>phase-specific</dimension>
61
61
 
@@ -86,8 +86,8 @@ Include: recommendation, rationale, versions, code examples, alternatives, pitfa
86
86
  Read `.planning/phase-{N}-research.md`. Present findings:
87
87
 
88
88
  ```bash
89
- node ~/.claude/bin/qualia-ui.js divider
90
- node ~/.claude/bin/qualia-ui.js ok "Research complete"
89
+ node ${QUALIA_BIN}/qualia-ui.js divider
90
+ node ${QUALIA_BIN}/qualia-ui.js ok "Research complete"
91
91
  ```
92
92
 
93
93
  Show:
@@ -116,7 +116,7 @@ git commit -m "docs(phase-{N}): research findings"
116
116
  ### 8. Route
117
117
 
118
118
  ```bash
119
- node ~/.claude/bin/qualia-ui.js end "PHASE {N} RESEARCH DONE" "/qualia-plan {N}"
119
+ node ${QUALIA_BIN}/qualia-ui.js end "PHASE {N} RESEARCH DONE" "/qualia-plan {N}"
120
120
  ```
121
121
 
122
122
  ## Rules
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-review
3
- description: "Production audit with scored diagnostics. Runs real commands, scores findings by severity. Trigger on 'review', 'audit', 'code review', 'security check', 'production check'."
3
+ description: "Read-only production audit with scored diagnostics. Runs real commands, scores findings by severity, writes REVIEW.md, and routes repair work to /qualia-fix, /qualia-polish, or /qualia-optimize. Trigger on 'review', 'audit', 'code review', 'security check', 'production check'."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -14,6 +14,15 @@ allowed-tools:
14
14
 
15
15
  Runs real diagnostic commands and scores every finding. Not a checklist — an executable audit.
16
16
 
17
+ Review is detection only. It never patches code. If the user wants the findings repaired, route by finding type:
18
+
19
+ | Finding type | Next command |
20
+ |---|---|
21
+ | Broken existing behavior, failing test, security leak, config error | `/qualia-fix` |
22
+ | Visual design quality or responsive polish | `/qualia-polish` |
23
+ | Broad performance, architecture, or alignment opportunities | `/qualia-optimize` |
24
+ | New missing capability | `/qualia-feature` or `/qualia-plan` |
25
+
17
26
  ## Usage
18
27
 
19
28
  - `/qualia-review` — Full audit (security + quality + performance)
@@ -23,15 +32,15 @@ Runs real diagnostic commands and scores every finding. Not a checklist — an e
23
32
  ## Process
24
33
 
25
34
  ```bash
26
- node ~/.claude/bin/qualia-ui.js banner review
35
+ node ${QUALIA_BIN}/qualia-ui.js banner review
27
36
  ```
28
37
 
29
38
  ### 0. Load Context
30
39
 
31
40
  ```bash
32
- node ~/.claude/bin/knowledge.js
33
- node ~/.claude/bin/knowledge.js load fixes
34
- node ~/.claude/bin/knowledge.js load patterns
41
+ node ${QUALIA_BIN}/knowledge.js
42
+ node ${QUALIA_BIN}/knowledge.js load fixes
43
+ node ${QUALIA_BIN}/knowledge.js load patterns
35
44
  ```
36
45
 
37
46
  Detect project shape:
@@ -127,7 +136,11 @@ grep -rn "const.*=.*await" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/n
127
136
 
128
137
  ### 4. Score and Report
129
138
 
130
- Write to `.planning/REVIEW.md`:
139
+ Create the report directory and write to `.planning/reports/review/REVIEW.md`:
140
+
141
+ ```bash
142
+ mkdir -p .planning/reports/review
143
+ ```
131
144
 
132
145
  ```markdown
133
146
  # Production Review — {YYYY-MM-DD}
@@ -156,6 +169,9 @@ Write to `.planning/REVIEW.md`:
156
169
 
157
170
  ## Verdict
158
171
  {PASS: no critical/high | FAIL: N blockers — fix before /qualia-ship}
172
+
173
+ ## Recommended Next Command
174
+ {`/qualia-fix`, `/qualia-polish`, `/qualia-optimize`, `/qualia-feature`, or `none`} — {one-line reason}
159
175
  ```
160
176
 
161
177
  **Scoring (deterministic — see `rules/grounding.md` for full rubric):**
@@ -173,11 +189,11 @@ Quick reference (computed from the formula — verified):
173
189
  - 4+ CRITICAL → 1
174
190
 
175
191
  ```bash
176
- node ~/.claude/bin/qualia-ui.js divider
177
- node ~/.claude/bin/qualia-ui.js info "Security: {score}/5 ({n} findings)"
178
- node ~/.claude/bin/qualia-ui.js info "Quality: {score}/5 ({n} findings)"
179
- node ~/.claude/bin/qualia-ui.js info "Perf: {score}/5 ({n} findings)"
180
- node ~/.claude/bin/qualia-ui.js end "REVIEW: {PASS|FAIL}" "{next command}"
192
+ node ${QUALIA_BIN}/qualia-ui.js divider
193
+ node ${QUALIA_BIN}/qualia-ui.js info "Security: {score}/5 ({n} findings)"
194
+ node ${QUALIA_BIN}/qualia-ui.js info "Quality: {score}/5 ({n} findings)"
195
+ node ${QUALIA_BIN}/qualia-ui.js info "Perf: {score}/5 ({n} findings)"
196
+ node ${QUALIA_BIN}/qualia-ui.js end "REVIEW: {PASS|FAIL}" "{recommended next command}"
181
197
  ```
182
198
 
183
199
  ## Rules
@@ -185,5 +201,5 @@ node ~/.claude/bin/qualia-ui.js end "REVIEW: {PASS|FAIL}" "{next command}"
185
201
  1. **Run every command.** Don't skip scans because "the code looks clean."
186
202
  2. **Every finding gets a severity.** No prose — CRITICAL/HIGH/MEDIUM/LOW.
187
203
  3. **Every finding gets a fix suggestion.** Not just "this is bad" — say what to do.
188
- 4. **Review detects. It does NOT fix.** This is an audit, not a refactor. Tell the user what to fix.
204
+ 4. **Review detects. It does NOT fix.** This is an audit, not a refactor. Route repair to `/qualia-fix`, design repair to `/qualia-polish`, and broad improvement to `/qualia-optimize`.
189
205
  5. **CRITICAL or HIGH = deploy blocker.** `/qualia-ship` checks for these.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-road
3
- description: "TERMINAL workflow map — Project → Journey → Milestones → Phases → Tasks. Use this in headless/SSH/no-browser sessions or when the user asks for the road in chat. For the HTML reference (default when a browser is available), use /qualia-help. Triggers: 'how does Qualia work', 'what's the workflow', 'show me the road', 'what command does X', 'how do projects flow', 'in terminal please', SSH context."
3
+ description: "TERMINAL workflow map — Project → Journey → Milestones → Phases → Tasks. Use this in headless/SSH/no-browser sessions or when the user asks for the road in chat. Triggers: 'how does Qualia work', 'what's the workflow', 'show me the road', 'what command does X', 'how do projects flow', 'in terminal please', SSH context."
4
4
  disable-model-invocation: true
5
5
  allowed-tools:
6
6
  - Read
@@ -33,29 +33,29 @@ Done.
33
33
  ```
34
34
 
35
35
  ## Design as a thread
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.
36
+ Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Builders run `slop-detect` on every frontend commit. Verifiers score 9 design dimensions per phase, including visual system and graphics.
37
37
 
38
38
  ## /qualia-polish is scope-adaptive
39
39
  ```
40
40
  /qualia-polish src/components/Button.tsx ~30s component touch-up
41
41
  /qualia-polish app/dashboard ~3m section pass
42
42
  /qualia-polish ~12m whole app, fan-out
43
- /qualia-polish --redesign ~30m ground-up redesign
43
+ /qualia-polish --redesign ~30m ground-up redesign + complex visual concept
44
44
  /qualia-polish --critique read-only scored audit
45
45
  /qualia-polish --quick ~1m gates only
46
46
  ```
47
47
 
48
- ## Design pivots — /qualia-vibe (v6.1+)
48
+ ## Design pivots — /qualia-polish --vibe
49
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
50
+ /qualia-polish --vibe fast aesthetic pivot: ONE proposed direction, swap tokens, keep layout (~3 min)
51
+ /qualia-polish --vibe brutalist explicit pivot to named direction
52
+ /qualia-polish --vibe --variants 3 opt-in menu (rare; default flow is one-opinion)
53
+ /qualia-polish --vibe --extract https://stripe.com reverse-engineer DESIGN.md from a reference URL
54
+ /qualia-polish --vibe --extract ./inspo.png same, from a local screenshot
55
+ /qualia-polish --vibe --sync show drift between code (CSS vars, Tailwind config) and DESIGN.md
56
+ /qualia-polish --vibe --sync --write patch DESIGN.md to match code, commit
57
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`.
58
+ `/qualia-polish --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
59
 
60
60
  ## /qualia-polish --loop — autonomous visual QA
61
61
  ```
@@ -65,39 +65,47 @@ Every road agent loads `PRODUCT.md + DESIGN.md + design-laws.md` substrate. Buil
65
65
  /qualia-polish --loop {url} --reduced-motion force prefers-reduced-motion
66
66
  /qualia-polish --loop --routes /a,/b,/c multi-route sweep
67
67
  ```
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.
68
+ Screenshots at 3 viewports (375/768/1440), scores 9 design dimensions using vision, fixes issues, re-screenshots, loops until all dims >= 3 or kill-switch triggers. Per-iteration git commits for clean revert.
69
69
 
70
70
  ## Deterministic-enforcement skills
71
71
  ```
72
- /qualia-hook-gen convert a CLAUDE.md/rules instruction into a deterministic pre-tool-use hook
73
72
  /qualia-optimize --deepen spawns 3 parallel interface-design variants per candidate (Step 5b)
74
73
  ```
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.
74
+ `/qualia-optimize --deepen` produces dramatically better refactor RFCs because 3 radically-different interfaces are surfaced and the human picks/hybridizes.
76
75
 
77
76
  ## Alignment substrate
78
77
  Before high-stakes phases, run alignment skills against `.planning/CONTEXT.md` (domain glossary) and `.planning/decisions/` (ADRs):
79
78
 
80
79
  ```
81
80
  /qualia-discuss → relentless one-question interview, updates CONTEXT.md inline
82
- /qualia-zoom → map an unfamiliar code area using glossary terms
83
81
  /qualia-optimize --deepen → find shallow modules, propose Ousterhout-style refactors
84
82
  /qualia-test --tdd → vertical-slice red→green→refactor for one feature
85
- /qualia-issues → break a phase plan into independent GH issues
86
- /qualia-triage → label + route open issues (ready-for-agent vs human)
87
83
  /qualia-map → adapt Qualia to an existing brownfield repo's conventions (5th onboarding agent)
88
84
  ```
89
85
 
90
86
  ## Auxiliary commands
91
87
  ```
92
88
  Lost? → /qualia (state router — tells you the next command)
93
- Stuck/weird? → /qualia-idk (diagnostic spawns plan-view + code-view agents in parallel)
94
- Single feature? → /qualia-feature (auto-scoped: inline for trivia, fresh spawn for 1-5 files)
95
- Paused? → /qualia-resume (restore from .continue-here.md or STATE.md)
89
+ Health? → /qualia-doctor (install, state, contracts, memory, ERP queue)
90
+ Stuck/weird? → /qualia (diagnostic branch scans planning + code when state alone is insufficient)
91
+ Broken thing? → /qualia-fix (root cause, minimal patch, verify, report)
92
+ Single feature? → /qualia-feature (new capability: inline for trivia, fresh spawn for 1-5 files)
93
+ Paused? → /qualia (restore from .continue-here.md or STATE.md)
96
94
  End of day? → /qualia-report (mandatory before clock-out; writes ERP payload)
97
- Debug bug? → /qualia-debug (feedback-loop-first investigation)
98
95
  Unsure plan? → /qualia-discuss (capture decisions before planning)
99
96
  ```
100
97
 
98
+ ## Outside-road command boundaries
99
+ ```
100
+ Need a repair? → /qualia-fix (mutates code, proves fix)
101
+ Need an investigation? → /qualia-review (read-only audit) or /qualia-fix (known broken behavior)
102
+ Need an audit? → /qualia-review (detect-only, scored findings)
103
+ Need improvement map? → /qualia-optimize (report/RFC, broad opportunities)
104
+ Need visual quality? → /qualia-polish (style/layout/accessibility)
105
+ Need new aesthetic? → /qualia-polish --vibe (tokens only, layout preserved)
106
+ Need new capability? → /qualia-feature (small net-new work)
107
+ ```
108
+
101
109
  ## Human gates
102
110
  Journey approval after `/qualia-new`, then one at each milestone boundary via `/qualia-milestone`. `--auto` runs everything between gates automatically.
103
111
 
@@ -16,7 +16,7 @@ Full deployment pipeline with quality gates.
16
16
  ## Process
17
17
 
18
18
  ```bash
19
- node ~/.claude/bin/qualia-ui.js banner ship
19
+ node ${QUALIA_BIN}/qualia-ui.js banner ship
20
20
  ```
21
21
 
22
22
  ### 0. State Guard — refuse to ship from an invalid state
@@ -24,14 +24,22 @@ node ~/.claude/bin/qualia-ui.js banner ship
24
24
  `/qualia-ship` is a terminal operation — it writes a deployed tag, bumps counters, and produces a verified URL. It must NEVER run on an unpolished, unverified, or malformed project.
25
25
 
26
26
  ```bash
27
- STATE=$(node ~/.claude/bin/state.js check 2>/dev/null)
27
+ STATE=$(node ${QUALIA_BIN}/state.js check 2>/dev/null)
28
28
  if [ -z "$STATE" ]; then
29
- node ~/.claude/bin/qualia-ui.js fail "No project loaded. Run /qualia-new first or cd to a Qualia-managed project."
29
+ node ${QUALIA_BIN}/qualia-ui.js fail "No project loaded. Run /qualia-new first or cd to a Qualia-managed project."
30
30
  exit 1
31
31
  fi
32
32
 
33
33
  STATUS=$(echo "$STATE" | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(d.status||'')}catch{}")
34
34
  VERIFICATION=$(echo "$STATE" | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(d.verification||'')}catch{}")
35
+ NEXT_COMMAND=$(echo "$STATE" | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write(d.next_command||'/qualia')}catch{process.stdout.write('/qualia')}")
36
+ ROLE=$(node -e "try{const fs=require('fs'),path=require('path'),os=require('os');const h=process.env.QUALIA_HOME||path.dirname(process.env.QUALIA_BIN||path.join(os.homedir(),'.claude','bin'));const c=JSON.parse(fs.readFileSync(path.join(h,'.qualia-config.json'),'utf8'));process.stdout.write((c.role||'').toUpperCase())}catch{}")
37
+
38
+ if [ "${QUALIA_SHIP_FORCE:-0}" = "1" ] && [ "$ROLE" != "OWNER" ]; then
39
+ node ${QUALIA_BIN}/qualia-ui.js fail "Owner override is OWNER-only."
40
+ node ${QUALIA_BIN}/qualia-ui.js info "Run $NEXT_COMMAND."
41
+ exit 1
42
+ fi
35
43
 
36
44
  # Valid ship-from states:
37
45
  # polished — /qualia-polish ran cleanly; ready for deploy
@@ -39,12 +47,11 @@ VERIFICATION=$(echo "$STATE" | node -e "try{const d=JSON.parse(require('fs').rea
39
47
  # Anything else (setup, planned, built, shipped, handed_off, verified+fail) is refused.
40
48
  if [ "$STATUS" != "polished" ] && ! { [ "$STATUS" = "verified" ] && [ "$VERIFICATION" = "pass" ]; }; then
41
49
  if [ "${QUALIA_SHIP_FORCE:-0}" = "1" ]; then
42
- node ~/.claude/bin/qualia-ui.js warn "Forced ship from state '$STATUS' (verification: ${VERIFICATION:-none}). Record the reason in the final report."
50
+ node ${QUALIA_BIN}/qualia-ui.js warn "Forced ship from state '$STATUS' (verification: ${VERIFICATION:-none}). Record the reason in the final report."
43
51
  else
44
- node ~/.claude/bin/qualia-ui.js fail "Cannot ship from state '$STATUS' (verification: ${VERIFICATION:-none})."
45
- node ~/.claude/bin/qualia-ui.js info "Run /qualia-polish first, or /qualia-verify {phase} if verification is still pending."
46
- node ~/.claude/bin/qualia-ui.js info "Hotfix override: set QUALIA_SHIP_FORCE=1 only when the user explicitly approved it."
47
- exit 1
52
+ node ${QUALIA_BIN}/qualia-ui.js fail "Ship refused from state '$STATUS' (verification: ${VERIFICATION:-none})."
53
+ node ${QUALIA_BIN}/qualia-ui.js info "Run $NEXT_COMMAND."
54
+ exit 1
48
55
  fi
49
56
  fi
50
57
  ```
@@ -64,7 +71,7 @@ On failure:
64
71
  1. Summarize what failed in plain language
65
72
  2. Auto-fix
66
73
  3. Re-run the gate
67
- 4. If still failing after 2 attempts: tell the employee, suggest `/qualia-debug`
74
+ 4. If still failing after 2 attempts: tell the employee, suggest `/qualia-fix`
68
75
 
69
76
  ### 2. Security Check — full depth
70
77
 
@@ -76,7 +83,7 @@ SEC_FAIL=0
76
83
  # CRITICAL: service_role in client-facing code
77
84
  HITS=$(grep -rn "service_role" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | grep -v "\.server\.\|[\\/]server[\\/]\|[\\/]app[\\/]api[\\/]\|route\.\|middleware\.")
78
85
  if [ -n "$HITS" ]; then
79
- node ~/.claude/bin/qualia-ui.js fail "service_role leaked to client code:"
86
+ node ${QUALIA_BIN}/qualia-ui.js fail "service_role leaked to client code:"
80
87
  echo "$HITS" | head -5
81
88
  SEC_FAIL=1
82
89
  fi
@@ -84,7 +91,7 @@ fi
84
91
  # CRITICAL: hardcoded secrets
85
92
  HITS=$(grep -rn "sk_live\|sk_test\|SUPABASE_SERVICE_ROLE\|eyJhbGciOi" --include="*.ts" --include="*.tsx" --include="*.js" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | grep -v "\.env")
86
93
  if [ -n "$HITS" ]; then
87
- node ~/.claude/bin/qualia-ui.js fail "Hardcoded secret found:"
94
+ node ${QUALIA_BIN}/qualia-ui.js fail "Hardcoded secret found:"
88
95
  echo "$HITS" | head -5
89
96
  SEC_FAIL=1
90
97
  fi
@@ -92,7 +99,7 @@ fi
92
99
  # CRITICAL: dangerouslySetInnerHTML / eval
93
100
  HITS=$(grep -rn "dangerouslySetInnerHTML\|eval(" --include="*.ts" --include="*.tsx" --include="*.js" app/ components/ src/ 2>/dev/null | grep -v node_modules)
94
101
  if [ -n "$HITS" ]; then
95
- node ~/.claude/bin/qualia-ui.js fail "Dangerous innerHTML/eval pattern:"
102
+ node ${QUALIA_BIN}/qualia-ui.js fail "Dangerous innerHTML/eval pattern:"
96
103
  echo "$HITS" | head -5
97
104
  SEC_FAIL=1
98
105
  fi
@@ -100,13 +107,13 @@ fi
100
107
  # CRITICAL: .env files tracked in git
101
108
  HITS=$(git ls-files | grep -i "\.env" | grep -v "\.example\|\.template\|\.sample")
102
109
  if [ -n "$HITS" ]; then
103
- node ~/.claude/bin/qualia-ui.js fail ".env files tracked in git:"
110
+ node ${QUALIA_BIN}/qualia-ui.js fail ".env files tracked in git:"
104
111
  echo "$HITS"
105
112
  SEC_FAIL=1
106
113
  fi
107
114
 
108
115
  if [ $SEC_FAIL -ne 0 ]; then
109
- node ~/.claude/bin/qualia-ui.js fail "Security check failed. Fix findings above or run /qualia-review for full audit."
116
+ node ${QUALIA_BIN}/qualia-ui.js fail "Security check failed. Fix findings above or run /qualia-review for full audit."
110
117
  exit 1
111
118
  fi
112
119
  ```
@@ -140,8 +147,8 @@ Read the deployed URL from `tracking.json.deployed_url` or from an explicit user
140
147
  # exact value before running this block. Otherwise use tracking.json.
141
148
  URL="${QUALIA_SHIP_URL:-$(node -e 'try{const t=JSON.parse(require("fs").readFileSync(".planning/tracking.json","utf8"));process.stdout.write(t.deployed_url||"")}catch{}')}"
142
149
  if [ -z "$URL" ]; then
143
- node ~/.claude/bin/qualia-ui.js warn "No deployed_url in tracking.json — parse it from the deploy command output (vercel/supabase/wrangler all print the URL on success)."
144
- node ~/.claude/bin/qualia-ui.js info "Re-run with: /qualia-ship --url https://your-site.com, then export that value as QUALIA_SHIP_URL for this check."
150
+ node ${QUALIA_BIN}/qualia-ui.js warn "No deployed_url in tracking.json — parse it from the deploy command output (vercel/supabase/wrangler all print the URL on success)."
151
+ node ${QUALIA_BIN}/qualia-ui.js info "Re-run with: /qualia-ship --url https://your-site.com, then export that value as QUALIA_SHIP_URL for this check."
145
152
  exit 1
146
153
  fi
147
154
 
@@ -151,7 +158,7 @@ HTTP_CODE=$(echo "$RESP" | awk '{print $1}')
151
158
  LATENCY=$(echo "$RESP" | awk '{print $2}')
152
159
 
153
160
  if [ "$HTTP_CODE" != "200" ]; then
154
- node ~/.claude/bin/qualia-ui.js fail "Post-deploy check failed: HTTP $HTTP_CODE at $URL"
161
+ node ${QUALIA_BIN}/qualia-ui.js fail "Post-deploy check failed: HTTP $HTTP_CODE at $URL"
155
162
  exit 1
156
163
  fi
157
164
 
@@ -162,18 +169,18 @@ AUTH_CODE=$(curl -sS -o /dev/null -w "%{http_code}" --max-time 10 "$URL/api/auth
162
169
  ### 6. Report
163
170
 
164
171
  ```bash
165
- node ~/.claude/bin/qualia-ui.js divider
166
- node ~/.claude/bin/qualia-ui.js ok "URL: $URL"
167
- node ~/.claude/bin/qualia-ui.js ok "Status: HTTP $HTTP_CODE"
168
- node ~/.claude/bin/qualia-ui.js ok "Latency: ${LATENCY}s"
169
- [ "$AUTH_CODE" = "200" ] || [ "$AUTH_CODE" = "401" ] && node ~/.claude/bin/qualia-ui.js ok "Auth endpoint responds (HTTP $AUTH_CODE)"
172
+ node ${QUALIA_BIN}/qualia-ui.js divider
173
+ node ${QUALIA_BIN}/qualia-ui.js ok "URL: $URL"
174
+ node ${QUALIA_BIN}/qualia-ui.js ok "Status: HTTP $HTTP_CODE"
175
+ node ${QUALIA_BIN}/qualia-ui.js ok "Latency: ${LATENCY}s"
176
+ [ "$AUTH_CODE" = "200" ] || [ "$AUTH_CODE" = "401" ] && node ${QUALIA_BIN}/qualia-ui.js ok "Auth endpoint responds (HTTP $AUTH_CODE)"
170
177
  ```
171
178
 
172
179
  ```bash
173
- node ~/.claude/bin/state.js transition --to shipped --deployed-url "$URL"
180
+ node ${QUALIA_BIN}/state.js transition --to shipped --deployed-url "$URL"
174
181
  ```
175
182
  Do NOT manually edit STATE.md or tracking.json — state.js handles both.
176
183
 
177
184
  ```bash
178
- node ~/.claude/bin/qualia-ui.js end "SHIPPED" "/qualia-handoff"
185
+ node ${QUALIA_BIN}/qualia-ui.js end "SHIPPED" "/qualia-handoff"
179
186
  ```