qualia-framework 5.5.0 → 5.9.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 (45) hide show
  1. package/README.md +17 -13
  2. package/agents/plan-checker.md +8 -0
  3. package/agents/qa-browser.md +7 -0
  4. package/agents/research-synthesizer.md +4 -1
  5. package/agents/researcher.md +6 -1
  6. package/agents/roadmapper.md +8 -0
  7. package/agents/verifier.md +14 -1
  8. package/agents/visual-evaluator.md +1 -1
  9. package/bin/cli.js +30 -1
  10. package/bin/erp-retry.js +289 -0
  11. package/bin/install.js +12 -6
  12. package/bin/slop-detect.mjs +1 -1
  13. package/bin/state.js +10 -1
  14. package/docs/onboarding.html +621 -0
  15. package/docs/playwright-loop-pilot-results.md +7 -5
  16. package/docs/research/2026-05-11-deep-research.md +189 -0
  17. package/guide.md +5 -6
  18. package/hooks/session-start.js +19 -1
  19. package/package.json +3 -2
  20. package/rules/speed.md +1 -2
  21. package/skills/qualia-discuss/SKILL.md +106 -6
  22. package/skills/qualia-feature/SKILL.md +216 -0
  23. package/skills/qualia-milestone/SKILL.md +73 -1
  24. package/skills/qualia-new/SKILL.md +52 -25
  25. package/skills/qualia-optimize/SKILL.md +1 -1
  26. package/skills/{qualia-polish-loop → qualia-polish}/REFERENCE.md +5 -5
  27. package/skills/qualia-polish/SKILL.md +13 -4
  28. package/skills/{qualia-polish-loop → qualia-polish}/scripts/loop.mjs +2 -2
  29. package/skills/{qualia-polish-loop → qualia-polish}/scripts/playwright-capture.mjs +1 -1
  30. package/skills/qualia-report/SKILL.md +64 -2
  31. package/skills/qualia-road/SKILL.md +10 -11
  32. package/skills/qualia-verify/SKILL.md +16 -0
  33. package/templates/help.html +2 -3
  34. package/templates/project-discovery.md +83 -0
  35. package/templates/project.md +7 -0
  36. package/tests/bin.test.sh +97 -67
  37. package/tests/refs.test.sh +146 -0
  38. package/tests/slop-detect.test.sh +2 -2
  39. package/skills/qualia-polish-loop/SKILL.md +0 -201
  40. package/skills/qualia-prd/SKILL.md +0 -199
  41. package/skills/qualia-quick/SKILL.md +0 -44
  42. package/skills/qualia-task/SKILL.md +0 -98
  43. /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/broken.html +0 -0
  44. /package/skills/{qualia-polish-loop → qualia-polish}/fixtures/clean.html +0 -0
  45. /package/skills/{qualia-polish-loop → qualia-polish}/scripts/score.mjs +0 -0
