qualia-framework 3.2.0 → 3.2.1

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.
@@ -0,0 +1,476 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Qualia Framework — Reference</title>
7
+ <style>
8
+ :root {
9
+ --teal: #00ced1;
10
+ --teal-glow: #00aab0;
11
+ --teal-dim: #008285;
12
+ --bg: #0b1415;
13
+ --bg-subtle: #0f1c1e;
14
+ --bg-card: #121f21;
15
+ --text: #dce1e6;
16
+ --text-muted: #6b7a85;
17
+ --text-subtle: #4a5560;
18
+ --border: #1a2e30;
19
+ --green: #34d399;
20
+ --yellow: #eab308;
21
+ --red: #ef4444;
22
+ --blue: #60a5fa;
23
+ --font-display: 'Outfit', system-ui, sans-serif;
24
+ --font-body: 'Inter', system-ui, sans-serif;
25
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
26
+ }
27
+
28
+ @import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&family=Inter:wght@400;500&family=JetBrains+Mono:wght@400;500&display=swap');
29
+
30
+ * { margin: 0; padding: 0; box-sizing: border-box; }
31
+
32
+ body {
33
+ font-family: var(--font-body);
34
+ background: var(--bg);
35
+ color: var(--text);
36
+ line-height: 1.6;
37
+ -webkit-font-smoothing: antialiased;
38
+ }
39
+
40
+ /* ─── Header ─────────────────────────────── */
41
+ .header {
42
+ padding: clamp(2rem, 6vw, 4rem) clamp(1.5rem, 5vw, 4rem);
43
+ border-bottom: 1px solid var(--border);
44
+ background: linear-gradient(160deg, var(--bg-subtle), var(--bg));
45
+ position: relative;
46
+ overflow: hidden;
47
+ }
48
+ .header::before {
49
+ content: '';
50
+ position: absolute;
51
+ top: -40%;
52
+ right: -10%;
53
+ width: 400px;
54
+ height: 400px;
55
+ background: radial-gradient(circle, rgba(0,206,209,0.08), transparent 70%);
56
+ pointer-events: none;
57
+ }
58
+ .header-content { position: relative; max-width: 900px; margin: 0 auto; }
59
+ .header h1 {
60
+ font-family: var(--font-display);
61
+ font-weight: 300;
62
+ font-size: clamp(2rem, 1rem + 3vw, 3rem);
63
+ letter-spacing: -0.02em;
64
+ color: var(--text);
65
+ }
66
+ .header h1 span { color: var(--teal); font-weight: 600; }
67
+ .header p {
68
+ color: var(--text-muted);
69
+ font-size: 1rem;
70
+ margin-top: 0.75rem;
71
+ max-width: 50ch;
72
+ }
73
+ .version {
74
+ display: inline-block;
75
+ margin-top: 1rem;
76
+ padding: 0.25rem 0.75rem;
77
+ border: 1px solid var(--border);
78
+ border-radius: 999px;
79
+ font-family: var(--font-mono);
80
+ font-size: 0.75rem;
81
+ color: var(--teal-dim);
82
+ }
83
+
84
+ /* ─── Layout ─────────────────────────────── */
85
+ .content {
86
+ max-width: 900px;
87
+ margin: 0 auto;
88
+ padding: clamp(2rem, 5vw, 4rem) clamp(1.5rem, 5vw, 4rem);
89
+ }
90
+
91
+ /* ─── Sections ───────────────────────────── */
92
+ section { margin-bottom: 3.5rem; }
93
+ section h2 {
94
+ font-family: var(--font-display);
95
+ font-weight: 500;
96
+ font-size: 1.35rem;
97
+ letter-spacing: -0.01em;
98
+ color: var(--teal);
99
+ margin-bottom: 1.25rem;
100
+ padding-bottom: 0.5rem;
101
+ border-bottom: 1px solid var(--border);
102
+ }
103
+
104
+ /* ─── The Road ───────────────────────────── */
105
+ .road {
106
+ display: flex;
107
+ flex-wrap: wrap;
108
+ gap: 0.5rem;
109
+ align-items: center;
110
+ margin: 1.5rem 0;
111
+ }
112
+ .road-step {
113
+ padding: 0.5rem 1rem;
114
+ background: var(--bg-card);
115
+ border: 1px solid var(--border);
116
+ border-radius: 8px;
117
+ font-family: var(--font-mono);
118
+ font-size: 0.8rem;
119
+ color: var(--text);
120
+ transition: border-color 0.15s ease-out;
121
+ }
122
+ .road-step:hover { border-color: var(--teal-dim); }
123
+ .road-arrow { color: var(--text-subtle); font-size: 0.9rem; }
124
+
125
+ /* ─── Command Cards ──────────────────────── */
126
+ .commands { display: grid; gap: 0.75rem; }
127
+ .cmd-group { margin-bottom: 1.5rem; }
128
+ .cmd-group h3 {
129
+ font-family: var(--font-display);
130
+ font-weight: 500;
131
+ font-size: 0.85rem;
132
+ text-transform: uppercase;
133
+ letter-spacing: 0.08em;
134
+ color: var(--text-subtle);
135
+ margin-bottom: 0.75rem;
136
+ }
137
+ .cmd {
138
+ display: flex;
139
+ gap: 1rem;
140
+ align-items: baseline;
141
+ padding: 0.625rem 1rem;
142
+ background: var(--bg-card);
143
+ border: 1px solid var(--border);
144
+ border-radius: 8px;
145
+ transition: border-color 0.15s ease-out;
146
+ }
147
+ .cmd:hover { border-color: var(--teal-dim); }
148
+ .cmd-name {
149
+ font-family: var(--font-mono);
150
+ font-size: 0.85rem;
151
+ color: var(--teal);
152
+ white-space: nowrap;
153
+ min-width: 160px;
154
+ }
155
+ .cmd-desc {
156
+ font-size: 0.85rem;
157
+ color: var(--text-muted);
158
+ }
159
+
160
+ /* ─── Rules ──────────────────────────────── */
161
+ .rules { list-style: none; }
162
+ .rules li {
163
+ padding: 0.625rem 0;
164
+ border-bottom: 1px solid var(--border);
165
+ font-size: 0.9rem;
166
+ display: flex;
167
+ gap: 0.75rem;
168
+ align-items: baseline;
169
+ }
170
+ .rules li:last-child { border-bottom: none; }
171
+ .rule-icon { color: var(--teal); font-size: 0.85rem; flex-shrink: 0; }
172
+
173
+ /* ─── Services ───────────────────────────── */
174
+ .services {
175
+ display: grid;
176
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
177
+ gap: 0.75rem;
178
+ }
179
+ .service {
180
+ padding: 1rem 1.25rem;
181
+ background: var(--bg-card);
182
+ border: 1px solid var(--border);
183
+ border-radius: 10px;
184
+ transition: border-color 0.15s ease-out;
185
+ }
186
+ .service:hover { border-color: var(--teal-dim); }
187
+ .service-name {
188
+ font-family: var(--font-display);
189
+ font-weight: 500;
190
+ font-size: 0.95rem;
191
+ color: var(--text);
192
+ margin-bottom: 0.25rem;
193
+ }
194
+ .service-desc { font-size: 0.8rem; color: var(--text-muted); }
195
+ .service-key {
196
+ font-family: var(--font-mono);
197
+ font-size: 0.7rem;
198
+ color: var(--teal-dim);
199
+ margin-top: 0.5rem;
200
+ }
201
+
202
+ /* ─── Scoring ────────────────────────────── */
203
+ .scoring {
204
+ display: grid;
205
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
206
+ gap: 0.75rem;
207
+ }
208
+ .score-dim {
209
+ padding: 1rem;
210
+ background: var(--bg-card);
211
+ border: 1px solid var(--border);
212
+ border-radius: 10px;
213
+ text-align: center;
214
+ }
215
+ .score-dim h4 {
216
+ font-family: var(--font-display);
217
+ font-weight: 500;
218
+ color: var(--teal);
219
+ font-size: 0.95rem;
220
+ margin-bottom: 0.25rem;
221
+ }
222
+ .score-dim p { font-size: 0.78rem; color: var(--text-muted); }
223
+ .score-bar {
224
+ display: flex;
225
+ gap: 3px;
226
+ justify-content: center;
227
+ margin-top: 0.5rem;
228
+ }
229
+ .score-bar span {
230
+ width: 18px;
231
+ height: 6px;
232
+ border-radius: 3px;
233
+ background: var(--border);
234
+ }
235
+ .score-bar span.filled { background: var(--teal); }
236
+ .score-bar span.threshold { background: var(--yellow); }
237
+
238
+ /* ─── Footer ─────────────────────────────── */
239
+ .footer {
240
+ padding: 2rem clamp(1.5rem, 5vw, 4rem);
241
+ border-top: 1px solid var(--border);
242
+ text-align: center;
243
+ font-size: 0.8rem;
244
+ color: var(--text-subtle);
245
+ }
246
+ .footer strong { color: var(--teal); font-weight: 500; }
247
+
248
+ /* ─── Responsive ─────────────────────────── */
249
+ @media (max-width: 640px) {
250
+ .cmd { flex-direction: column; gap: 0.25rem; }
251
+ .cmd-name { min-width: unset; }
252
+ .road { flex-direction: column; align-items: flex-start; }
253
+ .road-arrow { display: none; }
254
+ }
255
+
256
+ @media (prefers-reduced-motion: reduce) {
257
+ * { transition-duration: 0.01ms !important; }
258
+ }
259
+ </style>
260
+ </head>
261
+ <body>
262
+
263
+ <div class="header">
264
+ <div class="header-content">
265
+ <h1><span>Qualia</span> Framework</h1>
266
+ <p>Plan, build, verify, ship. The AI-powered workflow for Qualia Solutions.</p>
267
+ <div class="version">v{{VERSION}}</div>
268
+ </div>
269
+ </div>
270
+
271
+ <div class="content">
272
+
273
+ <!-- The Road -->
274
+ <section>
275
+ <h2>The Road</h2>
276
+ <p style="color: var(--text-muted); margin-bottom: 1rem;">Every project follows this path. No exceptions.</p>
277
+ <div class="road">
278
+ <div class="road-step">/qualia-new</div>
279
+ <span class="road-arrow">&rarr;</span>
280
+ <div class="road-step">/qualia-plan</div>
281
+ <span class="road-arrow">&rarr;</span>
282
+ <div class="road-step">/qualia-build</div>
283
+ <span class="road-arrow">&rarr;</span>
284
+ <div class="road-step">/qualia-verify</div>
285
+ <span class="road-arrow">&rarr;</span>
286
+ <div class="road-step">/qualia-polish</div>
287
+ <span class="road-arrow">&rarr;</span>
288
+ <div class="road-step">/qualia-ship</div>
289
+ <span class="road-arrow">&rarr;</span>
290
+ <div class="road-step">/qualia-handoff</div>
291
+ <span class="road-arrow">&rarr;</span>
292
+ <div class="road-step">/qualia-report</div>
293
+ </div>
294
+ </section>
295
+
296
+ <!-- Commands -->
297
+ <section>
298
+ <h2>Commands</h2>
299
+
300
+ <div class="cmd-group">
301
+ <h3>Navigation</h3>
302
+ <div class="commands">
303
+ <div class="cmd"><span class="cmd-name">/qualia</span><span class="cmd-desc">What should I do next? Reads project state, tells you the exact command.</span></div>
304
+ <div class="cmd"><span class="cmd-name">/qualia-idk</span><span class="cmd-desc">Same as /qualia. For when you're stuck.</span></div>
305
+ <div class="cmd"><span class="cmd-name">/qualia-resume</span><span class="cmd-desc">Pick up where you left off from a previous session.</span></div>
306
+ <div class="cmd"><span class="cmd-name">/qualia-pause</span><span class="cmd-desc">Save progress. Creates .continue-here.md for next session.</span></div>
307
+ </div>
308
+ </div>
309
+
310
+ <div class="cmd-group">
311
+ <h3>Project Setup</h3>
312
+ <div class="commands">
313
+ <div class="cmd"><span class="cmd-name">/qualia-new</span><span class="cmd-desc">Interactive wizard. Asks about client, scope, design, stack. Creates everything.</span></div>
314
+ </div>
315
+ </div>
316
+
317
+ <div class="cmd-group">
318
+ <h3>Build Loop</h3>
319
+ <div class="commands">
320
+ <div class="cmd"><span class="cmd-name">/qualia-plan</span><span class="cmd-desc">Plan the current phase. AI generates tasks with success criteria.</span></div>
321
+ <div class="cmd"><span class="cmd-name">/qualia-build</span><span class="cmd-desc">Build it. Fresh AI agent per task, parallel waves.</span></div>
322
+ <div class="cmd"><span class="cmd-name">/qualia-verify</span><span class="cmd-desc">Verify it actually works. Greps code, scores on 4 dimensions.</span></div>
323
+ </div>
324
+ </div>
325
+
326
+ <div class="cmd-group">
327
+ <h3>Quick Work</h3>
328
+ <div class="commands">
329
+ <div class="cmd"><span class="cmd-name">/qualia-quick</span><span class="cmd-desc">Skip planning. For bug fixes, tweaks, hot fixes under 1 hour.</span></div>
330
+ <div class="cmd"><span class="cmd-name">/qualia-task</span><span class="cmd-desc">One focused task. More structured than quick, lighter than build.</span></div>
331
+ </div>
332
+ </div>
333
+
334
+ <div class="cmd-group">
335
+ <h3>Design & Quality</h3>
336
+ <div class="commands">
337
+ <div class="cmd"><span class="cmd-name">/qualia-design</span><span class="cmd-desc">One-shot design fix. Reads DESIGN.md, kills AI slop, makes it professional.</span></div>
338
+ <div class="cmd"><span class="cmd-name">/qualia-polish</span><span class="cmd-desc">Full design pass. Typography, color, states, motion, a11y, responsive, hardening.</span></div>
339
+ <div class="cmd"><span class="cmd-name">/qualia-review</span><span class="cmd-desc">Production audit. Security, performance, reliability. Scored diagnostics.</span></div>
340
+ </div>
341
+ </div>
342
+
343
+ <div class="cmd-group">
344
+ <h3>Ship & Deliver</h3>
345
+ <div class="commands">
346
+ <div class="cmd"><span class="cmd-name">/qualia-ship</span><span class="cmd-desc">Quality gates, commit, push, deploy to Vercel, post-deploy verification.</span></div>
347
+ <div class="cmd"><span class="cmd-name">/qualia-handoff</span><span class="cmd-desc">Client delivery. Credentials, docs, handover package.</span></div>
348
+ <div class="cmd"><span class="cmd-name">/qualia-report</span><span class="cmd-desc">Log your session. Mandatory before clock-out. Uploads to ERP.</span></div>
349
+ </div>
350
+ </div>
351
+
352
+ <div class="cmd-group">
353
+ <h3>Debugging & Learning</h3>
354
+ <div class="commands">
355
+ <div class="cmd"><span class="cmd-name">/qualia-debug</span><span class="cmd-desc">Structured debugging. Symptom &rarr; diagnosis &rarr; root cause &rarr; fix.</span></div>
356
+ <div class="cmd"><span class="cmd-name">/qualia-learn</span><span class="cmd-desc">Save a pattern, fix, or client preference to the knowledge base.</span></div>
357
+ <div class="cmd"><span class="cmd-name">/qualia-test</span><span class="cmd-desc">Generate or run tests. Auto-detects framework.</span></div>
358
+ </div>
359
+ </div>
360
+
361
+ <div class="cmd-group">
362
+ <h3>CLI (Terminal)</h3>
363
+ <div class="commands">
364
+ <div class="cmd"><span class="cmd-name">qualia-framework install</span><span class="cmd-desc">Install or reinstall the framework.</span></div>
365
+ <div class="cmd"><span class="cmd-name">qualia-framework update</span><span class="cmd-desc">Update to the latest version.</span></div>
366
+ <div class="cmd"><span class="cmd-name">qualia-framework version</span><span class="cmd-desc">Show installed version + check for updates.</span></div>
367
+ <div class="cmd"><span class="cmd-name">qualia-framework migrate</span><span class="cmd-desc">Upgrade v2 settings to v3.</span></div>
368
+ <div class="cmd"><span class="cmd-name">qualia-framework analytics</span><span class="cmd-desc">Hook telemetry, verification pass rates, gap cycles.</span></div>
369
+ <div class="cmd"><span class="cmd-name">qualia-framework team</span><span class="cmd-desc">List, add, or remove team members.</span></div>
370
+ <div class="cmd"><span class="cmd-name">qualia-framework traces</span><span class="cmd-desc">View recent hook activity.</span></div>
371
+ </div>
372
+ </div>
373
+ </section>
374
+
375
+ <!-- Verification Scoring -->
376
+ <section>
377
+ <h2>Verification Scoring</h2>
378
+ <p style="color: var(--text-muted); margin-bottom: 1rem;">Every phase is scored on 4 dimensions. Any score below 3 = automatic FAIL.</p>
379
+ <div class="scoring">
380
+ <div class="score-dim">
381
+ <h4>Correctness</h4>
382
+ <p>Does it work as expected?</p>
383
+ <div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
384
+ </div>
385
+ <div class="score-dim">
386
+ <h4>Completeness</h4>
387
+ <p>Are all requirements met?</p>
388
+ <div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
389
+ </div>
390
+ <div class="score-dim">
391
+ <h4>Wiring</h4>
392
+ <p>Is everything connected end-to-end?</p>
393
+ <div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
394
+ </div>
395
+ <div class="score-dim">
396
+ <h4>Quality</h4>
397
+ <p>Code quality, security, a11y?</p>
398
+ <div class="score-bar"><span class="filled"></span><span class="filled"></span><span class="threshold"></span><span></span><span></span></div>
399
+ </div>
400
+ </div>
401
+ </section>
402
+
403
+ <!-- Rules -->
404
+ <section>
405
+ <h2>Rules</h2>
406
+ <ul class="rules">
407
+ <li><span class="rule-icon">1</span> Feature branches only &mdash; never push to main</li>
408
+ <li><span class="rule-icon">2</span> Read before write &mdash; understand files before editing</li>
409
+ <li><span class="rule-icon">3</span> MVP first &mdash; build what's asked, nothing extra</li>
410
+ <li><span class="rule-icon">4</span> /qualia-report before clock-out &mdash; mandatory, enforced by ERP</li>
411
+ <li><span class="rule-icon">5</span> No .env edits &mdash; ask Fawzi for secrets</li>
412
+ <li><span class="rule-icon">6</span> Stuck 30+ minutes? Ask Fawzi</li>
413
+ </ul>
414
+ </section>
415
+
416
+ <!-- Services -->
417
+ <section>
418
+ <h2>Our Stack</h2>
419
+ <div class="services">
420
+ <div class="service">
421
+ <div class="service-name">Supabase</div>
422
+ <div class="service-desc">Database, auth, storage. Every project. MCP + CLI available.</div>
423
+ <div class="service-key">Always enable RLS</div>
424
+ </div>
425
+ <div class="service">
426
+ <div class="service-name">Vercel</div>
427
+ <div class="service-desc">Hosting. 3 teams. No auto-deploy &mdash; CLI only via /qualia-ship.</div>
428
+ <div class="service-key">vercel --prod</div>
429
+ </div>
430
+ <div class="service">
431
+ <div class="service-name">Railway</div>
432
+ <div class="service-desc">Long-running agents, background jobs. MCP + CLI available.</div>
433
+ <div class="service-key">railway deploy</div>
434
+ </div>
435
+ <div class="service">
436
+ <div class="service-name">OpenRouter</div>
437
+ <div class="service-desc">AI model routing. One API key for all models.</div>
438
+ <div class="service-key">Ask Fawzi for a key</div>
439
+ </div>
440
+ <div class="service">
441
+ <div class="service-name">Retell AI</div>
442
+ <div class="service-desc">Voice agents. Primary voice platform.</div>
443
+ <div class="service-key">RETELL_API_KEY</div>
444
+ </div>
445
+ <div class="service">
446
+ <div class="service-name">ElevenLabs</div>
447
+ <div class="service-desc">Voice synthesis, cloning, streaming.</div>
448
+ <div class="service-key">ELEVENLABS_API_KEY</div>
449
+ </div>
450
+ </div>
451
+ </section>
452
+
453
+ <!-- GitHub -->
454
+ <section>
455
+ <h2>GitHub Organizations</h2>
456
+ <div class="services" style="grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));">
457
+ <div class="service">
458
+ <div class="service-name">QualiasolutionsCY</div>
459
+ <div class="service-desc">Primary org. All Qualia Solutions projects.</div>
460
+ </div>
461
+ <div class="service">
462
+ <div class="service-name">SakaniQualia</div>
463
+ <div class="service-desc">Sakani real estate platform.</div>
464
+ </div>
465
+ </div>
466
+ </section>
467
+
468
+ </div>
469
+
470
+ <div class="footer">
471
+ <strong>Welcome to the future with Qualia.</strong><br>
472
+ Qualia Solutions &mdash; Nicosia, Cyprus
473
+ </div>
474
+
475
+ </body>
476
+ </html>
package/templates/plan.md CHANGED
@@ -26,3 +26,17 @@ Goal: {what must be true when done}
26
26
  - [ ] {truth 1 — what the user can do}
