qualia-framework 3.1.0 → 3.2.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.
@@ -1,24 +1,11 @@
1
1
  ---
2
2
  name: qualia-polish
3
- description: "Design and UX pass — anti-AI-slop, genuine craft, responsive, accessible. Run after all phases are verified."
3
+ description: "Design and UX pass — critique, polish, harden. Run after all phases are verified."
4
4
  ---
5
5
 
6
6
  # /qualia-polish — Design Pass
7
7
 
8
- Makes it look like a human designer built it. Kills AI slop. Run after all feature phases are verified.
9
-
10
- ## The Standard
11
-
12
- Every site Qualia ships must feel **designed, not generated.** AI-generated sites have tells:
13
- - Identical card grids with rounded corners and soft shadows
14
- - Blue-purple gradients on everything
15
- - Inter/system-ui font with no hierarchy
16
- - Generic hero with centered text and a stock gradient background
17
- - Fixed-width containers leaving dead space on wide screens
18
- - No motion, no personality, no opinion
19
- - Perfect symmetry everywhere (real design has tension)
20
-
21
- **Kill all of these.** A Qualia site should make someone ask "who designed this?" — not "which template is this?"
8
+ Run after all feature phases are verified. Makes it look production-ready.
22
9
 
23
10
  ## Process
24
11
 
@@ -32,176 +19,139 @@ node ~/.claude/bin/qualia-ui.js banner polish
32
19
  cat .planning/DESIGN.md 2>/dev/null || echo "NO_DESIGN"
