qualia-framework 6.14.0 → 7.0.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 (72) hide show
  1. package/AGENTS.md +8 -5
  2. package/CHANGELOG.md +316 -0
  3. package/CLAUDE.md +3 -1
  4. package/agents/roadmapper.md +16 -14
  5. package/bin/agent-status.js +24 -11
  6. package/bin/batch-plan.js +111 -0
  7. package/bin/branch-hygiene.js +135 -0
  8. package/bin/command-surface.js +2 -0
  9. package/bin/compile-instructions.js +82 -0
  10. package/bin/design-tokens.js +131 -0
  11. package/bin/erp-event.js +177 -0
  12. package/bin/erp-retry.js +12 -1
  13. package/bin/eval-runner.js +218 -0
  14. package/bin/host-adapters.js +84 -12
  15. package/bin/install.js +44 -13
  16. package/bin/knowledge-flush.js +6 -3
  17. package/bin/last-report.js +207 -0
  18. package/bin/project-sync.js +315 -0
  19. package/bin/recall.js +172 -0
  20. package/bin/repo-map.js +188 -0
  21. package/bin/runtime-manifest.js +12 -0
  22. package/bin/state.js +112 -1
  23. package/bin/vault-access.js +82 -0
  24. package/bin/verify-panel.js +294 -0
  25. package/bin/wave-plan.js +211 -0
  26. package/docs/erp-contract.md +180 -0
  27. package/mcp/memory-mcp/server.js +257 -0
  28. package/package.json +6 -3
  29. package/qualia-design/design-dials.md +72 -0
  30. package/qualia-design/design-reference.md +24 -0
  31. package/rules/access.md +42 -0
  32. package/rules/codex-goal.md +28 -26
  33. package/rules/infrastructure.md +1 -1
  34. package/skills/qualia/SKILL.md +6 -0
  35. package/skills/qualia-build/SKILL.md +43 -9
  36. package/skills/qualia-eval/SKILL.md +83 -0
  37. package/skills/qualia-feature/SKILL.md +20 -4
  38. package/skills/qualia-fix/SKILL.md +13 -1
  39. package/skills/qualia-map/SKILL.md +15 -0
  40. package/skills/qualia-milestone/SKILL.md +12 -6
  41. package/skills/qualia-new/REFERENCE.md +6 -4
  42. package/skills/qualia-new/SKILL.md +41 -15
  43. package/skills/qualia-plan/SKILL.md +2 -2
  44. package/skills/qualia-polish/SKILL.md +3 -2
  45. package/skills/qualia-recall/SKILL.md +76 -0
  46. package/skills/qualia-report/SKILL.md +10 -0
  47. package/skills/qualia-scope/SKILL.md +3 -3
  48. package/skills/qualia-ship/SKILL.md +34 -4
  49. package/skills/qualia-update/SKILL.md +4 -0
  50. package/skills/qualia-verify/SKILL.md +53 -24
  51. package/templates/DESIGN.md +15 -0
  52. package/templates/instructions.md +32 -0
  53. package/templates/journey.md +1 -1
  54. package/templates/project-discovery.md +30 -23
  55. package/templates/requirements.md +7 -7
  56. package/tests/agent-status.test.sh +15 -0
  57. package/tests/batch-plan.test.sh +56 -0
  58. package/tests/branch-hygiene.test.sh +93 -0
  59. package/tests/design-tokens.test.sh +53 -0
  60. package/tests/erp-event.test.sh +78 -0
  61. package/tests/eval-runner.test.sh +147 -0
  62. package/tests/instructions.test.sh +109 -0
  63. package/tests/last-report.test.sh +156 -0
  64. package/tests/lib.test.sh +29 -4
  65. package/tests/project-sync.test.sh +175 -0
  66. package/tests/recall.test.sh +91 -0
  67. package/tests/repo-map.test.sh +70 -0
  68. package/tests/run-all.sh +12 -0
  69. package/tests/runner.js +363 -33
  70. package/tests/state.test.sh +92 -0
  71. package/tests/verify-panel.test.sh +162 -0
  72. package/tests/wave-plan.test.sh +153 -0
@@ -94,7 +94,8 @@ Before any work — design or otherwise — pass these gates. Skipping them prod
94
94
 
95
95
  | Gate | Required check | If fail |
96
96
  |---|---|---|
97
- | Substrate | `qualia-design/design-laws.md`, `design-brand.md`, `design-product.md`, `design-rubric.md`, `design-reference.md`, `frontend.md`, `graphics.md` exist and have been read when scope requires them | Read them. |
97
+ | Substrate | `qualia-design/design-laws.md`, `design-brand.md`, `design-product.md`, `design-rubric.md`, `design-reference.md`, `design-dials.md`, `frontend.md`, `graphics.md` exist and have been read when scope requires them | Read them. |
98
+ | Dials + pre-flight | `qualia-design/design-dials.md` read; the 3 dials resolved from DESIGN.md §0 (or register defaults); the ban→do-instead list loaded BEFORE any token/component edit | Read it; resolve dials; cite the bans you'll avoid. |
98
99
  | PRODUCT | `PRODUCT.md` exists at project root, has `register:` field, and is not placeholder (`[TODO]` markers, < 200 chars) | Run setup: ask 5 questions and generate it. Never synthesize from prompt alone. |