@@ -0,0 +1,189 @@
1
+ # Qualia Framework — Deep Research Audit
2
+
3
+ **Date:** 2026-05-11
4
+ **Version audited:** v5.8.0 (tip `387c422`)
5
+ **Auditors:** 4 parallel investigators (surface health, ERP integration, token economy + personalization, workflow outcomes)
6
+ **Method:** Grounded protocol — every claim carries `file:line` citation with quoted snippet.
7
+
8
+ ---
9
+
10
+ ## Headline verdict
11
+
12
+ The framework is **structurally solid** but carries three real failure modes the user was right to suspect:
13
+
14
+ 1. **Documentation drift is the loudest silent failure.** Three user-facing surfaces (`rules/speed.md`, `templates/help.html`, `docs/onboarding.html`) still list `/qualia-quick`, `/qualia-task`, `/qualia-design`, `/qualia-prd`, `/qualia-polish-loop` — commands removed in v5.7/v5.8. A new hire following onboarding.html immediately hits dead ends.
15
+ 2. **ERP health is better than the user feared, but one promise is a lie.** After 3 failed upload attempts the message says "will appear in ERP after retry" — there is no retry mechanism. No queue, no cron, no session-start re-try. Data sits locally until the employee manually re-runs `/qualia-report`. The retry logic that DOES exist (1s/3s/9s backoff, 401/422 permanent-fail distinction) is correct.
16
+ 3. **Always-loaded substrate is ~2× larger than the "Pocock discipline" claim implies.** CLAUDE.md is genuinely 24 lines, but the 8 rules files (~480 lines) + 33 skill descriptions (~14.7 KB) total **~10,300 tokens** on every session start. ~5,400 of those are recoverable without losing functionality.
17
+
18
+ Production-readiness score (framework as a product): **77 / 100**
19
+
20
+ | Dimension | Score | One-line |
21
+ |---|---:|---|
22
+ | Surface honesty | 6/10 | Dead refs in 3 user-facing files |
23
+ | ERP health | 7/10 | Real retry, false retry-promise, missing idempotency |
24
+ | Token discipline | 6/10 | Real where claimed, but ~5.4K tokens of recoverable bloat |
25
+ | Personalization | 3/10 | 4 employees are identical clones in the framework's eyes |
26
+ | Workflow speed | 7/10 | Road works; kickoff has redundant questions, no fast path |
27
+ | Verifier strictness | 7/10 | Strong protocol, INSUFFICIENT EVIDENCE silently treated as PASS |
28
+ | Test coverage | 8/10 | State machine excellently tested, workflow loop untested |
29
+ | Hooks (safety) | 9/10 | Genuinely well-engineered, zero token tax, real enforcement |
30
+
31
+ ---
32
+
33
+ ## CRITICAL findings (zero this round)
34
+
35
+ None of the four audits surfaced a CRITICAL severity issue (security breach / data loss / auth bypass / crash on happy path). The framework's safety hooks (`branch-guard`, `git-guardrails`, `migration-guard`, `pre-deploy-gate`) and state-machine locking are real defenses.
36
+
37
+ This is meaningful: the user's "I think this is very fucked up" suspicion about the ERP was wrong at the data-safety level — local commit always happens before upload, retry logic is correct, API key file is mode `0600`, no shell injection.
38
+
39
+ ---
40
+
41
+ ## HIGH findings (10 — fix before next minor)
42
+
43
+ ### Surface honesty
44
+
45
+ **H1. `rules/speed.md:50-51` lists removed `/qualia-quick` + `/qualia-task` as active.**
46
+ `speed.md` is read by users looking for shortcuts. Users will invoke commands that don't exist.
47
+
48
+ **H2. `templates/help.html:377-379` shows `/qualia-quick`, `/qualia-task`, `/qualia-design`.**
49
+ This is what `/qualia-help` opens in the browser. It's the canonical reference page.
50
+
51
+ **H3. `docs/onboarding.html:509, 524, 525, 556` shows 4 removed commands.**
52
+ This is the file the README explicitly recommends sending to new hires.
53
+
54
+ ### ERP
55
+
56
+ **H4. `skills/qualia-report/SKILL.md:238` — "will appear in ERP after retry" is a lie.**
57
+ There is no retry mechanism. No background queue, no cron, no session-start drain. Either build a retry queue at `~/.claude/.erp-retry-queue.json` and drain on session-start, OR change the message to honest "Re-run /qualia-report to retry."
58
+
59
+ **H5. `skills/qualia-report/SKILL.md:220-222` — no `Idempotency-Key` header sent.**
60
+ The ERP contract documents idempotency support with a 24h replay window (`docs/erp-contract.md:42-49`). The framework ignores this. The UPSERT on `(project_id, client_report_id)` covers most cases, but retries after a response-lost-mid-flight could double-count without the explicit header.
61
+
62
+ **H6. `session_duration_minutes` documented in ERP contract example but never sent.**
63
+ `docs/erp-contract.md:93` shows it; the payload builder at `skills/qualia-report/SKILL.md:192-205` never computes it. Trivial fix: `Math.round((Date.now() - new Date(t.session_started_at)) / 60000)`.
64
+
65
+ ### Workflow quality
66
+
67
+ **H7. `agents/verifier.md:47` — 25-call tool budget + `skills/qualia-verify/SKILL.md` doesn't block on INSUFFICIENT EVIDENCE.**
68
+ The verifier is told "mark unchecked criteria as INSUFFICIENT EVIDENCE" when budget exhausts. The orchestrator does not grep for that string before declaring PASS. Phases with 8+ tasks can pass verification with criteria literally not checked. **This is the #1 false-pass vector.**
69
+
70
+ **H8. `/qualia-new` has 15-21+ user questions before any code is written.**
71
+ 14 discovery + 1 design vibe + 1 client + 5 PRODUCT.md + N feature scoping. The PRODUCT.md questions at `skills/qualia-new/SKILL.md:163-169` overlap with discovery questions 2-5. Demos hit ~15 interactions despite the "8 questions for demos" framing.
72
+
73
+ ### Personalization
74
+
75
+ **H9. All 4 employees (Hasan, Moayad, Rama, Sally) have identical role descriptions.**
76
+ `bin/install.js:31-57` — every EMPLOYEE entry has the description "Developer. Feature branches only. Cannot push to main." No stack expertise, seniority, specialization. The framework cannot adapt explanation depth, task assignment, or review style per developer.
77
+
78
+ **H10. `architecture.md` is always-loaded but explicitly says "Do not auto-load this on quick fixes."**
79
+ `rules/architecture.md` is 125 lines (~1,560 tokens). It lives in `~/.claude/rules/` where Claude Code auto-loads everything. The file itself contradicts its location.
80
+
81
+ ---
82
+
83
+ ## MEDIUM findings (12 — fix this quarter)
84
+
85
+ | # | Where | What |
86
+ |---|---|---|
87
+ | M1 | `bin/state.js:332` | Progress bar formula `(phase-1)/total_phases` — completed project shows 66%, never 100% |
88
+ | M2 | `agents/builder.md:155`, `agents/planner.md:147`, `agents/research-synthesizer.md:91` | "likely", "probably" — hedging language the grounding protocol explicitly bans |
89
+ | M3 | `bin/state.js:375-376` | `polished → shipped` mandatory; no skip for API-only / backend-only projects |
90
+ | M4 | `skills/zoho-workflow/` | Completely unreferenced — orphan skill |
91
+ | M5 | `tests/skills.test.sh` | Tests structure, not behavior — no integration test for the plan→build→verify loop |
92
+ | M6 | `agents/plan-checker.md:83` | "Any shared file = wave conflict" forces unnecessary serialization (no read-only-overlap distinction) |
93
+ | M7 | `agents/plan-checker.md:173-179` | Scope-reduction Rule 10 substring-matches "v1", "basic version" — false REVISE on legit plans |
94
+ | M8 | `agents/verifier.md:315-317` + `:356-362` | Design rubric fires full 8-dim on any `.tsx` file presence — backend-heavy phases get disproportionate design scrutiny |
95
+ | M9 | `bin/cli.js:874-888` | `erp-ping` sends synthetic payload — does not validate current schema |
96
+ | M10 | `skills/qualia-report/SKILL.md:197` | `framework_version` reads from config snapshot at install time — stale after `npm update` |
97
+ | M11 | `skills/qualia-new/SKILL.md:163-169` | PRODUCT.md questions duplicate discovery questions 2-5 |
98
+ | M12 | `skills/qualia/SKILL.md:38-55` | Router has no row for "I want a one-off change outside the Road" — users must already know `/qualia-feature` exists |
99
+
100
+ ---
101
+
102
+ ## LOW findings (5)
103
+
104
+ - L1. `hooks/pre-compact.js:80-81` — default `--no-verify` + `--no-gpg-sign` (configurable, documented, but silent default)
105
+ - L2. `docs/playwright-loop-pilot-results.md:7,16,56,113` — references the renamed `skills/qualia-polish-loop/` path
106
+ - L3. `skills/qualia-report/SKILL.md:152` — error table shows the old `set-erp-key <key>` positional syntax (CLI now requires piped)
107
+ - L4. `bin/state.js:130` — trace probabilistic pruning (1% chance) may let `.qualia-traces/` grow unnecessarily on heavy installs
108
+ - L5. `agents/visual-evaluator.md:91` — `likely_file` (as JSON field name, borderline)
109
+
110
+ ---
111
+
112
+ ## Cross-cutting patterns
113
+
114
+ ### Pattern 1: Surface drift outpaces test coverage
115
+
116
+ `tests/skills.test.sh` validates that every SKILL.md has the right frontmatter. It does NOT validate that command references inside SKILL.md, rules/, docs/, templates/ point to skills that still exist. Three v5.7/v5.8 removals slipped through because the test surface is structural, not referential.
117
+
118
+ **Fix:** Add `tests/refs.test.sh` that greps every `.md` and `.html` for `/qualia-{name}` and asserts each name has a matching `skills/qualia-{name}/SKILL.md`.
119
+
120
+ ### Pattern 2: The framework is more disciplined than its tooling enforces
121
+
122
+ CLAUDE.md is genuinely lean. Design substrate was correctly moved off the always-loaded path. Hooks enforce deterministically. But:
123
+
124
+ - `rules/architecture.md` lives where it auto-loads despite its own warning
125
+ - Skill descriptions accumulate flavor text ("Karpathy-style", "v5.3 from Matt Pocock's...") on top of trigger phrases — every change invalidates the cache prefix
126
+ - 8 rules files always-load when 3 are sufficient for most sessions
127
+
128
+ **Fix:** A `tests/budget.test.sh` that asserts total always-loaded substrate stays under ~6,000 tokens.
129
+
130
+ ### Pattern 3: The verifier knows what to check but can't always afford to check it
131
+
132
+ The 3-level verification (Truths / Artifacts / Wiring) is the right abstraction. The 25-call budget makes it un-affordable on phases with 8+ tasks. INSUFFICIENT EVIDENCE is the escape hatch, but the orchestrator doesn't punish it. So the verifier silently approves under-verified phases.
133
+
134
+ **Fix:** Budget = `max(25, tasks * 5)`. AND: any INSUFFICIENT EVIDENCE in the verification file → verdict downgraded to FAIL.
135
+
136
+ ### Pattern 4: Personalization is structurally absent
137
+
138
+ There are 4 distinct humans (Hasan, Moayad, Rama, Sally) who get an identical one-sentence description. The daily-log, knowledge layer, learned-patterns, and commit history all contain per-user signal that is collected and never read for personalization.
139
+
140
+ **Fix:** Per-employee profile file under `~/.claude/team/{code}.md`, injected into CLAUDE.md template at install time. Auto-derived from daily logs via a `/qualia-flush` extension.
141
+
142
+ ---
143
+
144
+ ## Top 10 fixes ranked by ROI
145
+
146
+ 1. **Find-and-replace the 6 dead command references in `speed.md`, `help.html`, `onboarding.html`** — 15 min. Eliminates every user-facing dead end.
147
+ 2. **Add INSUFFICIENT EVIDENCE blocker to `qualia-verify`** — 20 min. Eliminates the #1 false-pass vector.
148
+ 3. **Stop lying about retry: either build the queue or change the message** — 30 min for the message change, ~3 hours for the queue.
149
+ 4. **Send `Idempotency-Key` + `session_duration_minutes` in ERP payload** — 20 min. Completes the documented contract.
150
+ 5. **Move `architecture.md` to `~/.claude/qualia-substrate/` (lazy-load)** — 10 min. Saves ~1,560 tokens per session.
151
+ 6. **Trim skill descriptions to trigger-phrases-only** — 1 hour. Saves ~1,500 tokens per session + improves cache stability.
152
+ 7. **Per-employee profile files (`team/{code}.md`)** — 2 hours. Transforms personalization from 0 to material.
153
+ 8. **Scale verifier budget to `max(25, tasks*5)`** — 5 min. Eliminates INSUFFICIENT EVIDENCE on large phases.
154
+ 9. **Merge PRODUCT.md questions into the discovery interview** — 30 min. Cuts ~3 questions from every kickoff.
155
+ 10. **Add `tests/refs.test.sh`** — 45 min. Prevents the next surface-drift incident.
156
+
157
+ **Total effort for all 10:** ~8-10 hours.
158
+ **Effort-weighted impact:** removes every found false-pass vector, every documented dead-link, ~3K of recoverable tokens, the framework's biggest UX papercut (personalization), and the largest invisible quality risk (INSUFFICIENT EVIDENCE silently passing).
159
+
160
+ ---
161
+
162
+ ## What the framework does WELL (honest acknowledgement)
163
+
164
+ These are not patronizing — they came up across all four audits.
165
+
166
+ 1. **State machine** (`bin/state.js`). 57 behavioral tests. Atomic dual-file writes. File-based locking with stale detection. Crash-recovery journaling. Gap-cycle circuit breaker with configurable limit. Schema validation + repair. This is real engineering.
167
+ 2. **Hook architecture.** Pure Node.js (Windows-safe). Zero model-token tax (deterministic enforcement, not instructional). Real protections: service_role leak scan, force-push-to-main block (role-aware), migration safety, Vercel account guard, env-empty guard.
168
+ 3. **Verifier abstraction** (Truths / Artifacts / Wiring). Most AI coding tools check "did the task run." The Qualia verifier checks "is the artifact substantive, is it imported, is it called." The stub-detection patterns are operational learning, not theory.
169
+ 4. **Polish-loop kill-switch.** Fingerprint regression detection + budget cap. Real engineering against the known infinite-loop failure mode of vision-model feedback loops.
170
+ 5. **ERP security hardening.** Native `https.request` instead of curl (no bearer in `/proc/cmdline`). API key mode `0600`. Refuses positional CLI args. Env-var passing in payload builder (no shell injection). Atomic tmp+rename writes.
171
+
172
+ ---
173
+
174
+ ## Resources & references
175
+
176
+ - All findings cite specific files. Original investigator outputs from this audit are not committed (held in conversation context).
177
+ - Grounding protocol: `/home/qualia-new/.claude/rules/grounding.md`
178
+ - Severity criteria: same file.
179
+ - Pocock instruction-budget pattern: referenced in README:8.
180
+ - ERP contract spec: `docs/erp-contract.md` (this file exists and was used by the ERP-integration audit).
181
+
182
+ ---
183
+
184
+ ## Open questions for the user
185
+
186
+ 1. **The retry-queue approach for ERP** — would you prefer (a) an honest message change ("re-run to retry"), (b) a queue file drained on session-start, or (c) a cron job? Each has different operational characteristics.
187
+ 2. **Personalization depth** — willing to spend an afternoon writing 4 profile files for Hasan/Moayad/Rama/Sally? Or want this auto-derived from daily logs over time?
188
+ 3. **Token cuts vs cache stability** — some of the cuts (e.g. trimming skill descriptions) will invalidate prompt caches for one cycle. Worth it once, or keep stable?
189
+ 4. **The 14-question discovery interview** — keep depth at the kickoff cost, or shave 4-5 questions and accept slightly fuzzier project framing?
package/guide.md CHANGED
@@ -1,9 +1,9 @@
1
- # Qualia Developer Guide (v5.3)
1
+ # Qualia Developer Guide (v5.8)
2
2
 