33
20
  ```
34
21
 
35
- If DESIGN.md exists → it's the standard. Read ALL 12 sections. Key sections for polish:
36
- - §1 Visual Theme — the feel and signature details
37
- - §2 Color Palette — exact hex values, CSS variables, contrast ratios
38
- - §3 Typography — hierarchy table with exact sizes/weights/spacing
39
- - §4 Components — exact button/card/input/badge specs
40
- - §5 Layout — spacing scale, grid strategy
41
- - §6 Depth & Elevation — shadow levels with exact rgba values
42
- - §7 Do's/Don'ts — brand-specific guardrails
43
- - §9 Agent Prompt Guide — quick reference for common patterns
44
- - §10 Accessibility — WCAG checklist
45
- - §11 Hardening — stress-test criteria
46
- - §12 Anti-Slop Detection — grep patterns for automated checks
47
-
48
- If no DESIGN.md → use `rules/frontend.md` defaults.
22
+ If DESIGN.md exists → use it as the standard. If not use Qualia defaults from `rules/frontend.md`.
49
23
 
50
24
  Read EVERY frontend file before modifying. No blind edits.
51
25
 
52
- ### 1. AI Slop Detector
53
-
54
- Run these checks first. Any hits = mandatory fixes.
55
-
56
- ```bash
57
- # Generic fonts (the #1 AI tell)
58
- grep -rn "Inter\|Roboto\|Arial\|Helvetica\|system-ui\|Space.Grotesk" --include="*.tsx" --include="*.css" --include="*.scss" --include="tailwind*" app/ components/ src/ 2>/dev/null | grep -v node_modules
59
-
60
- # Hardcoded max-width containers (screams template)
61
- grep -rn "max-w-7xl\|max-w-\[1200\|max-w-\[1280\|max-width.*1200\|max-width.*1280" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null
62
-
63
- # Blue-purple gradients
64
- grep -rn "from-blue.*to-purple\|from-purple.*to-blue\|linear-gradient.*blue.*purple\|linear-gradient.*purple.*blue\|from-indigo.*to-violet" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null
65
-
66
- # Card grid monotony (same card component repeated in a grid)
67
- grep -rn "grid-cols-3\|grid-cols-4" --include="*.tsx" app/ components/ src/ 2>/dev/null | head -5
68
-
69
- # Generic hero patterns
70
- grep -rn "text-center.*mx-auto\|Hero\|hero" --include="*.tsx" app/ components/ src/ 2>/dev/null | head -5
71
-
72
- # Scattered hardcoded colors (no design system)
73
- grep -rn "text-\[#\|bg-\[#\|border-\[#\|color:.*#\|background:.*#" --include="*.tsx" app/ components/ src/ 2>/dev/null | wc -l
74
- ```
75
-
76
- **Every hit gets fixed.** Not flagged fixed.
77
-
78
- ### 2. Typography Pass
79
-
80
- **Goal:** A reader should feel the type was chosen, not defaulted.
81
-
82
- - Pick a distinctive display font. Not Inter, not Roboto, not system. Something with character: Clash Display, Cabinet Grotesk, General Sans, Satoshi, Plus Jakarta Sans, Outfit, Sora, Manrope. Pair with a clean body font.
83
- - Establish clear hierarchy: display (hero text) h1 h2 → h3 → body → caption
84
- - Body: 16px minimum, line-height 1.5-1.7
85
- - Headings: tighter line-height (1.1-1.3), negative letter-spacing (-0.02em) for display sizes
86
- - Weight hierarchy: Regular (400) for body, Medium (500) for labels, Semibold (600) for headings, Bold (700) for display
87
- - Prose content: `max-width: 65ch`. Everything else: fluid full-width.
88
- - Use `clamp()` for fluid sizing: `clamp(2rem, 1rem + 3vw, 3.75rem)` for h1
89
-
90
- ### 3. Color & Surfaces
91
-
92
- **Goal:** A palette that looks intentional, not random.
93
-
94
- - Define all colors as CSS variables or Tailwind config — zero scattered hex values
95
- - One dominant brand color. One sharp accent for CTAs that pops against the page.
96
- - Surfaces: layer them. Background card → elevated card. Use subtle shade differences, not just white-on-white.
97
- - Dark mode (if present): rethink surfaces, don't just invert. Slightly reduce contrast. Use darker brand colors, not just white→black swap.
98
- - Semantic colors with non-color indicators: success (green + checkmark), error (red + icon), warning (amber + triangle)
99
- - Verify WCAG AA: 4.5:1 for normal text, 3:1 for large text (18px+ bold or 24px+)
100
-
101
- ### 4. Layout & Spacing
102
-
103
- **Goal:** Full-width, fluid, generous. No dead space gutters.
104
-
105
- - Full-width layouts with fluid padding: `clamp(1rem, 5vw, 4rem)` horizontal
106
- - 8px spacing grid: 4, 8, 12, 16, 24, 32, 48, 64, 96
107
- - Tight spacing within groups (related items). Generous spacing between sections.
108
- - Break symmetry where it serves the design — offset grids, overlapping elements, diagonal flow
109
- - Varied layouts: not every section should be a centered-text-with-cards-below. Use side-by-side, staggered, asymmetric, full-bleed.
110
- - Section spacing: `clamp(2rem, 8vw, 6rem)` vertical padding
111
-
112
- ### 5. Interactive States
113
-
114
- **Goal:** Every clickable thing responds. Every async operation shows progress.
115
-
116
- - **Hover:** color shift or underline within 150ms ease-out. `cursor: pointer` on ALL clickables.
117
- - **Focus:** visible ring (2px+ offset, contrasting color). Never `outline: none` without replacement.
118
- - **Active/pressed:** subtle scale down (`transform: scale(0.98)`) or color shift.
119
- - **Disabled:** opacity 0.5 + `cursor: not-allowed` + `aria-disabled="true"`
120
- - **Loading:** skeleton shimmer or spinner on every async operation. Never a blank void.
121
- - **Empty:** helpful message + CTA on empty lists/tables. Not just "No results."
122
- - **Error:** user-friendly message + recovery action. Not raw error text. Use `aria-live="assertive"`.
123
-
124
- ### 6. Motion & Personality
125
-
126
- **Goal:** The site feels alive, not static. But tasteful not a circus.
127
-
128
- - Page load: stagger children entrance (50-80ms delay between items, `fadeUp` animation, 300ms)
129
- - Hover transitions: 150-200ms ease-out
130
- - Section transitions: 300-500ms with `cubic-bezier(0.4, 0, 0.2, 1)`
131
- - One signature motion that gives the site personality (parallax, scroll-triggered reveal, magnetic buttons, morphing shapes)
132
- - **Always** `prefers-reduced-motion: reduce` disable non-essential animation
133
- - CSS-only for static sites, `motion/react` (formerly Framer Motion) for React
134
-
135
- ### 7. Accessibility (Non-Negotiable)
136
-
137
- - Semantic HTML: `nav`, `main`, `section`, `article`, `header`, `footer` — not div soup
138
- - One `h1` per page, sequential heading order (no h1 → h3 skip)
139
- - All images: descriptive `alt` (or `alt=""` + `aria-hidden` if decorative)
140
- - All form inputs: visible `<label>` with `htmlFor` — not placeholder-only
141
- - All interactive elements: keyboard accessible (Tab, Enter, Escape, Arrow keys)
142
- - Touch targets: 44x44px minimum
143
- - Skip link: `<a href="#main" class="sr-only focus:not-sr-only">` as first focusable element
144
- - `<html lang="en">` set
145
- - Color never the sole information carrier — icons, text, patterns as supplements
146
- - `aria-live="polite"` for toast notifications and dynamic content updates
147
-
148
- ### 8. Responsive (Mobile-First)
149
-
150
- - Base styles for mobile (320px), scale up with `min-width` breakpoints
151
- - Test at: 320px (small phone), 375px (iPhone), 768px (iPad), 1024px (laptop), 1440px (desktop)
152
- - No horizontal scroll at any viewport
153
- - Navigation: hamburger/drawer on mobile, full horizontal on desktop
154
- - Stack on mobile, expand on desktop
155
- - Fluid typography with `clamp()`
156
- - Images: `max-width: 100%`, responsive `srcset`, `next/image` with width/height
157
- - Tables: card layout or horizontal scroll on mobile
158
-
159
- ### 9. Harden (Edge Cases)
160
-
161
- After all visual work, stress-test:
162
- - Long text: does a 200-character username break the layout?
163
- - Empty everywhere: all lists empty, all data missing — does it still make sense?
164
- - Error everywhere: every fetch fails — are error states visible and helpful?
165
- - 320px viewport: nothing overflows, nothing clips, nothing overlaps
166
- - Keyboard only: Tab through the entire app — can you reach everything? Is focus visible?
167
- - Slow network: are loading states visible? Does content stream in or flash?
168
-
169
- ### 10. Verify & Ship
26
+ ### 1. Critique (Structured Audit)
27
+
28
+ Review the entire UI against this checklist. Check each item, note violations with file:line.
29
+
30
+ **Typography:**
31
+ - [ ] No generic fonts (Inter, Roboto, Arial, system-ui, Space Grotesk)
32
+ - [ ] Proper type scale with clear hierarchy (display heading body → caption)
33
+ - [ ] Body text: 16px+, line-height 1.5–1.7
34
+ - [ ] Headings: tighter line-height (1.1–1.3), negative letter-spacing for large sizes
35
+ - [ ] Prose max-width: 65ch
36
+ - [ ] Font weights used for hierarchy (Regular, Medium, Semibold, Bold)
37
+
38
+ **Color & Contrast:**
39
+ - [ ] Cohesive palette via CSS variables (not scattered hex values)
40
+ - [ ] All text passes WCAG AA contrast (4.5:1 normal, 3:1 large)
41
+ - [ ] CTA buttons use accent color stand out from the page
42
+ - [ ] No blue-purple gradients, no rainbow palettes
43
+ - [ ] Dark mode: rethought surfaces (not just inverted)
44
+ - [ ] Semantic colors used consistently (success=green, error=red, warning=amber)
45
+
46
+ **Layout & Spacing:**
47
+ - [ ] Full-width fluid layouts no hardcoded max-width caps
48
+ - [ ] 8px spacing grid followed consistently
49
+ - [ ] Tight spacing within groups, generous between sections
50
+ - [ ] Fluid padding: `clamp(1rem, 5vw, 4rem)` horizontal
51
+ - [ ] No identical card grids — varied visual hierarchy
52
+ - [ ] No generic heroes — purposeful, distinctive
53
+
54
+ **Interactive States:**
55
+ - [ ] Every button/link: hover (color shift, 150ms), focus (visible ring), active (press feedback), disabled
56
+ - [ ] Loading: skeleton or spinner on all async operations
57
+ - [ ] Empty: helpful message + action on empty lists/data
58
+ - [ ] Error: user-friendly message + recovery action on failed fetches
59
+ - [ ] Form validation: inline errors with `aria-describedby`
60
+
61
+ **Motion:**
62
+ - [ ] Hover/focus: 150–200ms transitions
63
+ - [ ] Page load: staggered entrance animations (50–80ms delay)
64
+ - [ ] Expand/collapse: 250ms ease-in-out
65
+ - [ ] `prefers-reduced-motion` respected (no animation for users who opt out)
66
+ - [ ] No jank: transforms and opacity only for animated properties
67
+
68
+ **Accessibility:**
69
+ - [ ] Semantic HTML: `nav`, `main`, `section`, `article`, `header`, `footer`
70
+ - [ ] One `h1` per page, sequential heading hierarchy
71
+ - [ ] All images: descriptive `alt` (or `alt=""` + `aria-hidden` if decorative)
72
+ - [ ] All form inputs: visible `<label>` with `htmlFor` not placeholder-only
73
+ - [ ] All interactive elements: keyboard accessible (Tab/Enter/Escape)
74
+ - [ ] Touch targets: 44px minimum
75
+ - [ ] Skip link: `<a href="#main">` as first focusable element
76
+ - [ ] No `outline: none` without focus replacement
77
+ - [ ] `<html lang="en">` set
78
+ - [ ] Color not sole information carrier — icons/text as supplements
79
+
80
+ **Responsive:**
81
+ - [ ] Mobile-first approach (base styles for mobile, min-width breakpoints for larger)
82
+ - [ ] No horizontal scroll at 320px
83
+ - [ ] Navigation: hamburger on mobile, expanded on desktop
84
+ - [ ] Touch targets adequate on mobile (44px min)
85
+ - [ ] Fluid typography with `clamp()`
86
+ - [ ] Images: `max-width: 100%`, responsive srcset where needed
87
+ - [ ] Tables: card view or horizontal scroll on mobile
88
+
89
+ **Performance:**
90
+ - [ ] Server Components by default `'use client'` only when needed
91
+ - [ ] Images via `next/image` with width/height
92
+ - [ ] No barrel file imports direct imports from source
93
+ - [ ] Heavy components lazy-loaded with `next/dynamic`
94
+ - [ ] Data fetched in parallel, not sequentially
95
+
96
+ ### 2. Fix Everything
97
+
98
+ Work through violations from the critique. Fix each category:
99
+
100
+ 1. Typography first (sets the visual foundation)
101
+ 2. Color & contrast (palette coherence)
102
+ 3. Layout & spacing (structural fixes)
103
+ 4. Interactive states (loading, empty, error, hover, focus)
104
+ 5. Motion (transitions, entrance animations, reduced-motion)
105
+ 6. Accessibility (semantic HTML, ARIA, keyboard, labels)
106
+ 7. Responsive (mobile breakpoints, fluid sizing)
107
+ 8. Performance (quick wins image optimization, dynamic imports)
108
+
109
+ ### 3. Harden
110
+
111
+ After polish, stress-test edge cases:
112
+ - Long text content (overflow, truncation, word-break)
113
+ - Extremely long usernames or email addresses
114
+ - Empty data everywhere simultaneously
115
+ - Error state on every fetch simultaneously
116
+ - 320px viewport width
117
+ - Keyboard-only navigation through entire flow
118
+ - Screen reader landmarks check (semantic HTML)
119
+ - Right-to-left text (if i18n is planned)
120
+ - Slow network (loading states visible, no flash of empty content)
121
+
122
+ ### 4. Verify
170
123
 
171
124
  ```bash