99
100
  | DESIGN | `DESIGN.md` exists. If missing on App / Redesign scope, BLOCK and run setup. If missing on Component / Section / Critique / Quick scope, NUDGE and proceed. | Generate from PRODUCT.md + 3 questions. |
100
101
  | Slop-detect | `bin/slop-detect.mjs` is callable | Install or pull from framework. |
@@ -103,7 +104,7 @@ Before any work — design or otherwise — pass these gates. Skipping them prod
103
104
  State this preflight explicitly before editing:
104
105
 
105
106
  ```
106
- POLISH_PREFLIGHT: substrate=pass product=pass design=pass|nudged graphics=loaded|skipped slop_detect=pass mutation=open
107
+ POLISH_PREFLIGHT: substrate=pass product=pass design=pass|nudged dials={VAR}/{MOT}/{DEN} graphics=loaded|skipped slop_detect=pass mutation=open
107
108
  ```
108
109
 
109
110
  ## Process
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: qualia-recall
3
+ description: "Recall curated prior lessons from the Qualia memory substrate — the knowledge layer + the qualia-memory vault, role-filtered. The read side of /qualia-learn. Triggers: 'recall', 'have we done this before', 'what did we learn about X', 'prior art', 'any notes on', 'check the vault'."
4
+ allowed-tools:
5
+ - Read
6
+ - Grep
7
+ - Bash
8
+ ---
9
+
10
+ # /qualia-recall — Recall Knowledge
11
+
12
+ The **read side** of memory. `/qualia-learn` writes; `/qualia-recall` reads. One
13
+ query, both stores:
14
+
15
+ 1. **Knowledge layer** — `${QUALIA_KNOWLEDGE}/` (patterns, fixes, client prefs)
16
+ 2. **qualia-memory vault** — `~/qualia-memory/wiki/` (the team's curated,
17
+ cross-project Obsidian LLM Wiki)
18
+
19
+ Use it BEFORE web search or before re-solving a problem — the team may already
20
+ have the answer, already filtered for relevance.
21
+
22
+ ## Usage
23
+
24
+ - `/qualia-recall {topic}` — recall across both stores
25
+ - `/qualia-recall {topic} --scope vault` — vault only (`knowledge` | `vault` | `all`)
26
+ - `/qualia-recall {topic} --json` — machine output
27
+
28
+ ## Access is role-aware (non-negotiable)
29
+
30
+ The vault carries an access manifest at `wiki/_meta/access.md`. `recall.js`
31
+ **enforces it deterministically**: when your role (from
32
+ `~/.claude/.qualia-config.json`, or `$QUALIA_ROLE`) is not `OWNER`, OWNER_ONLY
33
+ and CONDITIONAL paths (Finances, Clients, Team, raw sessions, the access manifest
34
+ itself) are filtered out of results — you still get every ALL_ROLES lesson.
35
+ Unknown role ⇒ fail-closed (restricted). See `${QUALIA_RULES}/access.md`.
36
+
37
+ ## Process
38
+
39
+ ```bash
40
+ node ${QUALIA_BIN}/qualia-ui.js banner recall 2>/dev/null || true
41
+ ```
42
+
43
+ ### 1. Run the recall
44
+
45
+ ```bash
46
+ node ${QUALIA_BIN}/recall.js "{topic}" # human digest
47
+ # or, to consume programmatically:
48
+ node ${QUALIA_BIN}/recall.js "{topic}" --json
49
+ ```
50
+
51
+ `recall.js` exits 0 even with zero hits, 2 on bad invocation. It delegates the
52
+ knowledge-layer search to `knowledge.js` (so newly-added knowledge files stay
53
+ discoverable) and greps `wiki/` for the vault.
54
+
55
+ ### 2. Read the strongest hits
56
+
57
+ The digest ranks files by hit count. `Read` the top files (or the specific
58
+ `file:line` for the vault page) to pull the full lesson before acting. For vault
59
+ pages, paths are relative to `~/qualia-memory/wiki/`.
60
+
61
+ ### 3. Apply, then consider learning
62
+
63
+ If the recall resolved your question, apply it. If you discovered something the
64
+ stores DON'T yet have, close the loop with `/qualia-learn`.
65
+
66
+ ## Command Output Contract
67
+
68
+ ```text
69
+ Command: /qualia-recall {topic}
70
+ Scope: knowledge layer + vault (role-filtered)
71
+ Intent: report
72
+ Mutation: none (read-only)
73
+ Evidence: recall.js across ${QUALIA_KNOWLEDGE}/ + ~/qualia-memory/wiki/
74
+ Output: ranked digest of prior lessons
75
+ Next: Read top hits → apply, or /qualia-learn if it's a new lesson
76
+ ```
@@ -123,6 +123,16 @@ if [ "$DRY_RUN" != "true" ] && [ -d .git ]; then
123
123
  fi