3
3
  > Follow the road. Type the commands. The framework handles the rest.
4
4
  > `--auto` chains the whole road end-to-end with only two human checkpoints per project.
5
5
 
6
- **v5.3 ships three Matt-Pocock gap closures:** `/qualia-prd` (synthesize conversation → durable spec), `/qualia-hook-gen` (CLAUDE.md instruction deterministic hook), `/qualia-optimize --deepen` Step 5b (3 parallel-interface design variants for refactor RFCs). Plus the visual-polish loop (`/qualia-polish-loop`) from v5.1 with reduced-motion + multi-route flags from v5.2.
6
+ **v5.8 cleans up the command surface:** `/qualia-polish-loop` is now `/qualia-polish --loop` (one flag instead of two skills). `/qualia-quick`, `/qualia-task`, and `/qualia-prd` are removed after their v5.7 deprecation window; use `/qualia-feature` for single-feature work and `/qualia-discuss` in PROJECT MODE for kickoff capture. Skill count goes from 35 to 32.
7
7
 
8
8
  ## The Road
9
9
 
@@ -52,14 +52,13 @@ Append `--auto` to `/qualia-new` and the framework chains every step:
52
52
  | Starting | `/qualia-new` | Set up project with full journey (all milestones → Handoff) |
53
53
  | Starting (auto) | `/qualia-new --auto` | Same + chain through building automatically |