172
125
  npx tsc --noEmit 2>&1 | head -20
173
126
  ```
174
127
 
175
- Fix any TypeScript errors.
128
+ Fix any TypeScript errors before committing.
129
+
130
+ ### 5. Commit & Transition
176
131
 
177
132
  ```bash
178
133
  git add {changed files}
179
- git commit -m "polish: design pass — typography, color, states, motion, responsive, a11y"
134
+ git commit -m "polish: design and UX pass — typography, accessibility, responsive, states"
180
135
  ```
181
136
 
182
137
  ```bash
183
138
  node ~/.claude/bin/state.js transition --to polished
184
139
  ```
140
+ Do NOT manually edit STATE.md or tracking.json — state.js handles both.
141
+
142
+ ### 6. Report
185
143
 
186
144
  ```bash
187
145
  node ~/.claude/bin/qualia-ui.js divider
188
- node ~/.claude/bin/qualia-ui.js ok "AI slop: killed"
189
- node ~/.claude/bin/qualia-ui.js ok "Typography: {brief}"
190
- node ~/.claude/bin/qualia-ui.js ok "Color: {brief}"
191
- node ~/.claude/bin/qualia-ui.js ok "Layout: {brief}"
192
- node ~/.claude/bin/qualia-ui.js ok "States: {brief}"
193
- node ~/.claude/bin/qualia-ui.js ok "Motion: {brief}"
194
- node ~/.claude/bin/qualia-ui.js ok "Accessibility: {brief}"
195
- node ~/.claude/bin/qualia-ui.js ok "Responsive: {brief}"
196
- node ~/.claude/bin/qualia-ui.js ok "Hardened: {brief}"
146
+ node ~/.claude/bin/qualia-ui.js info "Files modified: {N}"
147
+ node ~/.claude/bin/qualia-ui.js ok "Typography {brief}"
148
+ node ~/.claude/bin/qualia-ui.js ok "Color {brief}"
149
+ node ~/.claude/bin/qualia-ui.js ok "Layout {brief}"
150
+ node ~/.claude/bin/qualia-ui.js ok "States {brief}"
151
+ node ~/.claude/bin/qualia-ui.js ok "Motion {brief}"
152
+ node ~/.claude/bin/qualia-ui.js ok "Accessibility {brief}"
153
+ node ~/.claude/bin/qualia-ui.js ok "Responsive {brief}"
154
+ node ~/.claude/bin/qualia-ui.js ok "Performance {brief}"
155
+ node ~/.claude/bin/qualia-ui.js ok "Hardening — {brief}"
197
156
  node ~/.claude/bin/qualia-ui.js end "POLISHED" "/qualia-ship"
