Code Review
Correctness and security gate. High-conviction findings only — flag issues you
are certain about. Ambiguity defaults to "request changes." Structural concerns
(cohesion, abstraction altitude, circular deps, dead code) belong to the
structural-review skill; trust it on those axes and own correctness + security
here.
Stack rules from the repo's agent instruction file (Bun, Tailwind v4, Next.js 16,
shadcn/ui) are validated by the correctness review harness's rule-compliance
layer. Do not re-flag them here.
Contract
Inputs:
- A single diff, branch, or PR to review. Read-only
git/gh commands gather
scope.
Outputs:
- A findings list bucketed into Block Merge / Request Changes / Approve, each
with file, line, and a one-sentence rationale.
- A Spec report alongside the checklist: missing requirements, scope creep,
and wrong implementations relative to the originating issue. Keep the two axes
separate so one cannot mask the other.
Creates/Modifies:
- None. This skill reports; it does not edit files or open PRs.
External Side Effects:
- Read-only
git and gh invocations only. No mutations, no deploys.
Confirmation Required:
- None. All output is advisory.
Delegates To:
structural-review for cohesion/abstraction/dead-code axes.
security-audit for OWASP-depth security review.
codebase-design when a finding is about module depth or seam placement.
Spec Axis
The checklist below is the Standards axis (correctness + security + this
repo's hygiene). Run a Spec axis in parallel so a change that follows every
standard but implements the wrong thing cannot hide, and a change that matches
the issue but breaks conventions cannot hide.
A change can pass one axis and fail the other:
- Code that follows every standard but implements the wrong thing → Standards
pass, Spec fail.
- Code that does exactly what the issue asked but breaks project conventions →
Spec pass, Standards fail.
Report them under ## Standards and ## Spec. Do not merge or rerank findings
across axes.
1. Pin the fixed point
Whatever the user said is the fixed point — a commit SHA, branch name, tag,
main, HEAD~5. If they did not specify one, ask. Confirm it resolves and the
diff is non-empty (git diff <fixed-point>...HEAD) before reviewing.
2. Identify the spec source
Look for the originating spec, in this order:
- Issue references in commit messages (
#123, Closes #45) — fetch via gh.
- A path the user passed as an argument.
- A spec file under
docs/, specs/, or the issue body matching the branch.
- If nothing is found, ask. If there is no spec, skip the Spec axis and report
"no spec available".
3. Spec findings
Report:
- Requirements the spec asked for that are missing or partial
- Behaviour in the diff that was not asked for (scope creep)
- Requirements that look implemented but where the implementation looks wrong
Quote the spec line for each finding. Spec misses that drop required behaviour
are Block Merge. Scope creep is Request Changes unless the user already accepted
it.
Critical Checklist
1. Security and Data Isolation
- ALL queries filter by tenant/organization (if multi-tenant)
- ALL queries filter soft-deleted records (if applicable)
- No cross-tenant data access
- Auth guards on protected routes
- No unintended public endpoints — every route's auth posture is intentional
- Input validation via DTOs/schemas
- No secrets, tokens, or credentials committed or logged
2. TypeScript
- No
any types — define proper interfaces or named types in *.types.ts
- No bare
unknown without a type guard — bare unknown is deferred any
- No
as X casts without an explanatory comment
- Interfaces/props in dedicated files, not inline in component or service files
- Return types on all functions
- No
console.log — use the project logger (LoggerService, pino, winston)
- No
@ts-ignore or @ts-expect-error without an explanatory comment
3. Pattern Compliance
- Follows existing codebase patterns (verify 3+ real examples before flagging)
- Path aliases over relative imports
4. Database
- Tenant/organization filter in ALL queries (if applicable)
- Soft delete filter in ALL queries (if applicable)
- Projections for large documents
- Indexes exist for query patterns
- No N+1 queries visible in the diff
- Sequential
await db.update() calls that can leave the DB half-written on
failure must be wrapped in a transaction or collapsed to a single atomic write
5. Error Handling
- Try/catch blocks present
- Framework-specific exceptions (not generic
Error)
- Errors logged via logger service
- Generic messages to client (no internals exposed)
6. Testing
- Unit tests exist and pass
- All public methods tested
- Error cases tested
- Tests assert behavior, not just that code runs (no hollow snapshot tests)
7. Frontend
- Cleanup in
useEffect with async calls (AbortController)
- Loading and error states handled
- Semantic HTML with ARIA labels where interactive elements are added
8. API
- Proper HTTP status codes
- DTOs for request/response
- API documentation decorators present where the project uses them (e.g.
@ApiOperation / @ApiResponse)
- No internal stack traces leaked to API consumers
9. Devex Regressions
Changes that silently break the local dev loop for other engineers:
- Env var renames or additions — is there a corresponding update to
.env.example / .env.template? Is the rename announced (migration note,
changelog, or PR description)?
- Secret-read changes — new secrets accessed at runtime that are not in the
documented setup path; access moved from one provider/vault path to another
without updating the runbook
- Port or network remaps — service, dev-server, or docker-compose port
changed without updating README/setup docs and all dependent config files
- New mandatory setup scripts — a migration, seed, or one-time bootstrap
that must be run before the app starts; not documented in the PR description
or setup guide
- Build-flow changes — new required build steps, changed output directories,
added pre/post scripts in
package.json that break the existing
bun run dev / bun run build contract without a clear migration note
Block merge when a devex regression is unannounced. Request changes when it is
documented but the documentation is in the wrong place.
10. Feature-Flag / Gate Leaks
Features meant to be gated that are shipping unflagged or partially flagged:
- Obvious leaks — a new route, component, or API endpoint that the PR
description says is behind a flag, but the flag check is absent or only
applied to the UI, not the API handler
- Subtle leaks — flag check present in the happy path but absent in an
error handler, a background job, or an admin-only path that calls the same
service method
- Always-on constants —
const ENABLE_NEW_CHECKOUT = true standing in for
a real flag evaluation; will never be cleaned up and bypasses the flag service
- Flag introduced without a cleanup plan — no linked issue or TODO comment
for flag removal; flag names should make the intended lifetime obvious
- Rollout config inconsistencies — flag defined in the PR but the rollout
percentage / targeting rule is missing or set to 100% default, defeating the
purpose of gating
Flag leaks that expose unreleased functionality to all users are merge blockers.
Missing cleanup tickets are a "request changes."
Approval Criteria
Block Merge
- Security issues present
- Missing tenant/organization filtering (if required)
any types or bare unknown without type guards
- Tests failing or tests entirely absent for new public methods
- Build failing
- Feature-flag leak exposing unreleased functionality
- Unannounced devex regression (broken env, port, or build contract)
- Non-atomic multi-step DB mutations with no transaction
Request Changes
- Missing documentation for env var additions or setup-script requirements
- Performance concerns clearly visible in the diff (N+1, missing index)
- Pattern violations (raw HTML in files that already import the UI library)
- Feature flag introduced without a cleanup issue/TODO
- Hollow tests that assert execution rather than behavior
Approve
- All security checks pass
- Tests pass and assert real behavior
- Follows codebase patterns
- Devex impact documented
- Feature flags have cleanup plan
- Spec axis passes, or was skipped because no spec exists
Scope Boundary
This skill = correctness + security gate.
Use it for an individual diff or PR. Route a report-only multi-PR request such as
"review all PRs" through review-dispatch, which applies this gate per PR. The
only non-serial queue-drain mode is exact /merge force, owned by
merge-open-prs; never infer that mutating mode from a review request.
Structural and maintainability concerns — module cohesion, abstraction altitude,
circular dependencies, dead-code introduction, API surface sprawl, whether the
implementation matches the stated architecture — belong to the structural-review
skill. Do not re-litigate those axes here; trust structural-review to own them.
Security-audit depth (OWASP rubric, dependency CVEs, timing attacks, privilege
escalation paths) belongs to the security-audit skill. Surface obvious issues
found in the diff, but do not attempt a full security audit in this skill.
1---
2name: code-review
3description: >-
4 Correctness, security, and spec-fidelity gate for incoming pull requests.
5 Auto-invoked when reviewing a diff, evaluating a PR, running /code-review at
6 any effort level, or asked "is this safe to merge?" Covers bugs, TypeScript
7 hygiene, security, database safety, test existence, devex regressions,
8 feature-flag leaks, and whether the diff matches the originating issue/spec.
9 Multi-PR report-only review routes through review-dispatch; non-serial queue
10 draining is exposed only through exact /merge force.
11metadata:
12 version: "1.2.0"
13 tags: "code-review, correctness, security, testing, devex, feature-flags, spec"
14 author: Ship Shit Dev
15allowed-tools: Bash(git *) Bash(gh *)
16when_to_use: "review this PR, is this safe to merge, /code-review, check the diff, look at my changes, review my code, code review"
17---
18
19# Code Review
20
21Correctness and security gate. High-conviction findings only — flag issues you
22are certain about. Ambiguity defaults to "request changes." Structural concerns
23(cohesion, abstraction altitude, circular deps, dead code) belong to the
24`structural-review` skill; trust it on those axes and own correctness + security
25here.
26
27Stack rules from the repo's agent instruction file (Bun, Tailwind v4, Next.js 16,
28shadcn/ui) are validated by the correctness review harness's rule-compliance
29layer. Do not re-flag them here.
30
31## Contract
32
33Inputs:
34
35- A single diff, branch, or PR to review. Read-only `git`/`gh` commands gather
36 scope.
37
38Outputs:
39
40- A findings list bucketed into Block Merge / Request Changes / Approve, each
41 with file, line, and a one-sentence rationale.
42- A **Spec** report alongside the checklist: missing requirements, scope creep,
43 and wrong implementations relative to the originating issue. Keep the two axes
44 separate so one cannot mask the other.
45
46Creates/Modifies:
47
48- None. This skill reports; it does not edit files or open PRs.
49
50External Side Effects:
51
52- Read-only `git` and `gh` invocations only. No mutations, no deploys.
53
54Confirmation Required:
55
56- None. All output is advisory.
57
58Delegates To:
59
60- `structural-review` for cohesion/abstraction/dead-code axes.
61- `security-audit` for OWASP-depth security review.
62- `codebase-design` when a finding is about module depth or seam placement.
63
64## Spec Axis
65
66The checklist below is the **Standards** axis (correctness + security + this
67repo's hygiene). Run a **Spec** axis in parallel so a change that follows every
68standard but implements the wrong thing cannot hide, and a change that matches
69the issue but breaks conventions cannot hide.
70
71A change can pass one axis and fail the other:
72
73- Code that follows every standard but implements the wrong thing → Standards
74 pass, Spec fail.
75- Code that does exactly what the issue asked but breaks project conventions →
76 Spec pass, Standards fail.
77
78Report them under `## Standards` and `## Spec`. Do not merge or rerank findings
79across axes.
80
81### 1. Pin the fixed point
82
83Whatever the user said is the fixed point — a commit SHA, branch name, tag,
84`main`, `HEAD~5`. If they did not specify one, ask. Confirm it resolves and the
85diff is non-empty (`git diff <fixed-point>...HEAD`) before reviewing.
86
87### 2. Identify the spec source
88
89Look for the originating spec, in this order:
90
911. Issue references in commit messages (`#123`, `Closes #45`) — fetch via `gh`.
922. A path the user passed as an argument.
933. A spec file under `docs/`, `specs/`, or the issue body matching the branch.
944. If nothing is found, ask. If there is no spec, skip the Spec axis and report
95 "no spec available".
96
97### 3. Spec findings
98
99Report:
100
101- Requirements the spec asked for that are missing or partial
102- Behaviour in the diff that was not asked for (scope creep)
103- Requirements that look implemented but where the implementation looks wrong
104
105Quote the spec line for each finding. Spec misses that drop required behaviour
106are Block Merge. Scope creep is Request Changes unless the user already accepted
107it.
108
109## Critical Checklist
110
111### 1. Security and Data Isolation
112
113- ALL queries filter by tenant/organization (if multi-tenant)
114- ALL queries filter soft-deleted records (if applicable)
115- No cross-tenant data access
116- Auth guards on protected routes
117- No unintended public endpoints — every route's auth posture is intentional
118- Input validation via DTOs/schemas
119- No secrets, tokens, or credentials committed or logged
120
121### 2. TypeScript
122
123- No `any` types — define proper interfaces or named types in `*.types.ts`
124- No bare `unknown` without a type guard — bare `unknown` is deferred `any`
125- No `as X` casts without an explanatory comment
126- Interfaces/props in dedicated files, not inline in component or service files
127- Return types on all functions
128- No `console.log` — use the project logger (LoggerService, pino, winston)
129- No `@ts-ignore` or `@ts-expect-error` without an explanatory comment
130
131### 3. Pattern Compliance
132
133- Follows existing codebase patterns (verify 3+ real examples before flagging)
134- Path aliases over relative imports
135
136### 4. Database
137
138- Tenant/organization filter in ALL queries (if applicable)
139- Soft delete filter in ALL queries (if applicable)
140- Projections for large documents
141- Indexes exist for query patterns
142- No N+1 queries visible in the diff
143- Sequential `await db.update()` calls that can leave the DB half-written on
144 failure must be wrapped in a transaction or collapsed to a single atomic write
145
146### 5. Error Handling
147
148- Try/catch blocks present
149- Framework-specific exceptions (not generic `Error`)
150- Errors logged via logger service
151- Generic messages to client (no internals exposed)
152
153### 6. Testing
154
155- Unit tests exist and pass
156- All public methods tested
157- Error cases tested
158- Tests assert behavior, not just that code runs (no hollow snapshot tests)
159
160### 7. Frontend
161
162- Cleanup in `useEffect` with async calls (`AbortController`)
163- Loading and error states handled
164- Semantic HTML with ARIA labels where interactive elements are added
165
166### 8. API
167
168- Proper HTTP status codes
169- DTOs for request/response
170- API documentation decorators present where the project uses them (e.g.
171 `@ApiOperation` / `@ApiResponse`)
172- No internal stack traces leaked to API consumers
173
174### 9. Devex Regressions
175
176Changes that silently break the local dev loop for other engineers:
177
178- **Env var renames or additions** — is there a corresponding update to
179 `.env.example` / `.env.template`? Is the rename announced (migration note,
180 changelog, or PR description)?
181- **Secret-read changes** — new secrets accessed at runtime that are not in the
182 documented setup path; access moved from one provider/vault path to another
183 without updating the runbook
184- **Port or network remaps** — service, dev-server, or docker-compose port
185 changed without updating README/setup docs and all dependent config files
186- **New mandatory setup scripts** — a migration, seed, or one-time bootstrap
187 that must be run before the app starts; not documented in the PR description
188 or setup guide
189- **Build-flow changes** — new required build steps, changed output directories,
190 added pre/post scripts in `package.json` that break the existing
191 `bun run dev` / `bun run build` contract without a clear migration note
192
193Block merge when a devex regression is unannounced. Request changes when it is
194documented but the documentation is in the wrong place.
195
196### 10. Feature-Flag / Gate Leaks
197
198Features meant to be gated that are shipping unflagged or partially flagged:
199
200- **Obvious leaks** — a new route, component, or API endpoint that the PR
201 description says is behind a flag, but the flag check is absent or only
202 applied to the UI, not the API handler
203- **Subtle leaks** — flag check present in the happy path but absent in an
204 error handler, a background job, or an admin-only path that calls the same
205 service method
206- **Always-on constants** — `const ENABLE_NEW_CHECKOUT = true` standing in for
207 a real flag evaluation; will never be cleaned up and bypasses the flag service
208- **Flag introduced without a cleanup plan** — no linked issue or TODO comment
209 for flag removal; flag names should make the intended lifetime obvious
210- **Rollout config inconsistencies** — flag defined in the PR but the rollout
211 percentage / targeting rule is missing or set to 100% default, defeating the
212 purpose of gating
213
214Flag leaks that expose unreleased functionality to all users are merge blockers.
215Missing cleanup tickets are a "request changes."
216
217## Approval Criteria
218
219### Block Merge
220
221- Security issues present
222- Missing tenant/organization filtering (if required)
223- `any` types or bare `unknown` without type guards
224- Tests failing or tests entirely absent for new public methods
225- Build failing
226- Feature-flag leak exposing unreleased functionality
227- Unannounced devex regression (broken env, port, or build contract)
228- Non-atomic multi-step DB mutations with no transaction
229
230### Request Changes
231
232- Missing documentation for env var additions or setup-script requirements
233- Performance concerns clearly visible in the diff (N+1, missing index)
234- Pattern violations (raw HTML in files that already import the UI library)
235- Feature flag introduced without a cleanup issue/TODO
236- Hollow tests that assert execution rather than behavior
237
238### Approve
239
240- All security checks pass
241- Tests pass and assert real behavior
242- Follows codebase patterns
243- Devex impact documented
244- Feature flags have cleanup plan
245- Spec axis passes, or was skipped because no spec exists
246
247## Scope Boundary
248
249This skill = **correctness + security gate**.
250
251Use it for an individual diff or PR. Route a report-only multi-PR request such as
252"review all PRs" through `review-dispatch`, which applies this gate per PR. The
253only non-serial queue-drain mode is exact `/merge force`, owned by
254`merge-open-prs`; never infer that mutating mode from a review request.
255
256Structural and maintainability concerns — module cohesion, abstraction altitude,
257circular dependencies, dead-code introduction, API surface sprawl, whether the
258implementation matches the stated architecture — belong to the `structural-review`
259skill. Do not re-litigate those axes here; trust `structural-review` to own them.
260
261Security-audit depth (OWASP rubric, dependency CVEs, timing attacks, privilege
262escalation paths) belongs to the `security-audit` skill. Surface obvious issues
263found in the diff, but do not attempt a full security audit in this skill.