27
27
  - [ ] {truth 2}
28
28
  - [ ] {truth 3}
29
+
30
+ ## Verification Contract
31
+
32
+ ### Contract for Task 1 — {title}
33
+ **Check type:** {file-exists | grep-match | command-exit | behavioral}
34
+ **Command:** `{exact command the verifier will run}`
35
+ **Expected:** {what the output should be}
36
+ **Fail if:** {what constitutes failure}
37
+
38
+ ### Contract for Task 2 — {title}
39
+ **Check type:** {file-exists | grep-match | command-exit | behavioral}
40
+ **Command:** `{exact command}`
41
+ **Expected:** {expected output}
42
+ **Fail if:** {failure condition}
package/tests/bin.test.sh CHANGED
@@ -139,7 +139,7 @@ cat > "$TMP/.claude/.qualia-config.json" <<'EOF'
139
139
  "code": "QS-FAWZI-01",
140
140
  "installed_by": "Fawzi Goussous",
141
141
  "role": "OWNER",
142
- "version": "3.1.0",
142
+ "version": "2.8.1",
143
143
  "installed_at": "2026-04-10"
144
144
  }
145
145
  EOF
@@ -423,7 +423,7 @@ cat > "$TMP/.claude/.qualia-config.json" <<'EOF'
423
423
  "code": "QS-FAWZI-01",