198
157
  ```
199
-
200
- ## Rules
201
-
202
- 1. **Read before write.** Understand every file before changing it.
203
- 2. **DESIGN.md is law.** If it exists, follow it. Don't override client decisions.
204
- 3. **Don't break functionality.** Only change styling, never logic.
205
- 4. **AI slop is a bug.** Generic fonts, card grids, blue-purple gradients, centered-everything — treat these as defects, not preferences.
206
- 5. **TypeScript must pass** after every change.
207
- 6. **One commit** at the end — not per category.
@@ -73,35 +73,26 @@ git commit -m "report: session {YYYY-MM-DD}"
73
73
  git push
74
74
  ```
75
75
 
76
- ### 5. Upload to ERP (if enabled)
76
+ ### 5. Upload to ERP
77
77
 
78
- Read `~/.claude/.qualia-config.json` and check the `erp` object:
79
- - If `erp.enabled` is `false`, skip this step and print: "ERP upload skipped (disabled in config)."
80
- - If `erp.enabled` is `true` (default) or the `erp` field is missing (backward compatibility), proceed with the upload.
78
+ **This step is MANDATORY** — the clock-out modal requires the report to be uploaded.
81
79
 
82
80
  ```bash
83
- # Read ERP config
84
- ERP_URL=$(node -e "try{const c=JSON.parse(require('fs').readFileSync(require('os').homedir()+'/.claude/.qualia-config.json','utf8'));console.log(c.erp?.url||'https://portal.qualiasolutions.net')}catch{console.log('https://portal.qualiasolutions.net')}")
85
- ERP_ENABLED=$(node -e "try{const c=JSON.parse(require('fs').readFileSync(require('os').homedir()+'/.claude/.qualia-config.json','utf8'));console.log(c.erp?.enabled!==false)}catch{console.log('true')}")
86
-
81
+ ERP_URL="https://portal.qualiasolutions.net"
87
82
  API_KEY=$(cat ~/.claude/.erp-api-key 2>/dev/null)
88
83
  REPORT_FILE=".planning/reports/report-{date}.md"
89
84
  EMAIL=$(git config user.email)
90
85
  PROJECT=$(basename $(pwd))
91
86
 
92
- # Only upload if ERP is enabled
93
- if [ "$ERP_ENABLED" = "true" ]; then
94
- curl -s -X POST "$ERP_URL/api/claude/report-upload" \
95
- -H "X-API-Key: $API_KEY" \
96
- -F "file=@$REPORT_FILE" \
97
- -F "employee_email=$EMAIL" \
98
- -F "project_name=$PROJECT"
99
- fi
87
+ curl -s -X POST "$ERP_URL/api/claude/report-upload" \
88
+ -H "X-API-Key: $API_KEY" \
89
+ -F "file=@$REPORT_FILE" \
90
+ -F "employee_email=$EMAIL" \
91
+ -F "project_name=$PROJECT"
100
92
  ```
