|
| 1 | +--- |
| 2 | +name: fxa-review |
| 3 | +description: Thorough FXA-specific commit review using parallel specialist agents. Covers security, TypeScript, logic/bugs, test quality, and architecture. Agents explore call sites, git history, and monorepo conventions. |
| 4 | +allowed-tools: Bash, Read, Grep, Glob, Agent |
| 5 | +argument-hint: [commit-ref] |
| 6 | +user-invocable: true |
| 7 | +context: fork |
| 8 | +--- |
| 9 | + |
| 10 | +# FXA Thorough Review |
| 11 | + |
| 12 | +Review the most recent commit (or the commit specified in `$ARGUMENTS`) using specialized parallel agents. |
| 13 | + |
| 14 | +## Step 1: Get Commit Information |
| 15 | + |
| 16 | +```bash |
| 17 | +COMMIT_REF="${ARGUMENTS:-HEAD}" |
| 18 | +git show "$COMMIT_REF" --format="%H%n%an%n%ae%n%s%n%b" |
| 19 | +``` |
| 20 | + |
| 21 | +```bash |
| 22 | +COMMIT_REF="${ARGUMENTS:-HEAD}" |
| 23 | +git show --stat "$COMMIT_REF" |
| 24 | +``` |
| 25 | + |
| 26 | +Save the full diff output and commit metadata. You will pass these to each agent in Step 2. |
| 27 | + |
| 28 | +## Step 2: Spawn Parallel Review Agents |
| 29 | + |
| 30 | +Launch ALL FIVE agents **in parallel** using the Agent tool in a **single message**. Each agent receives the full diff and commit metadata in its prompt. |
| 31 | + |
| 32 | +Tell each agent to use Read/Grep/Glob to examine surrounding code in changed files for context. Provide the repo working directory path. |
| 33 | + |
| 34 | +Each agent MUST output findings as a JSON array ONLY (no markdown, no extra text). Each item has: severity (CRITICAL/HIGH/MEDIUM/LOW), category, subcategory, file, line, issue, recommendation. If no issues, return: [] |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +**Agent 1 — FXA Security Review** |
| 39 | +- subagent_type: general-purpose |
| 40 | +- model: opus |
| 41 | +- description: FXA security review |
| 42 | + |
| 43 | +Tell this agent it is a senior security engineer. It should: |
| 44 | + |
| 45 | +- Trace user input through changed code paths to check for injection (SQL, Redis, command, XSS) |
| 46 | +- Verify auth schemes on new route handlers — FXA auth-server uses 13 custom Hapi auth schemes, new routes must declare one |
| 47 | +- Check for PII exposure in logs and error messages (emails, UIDs, session tokens) — note: UIDs and emails in API response bodies are expected, focus on logs and error messages |
| 48 | +- Verify parameterized queries — no string concatenation in SQL or Redis commands |
| 49 | +- Check rate limiting on new public endpoints (customs server integration) |
| 50 | +- Verify session token rotation on privilege escalation (login, 2FA, password change) |
| 51 | +- Check CORS configuration — no `*` on credentialed endpoints |
| 52 | +- Verify OTP/TOTP handling: constant-time comparison, immediate invalidation, rate limiting |
| 53 | +- Check that secrets are accessed via Convict config, not hardcoded or read from env directly |
| 54 | + |
| 55 | +Output JSON array with fields: severity, category ("Security"), subcategory, file, line, issue, recommendation. |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +**Agent 2 — FXA TypeScript Review** |
| 60 | +- subagent_type: general-purpose |
| 61 | +- model: opus |
| 62 | +- description: FXA TypeScript review |
| 63 | + |
| 64 | +Tell this agent it is a senior TypeScript engineer familiar with FXA's mixed JS/TS codebase. It should: |
| 65 | + |
| 66 | +- Flag `any` usage — suggest `unknown`, interfaces, or generics instead. Note: `any` is permitted in auth-server during migration but should not be introduced in new code unnecessarily |
| 67 | +- Check for non-null assertions (`!` postfix) — `@typescript-eslint/no-non-null-assertion: error` |
| 68 | +- Verify `as any` is justified — needed for CJS/ESM interop or type system limitations, not hiding real type issues |
| 69 | +- Check mock type safety — mocks should use `satisfies` against real interfaces where possible |
| 70 | +- Flag missing return types on exported functions |
| 71 | +- Look for simplification: optional chaining, nullish coalescing, early returns, destructuring |
| 72 | +- Check import style: `@fxa/<domain>/<package>` for cross-package, relative within package |
| 73 | +- Flag new `require()` in `.ts` files — use `import` instead. Existing CJS patterns in auth-server `.js` files are fine. |
| 74 | +- Prefer `async/await` over `.then()` promise chains |
| 75 | +- For `.js` files: review general code patterns, no TypeScript-specific feedback |
| 76 | + |
| 77 | +Output JSON array with fields: severity, category ("TypeScript"), subcategory, file, line, issue, recommendation, code_before, code_after. |
| 78 | + |
| 79 | +--- |
| 80 | + |
| 81 | +**Agent 3 — FXA Logic and Bugs Review** |
| 82 | +- subagent_type: general-purpose |
| 83 | +- model: opus |
| 84 | +- description: FXA logic and bugs review |
| 85 | + |
| 86 | +Tell this agent it is a senior software engineer who knows FXA's auth-server patterns deeply. It should: |
| 87 | + |
| 88 | +- Follow data flow through changed functions — read callers and callees to verify assumptions |
| 89 | +- Check async correctness: missing `await`, unhandled promise rejections, race conditions — note: some fire-and-forget patterns (metrics, logging) are intentional, check context |
| 90 | +- Verify error propagation: Hapi route handlers should throw, not catch-and-rethrow |
| 91 | +- Check `AppError` usage — HTTP errors must use `AppError` from `@fxa/accounts/errors` |
| 92 | +- Verify logging uses the `log` object (mozlog format), not `console.log` |
| 93 | +- Check edge cases: empty arrays, zero values, null UIDs, expired tokens |
| 94 | +- Flag new `Container.get()`/`Container.set()` usage — linting rules to disallow these are coming |
| 95 | +- Check Convict config access: verify `config.get('key')` keys exist in `config/index.ts` |
| 96 | +- Flag catch blocks that swallow errors or re-throw without context |
| 97 | + |
| 98 | +Output JSON array with fields: severity, category ("Logic/Bugs"), subcategory, file, line, issue, recommendation. |
| 99 | + |
| 100 | +--- |
| 101 | + |
| 102 | +**Agent 4 — FXA Test Quality Review** |
| 103 | +- subagent_type: general-purpose |
| 104 | +- model: opus |
| 105 | +- description: FXA test quality review |
| 106 | + |
| 107 | +Tell this agent it is a QA engineer who understands FXA's testing patterns and common flakiness causes. It should: |
| 108 | + |
| 109 | +- Check new auth-server source files have co-located `*.spec.ts`; fxa-settings uses `*.test.tsx` convention |
| 110 | +- Flag new Mocha tests — all new tests must be Jest |
| 111 | +- Flag `proxyquire` in new code — should use `jest.mock()` |
| 112 | +- Check mock quality: tests that only assert output matches what the mock returns (tautological) |
| 113 | +- Verify interaction assertions: `.toHaveBeenCalledWith()` on mocked dependencies, not just checking return values |
| 114 | +- Flag `jest.clearAllMocks()` in `beforeEach` — unnecessary, `clearMocks: true` is global |
| 115 | +- Check for shared mutable state between tests, missing `await`, `setTimeout` in tests |
| 116 | +- Prefer `jest.useFakeTimers()` and `jest.setSystemTime()` over `setTimeout` or mocking `Date.now` directly |
| 117 | +- Flag patterns likely to cause open handle warnings (unclosed connections, uncleared timers) |
| 118 | +- Flag missing `act()` wrapping in React test state updates |
| 119 | +- Flag over-mocking: mocking internal functions in the same package instead of at system boundaries |
| 120 | + |
| 121 | +Output JSON array with fields: severity, category ("Test Quality"), subcategory, file, line, issue, recommendation. |
| 122 | + |
| 123 | +--- |
| 124 | + |
| 125 | +**Agent 5 — FXA Architecture Review** |
| 126 | +- subagent_type: general-purpose |
| 127 | +- model: opus |
| 128 | +- description: FXA architecture review |
| 129 | + |
| 130 | +Tell this agent it is a senior architect who knows FXA's monorepo structure and migration directions. It should: |
| 131 | + |
| 132 | +- Check if new shared/reusable code belongs in `libs/*` or `fxa-shared` instead of app-local — search the monorepo for existing helpers before flagging. Note: `fxa-shared` is migrating to `libs/`, check both locations. |
| 133 | +- Detect duplication: search `libs/**`, `fxa-shared/**`, and `packages/**` for functions/types with the same name or purpose |
| 134 | +- Flag new code in legacy packages: |
| 135 | + - `fxa-content-server` — should be in `fxa-settings` |
| 136 | + - `fxa-payments-server` — should target SubPlat 3.0 (`libs/payments/*`, `apps/payments/*`) |
| 137 | + - No new GraphQL — `fxa-graphql-api` was removed, `admin-server` GraphQL is legacy. Exception: CMS-related GraphQL. |
| 138 | +- Verify database migrations: |
| 139 | + - Never edit existing published migration files |
| 140 | + - New migration has corresponding rollback |
| 141 | + - Sequential patch numbering has no gaps |
| 142 | + - Index changes separate from schema changes |
| 143 | + - Test DB patches aligned with current test DB state (`/fxa-shared/test/db/models/**/*.sql`) |
| 144 | +- Check cross-package boundary violations: relative imports across package boundaries instead of `@fxa/*` aliases |
| 145 | +- Check for circular or bi-directional dependencies between packages/libs — these break build ordering and are hard to untangle later |
| 146 | +- Flag colliding exports: new exports that duplicate existing ones elsewhere in the monorepo |
| 147 | +- For fxa-settings changes: check React and Tailwind best practices (component composition, accessibility, responsive design) |
| 148 | +- Also apply the code smell checks from the `/check-smells` skill (`.claude/skills/check-smells/SKILL.md`) — read that file and incorporate its design, implementation, test, and dependency smell checks into this review |
| 149 | + |
| 150 | +**Migration direction compliance:** |
| 151 | +- Mocha → Jest (no new Mocha tests) |
| 152 | +- `proxyquire` → `jest.mock()` |
| 153 | +- Callbacks → `async/await` |
| 154 | +- `fxa-shared` → `libs/*` (in progress) |
| 155 | + |
| 156 | +Output JSON array with fields: severity, category ("Architecture"), subcategory, file, line, issue, recommendation. |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Step 3: Aggregate and Report |
| 161 | + |
| 162 | +After all agents return, parse each JSON output. Combine all findings into one list sorted by severity: CRITICAL then HIGH then MEDIUM then LOW. Number sequentially. If an agent returns malformed output, extract what you can and note the issue. |
| 163 | + |
| 164 | +Deduplicate issues flagged by multiple agents (keep the more detailed one, note which reviewers flagged it). |
| 165 | + |
| 166 | +Present the unified report: |
| 167 | + |
| 168 | +**Commit Review Summary** — commit hash, author, message, files changed count. |
| 169 | + |
| 170 | +**Changes Overview** — write your own summary of what the commit does from the diff (do not repeat the commit message). |
| 171 | + |
| 172 | +**AI Slop Check** — flag overly verbose comments, unnecessary abstractions, excessive error handling for impossible cases, redundant validation, or other signs of auto-generated code. |
| 173 | + |
| 174 | +**Issues Found** — markdown table with columns: #, Severity, Reviewer, Category, File, Line, Issue, Recommendation. |
| 175 | + |
| 176 | +Severity definitions: |
| 177 | +- CRITICAL — security vulnerabilities, data loss, editing published migrations, auth bypasses. Must fix. |
| 178 | +- HIGH — bugs, missing auth schemes, unsafe type assertions hiding real issues. Should fix. |
| 179 | +- MEDIUM — convention violations, code quality, missing tests. Consider fixing. |
| 180 | +- LOW — style, minor improvements. Optional. |
| 181 | + |
| 182 | +**Detailed Findings by Reviewer** — one subsection per reviewer (Security, TypeScript, Logic/Bugs, Test Quality, Architecture). Include code before/after examples for HIGH+ issues. If a reviewer found nothing, say "No issues found." |
| 183 | + |
| 184 | +**Verdict** — APPROVE, REQUEST CHANGES, or NEEDS DISCUSSION. Include blocking issue count (CRITICAL + HIGH), total issue count, and which reviewers reported issues. If all agents returned empty arrays: "All specialist reviewers agree — this commit is ready to merge." |
| 185 | + |
| 186 | +## Guidelines |
| 187 | + |
| 188 | +- Always launch all 5 agents in parallel in a single message |
| 189 | +- Be thorough but fair — not every commit needs to be perfect |
| 190 | +- Focus on actual problems, not style preferences |
| 191 | +- Deduplicate cross-agent findings |
| 192 | +- Write the Changes Overview yourself from the diff |
| 193 | +- Include code examples for HIGH+ issues in the detailed findings |
0 commit comments