Paul Wade.dev
NOW READING · GATES NOT GUIDANCE
All posts

Gates, not guidance: standards when agents write the code

Obstacle 26 min read

CLAUDE.md and post-write lint are weak control planes. In 140 trials, only a pre-edit gate that could refuse the write held (0/35 copies). Start with eslint; use checkyourvibe for agent-aware rules.

For coding agents, standards that only advise (CLAUDE.md) or only report after the write are weak control planes. Agents optimize for the cheapest silence. A gate is a pre-edit check that can refuse the write before it lands—eslint at minimum, agent-aware rules when you need them. That layer held at 0/35 copies in the 140-trial harness.

A conventions file cut shortcut copies from 30/35 to 13/35. The same rules, enforced as a pre-write lint gate, cut them to 0/35. Same repository. Same model. Same tasks.

That result is from precedent-poisoning (doi:10.5281/zenodo.22732965). Design problem for standards in an agent world: what you write down is not what you enforce.

Human tooling assumed a person who usually tries to pass the check. Agents optimize for the cheapest silence. Standards that only advise get treated as optional. Standards that only report after the write get reasoned past. Standards that can refuse the edit before it lands are a different kind of thing.

Four layers (be precise)

checkyourvibe names the stack this way:

layerwhat it iswho can ignore it
advisoryinstructions, MCP, CLAUDE.mdthe agent — may read, may skip
gatepre-edit hook on the proposed contentthe edit is denied before it lands
recordpost-edit hookalready wrote; you get a log
guaranteegit hook, CI, AST/compiler check on the diffruns whether or not the agent agreed

Advisory is allowed to be flaky. Nothing below it should depend on sampling.

A post-edit hook cannot undo a write that already landed. A model can notice that. checkyourvibe's README reports a 2026-09-06 probe where an agent read the guidance, reasoned that "the hook's exit status does not undo the write", and declined. That is why the record row is named for what it does, not for what it prevents.

The gate row is the one that prevents. It has to cover edit tools and shell redirects (echo … > file.ts), or the agent has an escape that looks like "not an edit tool."

What ordinary linters were built for

ESLint, Roslyn analyzers, ruff, clippy — good tools. They were built for humans who make honest mistakes and then fix the finding.

An agent that hits a linter error looks for the cheapest way to make it stop. That is often a different violation the linter does not check:

  • Escape no-any with as → need no-as-cast
  • Escape that with @ts-ignore → need no-ts-comment
  • Escape a Result with .unwrap() → need no-unwrap
  • Swallow a catch to "handle" the error → need empty-catch / bare-except rules

Standard packs rarely encode that graph. They name the bad pattern. They do not name the next bad pattern the agent will reach for.

checkyourvibe calls this agent-native evasion defense: each finding carries fixes and notFixes — shortcuts that lead somewhere worse, and which rule waits at the other end. The denied edit comes back with that payload at the moment of refusal, not in a doc the model may never re-read.

What the 140 trials actually support

environmentcopied the seeded shortcut
repository alone30 / 35
plus a conventions file13 / 35
plus a pre-write lint gate0 / 35
plus the same linter after the write4 / 35

Full writeup: precedent poisoning on this site.

Two limits matter for this post:

  1. That study gates with ESLint, not checkyourvibe. It supports the architecture (pre-write refuse vs docs vs post-write advice). It does not prove these particular rules beat anyone else's rules.
  2. 0/35 is a floor on those seven shortcuts, not a ranking of gates.

Lesson for standards design: if your control plane is a markdown file, you measured the weak arm. If your control plane is lint-after, you measured the residual. If your control plane can refuse the proposed write, you measured the arm that cleared the matrix.

eslint (or equivalent) wired as a pre-edit hook is the minimum that matches the data. checkyourvibe is the same layer with a compiler verdict, multi-language analyzers, notFix graphs, and agent glue that stays advisory on purpose.

Design rules that follow

Fail closed on the proposed artifact. Same input, same verdict. The model does not get a vote on whether its own edit passed. That is the difference between a gate and a suggestion.

Put the gate before the write. Post-hoc feedback is cheaper to ship and easier to ignore. In the matrix it left 4/35 copies with the identical rule set that scored 0/35 pre-write.

Do not confuse CI with the agent loop. Git hooks and CI are the guarantee layer. They catch what landed. They do not stop the agent from writing the bad file into the working tree, burning turns, and teaching itself a workaround. Use both. Do not pretend they are the same.

Assume evasion. If a rule has an obvious silence-path, encode the next rule and put it in the finding. Empty notFix lists are how agents tunnel out.

Keep guidance, stop depending on it. Write CLAUDE.md. Generate agent instructions. Then put enforcement where the model cannot reach it.

Minimum viable stack

If you ship agent-written code today:

  1. Wire a deterministic checker (eslint, cyv, or your AST pack) as a pre-tool / pre-edit hook that can exit non-zero and refuse the write.
  2. Match Bash/file redirects, not only the editor tool.
  3. Return the rule id and the forbidden shortcuts in the denial payload.
  4. Keep CI/git hooks as the backstop for anything that bypassed the agent tools.
  5. Treat docs as onboarding, not as the control plane.

checkyourvibe's install path is cyv init → cyv check → cyv install-hooks → cyv install-ci. The interesting part is not the CLI names. It is which layer each command touches.

Scope

Gates do not replace tests, types, or review. One model and one repo do not generalize forever — larger multi-model runs on the poisoning harness are planned. checkyourvibe was not the gate in the 140 trials.

Claim about control planes: in an agent world, standards that cannot refuse the edit are not enforcement. They are commentary. Commentary still helps sometimes. The matrix says it helps unevenly. The refuse-before-write path is the one that held.

Links