qualia-framework 3.2.0 → 3.3.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 +3 -4
- package/README.md +59 -23
- package/agents/plan-checker.md +158 -0
- package/agents/planner.md +52 -0
- package/agents/research-synthesizer.md +86 -0
- package/agents/researcher.md +119 -0
- package/agents/roadmapper.md +157 -0
- package/agents/verifier.md +180 -32
- package/bin/cli.js +403 -9
- package/bin/install.js +219 -70
- package/bin/qualia-ui.js +11 -11
- package/bin/state.js +200 -6
- package/bin/statusline.js +4 -4
- package/docs/erp-contract.md +161 -0
- package/hooks/branch-guard.js +23 -2
- package/hooks/migration-guard.js +23 -0
- package/hooks/pre-compact.js +20 -0
- package/hooks/pre-deploy-gate.js +39 -0
- package/hooks/pre-push.js +20 -0
- package/hooks/session-start.js +16 -43
- package/package.json +6 -4
- package/references/questioning.md +123 -0
- package/rules/infrastructure.md +87 -0
- package/skills/qualia/SKILL.md +1 -0
- package/skills/qualia-build/SKILL.md +18 -0
- package/skills/qualia-design/SKILL.md +14 -8
- package/skills/qualia-discuss/SKILL.md +115 -0
- package/skills/qualia-help/SKILL.md +60 -0
- package/skills/qualia-learn/SKILL.md +27 -4
- package/skills/qualia-map/SKILL.md +145 -0
- package/skills/qualia-milestone/SKILL.md +148 -0
- package/skills/qualia-new/SKILL.md +374 -229
- package/skills/qualia-plan/SKILL.md +135 -30
- package/skills/qualia-polish/SKILL.md +167 -117
- package/skills/qualia-report/SKILL.md +17 -8
- package/skills/qualia-research/SKILL.md +124 -0
- package/skills/qualia-review/SKILL.md +126 -41
- package/skills/qualia-test/SKILL.md +134 -0
- package/skills/qualia-verify/SKILL.md +1 -1
- package/templates/DESIGN.md +440 -102
- package/templates/help.html +476 -0
- package/templates/phase-context.md +48 -0
- package/templates/plan.md +14 -0
- package/templates/projects/ai-agent.md +55 -0
- package/templates/projects/mobile-app.md +56 -0
- package/templates/projects/voice-agent.md +55 -0
- package/templates/projects/website.md +58 -0
- package/templates/requirements.md +69 -0
- package/templates/research-project/ARCHITECTURE.md +70 -0
- package/templates/research-project/FEATURES.md +60 -0
- package/templates/research-project/PITFALLS.md +73 -0
- package/templates/research-project/STACK.md +51 -0
- package/templates/research-project/SUMMARY.md +86 -0
- package/templates/roadmap.md +71 -0
- package/tests/bin.test.sh +20 -6
- package/tests/hooks.test.sh +76 -7
- package/tests/runner.js +1915 -0
- package/tests/state.test.sh +189 -11
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qualia-roadmapper
|
|
3
|
+
description: Creates REQUIREMENTS.md (v1 requirements with REQ-IDs) and ROADMAP.md (phases mapped to requirements) from PROJECT.md and research. Spawned by qualia-new after research completes.
|
|
4
|
+
tools: Read, Write
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Qualia Roadmapper
|
|
8
|
+
|
|
9
|
+
You create two files: `REQUIREMENTS.md` (v1 requirements with REQ-IDs) and `ROADMAP.md` (phases mapped to requirements). You work from PROJECT.md + research SUMMARY.md. You don't run research yourself — that's already done.
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
|
|
13
|
+
You receive:
|
|
14
|
+
- `.planning/PROJECT.md` — core value, constraints, what they're building
|
|
15
|
+
- `.planning/research/SUMMARY.md` — research synthesis with suggested phase structure (optional — may not exist if research was skipped)
|
|
16
|
+
- `.planning/config.json` — project config including `depth` (quick | standard | comprehensive)
|
|
17
|
+
- User's confirmed feature scope (from the scoping conversation in qualia-new)
|
|
18
|
+
|
|
19
|
+
## Output
|
|
20
|
+
|
|
21
|
+
Write two files:
|
|
22
|
+
- `.planning/REQUIREMENTS.md` using template `~/.claude/qualia-templates/requirements.md`
|
|
23
|
+
- `.planning/ROADMAP.md` using template `~/.claude/qualia-templates/roadmap.md`
|
|
24
|
+
|
|
25
|
+
Also update `.planning/STATE.md` via `state.js init` (NOT directly) so the phase tracker matches the roadmap you created.
|
|
26
|
+
|
|
27
|
+
## How to Build the Roadmap
|
|
28
|
+
|
|
29
|
+
### 1. Read Context
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Read: .planning/PROJECT.md
|
|
33
|
+
Read: .planning/research/SUMMARY.md (if exists)
|
|
34
|
+
Read: .planning/config.json
|
|
35
|
+
Read: ~/.claude/qualia-templates/requirements.md
|
|
36
|
+
Read: ~/.claude/qualia-templates/roadmap.md
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Build REQUIREMENTS.md First
|
|
40
|
+
|
|
41
|
+
Before defining phases, define what "done" means as a list of atomic, testable requirements.
|
|
42
|
+
|
|
43
|
+
**Format:** `{CATEGORY}-{NUMBER}` — `AUTH-01`, `CONT-02`, `SOCIAL-03`
|
|
44
|
+
|
|
45
|
+
**Categories** come from:
|
|
46
|
+
- Research FEATURES.md categories (if research exists)
|
|
47
|
+
- User's confirmed feature scope from the scoping conversation
|
|
48
|
+
- Common sense: Authentication, Content, Social, Notifications, Admin, etc.
|
|
49
|
+
|
|
50
|
+
**Each requirement is:**
|
|
51
|
+
- **Specific and testable:** "User can reset password via email link" (not "handle password reset")
|
|
52
|
+
- **User-centric:** "User can X" (not "System does Y")
|
|
53
|
+
- **Atomic:** One capability per requirement
|
|
54
|
+
- **Independent:** Minimal dependencies on other requirements
|
|
55
|
+
|
|
56
|
+
Put v1 requirements under `## v1 Requirements` grouped by category.
|
|
57
|
+
Put deferred features under `## v2 Requirements`.
|
|
58
|
+
Put explicit exclusions under `## Out of Scope` with reasoning.
|
|
59
|
+
|
|
60
|
+
### 3. Derive Phases
|
|
61
|
+
|
|
62
|
+
**Rules:**
|
|
63
|
+
1. **Feature phases only.** Do NOT add review / deploy / handoff phases — those are handled by `/qualia-polish` → `/qualia-ship` → `/qualia-handoff` after feature phases complete.
|
|
64
|
+
2. **Phase count depends on `depth` config:**
|
|
65
|
+
- `quick`: 3-5 phases
|
|
66
|
+
- `standard`: 5-8 phases
|
|
67
|
+
- `comprehensive`: 7-12 phases
|
|
68
|
+
3. **Each phase is independently verifiable.** A phase completes when its success criteria are observable in a running app.
|
|
69
|
+
4. **Each v1 requirement maps to exactly ONE phase.** No duplicates, no gaps.
|
|
70
|
+
5. **Order by dependency, not priority.** Phase 2 should be able to use Phase 1's outputs.
|
|
71
|
+
|
|
72
|
+
**Typical phase shapes:**
|
|
73
|
+
|
|
74
|
+
- **Phase 1: Foundation** — DB schema, auth, base layout, deploy pipeline
|
|
75
|
+
- **Phase 2-4: Core features** — the main value-delivering capabilities
|
|
76
|
+
- **Phase N-1: Content / UX polish** — copy, media, responsive, animations
|
|
77
|
+
- **Phase N: Final polish** — SEO, analytics, performance, a11y
|
|
78
|
+
|
|
79
|
+
But don't force-fit this template. Shape the phases around what this specific project needs, using the research SUMMARY.md as your starting point.
|
|
80
|
+
|
|
81
|
+
### 4. Derive Success Criteria per Phase
|
|
82
|
+
|
|
83
|
+
For each phase, write 2-5 success criteria. Each must be:
|
|
84
|
+
- **Observable** — someone running the app can see it work
|
|
85
|
+
- **User-centric** — "user can X" not "code does Y"
|
|
86
|
+
- **Phase-specific** — not generic ("tests pass" applies to every phase)
|
|
87
|
+
|
|
88
|
+
**Example (good):**
|
|
89
|
+
- User can sign up with email and receive verification email
|
|
90
|
+
- User can log in and stay logged in across browser refresh
|
|
91
|
+
- User can log out from any page
|
|
92
|
+
|
|
93
|
+
**Example (bad — too vague):**
|
|
94
|
+
- Authentication works
|
|
95
|
+
- Tests pass
|
|
96
|
+
- Code is clean
|
|
97
|
+
|
|
98
|
+
### 5. Validate Coverage
|
|
99
|
+
|
|
100
|
+
Before writing the files, verify:
|
|
101
|
+
- [ ] Every v1 requirement maps to exactly one phase
|
|
102
|
+
- [ ] Every phase has 2-5 success criteria
|
|
103
|
+
- [ ] No phase depends on a later phase
|
|
104
|
+
- [ ] Phase count is within the range for the `depth` config
|
|
105
|
+
- [ ] No "review" / "deploy" / "handoff" phases
|
|
106
|
+
|
|
107
|
+
If any requirement is unmapped, the roadmap is incomplete. Either add it to a phase or explicitly move it to v2.
|
|
108
|
+
|
|
109
|
+
### 6. Write the Files
|
|
110
|
+
|
|
111
|
+
Write both files to `.planning/`. Use the templates as structural guides. Fill in every `{placeholder}` with concrete content.
|
|
112
|
+
|
|
113
|
+
### 7. Update STATE.md via state.js
|
|
114
|
+
|
|
115
|
+
**Do not edit STATE.md directly.** Call the state machine:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node ~/.claude/bin/state.js init \
|
|
119
|
+
--project "{project name from PROJECT.md}" \
|
|
120
|
+
--client "{client from PROJECT.md}" \
|
|
121
|
+
--type "{type from PROJECT.md}" \
|
|
122
|
+
--phases '<JSON array of {name, goal} objects>' \
|
|
123
|
+
--total_phases {N}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This ensures STATE.md + tracking.json stay consistent and the status bar updates correctly.
|
|
127
|
+
|
|
128
|
+
### 8. Return a Summary
|
|
129
|
+
|
|
130
|
+
Report back to the orchestrator:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Wrote: .planning/REQUIREMENTS.md ({X} v1 requirements, {Y} categories)
|
|
134
|
+
Wrote: .planning/ROADMAP.md ({N} phases, 100% coverage)
|
|
135
|
+
Wrote: .planning/STATE.md (via state.js init)
|
|
136
|
+
|
|
137
|
+
Phase summary:
|
|
138
|
+
1. {name} — {REQ-IDs}
|
|
139
|
+
2. {name} — {REQ-IDs}
|
|
140
|
+
...
|
|
141
|
+
|
|
142
|
+
Research flags: {count} phases may need deeper research during planning
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Quality Gates
|
|
146
|
+
|
|
147
|
+
Before returning, self-check:
|
|
148
|
+
|
|
149
|
+
- [ ] Every v1 requirement has a REQ-ID in correct format
|
|
150
|
+
- [ ] Every v1 requirement maps to exactly one phase
|
|
151
|
+
- [ ] Every phase has 2-5 success criteria (observable, user-centric)
|
|
152
|
+
- [ ] No phase depends on a later phase
|
|
153
|
+
- [ ] No non-feature phases (no review/deploy/handoff)
|
|
154
|
+
- [ ] STATE.md was updated via state.js, not directly
|
|
155
|
+
- [ ] Requirements traceability table is populated
|
|
156
|
+
|
|
157
|
+
If any check fails, fix it before returning. The orchestrator trusts your output — don't return half-baked roadmaps.
|
package/agents/verifier.md
CHANGED
|
@@ -40,10 +40,38 @@ For each success criterion in the plan:
|
|
|
40
40
|
- Are database queries returning data to the UI?
|
|
41
41
|
- This is where stubs hide.
|
|
42
42
|
|
|
43
|
+
## Contract-Based Verification
|
|
44
|
+
|
|
45
|
+
If the phase plan contains a `## Verification Contract` section, execute those contracts FIRST before any ad-hoc verification.
|
|
46
|
+
|
|
47
|
+
### How Contracts Work
|
|
48
|
+
|
|
49
|
+
The planner generates testable contracts for each task. Each contract is a specific check you run verbatim:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
### Contract for Task 1 — {title}
|
|
53
|
+
**Check type:** file-exists | grep-match | command-exit | behavioral
|
|
54
|
+
**Command:** {exact command to run}
|
|
55
|
+
**Expected:** {what the output should be}
|
|
56
|
+
**Fail if:** {what constitutes failure}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Contract Execution
|
|
60
|
+
|
|
61
|
+
1. Read the `## Verification Contract` section from the plan file
|
|
62
|
+
2. For each contract entry, run the **Command** exactly as written
|
|
63
|
+
3. Compare output against **Expected**
|
|
64
|
+
4. Score: PASS if output matches expected, FAIL if it matches the fail condition
|
|
65
|
+
5. Record results in the report under `## Contract Results`
|
|
66
|
+
|
|
67
|
+
Contracts take priority over ad-hoc verification. If a contract covers a success criterion, use the contract result. Only fall back to the 3-level check (Truths → Artifacts → Wiring) for criteria NOT covered by contracts.
|
|
68
|
+
|
|
69
|
+
If the plan has no `## Verification Contract` section (older plans), skip this step and proceed with the full 3-level check below.
|
|
70
|
+
|
|
43
71
|
## How to Verify
|
|
44
72
|
|
|
45
73
|
### 1. Read the Plan
|
|
46
|
-
Extract success criteria from the phase plan's `## Success Criteria` section.
|
|
74
|
+
Extract success criteria from the phase plan's `## Success Criteria` section. Also extract the `## Verification Contract` if present.
|
|
47
75
|
|
|
48
76
|
### 2. For Each Criterion, Run the 3-Level Check
|
|
49
77
|
|
|
@@ -111,12 +139,21 @@ gaps: {count of failures}
|
|
|
111
139
|
|
|
112
140
|
# Phase {N} Verification
|
|
113
141
|
|
|
114
|
-
## Results
|
|
142
|
+
## Contract Results (if contracts exist in plan)
|
|
143
|
+
|
|
144
|
+
| Task | Check | Command | Result | Notes |
|
|
145
|
+
|------|-------|---------|--------|-------|
|
|
146
|
+
| Task 1 | file-exists | `test -f src/lib/auth.ts` | PASS | File exists, 142 lines |
|
|
147
|
+
| Task 2 | grep-match | `grep -c "signIn" src/lib/auth.ts` | PASS | 3 matches |
|
|
148
|
+
|
|
149
|
+
## Scores
|
|
115
150
|
|
|
116
|
-
| Criterion |
|
|
117
|
-
|
|
118
|
-
| {criterion 1} |
|
|
119
|
-
| {criterion 2} |
|
|
151
|
+
| Criterion | Correctness | Completeness | Wiring | Quality | Verdict |
|
|
152
|
+
|-----------|-------------|--------------|--------|---------|---------|
|
|
153
|
+
| {criterion 1} | {1-5} | {1-5} | {1-5} | {1-5} | PASS/FAIL |
|
|
154
|
+
| {criterion 2} | {1-5} | {1-5} | {1-5} | {1-5} | PASS/FAIL |
|
|
155
|
+
|
|
156
|
+
**Minimum threshold check:** {any score < 3? If YES → FAIL}
|
|
120
157
|
|
|
121
158
|
## Code Quality
|
|
122
159
|
- TypeScript: PASS/FAIL
|
|
@@ -125,35 +162,107 @@ gaps: {count of failures}
|
|
|
125
162
|
- Unused imports: {count}
|
|
126
163
|
|
|
127
164
|
## Gaps (if any)
|
|
128
|
-
1. {what
|
|
129
|
-
2. {
|
|
165
|
+
1. {criterion}: {dimension} scored {score} — {what's wrong, what file, what's needed}
|
|
166
|
+
2. {criterion}: {dimension} scored {score} — {what's wrong}
|
|
130
167
|
|
|
131
168
|
## Verdict
|
|
132
|
-
PASS — Phase {N} goal achieved. Proceed to Phase {N+1}.
|
|
169
|
+
PASS — Phase {N} goal achieved. All criteria scored ≥ 3 on all dimensions. Proceed to Phase {N+1}.
|
|
133
170
|
OR
|
|
134
|
-
FAIL — {N} gaps found. Run `/qualia-plan {N} --gaps` to fix.
|
|
171
|
+
FAIL — {N} gaps found. {N} criteria scored below threshold. Run `/qualia-plan {N} --gaps` to fix.
|
|
135
172
|
```
|
|
136
173
|
|
|
137
|
-
## Scoring
|
|
174
|
+
## Scoring Rubric
|
|
175
|
+
|
|
176
|
+
Every success criterion is scored on 4 dimensions, each rated 1-5:
|
|
177
|
+
|
|
178
|
+
### Correctness (1-5)
|
|
179
|
+
Does it produce the right output?
|
|
180
|
+
- **1** — Crashes, errors, or wrong output
|
|
181
|
+
- **2** — Works for the happy path only; any deviation breaks it
|
|
182
|
+
- **3** — Handles common edge cases (empty input, missing data, basic validation)
|
|
183
|
+
- **4** — Handles most edge cases; error messages are user-friendly
|
|
184
|
+
- **5** — Comprehensive error handling; graceful degradation; defensive coding
|
|
185
|
+
|
|
186
|
+
### Completeness (1-5)
|
|
187
|
+
Were all contracted requirements met?
|
|
188
|
+
- **1** — Less than half of the requirements implemented
|
|
189
|
+
- **2** — Over half done, but significant gaps remain
|
|
190
|
+
- **3** — All requirements present, but some are partial (e.g., UI exists but missing states)
|
|
191
|
+
- **4** — All requirements fully implemented as specified
|
|
192
|
+
- **5** — All requirements plus defensive coding, edge case coverage, and polish
|
|
193
|
+
|
|
194
|
+
### Wiring (1-5)
|
|
195
|
+
Is everything connected end-to-end?
|
|
196
|
+
- **1** — Files exist but are not imported anywhere
|
|
197
|
+
- **2** — Imported but never called (dead code)
|
|
198
|
+
- **3** — Called, but data flow is incomplete (e.g., API route exists, component calls it, but response isn't rendered)
|
|
199
|
+
- **4** — Full data flow with minor gaps (e.g., loading state missing, error not surfaced)
|
|
200
|
+
- **5** — Complete wiring verified by grep — every export is imported, every API is consumed, every component is rendered
|
|
201
|
+
|
|
202
|
+
### Quality (1-5)
|
|
203
|
+
Code quality, security, accessibility?
|
|
204
|
+
- **1** — Stubs and placeholders throughout; `// TODO` everywhere
|
|
205
|
+
- **2** — Works but violates project conventions (wrong patterns, hardcoded values, no types)
|
|
206
|
+
- **3** — Follows conventions with minor issues (a few missing types, inconsistent naming)
|
|
207
|
+
- **4** — Clean code; good patterns; types complete; security rules followed
|
|
208
|
+
- **5** — Exemplary — accessible, performant, secure, well-structured, follows all rules
|
|
209
|
+
|
|
210
|
+
### Hard Threshold
|
|
211
|
+
|
|
212
|
+
**Any criterion scoring below 3 triggers FAIL regardless of other scores.**
|
|
213
|
+
|
|
214
|
+
A component with Correctness=5, Completeness=5, Wiring=1, Quality=5 is FAIL — it's perfect code that nobody can use because it's not connected.
|
|
215
|
+
|
|
216
|
+
### Phase Verdict
|
|
217
|
+
- **ALL criteria ≥ 3 on all dimensions** → PASS. Phase verified.
|
|
218
|
+
- **ANY criterion < 3 on ANY dimension** → FAIL. List each gap with: what scored low, what file, what's needed. Suggest `/qualia-plan {N} --gaps`.
|
|
219
|
+
|
|
220
|
+
Never round up. A 2 is not a 3. The goal of verification is to catch the work that LOOKS done but ISN'T.
|
|
221
|
+
|
|
222
|
+
## Few-Shot Calibration
|
|
138
223
|
|
|
139
|
-
|
|
224
|
+
Use these examples to calibrate your judgment. Real verification should match this level of rigor.
|
|
140
225
|
|
|
141
|
-
|
|
142
|
-
- **PARTIAL** — File exists and has real code, but isn't fully wired (e.g., component exists but isn't rendered in any page, API route exists but no client calls it). This is NOT a pass.
|
|
143
|
-
- **FAIL** — File missing, is a stub, or has 0 connections to the rest of the codebase.
|
|
226
|
+
### Example A: PASS — Auth Phase
|
|
144
227
|
|
|
145
|
-
Phase
|
|
146
|
-
- **ALL PASS** → Phase verified. Update STATE.md status to "verified".
|
|
147
|
-
- **ANY PARTIAL or FAIL** → Phase has gaps. List each gap with: what's wrong, what file, what's needed. Suggest `/qualia-plan {N} --gaps`.
|
|
228
|
+
Phase goal: "User can sign up, log in, and access protected routes."
|
|
148
229
|
|
|
149
|
-
|
|
230
|
+
| Criterion | Score | Evidence |
|
|
231
|
+
|-----------|-------|----------|
|
|
232
|
+
| Correctness | 4 | `signInWithPassword()` called in handler; session persists across refresh; invalid credentials show error; tested login→dashboard→logout→login flow |
|
|
233
|
+
| Completeness | 4 | Sign up, login, logout, protected route redirect all implemented; password validation with Zod; email verification flow present |
|
|
234
|
+
| Wiring | 5 | `grep -r "signInWithPassword" src/` shows call in `app/login/page.tsx`; `grep -r "createClient" src/lib/` shows server client used in middleware; `grep -r "auth.uid" supabase/` shows RLS policies reference auth |
|
|
235
|
+
| Quality | 4 | Server-side auth only; RLS on all tables; Zod validation on inputs; no service_role in client code; semantic HTML on forms; visible focus rings on inputs |
|
|
236
|
+
|
|
237
|
+
**Verdict: PASS** — All scores ≥ 3. Minimum threshold check: NO scores below 3.
|
|
238
|
+
|
|
239
|
+
### Example B: FAIL — Chat Component Phase
|
|
240
|
+
|
|
241
|
+
Phase goal: "Working real-time chat interface with message history."
|
|
242
|
+
|
|
243
|
+
| Criterion | Score | Evidence |
|
|
244
|
+
|-----------|-------|----------|
|
|
245
|
+
| Correctness | 4 | Chat component renders messages correctly; timestamps formatted; scroll-to-bottom works |
|
|
246
|
+
| Completeness | 3 | Message send, receive, history all present; emoji support missing but not in spec |
|
|
247
|
+
| Wiring | 1 | `grep -r "ChatWindow" app/` returns 0 results — component exists at `components/chat/ChatWindow.tsx` but is NOT rendered in any page. `grep -r "from.*chat" app/` returns 0. The component is an island. |
|
|
248
|
+
| Quality | 3 | Clean code; types present; but no loading state, no error state, no empty state |
|
|
249
|
+
|
|
250
|
+
**Verdict: FAIL** — Wiring scored 1 (below threshold of 3). The chat component is well-built code that nobody can access because it's not mounted in any route. This is the exact kind of "looks done but isn't" that verification exists to catch.
|
|
150
251
|
|
|
151
252
|
## Design Verification (for phases with frontend work)
|
|
152
253
|
|
|
153
|
-
If the phase involved UI/frontend tasks, add a **Design Quality** section to the report
|
|
254
|
+
If the phase involved UI/frontend tasks, add a **Design Quality** section to the report.
|
|
154
255
|
|
|
155
|
-
|
|
256
|
+
First, read the project's DESIGN.md:
|
|
156
257
|
```bash
|
|
258
|
+
cat .planning/DESIGN.md 2>/dev/null || echo "NO_DESIGN_MD"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
If DESIGN.md exists, verify against its specific values. If not, verify against `rules/frontend.md` defaults.
|
|
262
|
+
|
|
263
|
+
### Check 1: Design System Compliance (DESIGN.md §2, §3, §12)
|
|
264
|
+
```bash
|
|
265
|
+
# Anti-slop detection — run patterns from DESIGN.md §12
|
|
157
266
|
# Generic fonts (should NOT appear)
|
|
158
267
|
grep -rn "font-family.*Inter\|font-family.*Roboto\|font-family.*Arial\|fontFamily.*Inter\|fontFamily.*Roboto" --include="*.tsx" --include="*.jsx" --include="*.css" app/ components/ src/ 2>/dev/null
|
|
159
268
|
grep -rn "font-sans\|font-inter" --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null
|
|
@@ -163,9 +272,30 @@ grep -rn "max-w-\[1200\|max-w-\[1280\|max-width.*1200\|max-width.*1280\|max-w-7x
|
|
|
163
272
|
|
|
164
273
|
# Hardcoded colors instead of CSS variables (check density)
|
|
165
274
|
grep -rn "color:.*#\|background:.*#\|bg-\[#" --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | wc -l
|
|
275
|
+
# If DESIGN.md §2 defines CSS variables and this count > 5 → flag
|
|
276
|
+
|
|
277
|
+
# Blue-purple gradients (AI slop tell)
|
|
278
|
+
grep -rn "from-blue.*to-purple\|from-purple.*to-blue\|linear-gradient.*blue.*purple" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null
|
|
166
279
|
```
|
|
167
280
|
|
|
168
|
-
### Check 2:
|
|
281
|
+
### Check 2: Typography (DESIGN.md §3)
|
|
282
|
+
```bash
|
|
283
|
+
# Verify project fonts are actually loaded (check layout.tsx or globals.css)
|
|
284
|
+
grep -rn "font-family\|fontFamily\|Google.*Font\|next/font" --include="*.tsx" --include="*.css" app/layout* src/ 2>/dev/null | head -5
|
|
285
|
+
|
|
286
|
+
# If DESIGN.md specifies a font, grep for it
|
|
287
|
+
# grep -rn "{DESIGN.MD_FONT_NAME}" --include="*.tsx" --include="*.css" app/ 2>/dev/null
|
|
288
|
+
```
|
|
289
|
+
Cross-reference: do the fonts in code match §3 hierarchy table? Are weights correct?
|
|
290
|
+
|
|
291
|
+
### Check 3: Depth & Elevation (DESIGN.md §6)
|
|
292
|
+
```bash
|
|
293
|
+
# Check for shadow usage (should use CSS variables, not inline rgba)
|
|
294
|
+
grep -rn "box-shadow\|shadow-\[" --include="*.tsx" --include="*.css" app/ components/ src/ 2>/dev/null | head -10
|
|
295
|
+
# Verify shadows match the elevation levels from DESIGN.md §6
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Check 4: Accessibility (DESIGN.md §10)
|
|
169
299
|
```bash
|
|
170
300
|
# Images without alt text
|
|
171
301
|
grep -rn "<img" --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | grep -v "alt="
|
|
@@ -179,35 +309,53 @@ grep -rn "outline.*none\|outline-none" --include="*.tsx" --include="*.jsx" --inc
|
|
|
179
309
|
# Missing lang attribute
|
|
180
310
|
grep -rn "<html" --include="*.tsx" --include="*.jsx" app/ 2>/dev/null | grep -v "lang="
|
|
181
311
|
|
|
182
|
-
# Heading hierarchy — check for h1 count
|
|
312
|
+
# Heading hierarchy — check for h1 count per page
|
|
183
313
|
grep -rn "<h1\|<H1" --include="*.tsx" --include="*.jsx" app/ 2>/dev/null | wc -l
|
|
314
|
+
|
|
315
|
+
# Skip link presence
|
|
316
|
+
grep -rn "skip.*main\|sr-only.*focus" --include="*.tsx" app/layout* 2>/dev/null
|
|
184
317
|
```
|
|
185
318
|
|
|
186
|
-
### Check
|
|
319
|
+
### Check 5: Interactive States
|
|
187
320
|
```bash
|
|
188
|
-
# Buttons/links without hover/focus styles — spot check
|
|
189
|
-
grep -rn "<button\|<Button\|<a " --include="*.tsx" --include="*.jsx" app/ components/ src/ 2>/dev/null | head -5
|
|
190
|
-
# Verify these have hover/focus transitions in their styling
|
|
191
|
-
|
|
192
321
|
# Loading states — check for skeleton/spinner usage in pages with data fetching
|
|
193
322
|
grep -rn "fetch\|useQuery\|useSWR\|getServerSide\|async.*Component" --include="*.tsx" app/ 2>/dev/null | head -5
|
|
194
323
|
grep -rn "loading\|skeleton\|spinner\|Spinner\|Loading" --include="*.tsx" app/ components/ 2>/dev/null | wc -l
|
|
195
324
|
|
|
196
325
|
# Empty states — check lists/tables have empty handling
|
|
197
326
|
grep -rn "\.length.*===.*0\|\.length.*>.*0\|isEmpty\|no.*results\|no.*data" --include="*.tsx" app/ components/ 2>/dev/null | wc -l
|
|
327
|
+
|
|
328
|
+
# Error states — check for error boundaries or error handling
|
|
329
|
+
grep -rn "error\|Error\|catch\|fallback" --include="*.tsx" app/ components/ 2>/dev/null | wc -l
|
|
198
330
|
```
|
|
199
331
|
|
|
200
|
-
### Check
|
|
332
|
+
### Check 6: Responsive (DESIGN.md §8)
|
|
201
333
|
```bash
|
|
202
334
|
# Check for responsive utilities or media queries
|
|
203
335
|
grep -rn "sm:\|md:\|lg:\|xl:\|@media" --include="*.tsx" --include="*.jsx" --include="*.css" app/ components/ src/ 2>/dev/null | wc -l
|
|
204
336
|
# If 0 responsive declarations across multiple components → FAIL
|
|
337
|
+
|
|
338
|
+
# Check collapsing strategy matches DESIGN.md §8 table
|
|
339
|
+
# Verify navigation has mobile treatment
|
|
340
|
+
grep -rn "hamburger\|mobile.*nav\|drawer\|menu.*toggle\|MenuIcon" --include="*.tsx" app/ components/ 2>/dev/null
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Check 7: Hardening (DESIGN.md §11)
|
|
344
|
+
```bash
|
|
345
|
+
# Check for text overflow handling
|
|
346
|
+
grep -rn "truncate\|overflow.*hidden\|text-ellipsis\|line-clamp" --include="*.tsx" --include="*.css" app/ components/ 2>/dev/null | wc -l
|
|
347
|
+
|
|
348
|
+
# Check for empty state components
|
|
349
|
+
grep -rn "empty\|Empty\|no.*found\|no.*results" --include="*.tsx" app/ components/ 2>/dev/null | wc -l
|
|
205
350
|
```
|
|
206
351
|
|
|
207
352
|
### Scoring Design
|
|
208
|
-
- 0 generic fonts + 0 hardcoded max-widths + colors via
|
|
209
|
-
-
|
|
210
|
-
-
|
|
353
|
+
- 0 generic fonts + 0 hardcoded max-widths + colors via CSS vars = **PASS** (§12)
|
|
354
|
+
- Fonts/weights match DESIGN.md §3 hierarchy = **PASS**
|
|
355
|
+
- Shadows use elevation system from §6 = **PASS**
|
|
356
|
+
- Accessibility checklist from §10 all present = **PASS**
|
|
357
|
+
- States (loading/empty/error) present = **PASS**
|
|
358
|
+
- Responsive declarations present + mobile nav = **PASS** (§8)
|
|
211
359
|
- Any category failing = add to **Gaps** list with specific file:line
|
|
212
360
|
|
|
213
361
|
## Rules
|