101
93
 
102
94
  If the upload succeeds, print: "Report uploaded to ERP. You can now clock out."
103
95
  If it fails (no API key, network error), print the error and tell the employee to ask Fawzi.
104
- If ERP is disabled, print: "ERP upload skipped (disabled in config)."
105
96
 
106
97
  ### 6. Update State
107
98
 
@@ -1,161 +1,76 @@
1
1
  ---
2
2
  name: qualia-review
3
- description: "Production audit with scored diagnostics. Runs real commands, scores findings by severity. Trigger on 'review', 'audit', 'code review', 'security check', 'production check'."
3
+ description: "Production audit and code review. General review, --web for web app audit, --ai for AI/voice agent audit. Trigger on 'review', 'audit', 'code review', 'security check', 'production check'."
4
4
  ---
5
5
 
6
6
  # /qualia-review — Production Audit
7
7
 
8
- Runs real diagnostic commands and scores every finding. Not a checklist an executable audit.
8
+ Deep review with severity-scored findings. Different from `/qualia-verify` (which checks phase goals). This checks production readiness.
9
9
 
10
10
  ## Usage
11
11
 
12
- - `/qualia-review` — Full audit (security + quality + performance)
13
- - `/qualia-review --web` — Adds web-specific checks (headers, CORS, vitals)
14
- - `/qualia-review --ai` — Adds AI/voice agent checks (prompt safety, latency)
12
+ - `/qualia-review` — General code review
13
+ - `/qualia-review --web` — Web app production audit
14
+ - `/qualia-review --ai` — AI/voice agent audit
15
15
 