54
54
  | Brownfield | `/qualia-map` | Map an existing codebase BEFORE `/qualia-new` |
55
- | Mid-project spec | `/qualia-prd` | Synthesize the current conversation into a durable feature spec (v5.3+) |
56
55
  | Building | `/qualia-plan` | Plan the current phase |
57
56
  | | `/qualia-build` | Build it (parallel tasks) |
58
57
  | | `/qualia-verify` | Check it actually works |
59
58
  | Milestone | `/qualia-milestone` | Close current, open next from JOURNEY.md |
60
- | Quick fix | `/qualia-quick` | Skip planning, just do it |
61
- | Finishing | `/qualia-polish` | Design and UX pass (scope-adaptive: component / route / app / redesign / critique / quick) |
62
- | | `/qualia-polish-loop` | Autonomous visual-polish loop screenshot vision-eval fix repeat (v5.1+) |
59
+ | Single feature | `/qualia-feature` | Auto-scoped: inline for trivia, fresh spawn for 1-5 files |
60
+ | Finishing | `/qualia-polish` | Design and UX pass (scope-adaptive: component / route / app / redesign / critique / quick / loop) |
61
+ | | `/qualia-polish --loop` | Autonomous visual-polish loop: screenshot, vision-eval, fix, repeat |
63
62
  | | `/qualia-ship` | Deploy to production |
