← Back to blog

Teaching an AI Reviewer Your Team’s Standards: Custom Rules That Actually Work

An AI reviewer ships knowing general best practice. It does not know your team decided repositories never call HTTP clients directly. Custom rules are how it learns — if you write them like specs, not vibes.

7 min read
Teaching an AI Reviewer Your Team’s Standards: Custom Rules That Actually Work

Your standards are the product. The reviewer is just the enforcement.

Every engineering team carries a body of decisions that exists nowhere in particular. Repositories never call HTTP clients directly — that lives in a senior engineer's head. Errors crossing a service boundary get wrapped with context — that lives in a code review comment from 2024 that four people saw. New feature flags need an owner and an expiry — that lives in a wiki page nobody has opened since the reorg.

An AI reviewer ships knowing general best practice: injection sinks, N+1 queries, missing error handling, the universal catalogue. What it cannot know is any of the above, because none of it is written down anywhere a machine — or a new hire — can find it. Teams that stop here conclude the reviewer "doesn't get our codebase." Teams that get real value do the unglamorous thing first: they write the standards down as rules, and feed them to the reviewer as custom instructions.

This post is a practical guide to writing those rules — what belongs in them, what emphatically does not, and how to keep them alive once written.

What belongs in a custom rule

The test is simple: a good rule encodes a decision your team has already made and would repeat in human review. You are not asking the AI to invent standards; you are transferring enforcement of standards that already cost you review cycles. The categories that pay off, roughly in order:

  • Layering and dependency direction. "UI components must not import from the persistence layer. Data access goes through repository classes in src/repositories." Architecture drift is invisible in a single diff and obvious across fifty — exactly the kind of thing a tireless first-pass reviewer catches.
  • Forbidden and preferred APIs. "Use our fetchJson wrapper, never raw fetch, so retries and tracing stay consistent." Include the preferred alternative in the rule — a prohibition without a replacement produces findings nobody can act on.
  • Error, logging, and observability conventions. "Log with the structured logger, include request_id, never log tokens or emails." These rules double as security review.
  • Dangerous-change rituals. "Schema migrations must be backwards-compatible for one release; destructive migrations require a two-step deploy." The reviewer flags the PR that forgot the ritual before it reaches the person who gets paged for it.
  • Domain invariants. "Money is always integer cents, never floats. Timestamps are UTC ISO 8601 at the boundary." Small rules, catastrophic when violated, trivially checkable in every diff.

What does not belong: the linter's job stays the linter's job

The most common failure mode is dumping the entire style guide into the reviewer's instructions. Indentation, import order, trailing commas, naming casing — a formatter and linter enforce these deterministically, for free, in milliseconds. Duplicating them as AI rules buys you nothing except noisy findings and a spent review budget on things eslint would have caught anyway.

The division of labour is clean: anything a machine can check by counting belongs in the linter. Anything that requires reading the surrounding code and understanding intent — "is this error swallowed or genuinely handled?", "does this new endpoint follow our authorization pattern?" — is judgment-shaped, and judgment-shaped conventions are precisely where an LLM reviewer earns its keep.

A second thing that does not belong: rules your team has not actually agreed on. If two senior engineers would argue about it in a PR thread, it is a discussion, not a rule. Feeding contested opinions to the reviewer just automates the argument — the AI cites the rule, the author disagrees with the rule, and the dismissal rate climbs. Settle it first, then encode it.

Write rules like specs, not vibes

"Follow clean architecture principles" is a vibe. The reviewer will interpret it differently on every PR, and its findings will feel arbitrary. Compare a rule written like a spec:

Modules under src/core must not import from src/adapters or src/api. If core logic needs an external capability, it depends on an interface defined in src/core/ports. Flag any import that violates this direction and suggest the port-based alternative.

Three properties make that rule work, and they generalize:

  • Concrete trigger. The reviewer can tell unambiguously when the rule applies — specific paths, specific APIs, specific patterns.
  • Stated remedy. The finding can include what to do instead, which is the difference between a comment that gets fixed and one that gets dismissed.
  • A why, in one sentence. Rules with rationale get better compliance from humans and better judgment from the model on borderline cases — it can tell when the spirit of the rule applies even if the letter is ambiguous.

Examples multiply the effect. A one-line good/bad pair anchors the model far better than another paragraph of prose. Where a rule has legitimate exceptions — generated code, test fixtures, a legacy directory mid-migration — say so explicitly, or the exceptions become your false-positive factory.

Rules are code: version them, review them, prune them

Custom rules live longest when they live in the repository — a rules file checked in next to the code it governs, changed through pull requests like everything else. That gives you history ("why does this rule exist?" has a commit message), review ("do we actually want this rule?" happens before enforcement, not after), and scoping (monorepos can layer org-wide rules with per-package rules, which pairs naturally with per-area review configuration).

Then treat the rule set as a garden, not a monument. On a monthly or quarterly pass, look at which rules generate findings and what happens to them. A rule whose findings are routinely fixed is earning its place. A rule whose findings are routinely dismissed is doing damage — every ignored comment teaches the team to skim past the reviewer, and the habit does not distinguish between the noisy rule and the one that just caught a real injection sink. Sharpen the wording, add the missing exception, or delete it. Deleting a bad rule is a feature, and it is a two-line PR.

How this works in PURA

PURA was built around the assumption that every team's review policy is different. Review agents take custom instructions — your rules file, in plain language — and apply them alongside the built-in review passes, so findings cite your convention rather than a generic best practice. Because PURA is self-hosted, the rules and the code they describe never leave your infrastructure, which matters when the conventions themselves encode how your security-sensitive paths work.

Scoping comes from the same machinery as everything else: different agents for different repositories or teams, each with its own instructions and its own budget, so the platform team's strict layering rules do not fire on the hackathon repo. Start with five rules — your five most repeated review comments — wire them into one agent, and watch what happens to those comments over the next month. That is the whole adoption plan, and it compounds from there.

Frequently asked questions

What makes a good custom rule for an AI code reviewer?
Rules that encode a decision your team already made and would repeat in review: naming and layering conventions, forbidden APIs, required patterns for errors, logging, and migrations. If two senior engineers would disagree about a rule, it is not ready to be one.
Should linter rules be duplicated as AI reviewer rules?
No. Style that a formatter or linter can enforce deterministically should stay in the formatter and linter. AI review rules earn their keep on judgment-shaped conventions — the ones that need to read surrounding code and intent, not count spaces.
How do teams keep AI review rules from going stale?
Treat rules like code: keep them in the repository, change them through pull requests, and prune them on a schedule. When a rule keeps producing dismissed findings, either sharpen its wording and examples or delete it — a rule the team ignores trains the team to ignore the reviewer.

Ready to put your AI review spend on rails?

Install PURA on your GitHub repos and start setting budgets in minutes — not months.

Install PURA for free