16
- ## Process
16
+ ## General Review (default)
17
17
 
18
18
  ```bash
19
19
  node ~/.claude/bin/qualia-ui.js banner review
20
20
  ```
21
21
 
22
- ### 0. Load Context
22
+ Spawn parallel agents analyzing:
23
23
 
24
- ```bash
25
- cat ~/.claude/knowledge/common-fixes.md 2>/dev/null
26
- cat ~/.claude/knowledge/learned-patterns.md 2>/dev/null
27
- ```
24
+ 1. **Code Quality** — Clean code, TypeScript strictness, naming, readability
25
+ 2. **Security** — OWASP top 10, auth server-side, RLS policies, secrets scan
26
+ 3. **Architecture** — Component boundaries, coupling, API contracts
27
+ 4. **Performance** — N+1 queries, bundle size, caching, render performance
28
+ 5. **Test Coverage** — Gaps, edge cases, test quality
28
29
 
29
- Detect project shape:
30
- ```bash
31
- ls package.json next.config.* tsconfig.json supabase/ app/ src/ 2>/dev/null
32
- ```
30
+ ## --web (Web App Audit)
33
31
 
34
- ### 1. Security Scan
32
+ Full production readiness for Next.js + Supabase + Vercel:
35
33
 
36
- Run every command. Record each finding with severity.
34
+ **Security:** No secrets in code, HTTPS, CORS restricted, CSP headers, rate limiting, npm audit clean.
37
35
 
