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.
- package/CLAUDE.md +4 -3
- package/README.md +5 -10
- package/agents/planner.md +0 -52
- package/agents/verifier.md +32 -180
- package/bin/cli.js +9 -403
- package/bin/install.js +61 -113
- package/bin/qualia-ui.js +15 -0
- package/bin/state.js +6 -200
- package/bin/statusline.js +4 -4
- package/hooks/auto-update.js +30 -8
- package/hooks/branch-guard.js +2 -23
- package/hooks/migration-guard.js +0 -23
- package/hooks/pre-compact.js +0 -20
- package/hooks/pre-deploy-gate.js +0 -39
- package/hooks/pre-push.js +0 -20
- package/hooks/session-start.js +44 -0
- package/package.json +4 -5
- package/skills/qualia/SKILL.md +0 -1
- package/skills/qualia-build/SKILL.md +0 -18
- package/skills/qualia-design/SKILL.md +8 -14
- package/skills/qualia-learn/SKILL.md +4 -27
- package/skills/qualia-optimize/SKILL.md +417 -0
- package/skills/qualia-polish/SKILL.md +117 -167
- package/skills/qualia-report/SKILL.md +8 -17
- package/skills/qualia-review/SKILL.md +41 -126
- package/skills/qualia-verify/SKILL.md +1 -1
- package/templates/DESIGN.md +102 -440
- package/templates/plan.md +0 -14
- package/tests/bin.test.sh +6 -20
- package/tests/hooks.test.sh +7 -76
- package/tests/state.test.sh +11 -189
- package/docs/erp-contract.md +0 -161
- package/hooks/block-env-edit.js +0 -52
- package/rules/infrastructure.md +0 -87
- package/skills/qualia-help/SKILL.md +0 -60
- package/skills/qualia-test/SKILL.md +0 -134
- package/templates/help.html +0 -476
- package/tests/runner.js +0 -1956
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qualia-polish
|
|
3
|
-
description: "Design and UX pass —
|
|
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
|
-
|
|
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
|
|
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.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
**
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
###
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
|
|
148
|
-
###
|
|
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,
|
|
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
|
|
189
|
-
node ~/.claude/bin/qualia-ui.js ok "Typography
|
|
190
|
-
node ~/.claude/bin/qualia-ui.js ok "Color
|
|
191
|
-
node ~/.claude/bin/qualia-ui.js ok "Layout
|
|
192
|
-
node ~/.claude/bin/qualia-ui.js ok "States
|
|
193
|
-
node ~/.claude/bin/qualia-ui.js ok "Motion
|
|
194
|
-
node ~/.claude/bin/qualia-ui.js ok "Accessibility
|
|
195
|
-
node ~/.claude/bin/qualia-ui.js ok "Responsive
|
|
196
|
-
node ~/.claude/bin/qualia-ui.js ok "
|
|
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
|
|
76
|
+
### 5. Upload to ERP
|
|
77
77
|
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
|
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
|
-
|
|
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` —
|
|
13
|
-
- `/qualia-review --web` —
|
|
14
|
-
- `/qualia-review --ai` —
|
|
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
|
-
##
|
|
16
|
+
## General Review (default)
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
node ~/.claude/bin/qualia-ui.js banner review
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Spawn parallel agents analyzing:
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32
|
+
Full production readiness for Next.js + Supabase + Vercel:
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
**Security:** No secrets in code, HTTPS, CORS restricted, CSP headers, rate limiting, npm audit clean.
|
|
37
35
|
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
git ls-files | grep -i "\.env" | grep -v "\.example\|\.template\|\.sample"
|
|
42
|
+
## --ai (AI/Voice Agent Audit)
|
|
50
43
|
|
|
51
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
52
|
+
**RAG (if detected):** Embedding consistency, chunk size, retrieval relevance, index refresh.
|
|
69
53
|
|
|
70
|
-
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
58
|
+
Every finding:
|
|
59
|
+
- **What** — description
|
|
60
|
+
- **Where** — `file:line`
|
|
61
|
+
- **Fix** — concrete suggestion
|
|
62
|
+
- **Severity** — CRITICAL / HIGH / MEDIUM / LOW
|
|
79
63
|
|
|
80
|
-
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
|
36
|
+
Phase plan with success criteria:
|
|
37
37
|
@.planning/phase-{N}-plan.md
|
|
38
38
|
|
|
39
39
|
{If re-verification: Previous verification with gaps:}
|