64
63
  | | `/qualia-handoff` | Deliver to client (4 mandatory deliverables) |
65
64
  | Reporting | `/qualia-report` | Log what you did (mandatory before clock-out) |
@@ -26,6 +26,8 @@ const STATE_FILE = path.join(".planning", "STATE.md");
26
26
  const CONTINUE_HERE = ".continue-here.md";
27
27
  const NOTIF_FILE = path.join(HOME, ".claude", ".qualia-update-available.json");
28
28
  const HEALTH_FILE = path.join(HOME, ".claude", ".qualia-install-health.json");
29
+ const ERP_RETRY = path.join(HOME, ".claude", "bin", "erp-retry.js");
30
+ const ERP_QUEUE = path.join(HOME, ".claude", ".erp-retry-queue.json");
29
31
 
30
32
  // Critical files referenced by skills via @-import. If any are missing, skills
31
33
  // silently get empty context and produce ungrounded output. We spot-check these
@@ -115,6 +117,21 @@ function fallbackText() {
115
117
  }
116
118
  }
117
119
 
120
+ function maybeDrainErpQueue() {
121
+ // Fire-and-forget drain of any reports stranded from a prior /qualia-report
122
+ // upload failure. Cheap fast-path: only spawn if the queue file exists and
123
+ // erp-retry.js is installed. Quiet mode + small max so we never block the
124
+ // session-start critical path. The script itself exits 0 even on internal
125
+ // errors — see erp-retry.js's CLI tail.
126
+ try {
127
+ if (!fs.existsSync(ERP_QUEUE) || !fs.existsSync(ERP_RETRY)) return;
128
+ spawnSync(process.execPath, [ERP_RETRY, "drain", "--quiet", "--max=5", "--timeout=2500"], {
129
+ stdio: "ignore",
130
+ timeout: 8000,
131
+ });
132
+ } catch {}
133
+ }
134
+
118
135
  function maybeRenderUpdateBanner() {
119
136
  // EMPLOYEE-only sticky banner. auto-update.js writes NOTIF_FILE when a new
120
137
  // version is detected; we render it every session until the user actually
@@ -144,6 +161,7 @@ function renderHealthWarning(missing) {
144
161
 
145
162
  try {
146
163
  maybeRenderUpdateBanner();
164
+ maybeDrainErpQueue();
147
165
 
148
166
  const healthMissing = checkInstallHealth();
149
167
  if (healthMissing) renderHealthWarning(healthMissing);
@@ -173,7 +191,7 @@ try {
173
191
  console.log(` ${DIM}Start here:${RESET}`);
174
192
  console.log(` ${TEAL}/qualia-new${RESET} ${DIM}Set up a new project${RESET}`);
175
193
  console.log(` ${TEAL}/qualia${RESET} ${DIM}What should I do next?${RESET}`);
176
- console.log(` ${TEAL}/qualia-quick${RESET} ${DIM}Quick fix (skip planning)${RESET}`);
194
+ console.log(` ${TEAL}/qualia-feature${RESET} ${DIM}Single feature (auto-scoped)${RESET}`);
177
195
  console.log("");
178
196
  }
179
197
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qualia-framework",
3
- "version": "5.5.0",
3
+ "version": "5.9.0",
4
4
  "description": "Claude Code workflow framework by Qualia Solutions. Plan, build, verify, ship.",
5
5
  "bin": {
6
6
  "qualia-framework": "./bin/cli.js"
@@ -31,7 +31,8 @@
31
31
  "test:skills": "bash tests/skills.test.sh",
32
32
  "test:slop-detect": "bash tests/slop-detect.test.sh",
33
33
  "test:statusline": "bash tests/statusline.test.sh",
34
- "test:shell": "bash tests/statusline.test.sh && bash tests/state.test.sh && bash tests/hooks.test.sh && bash tests/bin.test.sh && bash tests/lib.test.sh && bash tests/skills.test.sh && bash tests/slop-detect.test.sh"
34
+ "test:refs": "bash tests/refs.test.sh",
35
+ "test:shell": "bash tests/statusline.test.sh && bash tests/state.test.sh && bash tests/hooks.test.sh && bash tests/bin.test.sh && bash tests/lib.test.sh && bash tests/skills.test.sh && bash tests/refs.test.sh && bash tests/slop-detect.test.sh"
35
36
  },
36
37
  "files": [
37
38
  "bin/",
package/rules/speed.md CHANGED
@@ -47,8 +47,7 @@ The pattern: **on-demand by default; always-on only when the data is irreducibly
47
47
 
48
48
  When a Qualia command exists for the situation, use it — don't reinvent:
49
49
  - `/qualia` — what's my next step?
50
- - `/qualia-quick` — small inline fix, no plan, no spawn
51
- - `/qualia-task` — single focused task, fresh builder spawn, atomic commit
50
+ - `/qualia-feature` — single feature, auto-scoped: inline for trivia, fresh builder spawn for 1-5 file features
52
51
  - `/qualia-ship` — full deploy pipeline (quality gates → commit → deploy → verify)
53
52
  - `/qualia-review` — production audit
54
53
  - `/qualia-pause` — save context before clearing the conversation
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-discuss
3
- description: "Aggressive alignment interview before planning a phase asks ONE question at a time, proposes a recommended answer with each, walks every branch of the decision tree until resolved. Updates .planning/CONTEXT.md inline as terms crystallize and writes ADRs for hard-to-reverse decisions. Output: .planning/phase-{N}-context.md (locked input the planner honors). Use BEFORE /qualia-plan for high-stakes phases (regulatory, auth, payments, multi-tenant, architectural forks), or when the user says 'discuss', 'grill me', 'stress test this plan', 'wait let's think about this one', 'I'm not sure how to approach this'."
3
+ description: "Alignment interview. Two modes. PROJECT MODE (default, no args) is the non-technical kickoff before /qualia-new 8 questions for demo projects, 14 for full projects, output is .planning/project-discovery.md. PHASE MODE (with N arg, e.g. /qualia-discuss 2) is the technical aggressive grilling before /qualia-plan N one question at a time with recommended answer, output is .planning/phase-{N}-context.md. Trigger phrases: 'discuss', 'kickoff interview', 'grill me', 'stress test this plan', 'wait let's think about this one', 'I'm not sure how to approach this'."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -11,24 +11,124 @@ allowed-tools:
11
11
  - AskUserQuestion
12
12
  ---
13
13
 
14
- # /qualia-discuss — Alignment Interview Before Planning
14
+ # /qualia-discuss — Alignment Interview
15
+
16
+ Two modes. The skill picks one based on whether an arg is passed.
17
+
18
+ | Arg | Mode | When | Output |
19
+ |-----|------|------|--------|
20
+ | (none) | **PROJECT MODE** | Kickoff, before `/qualia-new`. Non-technical, audience-facing. | `.planning/project-discovery.md` |
21
+ | `N` (e.g. `2`) | **PHASE MODE** | Before `/qualia-plan N`. Technical, aggressive grilling. | `.planning/phase-{N}-context.md` |
22
+
23
+ ## Mode routing
24
+
25
+ ```bash
26
+ if [ -z "$1" ] || ! [[ "$1" =~ ^[0-9]+$ ]]; then
27
+ MODE="project"
28
+ else
29
+ MODE="phase"
30
+ PHASE_N="$1"
31
+ fi
32
+ ```
33
+
34
+ If `MODE=project` → jump to **PROJECT MODE** section below.
35
+ If `MODE=phase` → jump to **PHASE MODE** section below.
36
+
37
+ ---
38
+
39
+ # PROJECT MODE — Kickoff Interview (no args)
40
+
41
+ The non-technical conversation that runs at the very start of `/qualia-new`, BEFORE any roadmapping or research. Captures what the client wants, who it's for, brand voice, and constraints — in the client's own words.
42
+
43
+ Hard rule: **never go technical here.** No "Should we use Supabase or Postgres?". The technical decisions happen in PHASE MODE, per phase. This mode is for the human shape of the project.
44
+
45
+ ## When PROJECT MODE runs
46
+
47
+ - Triggered automatically by `/qualia-new` after Step 0 banner, BEFORE journey generation.
48
+ - Or invoked manually (e.g. on a brownfield project that already has code but no discovery doc).
49
+
50
+ ## Process — PROJECT MODE
51
+
52
+ ### P1. Detect project type (or accept it from `/qualia-new`)
53
+
54
+ If `/qualia-new` already asked the Demo vs Full gate, it passes the type in as `PROJECT_TYPE=demo` or `PROJECT_TYPE=full` via env or arg. Otherwise ask first:
55
+
56
+ - header: "Project shape"
57
+ - question: "Is this a demo (single shippable milestone, sales conversation, ~1 to 2 weeks) or a full project (multi-milestone arc to Handoff)?"
58
+ - options: ["Demo", "Full project"]
59
+
60
+ This is the only fork. Demo runs §1-§8 of the discovery template. Full project runs all 14 questions.
61
+
62
+ ### P2. Banner and open
63
+
64
+ ```bash
65
+ node ~/.claude/bin/qualia-ui.js banner discuss-project
66
+ ```
67
+
68
+ Say: **"Eight quick questions for the demo path"** or **"Fourteen questions to shape the full project — we'll move fast"** depending on type.
69
+
70
+ ### P3. One question at a time, copy from `templates/project-discovery.md`
71
+
72
+ For each question §1..§8 (demo) or §1..§14 (full), ask in plain language. Format:
73
+
74
+ ```
75
+ **Question {N}/{total}:** {question text from template}
76
+
77
+ ({one-line clarifier showing the kind of answer that helps)
78
+ ```
79
+
80
+ NO "my recommendation" line in PROJECT MODE — this is open discovery, not technical grilling. Wait for the user's answer. Don't paraphrase back; capture verbatim. If the answer is too thin, ask one follow-up max, then move on.
81
+
82
+ Allowed `[Enter]` defaults exist on §2, §3, §5 only (inferred from project type). All other questions require an answer.
83
+
84
+ ### P4. Write `.planning/project-discovery.md`
85
+
86
+ Fill the template at `~/.claude/qualia-templates/project-discovery.md` with the user's verbatim answers. Set frontmatter `project_type` and `discovered_at`.
87
+
88
+ ### P5. Hand back to `/qualia-new`
89
+
90
+ ```bash
91
+ git add .planning/project-discovery.md
92
+ git commit -m "docs: project discovery interview ($PROJECT_TYPE)"
93
+ node ~/.claude/bin/qualia-ui.js ok "Discovery captured — back to /qualia-new"
94
+ ```
95
+
96
+ If invoked standalone (not from `/qualia-new`), end with:
97
+
98
+ ```bash
99
+ node ~/.claude/bin/qualia-ui.js end "DISCOVERY CAPTURED" "/qualia-new"
100
+ ```
101
+
102
+ If invoked inline by `/qualia-new`, return control silently — `/qualia-new` continues from Step 2.
103
+
104
+ ## Rules — PROJECT MODE
105
+
106
+ 1. **Never technical.** No stack questions, no architecture forks. Those are PHASE MODE.
107
+ 2. **Verbatim capture.** Don't translate the client's words into framework-speak. The client's exact phrasing is the input to PRODUCT.md voice and CONTEXT.md glossary.
108
+ 3. **One question, one answer, move on.** No batching. No drilling deeper than one follow-up.
109
+ 4. **Demo stops at §8.** Don't ask demo clients milestone-arc questions — they don't have an arc yet.
110
+ 5. **Anti-references are required.** If the user can't name three sites this should NOT look like, the design will end up generic. Push back once, then capture whatever they give you.
111
+
112
+ ---
113
+
114
+ # PHASE MODE — Pre-Plan Grilling (`/qualia-discuss N`)
15
115
 
16
116
  Surface and lock the decisions, trade-offs, and constraints that must inform a phase plan. Output: `.planning/phase-{N}-context.md` (locked input). Side effects: `.planning/CONTEXT.md` gains new terms; `.planning/decisions/` may gain ADRs.
17
117
 
18
- ## When to use
118
+ ## When PHASE MODE runs
19
119
  - Regulated domains (legal, medical, financial) where wrong choices have legal cost
20
120
  - Phases with architectural forks ("auth via middleware or RLS?")
21
121
  - Phases with external dependencies you want to lock first
22
122
  - User says "wait, let's think about this one"
23
123
 
24
- ## The four grilling rules
124
+ ## The four grilling rules (PHASE MODE)
25
125
 
26
126
  1. **One question at a time.** Wait for the answer before asking the next. Never batch.
27
127
  2. **Propose your recommended answer first.** Format every question as `Question / Recommendation / Trade-offs`. The user accepts, edits, or rejects — way faster than open interview.
28
128
  3. **If the codebase can answer, explore instead of asking.** Don't make the user say what `git grep` could tell you.
29
129
  4. **Walk every branch.** When the user picks A over B, the next question is the one that A makes load-bearing. Resolve dependencies one-by-one until the tree is fully traversed.
30
130
 
31
- ## Process
131
+ ## Process — PHASE MODE
32
132
 
33
133
  ### 1. Load substrate
34
134
 
@@ -108,7 +208,7 @@ git commit -m "docs(phase-{N}): lock context, glossary terms, ADRs"
108
208
  node ~/.claude/bin/qualia-ui.js end "PHASE {N} CONTEXT LOCKED" "/qualia-plan {N}"
109
209
  ```
110
210
 
111
- ## Rules
211
+ ## Rules — PHASE MODE
112
212
 
113
213
  1. **One session, one phase.** Don't discuss phases 1 and 2 in the same invocation.
114
214
  2. **Locked decisions are NON-NEGOTIABLE.** The planner honors them exactly. Don't lock what you're unsure of — defer it instead.