| name | code-police |
| description | Review code for quality, simplicity, and common mistakes before declaring work complete. |
| context | fork |
| model | sonnet |
| argument-hint | [--no-elegance] |
Code Police
Review the current changes (scoped to the current branch/PR) against the rules
below plus any project rules. The three passes — rule checklist, fact-check,
elegance — run as sub-agents on fresh contexts: the implementer's main context
just wrote the diff and is biased to rationalize it; sub-agents start cold.
The orchestrator stitches their findings into one summary.
Arguments
--no-elegance — skip Pass 3 entirely (report
Elegance | – | Skipped (--no-elegance)). Use when /simplify already ran
over this same tree; without the flag Pass 3 would re-invoke it for a
near-guaranteed no-op. Passes 1–2 still run.
Project rules
Before spawning the passes, read .agency/code-police.md if it exists —
its rules (inline or via pointer) are additions to the built-in list, appearing
as separate Pass 1 rows under the project's rule IDs. Missing file → built-in
rules only.
Reviewing principles
Apply to every pass, and to the orchestrator (push back on a sub-agent that
violates them rather than laundering its dismissal into the summary):
- NEVER talk yourself out of a finding. No "However…", no "acceptable
tradeoff", no "theoretically X but practically Y".
- NEVER issue "no action needed" on a finding you just described, and
never end with reassurance unless you genuinely found zero issues.
- Assume the code is wrong until proven right — prosecutor, not defense.
Rules
dry-rule-of-three
Two similar instances are fine; three is the threshold for extraction. But
identical content that must stay in sync (same HTML, version string, port,
path) is deduplicated immediately regardless of count.
prefer-focused-library
Before hand-rolling a utility (tokenizer, parser, date/semver/URL helper, arg
parser, tree walker, path normalizer…), search for a focused library — and
prefer it even as a new dependency when scope and bundle cost fit. "Zero deps"
is an easiness judgment: code you don't own doesn't bitrot and its edge cases
are someone else's problem. Hand-roll only when the library adds surface you
actively don't want, or the hand-roll is genuinely a few branch-free lines.
Neither "it's already in the tree" nor "only ~40 lines" gates this — judge
scope fit and bundle cost, in both directions (left-pad exists).
invalid-states-unrepresentable
Discriminated unions, not booleans or stringly-typed fields. If two fields
can't both be undefined, the type says so.
no-dead-code
Aggressively remove unused code — no commented-out blocks, no "just in case".
no-silent-error-swallowing
No empty catch {}, bare catch: pass, or || true. At minimum log; an
intentional best-effort catch carries a comment saying why ignoring is safe.
no-unbounded-growth
Collections, buffers, and listeners that grow with usage need a bound or
cleanup path: cap or evict arrays pushed from handlers; debounce/throttle
high-frequency sources (fs.watch, resize, scroll, onmessage) unless
the handler is O(1) and allocation-free; stream instead of whole-file buffers
when the source can grow; share watchers instead of per-caller installs.
LLM-generated code defaults to the simplest correct implementation, which is
often O(n) in session lifetime — fix at write time (cap, debounce, stream,
share); it's rarely caught in review because the code is functionally correct.
comment-the-non-obvious
At every non-trivial declaration or block, ask: can a reader who didn't write
this tell what it does or why this shape? Write the comment that
supplies whichever is missing (design intent, control-flow semantics, a hidden
constraint types don't carry). "Obvious to me because I just wrote it" is the
failure mode.
Running the passes
Spawn Pass 1 and Pass 2 as two parallel read-only sub-agents
(subagent_type: "Explore"; both Agent blocks in one response). Each prompt
is self-contained and points at this file for the rules-of-record. Pass 3 runs
after they return (it applies fixes and would race their reads); skip it
under --no-elegance. Then stitch all outputs into the summary.
Pass 1 (rule checklist) — sub-agent prompt must direct it to: read the
"Reviewing principles" and "Rules" sections of
.apm/skills/code-police/SKILL.md plus .agency/code-police.md if present;
scope to git diff origin/HEAD...HEAD (or the appropriate base ref); and
return one table covering every rule (built-in + project):
| Rule ID | Violation found? | What was identified | Action taken |
|---|
Every "No" requires a Checked by: field — the grep that confirmed
absence (negative rules), or the enumeration of positive candidates ruled out
(bidirectional rules like comment-the-non-obvious). A "No" without
Checked by: is malformed. No skipped rows, no fixes applied (the
orchestrator routes them).
Pass 2 (fact-check) — sub-agent prompt must direct it to: read the
"Reviewing principles" and apply them verbatim; scope as above; this is a
logic review, not style — find where the code lies to itself: silent error
swallowing, inaccurate fallbacks (defaults masking misconfiguration), wishful
thinking (unvalidated boundary inputs, "can't fail" code that can, races
papered over with comments), logic errors (always-true conditions, off-by-one,
shadowing), and slow leaks (unbounded growth, undebounced hot handlers,
per-caller watchers). Fail loud over fail silent; every fallback justified for
the failure case; precision over coverage (3 real issues beat 20 maybes). Per
finding: file, line, one-line risk, concrete fix. No fixes applied.
Pass 3 (elegance) — skip under --no-elegance; skip when the diff is
under 10 lines (Elegance | 0 | Skipped (tiny diff)) — the fan-out overhead
is disproportionate there. Otherwise: under Claude Code, invoke the bundled
/simplify via the Skill tool (three parallel lenses, applies fixes). On
harnesses without it, run 3 iterations of understand → research → apply →
verify, preferring fewer lines, clearer intent, idiomatic style — remove
abstractions, don't add them. The reviewing principles bind here too.
Output
| Pass | Issues found | Details |
|---|
| Rules | N | Brief summary or "Clean" |
| Fact-check | N | Brief summary or "Clean" |
| Elegance | N | Brief summary or "Clean" |
Below the table, reproduce each pass's full findings verbatim (so a caller
like /do can commit each violation individually). Any pass found issues →
state "Violations or issues found"; all clean → "All clear".
Additional principles
- Simple, not easy: modules do one thing; data flows through arguments
and returns, not shared mutable state. No interfaces with one implementor,
no "for future use" code, plain data over objects with behavior.
- Completeness: implement the full spec; run tests and local CI before
declaring done.
- Justfile: every recipe carries a doc comment.
- Volatility-based module structure: group by rate of change; each module
owns one volatility zone; shared constants get their own file.
- Readability: exported types and components get doc comments; extract
deeply nested callbacks into named functions.