124
124
  ```
125
125
 
126
+ ### Step 5b — Branch hygiene sweep (clock-out safety net)
127
+
128
+ Ship integrates every deploy into `main`, but work that was built and never shipped strands on a branch, and review PRs can linger. Surface both before the employee leaves — informational, never blocks:
129
+
130
+ ```bash
131
+ node ${QUALIA_BIN}/branch-hygiene.js
132
+ ```
133
+
134
+ Exit 1 → it lists branches with unshipped commits ahead of `main` (run `/qualia-ship` or merge them, or delete if abandoned) and any stale open PRs. Exit 0 → nothing stranded. Include the summary in the closing message so the OWNER sees it in the report.
135
+
126
136
  ### Step 6 — Upload to ERP
127
137
 
128
138
  The full payload-builder + 3-attempt-retry logic lives unchanged from v4 — see the **ERP Upload** section below for the canonical implementation. Behavior summary:
@@ -45,7 +45,7 @@ The non-technical conversation at the start of `/qualia-new`, BEFORE roadmapping
45
45
 
46
46
  ### P1. Project type (or accept it from `/qualia-new`)
47
47
 
48
- If `/qualia-new` already asked the Demo vs Full gate (its literal first question), it passes `PROJECT_TYPE=demo` | `PROJECT_TYPE=full` via env/arg — **skip the gate, do not re-ask.** Only ask it when invoked standalone, via **AskUserQuestion** (header "Project shape"): "Demo (single shippable milestone, sales conversation)" vs "Full project (multi-milestone arc to Handoff)". Demo runs §1–§8 of the discovery template; Full runs all 14.
48
+ If `/qualia-new` already asked the Demo vs Full gate (its literal first question), it passes `PROJECT_TYPE=demo` | `PROJECT_TYPE=full` via env/arg — **skip the gate, do not re-ask.** Only ask it when invoked standalone, via **AskUserQuestion** (header "Project shape"): "Demo (single shippable milestone, sales conversation)" vs "Full project (multi-milestone arc to Handoff)". Demo runs §1–§8 of the discovery template; Full runs §1–§15 (adds the capability-completeness pass + delivery questions).
49
49
 
50
50
  ### P2. Open
51
51
 
@@ -53,11 +53,11 @@ If `/qualia-new` already asked the Demo vs Full gate (its literal first question
53
53
  node ${QUALIA_BIN}/qualia-ui.js banner scope 2>/dev/null || true
54
54
  ```
55
55
 
56
- Say **"Eight quick questions for the demo path"** or **"Fourteen questions to shape the full project — we'll move fast."**
56
+ Say **"Eight quick questions for the demo path"** or **"Fifteen questions to shape the full project — we'll move fast. The middle ones map out everything the project needs to be DONE."**
57
57
 
58
58
  ### P3. One question at a time, from `templates/project-discovery.md`
59
59
 
60
- For each §1..§8 (demo) or §1..§14 (full), ask in plain language:
60
+ For each §1..§8 (demo) or §1..§15 (full), ask in plain language:
61
61
 
62
62
  ```
63
63
  **Question {N}/{total}:** {question text from the template}
@@ -121,17 +121,37 @@ if [ $SEC_FAIL -ne 0 ]; then
121
121
  fi
122
122
  ```
123
123
 
124
- ### 3. Git
124
+ ### 3. Integrate to main (ship IS the merge point)
125
+
126
+ Ship is the one place feature work lands on `main`, so `main` is always exactly what's in production and no branch lingers. Commit, then fast-forward-integrate into `main` and push. `branch-guard` records the main push (accountability, not a block — see `rules/infrastructure.md`).
125
127
 
126
128
  ```bash
127
129
  git add {specific changed files}
128
130
  git commit -m "ship: {project name} production deploy"
129
- git push
131
+
132
+ BR=$(git branch --show-current)
133
+ if [ "$BR" != "main" ] && [ "$BR" != "master" ]; then
134
+ git checkout main
135
+ git pull --ff-only origin main 2>/dev/null || true # sync with remote first
136
+ if git merge --ff-only "$BR"; then
137
+ : # clean fast-forward
138
+ else
139
+ # main moved since the branch started — rebase the feature, then ff.
140
+ git checkout "$BR" && git rebase main || {
141
+ node ${QUALIA_BIN}/qualia-ui.js fail "Rebase conflict integrating $BR → main. Resolve, then re-run /qualia-ship."
142
+ exit 1
143
+ }
144
+ git checkout main && git merge --ff-only "$BR"
145
+ fi
146
+ fi
147
+ git push origin HEAD
130
148
  ```
131
149
 
132
- Employee stays on feature branch. Never push to main.
150
+ If anything in this block fails (conflict, push rejected), STOP and surface it — do not deploy a half-integrated tree.
151
+
152
+ ### 4. Deploy (from main)
133
153
 
134
- ### 4. Deploy
154
+ Deploy runs on `main` HEAD — what you just integrated — so the deployed artifact and `main` are byte-identical.
135
155
 
136
156
  ```bash
137
157
  vercel --prod # Website/AI agent
@@ -141,6 +161,16 @@ supabase functions deploy # Edge functions
141
161
  wrangler deploy # Cloudflare Workers
142
162
  ```
143
163
 
164
+ ### 4b. Close the branch
165
+
166
+ On a verified successful deploy, delete the integrated feature branch so nothing lingers (skip if you shipped directly from `main`):
167
+
168
+ ```bash
169
+ if [ -n "$BR" ] && [ "$BR" != "main" ] && [ "$BR" != "master" ]; then
170
+ git branch -d "$BR" 2>/dev/null && git push origin --delete "$BR" 2>/dev/null || true
171
+ fi
172
+ ```
173
+
144
174
  ### 5. Post-Deploy Verification
145
175
 
146
176
  Read the deployed URL from `tracking.json.deployed_url` or from an explicit user-provided URL. Do NOT use a `{domain}` placeholder — that expects the LLM to hallucinate the URL, which is exactly the kind of silent fail the state guard above prevents.