38
- ```bash
39
- # CRITICAL: service_role in client code
40
- grep -rn "service_role" --include="*.ts" --include="*.tsx" --include="*.js" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | grep -v "\.server\.\|[\\/]server[\\/]\|[\\/]app[\\/]api[\\/]\|route\.\|middleware\."
36
+ **Performance:** Core Web Vitals (LCP < 2.5s, CLS < 0.1), image optimization, bundle analysis, query performance.
41
37
 
42
- # CRITICAL: hardcoded secrets
43
- grep -rn "sk_live\|sk_test\|SUPABASE_SERVICE_ROLE\|eyJhbGciOi" --include="*.ts" --include="*.tsx" --include="*.js" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | grep -v "\.env"
38
+ **Reliability:** Error boundaries, API error handling, graceful degradation, health check endpoint.
44
39
 
45
- # CRITICAL: dangerous patterns
46
- grep -rn "dangerouslySetInnerHTML\|eval(" --include="*.ts" --include="*.tsx" --include="*.js" app/ components/ src/ 2>/dev/null | grep -v node_modules
40
+ **Observability:** Error tracking (Sentry), structured logging, uptime monitoring, analytics.
47
41
 
48
- # CRITICAL: .env files tracked in git
49
- git ls-files | grep -i "\.env" | grep -v "\.example\|\.template\|\.sample"
42
+ ## --ai (AI/Voice Agent Audit)
50
43
 
51
- # HIGH: API routes without auth
52
- for f in $(find app/api -name "route.ts" -o -name "route.js" 2>/dev/null); do
53
- grep -qL "getUser\|getSession\|auth()\|createClient" "$f" && echo "UNPROTECTED: $f"
54
- done
44
+ Auto-detect stack (VAPI, ElevenLabs, Retell, OpenAI, Anthropic, pgvector).
55
45
 
56
- # HIGH: API routes without input validation
57
- for f in $(find app/api -name "route.ts" -o -name "route.js" 2>/dev/null); do
58
- grep -L "z\.\|zod\|Zod\|parse\|safeParse" "$f" 2>/dev/null
59
- done
46
+ **Prompt Safety:** System prompts not exposed, injection defenses, no eval() on AI output, token limits.
60
47
 
61
- # HIGH: client-side database mutations
62
- grep -rn "\.insert\|\.update\|\.delete\|\.upsert" --include="*.tsx" --include="*.jsx" app/ components/ 2>/dev/null | grep -v "use server" | grep -v "\.server\."
48
+ **Conversation Flow:** Off-topic handling, context window management, error recovery, human handoff.
63
49
 
64
- # MEDIUM: npm vulnerabilities
65
- npm audit --json 2>/dev/null | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));const v=d.metadata?.vulnerabilities||{};console.log('critical:',v.critical||0,'high:',v.high||0,'moderate:',v.moderate||0)}catch{console.log('audit unavailable')}"
66
- ```
50
+ **Voice (if detected):** Latency < 500ms, interruption handling, silence timeout, webhook security.
67
51
 
68
- ### 2. Code Quality Scan
52
+ **RAG (if detected):** Embedding consistency, chunk size, retrieval relevance, index refresh.
69
53
 
70
- ```bash
71
- # TypeScript errors (HIGH if >0)
72
- npx tsc --noEmit 2>&1 | grep -c "error TS"
54
+ **Resilience:** Provider failover, timeout handling, cost monitoring, streaming error recovery.
73
55
 
74
- # 'any' type usage (MEDIUM — count)
75
- grep -rn ": any\| as any" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | wc -l
56
+ ## Output
76
57
 
77
- # Empty catch blocks (HIGH)
78
- grep -rn "catch\s*{}\|catch\s*(.*)\s*{\s*}" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | head -10
58
+ Every finding:
59
+ - **What** description
60
+ - **Where** — `file:line`
61
+ - **Fix** — concrete suggestion
62
+ - **Severity** — CRITICAL / HIGH / MEDIUM / LOW
79
63
 
80
- # TODO/FIXME left in code (LOWcount)
81
- grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.ts" --include="*.tsx" app/ components/ src/ lib/ 2>/dev/null | grep -v node_modules | wc -l
64
+ Write to `.planning/REVIEW.md`. CRITICAL or HIGH findings are deploy blockers `/qualia-ship` checks for them.
82
65
 
83
- # console.log in production code (LOW — count)
84
- grep -rn "console\.log" --include="*.ts" --include="*.tsx" app/ components/ src/ 2>/dev/null | grep -v node_modules | wc -l
85
66
  ```