424
424
  "installed_by": "Fawzi Goussous",
425
425
  "role": "OWNER",
426
- "version": "3.1.0",
426
+ "version": "2.8.1",
427
427
  "installed_at": "2026-04-10"
428
428
  }
429
429
  EOF
@@ -476,10 +476,10 @@ else
476
476
  fail_case "CLAUDE.md role substitution"
477
477
  fi
478
478
 
479
- # 31. All 7 hooks installed (block-env-edit.js retired in v3.2.0)
479
+ # 31. All 8 hooks installed
480
480
  HOOK_COUNT=$(ls "$TMP/.claude/hooks/"*.js 2>/dev/null | wc -l)
481
- if [ "$HOOK_COUNT" -eq 7 ]; then
482
- pass "7 hooks installed in hooks/"
481
+ if [ "$HOOK_COUNT" -eq 8 ]; then
482
+ pass "8 hooks installed in hooks/"
483
483
  else
484
484
  fail_case "hook count" "got $HOOK_COUNT"
485
485
  fi
@@ -494,7 +494,21 @@ else
494
494
  fail_case "settings.json contents"
495
495
  fi
496
496
 
497
- # 33. Lowercase code works (resolveTeamCode normalizes)
497
+ # 33. settings.json contains all 8 hooks wired correctly
498
+ if grep -q 'block-env-edit.js' "$TMP/.claude/settings.json" \
499
+ && grep -q 'branch-guard.js' "$TMP/.claude/settings.json" \
500
+ && grep -q 'migration-guard.js' "$TMP/.claude/settings.json" \
501
+ && grep -q 'pre-push.js' "$TMP/.claude/settings.json" \
502
+ && grep -q 'pre-deploy-gate.js' "$TMP/.claude/settings.json" \
503
+ && grep -q 'auto-update.js' "$TMP/.claude/settings.json" \
504
+ && grep -q 'session-start.js' "$TMP/.claude/settings.json" \
505
+ && grep -q 'pre-compact.js' "$TMP/.claude/settings.json"; then
506
+ pass "settings.json has all 8 hooks wired"
507
+ else
508
+ fail_case "settings.json missing hooks"
509
+ fi
510
+
511
+ # 34. Lowercase code works (resolveTeamCode normalizes)
498
512
  TMP=$(mktmp)
499
513
  echo "qs-fawzi-01" | HOME="$TMP" $NODE "$INSTALL_JS" > "$TMP/out.log" 2>&1
500
514
  EXIT=$?