@@ -54,6 +54,10 @@ Keep it small and shippable. A bug fix, a copy change, a new section, a single
54
54
  feature. If it's larger than ~5 files or needs its own milestone arc, it's a new
55
55
  `build`-mode milestone — use `/qualia-milestone`, not an update.
56
56
 
57
+ ### 2b. Set the work-unit goal
58
+
59
+ Per `rules/codex-goal.md` — set the work-unit goal with scope `feature` (Codex `/goal`; on Claude Code, a tracked task + budget). An update runs its own lean loop without `/qualia-plan`, so set the objective + budget here so the change stays one coherent, bounded unit.
60
+
57
61
  ### 3. Run the lean loop
58
62
 
59
63
  Reuse the real lifecycle skills, scoped to this one change:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-verify
3
- description: "Goal-backward verification of a built phase — fresh verifier agent greps code against acceptance criteria, scores design rubric, optional adversarial second pass. Triggers: 'verify this phase', 'check if it works', 'run verification', 'did the build pass'."
3
+ description: "Goal-backward verification of a built phase — a parallel verifier PANEL (one lens each) greps code against acceptance criteria, per-finding adversarial skeptics vote majority-survives, and verify-panel.js aggregates a deterministic verdict. Triggers: 'verify this phase', 'check if it works', 'run verification', 'did the build pass'."
4
4
  allowed-tools:
5
5
  - Bash
6
6
  - Read
@@ -19,7 +19,7 @@ Spawn verifier to check phase goal. Does NOT trust build summaries; greps codeba
19
19
  `/qualia-verify` — verify current built phase
20
20
  `/qualia-verify {N}` — verify specific phase
21
21
  `/qualia-verify {N} --auto` — verify + auto-chain: PASS → next phase/milestone; FAIL → gap closure; gap limit → halt
22
- `/qualia-verify {N} --adversarial` — second verifier in fresh context with adversarial prompt. Union findings. Recommended for high-stakes phases (Handoff, payment/auth/migration).
22
+ `/qualia-verify {N} --adversarial` — deepen the panel: 5 skeptics per finding instead of 3. Recommended for high-stakes phases (Handoff, payment/auth/migration).
23
23
 
24
24
  ## Process
25
25
 
@@ -44,25 +44,39 @@ node ${QUALIA_BIN}/contract-runner.js .planning/phase-{N}-contract.json
44
44
 
45
45
  If it fails, the phase cannot PASS. Still spawn the verifier to explain the failure and identify the smallest gap-closure tasks. If it passes, pass the evidence file into the verifier prompt.
46
46
 
47
- ### 3. Spawn Verifier (Fresh Context)
47
+ ### 3. Spawn Verifier Panel (parallel lenses, fresh context each)
48
+
49
+ A single LLM judge is adversarially fragile (a lone stray token flips ~35% of verdicts). Replace single-pass review with a **panel**: one verifier per *relevant* lens, spawned in parallel (separate `Agent()` calls in the SAME turn), each scoped to one concern and anchored on the SAME machine evidence (contract-run + harness-eval) as shared ground truth.
48
50
 
49
51
  ```bash
50
52
  node ${QUALIA_BIN}/qualia-ui.js banner verify {N} "{phase name}"
51
- node ${QUALIA_BIN}/qualia-ui.js spawn verifier "Goal-backward check..."
52
53
  ```
53
54
 