86
-
87
- ### 3. Performance Scan
88
-
89
- ```bash
90
- # Build output — route sizes and first load JS
91
- npx next build 2>&1 | grep -E "Route|First Load|shared by all|○|●|ƒ|λ" | tail -25
92
-
93
- # Heavy files (>300 lines often means split needed)
94
- find app/ components/ src/ -name "*.tsx" -o -name "*.ts" 2>/dev/null | xargs wc -l 2>/dev/null | sort -rn | head -10
95
-
96
- # Missing next/image (MEDIUM)
97
- grep -rn "<img " --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | grep -v "next/image" | wc -l
98
-
99
- # Client component ratio
100
- echo "use client: $(grep -rl "'use client'" --include="*.tsx" app/ components/ src/ 2>/dev/null | wc -l)"
101
- echo "total tsx: $(find app/ components/ src/ -name '*.tsx' 2>/dev/null | wc -l)"
102
-
103
- # Sequential data fetching (HIGH)
104
- grep -rn "const.*=.*await" --include="*.tsx" --include="*.ts" app/ src/ 2>/dev/null | grep -v "Promise.all\|Promise.allSettled" | head -10
67
+ ⬢ Review Complete
68
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
69
+ Critical: {N}
70
+ High: {N}
71
+ Medium: {N}
72
+ Low: {N}
73
+
74
+ {If blockers: Fix CRITICAL/HIGH before /qualia-ship}
75
+ {If clean: Ready to ship}
105
76
  ```
106
-
107
- ### 4. Score and Report
108
-
109
- Write to `.planning/REVIEW.md`:
110
-
111
- ```markdown
112
- # Production Review — {YYYY-MM-DD}
113
-
114
- ## Summary
115
- | Category | Critical | High | Medium | Low | Score |
116
- |----------|----------|------|--------|-----|-------|
117
- | Security | {n} | {n} | {n} | {n} | {1-5} |
118
- | Quality | {n} | {n} | {n} | {n} | {1-5} |
119
- | Perf | {n} | {n} | {n} | {n} | {1-5} |
120
- | **Total** | {n} | {n} | {n} | {n} | **{avg}/5** |
121
-
122
- ## Findings
123
-
124
- ### CRITICAL
125
- - **{title}** — `{file}:{line}` — {what's wrong} — Fix: {how}
126
-
127
- ### HIGH
128
- - ...
129
-
130
- ### MEDIUM
131
- - ...
132
-
133
- ### LOW
134
- - ...
135
-
136
- ## Verdict
137
- {PASS: no critical/high | FAIL: N blockers — fix before /qualia-ship}
138
- ```
139
-
140
- **Scoring:**
141
- - 5 = zero high/critical, fewer than 3 medium
142
- - 4 = zero critical, 1 high or fewer than 5 medium
143
- - 3 = zero critical, 2-3 high
144
- - 2 = 1 critical or 4+ high
145
- - 1 = multiple critical
146
-
147
- ```bash
148
- node ~/.claude/bin/qualia-ui.js divider
149
- node ~/.claude/bin/qualia-ui.js info "Security: {score}/5 ({n} findings)"
150
- node ~/.claude/bin/qualia-ui.js info "Quality: {score}/5 ({n} findings)"
151
- node ~/.claude/bin/qualia-ui.js info "Perf: {score}/5 ({n} findings)"
152
- node ~/.claude/bin/qualia-ui.js end "REVIEW: {PASS|FAIL}" "{next command}"
153
- ```
154
-
155
- ## Rules
156
-
157
- 1. **Run every command.** Don't skip scans because "the code looks clean."
158
- 2. **Every finding gets a severity.** No prose — CRITICAL/HIGH/MEDIUM/LOW.
159
- 3. **Every finding gets a fix suggestion.** Not just "this is bad" — say what to do.
160
- 4. **Review detects. It does NOT fix.** This is an audit, not a refactor. Tell the user what to fix.
161
- 5. **CRITICAL or HIGH = deploy blocker.** `/qualia-ship` checks for these.
@@ -33,7 +33,7 @@ node ~/.claude/bin/qualia-ui.js spawn verifier "Goal-backward check..."
33
33
  Agent(prompt="
34
34
  Read your role: @agents/verifier.md
35
35
 
36
- Phase plan with success criteria AND verification contracts:
36
+ Phase plan with success criteria:
37
37
  @.planning/phase-{N}-plan.md
38
38
 
39
39
  {If re-verification: Previous verification with gaps:}