|
| 1 | +--- |
| 2 | +name: verify-feature |
| 3 | +description: Full codebase rules audit — runs at END of every feature, loops until zero issues |
| 4 | +--- |
| 5 | + |
| 6 | +# /verify-feature |
| 7 | + |
| 8 | +Comprehensive audit of ALL project rules. **Loops automatically** — fix every issue found, re-audit, repeat until zero issues. |
| 9 | + |
| 10 | +## When this runs |
| 11 | + |
| 12 | +- **Automatically at the END of every feature** (before reporting done — see `automation.md § Feature lifecycle`) |
| 13 | +- **Manually** via `/verify-feature` when you want a full check |
| 14 | + |
| 15 | +## Instructions |
| 16 | + |
| 17 | +### Phase 1 — Structural audit (read-only, do it yourself) |
| 18 | + |
| 19 | +Detect changed files: |
| 20 | +```bash |
| 21 | +git diff --name-only HEAD # uncommitted changes |
| 22 | +``` |
| 23 | + |
| 24 | +If no uncommitted changes, use `git diff origin/master...HEAD --name-only` scoped to `packages/app/src/`. |
| 25 | + |
| 26 | +Run ALL checks below on the changed files. If a check is not relevant to the changed files, mark it `SKIP` and move on. |
| 27 | + |
| 28 | +--- |
| 29 | + |
| 30 | +#### 1.1 Forms — react-hook-form everywhere (`code-quality.md § Form conventions`) |
| 31 | + |
| 32 | +For every `.tsx` file with `<form` or `useMutation`: |
| 33 | +- `useState` for form field data without `useZodForm` → **VIOLATION** |
| 34 | +- Manual `e.preventDefault()` in `handleSubmit` without `form.handleSubmit` → **VIOLATION** (exception: parameterless confirmation mutations) |
| 35 | +- Dual state: `useState` duplicating data already in `useZodForm` → **VIOLATION** |
| 36 | +- `useState` for UI-only state (saved, errors, modals) → OK |
| 37 | + |
| 38 | +#### 1.2 Schemas — Zod in the right places (`code-quality.md § Form conventions`, `trpc-api.md`) |
| 39 | + |
| 40 | +```bash |
| 41 | +# Must return ZERO — no Zod in routers |
| 42 | +grep -rn "from ['\"]zod['\"]" src/server/api/routers/ --include="*.ts" |
| 43 | + |
| 44 | +# Must return ZERO — no Zod in components |
| 45 | +grep -rn "from ['\"]zod['\"]" src/modules/ --include="*.tsx" |
| 46 | + |
| 47 | +# Must return ZERO — no inline z.object in API routes |
| 48 | +grep -rn "z\.object(" src/app/api/ --include="*.ts" |
| 49 | +``` |
| 50 | + |
| 51 | +#### 1.3 Schema quality (`code-quality.md § DRY`) |
| 52 | + |
| 53 | +- No two schemas defining the same shape across files |
| 54 | +- No dead exports (types/schemas exported but never imported) |
| 55 | +- Every `modules/*/schemas.ts` re-exported from its `modules/*/index.ts` barrel |
| 56 | + |
| 57 | +#### 1.4 File size (`code-quality.md § File size`) |
| 58 | + |
| 59 | +```bash |
| 60 | +# Flag files over 400 lines (split required) — BLOCK files over 800 |
| 61 | +wc -l $(git diff --name-only HEAD -- '*.ts' '*.tsx') 2>/dev/null | sort -rn | head -20 |
| 62 | +``` |
| 63 | + |
| 64 | +#### 1.5 Imports (`code-quality.md § Imports`) |
| 65 | + |
| 66 | +```bash |
| 67 | +# Must return ZERO — no deep relative imports |
| 68 | +grep -rn "from ['\"]\.\.\/\.\.\/" src/modules/ --include="*.ts" --include="*.tsx" |
| 69 | +``` |
| 70 | + |
| 71 | +#### 1.6 No custom components in src/app/ (`code-quality.md § No custom components`) |
| 72 | + |
| 73 | +```bash |
| 74 | +# Must return ZERO — only route files allowed |
| 75 | +find src/app -name "*.tsx" ! -name "page.tsx" ! -name "layout.tsx" ! -name "loading.tsx" ! -name "error.tsx" ! -name "not-found.tsx" ! -name "global-error.tsx" ! -name "template.tsx" ! -name "default.tsx" ! -name "opengraph-image.tsx" ! -path "*/__tests__/*" | head -20 |
| 76 | +``` |
| 77 | + |
| 78 | +#### 1.7 TypeScript (`code-quality.md § TypeScript`) |
| 79 | + |
| 80 | +```bash |
| 81 | +# Must return ZERO — no explicit any (excluding tests) |
| 82 | +grep -rn ": any\b\|as any\b" src/modules/ src/server/ --include="*.ts" --include="*.tsx" | grep -v "__tests__" | grep -v "\.test\." |
| 83 | +``` |
| 84 | + |
| 85 | +#### 1.8 Environment variables (`code-quality.md § Environment variables`) |
| 86 | + |
| 87 | +```bash |
| 88 | +# Must return ZERO — no direct process.env (excluding allowed files) |
| 89 | +grep -rn "process\.env" src/ --include="*.ts" --include="*.tsx" | grep -v "env.js" | grep -v "instrumentation.ts" | grep -v "next.config" | grep -v "trpc/react.tsx" |
| 90 | +``` |
| 91 | + |
| 92 | +#### 1.9 Database (`database-drizzle.md`) |
| 93 | + |
| 94 | +For changed files in `src/server/`: |
| 95 | +- Multi-write without `db.transaction()` → **VIOLATION** |
| 96 | +- `new Date()` at module scope → **VIOLATION** |
| 97 | + |
| 98 | +#### 1.10 React components (`react-components.md`) |
| 99 | + |
| 100 | +For changed `.tsx` files: |
| 101 | +- Inline `<svg>` → **VIOLATION** (blocked by hook) |
| 102 | +- Raw `<img>` → **VIOLATION** (blocked by hook) |
| 103 | +- `.map()` callback over 5 lines of JSX → **VIOLATION** |
| 104 | + |
| 105 | +#### 1.11 Styling (`styling-dsfr.md`) |
| 106 | + |
| 107 | +For changed `.scss` and `.tsx` files: |
| 108 | +- Raw `@media` with width/screen → **VIOLATION** |
| 109 | +- Hardcoded hex/rgb colors → **VIOLATION** |
| 110 | +- `style={` inline → **VIOLATION** (blocked by hook) |
| 111 | + |
| 112 | +#### 1.12 Testing (`testing.md`) |
| 113 | + |
| 114 | +For changed files: |
| 115 | +- New component/function without corresponding test → **WARNING** |
| 116 | +- Test mocks duplicating `src/test/setup.ts` mocks → **VIOLATION** |
| 117 | +- New page without E2E test → **WARNING** |
| 118 | + |
| 119 | +#### 1.13 tRPC & Security (`trpc-api.md`, `automation.md § Gate 3`) |
| 120 | + |
| 121 | +For changed files in `src/server/`: |
| 122 | +- tRPC input without schema from `~/modules/{domain}/schemas` → **VIOLATION** |
| 123 | +- Router file importing `z` from `zod` → **VIOLATION** |
| 124 | +- Mutation without ownership check → **WARNING** |
| 125 | +- Multi-write without `db.transaction()` → **VIOLATION** |
| 126 | +- Raw SQL → **VIOLATION** |
| 127 | + |
| 128 | +#### 1.14 Accessibility (`automation.md § Gate 2`) |
| 129 | + |
| 130 | +For changed `.tsx` files: |
| 131 | +- `<input>` without associated `<label>` → **VIOLATION** |
| 132 | +- `target="_blank"` without `<NewTabNotice />` → **VIOLATION** |
| 133 | +- Decorative icon without `aria-hidden="true"` → **WARNING** |
| 134 | +- Heading hierarchy skipping levels → **VIOLATION** |
| 135 | +- Form groups without `<fieldset>` + `<legend>` → **WARNING** |
| 136 | + |
| 137 | +--- |
| 138 | + |
| 139 | +### Phase 2 — Quality gates (matches `automation.md § Automatic quality gates`) |
| 140 | + |
| 141 | +Launch **3 parallel agents** for validation: |
| 142 | + |
| 143 | +1. **Agent: typecheck** — `pnpm typecheck` |
| 144 | +2. **Agent: tests** — `pnpm test` |
| 145 | +3. **Agent: lint+format** — `pnpm lint:check && pnpm format:check` |
| 146 | + |
| 147 | +Then launch **2 parallel agents** for audits (scoped to changed files): |
| 148 | + |
| 149 | +4. **Agent: RGAA** — delegate to `rgaa-auditor` agent (`.claude/agents/rgaa-auditor/AGENT.md`) on all changed `.tsx` files. If no `.tsx` files changed → `SKIP`. |
| 150 | +5. **Agent: Security** — delegate to `security-auditor` agent (`.claude/agents/security-auditor/AGENT.md`) on all changed `.ts/.tsx` files in `server/`, `routers/`, or tRPC. If none → `SKIP`. |
| 151 | + |
| 152 | +--- |
| 153 | + |
| 154 | +### Phase 3 — Fix loop |
| 155 | + |
| 156 | +If **any VIOLATION** was found in Phase 1 or Phase 2: |
| 157 | + |
| 158 | +1. Fix all violations |
| 159 | +2. Go back to **Phase 1 step 1** — re-run the full audit |
| 160 | +3. Repeat until **zero violations** across both phases |
| 161 | + |
| 162 | +**Never report completion with known violations.** |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +### Phase 4 — Final report |
| 167 | + |
| 168 | +Only after zero violations remain: |
| 169 | + |
| 170 | +``` |
| 171 | +## Feature Verification: PASS ✅ |
| 172 | +
|
| 173 | +### Rules checked |
| 174 | +| Rule | Files | Status | |
| 175 | +|---|---|---| |
| 176 | +| Forms (react-hook-form) | X files | PASS | |
| 177 | +| Schemas (no inline Zod) | X routers | PASS | |
| 178 | +| File size (< 400 lines) | X files | PASS | |
| 179 | +| Imports (no deep relative) | X files | PASS | |
| 180 | +| TypeScript (no any) | X files | PASS | |
| 181 | +| Env vars (no process.env) | X files | PASS | |
| 182 | +| ... | ... | ... | |
| 183 | +
|
| 184 | +### Quality gates |
| 185 | +| Gate | Status | |
| 186 | +|---|---| |
| 187 | +| Typecheck | clean | |
| 188 | +| Tests | X/X passed | |
| 189 | +| Lint + Format | clean | |
| 190 | +| RGAA | PASS / SKIP | |
| 191 | +| Security | PASS / SKIP | |
| 192 | +``` |
0 commit comments