55
+ Pick lenses by what the phase touches (scale cost to risk — don't run all four on a one-file change):
56
+ - **correctness** — always.
57
+ - **security** — if the plan touches `auth|payment|rls|service_role|migration|secret|upload`.
58
+ - **performance** — if it touches data fetching, network-in-loop, large lists, or `--perf` is set.
59
+ - **design** — if it touches `.tsx/.jsx/.css/.scss` or `app/|components/|pages/`.
60
+
61
+ For each chosen lens `L`, spawn (all in one turn, then wait for all):
62
+
54
63
  ```
55
64
  Agent(prompt="
56
65
  Role: @${QUALIA_AGENTS}/verifier.md
57
66
 
67
+ LENS: {L}. Review ONLY through the {L} lens — concerns owned by other lenses have their own reviewer; do not duplicate them.
68
+
58
69
  Project: @.planning/PROJECT.md
59
70
  Plan + AC + validation: @.planning/phase-{N}-plan.md
60
71
  Machine contract: @.planning/phase-{N}-contract.json
61
- Contract evidence: @.planning/evidence/phase-{N}-contract-run.json
72
+ Contract evidence (shared ground truth — do not re-derive): @.planning/evidence/phase-{N}-contract-run.json
62
73
  {Re-verify → previous gaps: @.planning/phase-{N}-verification.md}
63
74
 
64
- Verify phase. Every finding needs file:line evidence. Severity Rubric for all labels. Output: .planning/phase-{N}-verification.md
65
- ", subagent_type="qualia-verifier", description="Verify phase {N}")
75
+ Verify the {L} concerns of this phase. Every finding needs file:line evidence and a Severity Rubric label.
76
+ Write your findings as a JSON array to .planning/phase-{N}-panel-{L}.json:
77
+ [{\"file\":\"path\",\"line\":N,\"severity\":\"CRITICAL|HIGH|MEDIUM|LOW\",\"title\":\"one-line claim\"}]
78
+ Empty array [] if the {L} lens is clean. Also append a human '## {L} lens' section to .planning/phase-{N}-verification.md.
79
+ ", subagent_type="qualia-verifier", description="Verify phase {N} — {L} lens")
66
80
  ```
67
81
 
68
82
  ### 3b. Browser QA (if phase touched frontend)
@@ -89,34 +103,41 @@ Drive dev server, test routes phase touched. Append '## Browser QA' to verificat
89
103
 
90
104
  Wait for both verifier + QA before step 3. Playwright MCP unavailable → QA returns BLOCKED (note, not phase failure).
91
105
 
92
- ### 3c. Adversarial Second Opinion (--adversarial flag, optional)
106
+ ### 3c. Skeptic Pass + Deterministic Aggregation
107
+
108
+ The panel FINDS; skeptics decide what's REAL; `verify-panel.js` decides the verdict — math, not a vibe.
93
109
 
94
- `--adversarial` in args, OR milestone is `Handoff`, OR plan touches `auth|payment|migration|rls|service_role` → spawn SECOND verifier in fresh context. Mitigates self-grading bias (~70% fewer findings without adversarial pass).
110
+ **1. Assemble** the per-lens finding files into one panel skeleton (votes zeroed):
95
111
 
96
112
  ```bash
97
- node ${QUALIA_BIN}/qualia-ui.js spawn verifier "Adversarial pass — find what's wrong"
113
+ node ${QUALIA_BIN}/verify-panel.js assemble {N} # .planning/phase-{N}-panel.json
98
114
  ```
99
115
 
116
+ **2. Skeptic vote** on each CRITICAL/HIGH finding (MEDIUM/LOW auto-survive — they don't flip the C/H verdict; skipping skeptics on them is the documented cost bound, not a silent cap). For each such finding spawn **3 skeptics** (5 if `--adversarial`, Handoff milestone, or the finding's lens is `security`), each in fresh context, each prompted to REFUTE:
117
+
100
118
  ```
101
119
  Agent(prompt="
102
120
  Role: @${QUALIA_AGENTS}/verifier.md
103
121
 
104
- ADVERSARIAL reviewer. Find what's WRONG. Assume cooperative verifier missed something. Same Severity Rubric + evidence-citation req. Bias toward edge cases:
105
- - Untested error paths?
106
- - Crash-inducing input?
107
- - Unhandled concurrent access?
108
- - Downstream breaks if contract changes?
109
- - Security assumption (auth, RLS, secrets) implicit not enforced?
122
+ SKEPTIC. A panel verifier claims this finding. Try to REFUTE it: is it actually reachable on a real path, or already handled elsewhere, or a false positive? Default to refuted ONLY with evidence uncertainty is NOT refutation.
110
123
 
111
- Project: @.planning/PROJECT.md
112
- Plan: @.planning/phase-{N}-plan.md
113
- Cooperative report (find what they MISSED): @.planning/phase-{N}-verification.md
124
+ Finding: {severity} — {title}
125
+ Location: {file}:{line}
126
+ Evidence to re-check yourself: @{file}
127
+
128
+ Return exactly one line: REAL — {file:line reason} OR NOT_REAL — {file:line reason}
129
+ ", subagent_type="qualia-verifier", description="Skeptic {i}/3 — {title}")
130
+ ```
131
+
132
+ Tally each finding's votes into `.planning/phase-{N}-panel.json` (`votes.real` / `votes.notReal`).
133
+
134
+ **3. Aggregate** deterministically:
114
135
 
115
- Append '## Adversarial Findings' to verification file. Empty section fine if nothing found.
116
- ", subagent_type="qualia-verifier", description="Adversarial verify phase {N}")
136
+ ```bash
137
+ node ${QUALIA_BIN}/verify-panel.js .planning/phase-{N}-panel.json --write
117
138
  ```
118
139
 
119
- Findings merge into main report. Union PASS/FAIL: either pass found CRITICAL/HIGH → phase FAIL.
140
+ `verify-panel.js` dedupes findings across lenses, applies **majority-survives** (a finding is killed only when skeptics are a strict majority calling it not-real; ties and unvoted findings survive), computes category scores via the `rules/grounding.md` formula, and exits **0 = PASS / 1 = FAIL** (any surviving CRITICAL/HIGH → FAIL). That exit code IS the panel verdict — carry it into step 4. Artifacts: `.planning/phase-{N}-verification-panel.{json,md}`.
120
141
 
121
142
  ### 3d. INSUFFICIENT EVIDENCE downgrade (mandatory)
122
143
 
@@ -132,7 +153,7 @@ if [ "$IE_COUNT" -gt 0 ]; then
132
153
  fi
133
154
  ```
134
155
 
135
- The same check runs after the adversarial pass if it executed.
156
+ The same check runs across every lens section the panel wrote.
136
157
 
137
158
  ### 3. Present Results
138
159
 
@@ -181,7 +202,7 @@ Run the zero-token anti-slop scan as a deterministic gate (same role as `migrati
181
202
  node ${QUALIA_BIN}/slop-detect.mjs --severity=critical
182
203
  ```
183
204
 
184
- If the eval status is `FAIL` or anti-slop exits non-zero, do not mark the phase PASS. The state machine also refuses PASS when a contract exists but `.planning/evidence/phase-{N}-contract-run.json` is missing/failing, or when the verification report contains `INSUFFICIENT EVIDENCE`.
205
+ The phase is PASS only if ALL of these agree: the panel verdict (§3c `verify-panel.js` exit 0), the harness-eval status, and the anti-slop scan. If any is FAIL/non-zero, mark the phase FAIL. The state machine also refuses PASS when a contract exists but `.planning/evidence/phase-{N}-contract-run.json` is missing/failing, or when the verification report contains `INSUFFICIENT EVIDENCE`.
185
206
 
186
207
  ```bash
187
208
  node ${QUALIA_BIN}/state.js transition --to verified --phase {N} --verification {pass|fail} --evidence .planning/evals/harness-eval-*.json
@@ -191,6 +212,14 @@ FAIL + gap_cycles >= limit → GAP_CYCLE_LIMIT, escalate.
191
212
  FAIL + gap_cycles < limit → `/qualia-plan {N} --gaps`.
192
213
  Do NOT edit STATE.md or tracking.json manually; state.js handles both.
193
214
 
215
+ **Emit the lifecycle event** (R14 — feeds the ERP live run-tree). Signed, non-blocking, a no-op when ERP is disabled:
216
+
217
+ ```bash
218
+ node ${QUALIA_BIN}/erp-event.js emit {verify_pass|verify_fail} --target project:{project} ${ERP_PROJECT_ID:+--project $ERP_PROJECT_ID}
219
+ ```
220
+
221
+ Use `verify_pass` on PASS, `verify_fail` on FAIL. The same emitter serves other lifecycle points — `session_started` (session start), `phase_planned` (`/qualia-plan`), `build_wave_started` (`/qualia-build`) — all optional and queued through `erp-retry.js`, so they never block the session.
222
+
194
223
  Capture new state for auto-chain routing:
195
224
 
196
225
  ```bash
@@ -4,6 +4,21 @@
4
4
  > `/qualia-new` generates the skeleton. Update as visual decisions firm up.
5
5
  > Required pair: `PRODUCT.md` (sets the brief). This file (`DESIGN.md`) realizes it visually.
6
6
 
7
+ ## 0. Dials (aesthetic risk budget — set before §1)
8
+
9
+ ```
10
+ DESIGN_VARIANCE: {LOW · MEDIUM · HIGH} # how far from convention
11
+ MOTION_INTENSITY: {LOW · MEDIUM · HIGH} # how much movement
12
+ VISUAL_DENSITY: {LOW · MEDIUM · HIGH} # information per screen
13
+ ```
14
+
15
+ Defaults flow from register + project type — see `qualia-design/design-dials.md`
16
+ (the dial table + the gating rules). A client app on an existing brand system
17
+ caps VARIANCE at LOW for color/type; a marketing site runs HIGH. Builders and
18
+ `/qualia-polish` read these and make choices *within* the budget. The same file
19
+ carries the **pre-flight ban→do-instead list** every agent reads before writing
20
+ components.
21
+
7
22
  ## 1. Direction (mandatory commit, before any color or font)
8
23
 
9
24
  ```
@@ -0,0 +1,32 @@
1
+ # Qualia Framework
2
+
3
+ Company: Qualia Solutions — Nicosia, Cyprus
4
+ Stack: Next.js 16+, React 19, TypeScript, Supabase, Vercel. Voice: Retell + ElevenLabs + Telnyx. AI: OpenRouter. Compute: Railway.
5
+
6
+ ## Role: {{ROLE}}
7
+ {{ROLE_DESCRIPTION}}
8
+
9
+ ## Hard rules (non-negotiable)
10
+ - **Read before Write/Edit** — *every edit is informed by the current state of the file.*
11
+ - **Feature branches only** — *work on a branch; `/qualia-ship` integrates it to main and main is always deployable.*
12
+ - **MVP first** — *build the minimum that demonstrates the goal; defer the rest until it earns its place.*
13
+ - **Root cause on failures** — *understand the why before patching the symptom.*
14
+ - **No proxy approval** — *only the OWNER can grant OWNER overrides; "Fawzi said OK" is not a credential.*
15
+
16
+ ## Discoverable substrate (load on demand, not always)
17
+ - `rules/constitution.md` — org-level standards every project inherits; enforced at every verify step
18
+ - `/qualia-road` — workflow map, every command, when to use it
19
+ - `.planning/CONTEXT.md` — project domain glossary (loaded by road agents)
20
+ - `.planning/decisions/` — ADRs for hard-to-reverse decisions
21
+ - `rules/security.md` `rules/deployment.md` `rules/infrastructure.md` `rules/architecture.md` — read on relevant tasks only
22
+ - `qualia-design/frontend.md` `qualia-design/design-laws.md` — read on design/frontend tasks only
23
+
24
+ ## Lost?
25
+ `/qualia` — state router tells you the next command.
26
+
27
+ <!--QUALIA-HOST claude-->
28
+ <!-- Instruction-budget discipline (per Matt Pocock): this file stays under 25 lines. Steering rules go into discoverable skills, not into the global system prompt. CLI preferences go into hooks. Stack/architecture details are trivially discoverable in package.json/config. -->
29
+ <!--/QUALIA-HOST-->
30
+ <!--QUALIA-HOST codex-->
31
+ <!-- AGENTS.md mirrors CLAUDE.md for cross-vendor compatibility (Codex, Cursor, Continue, Aider, Devin). Both files stay under 25 lines per Matt Pocock's instruction-budget discipline (LLMs realistically hold 300–500 instructions; bloating this file hamstrings every spawn). -->
32
+ <!--/QUALIA-HOST-->
@@ -100,7 +100,7 @@ M1 ─── M2 ─── M3 ─── ... ─── M{N} (Handoff)
100
100
 
101
101
  ## Rules for This Journey
102
102
 
103
- 1. **Hard ceiling: 5 milestones.** If the project needs more, defer to a v2 release after handoff.
103
+ 1. **No milestone ceiling the arc spans the whole agreed scope.** Plan as many milestones as the capability inventory (discovery §9) needs to reach the §10 done-state. Do NOT compress real work to hit a number, and do NOT defer agreed work to a "v2" the only deferrals are what the client explicitly marked Out of Scope (discovery §8). An arc that stops short of the agreed scope is the root cause of teams improvising off-plan later.
104
104
  2. **Hard floor: 2 milestones.** Anything smaller should use `/qualia-new --quick` instead.
105
105
  3. **In BUILD mode, the final milestone is Handoff.** This is the convention for a one-shot client build that ends with a handoff. It is **not** a universal law: once a project launches and enters the `operate` lifecycle (`state.js launch`), it becomes an *update stream* with no forced Handoff — it ships updates indefinitely. Don't author a Handoff milestone for a product/retainer that will keep shipping; launch it instead.
106
106
  4. **Milestones ≥ 2 phases OR are a shipped release gate.** A 1-phase milestone is a phase, not a milestone.
@@ -6,9 +6,9 @@ discovery_mode: project
6
6
 
7
7
  # Project Discovery, {Project Name}
8
8
 
9
- The non-technical kickoff interview output. `/qualia-scope` writes this in PROJECT MODE before `/qualia-new` generates JOURNEY.md. Captures intent, audience, brand, and constraints in the user's own words.
9
+ The non-technical kickoff interview output. `/qualia-scope` writes this in PROJECT MODE before `/qualia-new` generates JOURNEY.md. Captures intent, audience, brand, constraints — and, for full projects, the **complete capability set that defines the project as DONE** so the roadmap can span the whole arc, not a v1 slice.
10
10
 
11
- Demo path: 8 questions. Full-project path: 14 questions.
11
+ Demo path: §1–§8 (8 questions). Full-project path: §1–§15 (adds the completeness pass + delivery questions).
12
12
 
13
13
  ## 1. The one-line pitch
14
14
 
@@ -36,48 +36,55 @@ Demo path: 8 questions. Full-project path: 14 questions.
36
36
 
37
37
  ## 7. Hard constraints
38
38
 
39
- > {Anything that is non-negotiable: stack, deadline, compliance, integrations, budget.}
39
+ > {Anything non-negotiable: stack, deadline, compliance, integrations, budget.}
40
40
 
41
- ## 8. Out of scope
41
+ ## 8. Out of scope (explicitly deferred)
42
42
 
43
- > {What is intentionally NOT in this project, even if it would be obvious to add.}
43
+ > {What is intentionally NOT in this project — work the client has consciously deferred, even if obvious to add. This is the ONLY place work leaves the arc; anything not listed here is in-scope and must land in a milestone.}
44
44
 
45
45
  ---
46
46
 
47
- The remaining six questions only run for `project_type: full`. Demo mode stops here.
47
+ The remaining questions only run for `project_type: full`. Demo mode stops here.
48
48
 
49
- ## 9. Milestone arc, in the client's words
49
+ ## 9. Capability inventory the WHOLE project
50
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.}
51
+ > {List EVERY capability this project must have to be considered finished — not a v1 slice, the whole thing. One bullet per capability, plain language. Push for completeness: "what else does it need before you'd call it done?" Keep asking until the client says "that's everything." This list becomes the REQ-IDs and milestones anything missing here is what the team is later forced to improvise, so it is the most important answer in the interview.}
52
52
 
53
- ## 10. Compliance and legal
53
+ ## 10. Definition of done — for the entire project
54
+
55
+ > {Describe the end state where there is no more agreed work. What is true when the project is finished and the team stops? This anchors the final milestone (Handoff for client projects) and tells the roadmapper how far the arc must reach.}
56
+
57
+ ## 11. Shipping order
58
+
59
+ > {Roughly what order should the capabilities in §9 ship in? Group them into chapters if natural. We shape milestones from this — as many as the scope needs, no artificial cap. For client projects the last chapter is Handoff; for an internal or ongoing product it may have no Handoff.}
60
+
61
+ ## 12. Compliance and legal
54
62
 
55
63
  > {Anything regulated: payments, medical, legal, finance, accessibility commitments, data residency.}
56
64
 
57
- ## 11. Integrations
65
+ ## 13. Integrations
58
66
 
59
67
  > {Third-party systems this must talk to, in priority order.}
60
68
 
61
- ## 12. Content and copy
69
+ ## 14. Content and copy
62
70
 
63
71
  > {Who writes the copy and where does it live, today and after handoff?}
64
72
 
65
- ## 13. Team and roles after handoff
73
+ ## 15. Ownership, team, and delivery shape
66
74
 
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.}
75
+ > {Who maintains this after we ship what can they do, what can't they? And: fixed deadline, fixed scope, or fixed budget? Pick one — the other two flex.}
72
76
 
73
77
  ---
74
78
 
75
79
  ## How this feeds `/qualia-new`
76
80
 
77
- - §15 seed PROJECT.md (one-line pitch, what we're building) and PRODUCT.md (users, register, voice, anti-references).
81
+ - §1–§5 seed PROJECT.md (one-line pitch, what we're building) and PRODUCT.md (users, register, voice, anti-references).
78
82
  - §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`.
83
+ - §7 populates PROJECT.md's constraints section.
84
+ - §8 populates PROJECT.md's "Out of Scope" the explicit, client-agreed deferrals (the roadmapper must NOT defer anything else here).
85
+ - **§9 (full only) is the capability inventory every item becomes a REQ-ID in REQUIREMENTS.md, assigned to exactly one milestone. The roadmapper must cover ALL of §9 across the arc — no overflow into an unplanned "v2".**
86
+ - **§10 (full only) defines the arc's endpoint → the roadmapper builds milestones until the whole capability set reaches this done-state.**
87
+ - §11 (full only) seeds JOURNEY.md milestone order + "why now" lines (no milestone cap the arc is as long as §9 requires).
88
+ - §12–§15 (full only) feed research scoping, integrations, and the Handoff milestone checklist.
89
+
90
+ Demo projects skip §9–§15 because they ARE one milestone — the journey is just that milestone plus an implicit "client signs, we extend" branch handled by `/qualia-milestone`.
@@ -75,17 +75,17 @@ Fixed scope for every project. Do not reassign these elsewhere.
75
75
 
76
76
  ## Post-Handoff (v2)
77
77
 
78
- Features acknowledged but deferred past initial handoff. Not in current journey.
78
+ **Only** capabilities the client EXPLICITLY deferred in discovery §8 (Out of Scope) belong here. This is NOT an overflow bucket for a milestone cap — there is no cap; everything in the capability inventory (discovery §9) must be a REQ-ID mapped to a milestone above. If a capability is agreed but absent from the arc, that's a roadmap bug, not a v2 item.
79
79
 
80
80
  ### {Category}
81
81
 
82
- - **{CAT}-XX**: {capability}
82
+ - **{CAT}-XX**: {capability} — deferred by client (discovery §8)
83
83
 
84
84
  ---
85
85
 
86
86
  ## Out of Scope
87
87
 
88
- Explicit exclusions with reasoning. Prevents scope creep.
88
+ Explicit exclusions with reasoning, drawn from discovery §8. Prevents scope creep.
89
89
 
90
90
  | Feature | Reason |
91
91
  |---------|--------|
@@ -95,16 +95,16 @@ Explicit exclusions with reasoning. Prevents scope creep.
95
95
 
96
96
  ## Traceability
97
97
 
98
- Populated during roadmap creation. Every v1 requirement maps to exactly one milestone + phase.
98
+ Populated during roadmap creation. Every capability from discovery §9 maps to exactly one milestone + phase. Coverage of the full inventory — not a v1 slice — is the gate.
99
99
 
100
100
  | Requirement | Milestone | Phase | Status |
101
101
  |-------------|-----------|-------|--------|
102
102
  | {CAT}-01 | M1: {name} | Phase {N} | Pending |
103
103
 
104
- **Coverage:**
105
- - v1 requirements (all feature milestones + Handoff): {X} total
104
+ **Coverage (must be 100% of the §9 capability inventory):**
105
+ - Agreed capabilities (discovery §9, whole project): {X} total
106
106
  - Mapped to milestones + phases: {Y}
107
- - Unmapped: {Z}
107
+ - Unmapped: {Z} ← MUST be 0 before the journey-approval gate passes
108
108
 
109
109
  ---
110
110
 
@@ -114,6 +114,21 @@ assert_exit "BLOCKED task holds barrier" 1 $RC
114
114
  assert_contains "barrier json counts blocked" "$OUT" '"blocked": 1'
115
115
  rm -rf "$TMP"
116
116
 
117
+ # --- barrier --tasks (explicit batch gate, no contract needed; R16 wave-plan) ---
118
+ TMP=$(mktemp -d)
119
+ $NODE "$AS" write T1 DONE --commit a --cwd "$TMP" >/dev/null 2>&1
120
+ $NODE "$AS" write T2 RUNNING --cwd "$TMP" >/dev/null 2>&1
121
+ $NODE "$AS" write T5 DONE --commit b --cwd "$TMP" >/dev/null 2>&1
122
+ # batch {T1,T5} both DONE → pass, with no contract file present
123
+ $NODE "$AS" barrier --tasks T1,T5 --cwd "$TMP" >/dev/null 2>&1
124
+ assert_exit "barrier --tasks all DONE → pass (no contract)" 0 $?
125
+ # batch {T1,T2} → T2 RUNNING → hold
126
+ $NODE "$AS" barrier --tasks T1,T2 --cwd "$TMP" >/dev/null 2>&1
127
+ assert_exit "barrier --tasks with a RUNNING member → hold" 1 $?
128
+ OUT=$($NODE "$AS" barrier --tasks T1,T2 --cwd "$TMP" 2>&1)
129
+ assert_contains "barrier --tasks scope label" "$OUT" "batch T1,T2"
130
+ rm -rf "$TMP"
131
+
117
132
  # --- list + clear ---
118
133
  TMP=$(mktemp -d)
119
134
  $NODE "$AS" write T1 DONE --cwd "$TMP" >/dev/null 2>&1