cd /news/ai-agents/config-files-vs-hooks-where-agent-en… · home topics ai-agents article
[ARTICLE · art-136715] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Config files vs hooks: where agent enforcement actually belongs

A developer outlined a four-level enforcement ladder for AI coding agents, arguing that rules which must never be violated belong in deterministic hooks and CI rather than in prose configuration files like CLAUDE.md. The approach places linters and CI at the most reliable level, PreToolUse hooks next, and reserves prose for judgment-based scoped and always-on rules, since prose is sampled rather than executed. The developer packaged the split into a commercial kit, AgentConfig Studio, with a free MIT-licensed Next.js sample.

by read2 min views3 publishedSep 22, 2026

A rule in CLAUDE.md is a request. A hook is a guarantee. Mixing these

two up is the most common config mistake I see: teams write "never

commit secrets" as prose, then act surprised when a secret gets

committed. This post is the split I use: what belongs in prose, what

belongs in a hook, and the four-level ladder that decides.

Prose config changes what the model tries to do. Hooks and CI change

what is possible to do. Anything that must never happen does not

belong in prose, because prose is sampled, not executed.

For any rule you want, ask which level it actually needs:

Level 1  Linter/types/CI      deterministic, catches most code issues
Level 2  Hooks (PreToolUse)   blocks the command/file before it runs
Level 3  Scoped rules         prose, loads only for matching files
Level 4  Always-on config     prose, worth spending context on every call

The ladder is ordered by reliability, and the reliable end is free of

tokens. Every rule you can push down a level saves context and removes

a failure mode.

Concrete examples from my own setup:

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash", "command": "block-dangerous.sh" },
      { "matcher": "Edit|Write", "command": "protect-env.sh" }
    ]
  }
}

rm -rf outside a target dir, force-push to main, drop table. A regex in a PreToolUse hook blocks these with certainty. In prose, "be careful with rm" works maybe nine times out of ten, and you only hear about the tenth..env, keys, generated files. The hook returns a block reason and the agent adapts. No token spent until the moment of the attempt. The things hooks cannot decide, because they need judgment:

The clearest smell is any line in CLAUDE.md that starts with "always

run" or "never commit". If CI can check it, CI should check it.

Every prose duplicate of a linter rule is a line of context spent on

something the machine already guarantees, and a contradiction waiting

when the two drift.

Our kits keep prose for judgment and push everything checkable down

the ladder. That is also why the validator rejects placeholder

instruction files: prose that restates the linter is worse than no

file, because it trains you to stop reading your own config.

Older setups (plain .cursorrules, bare AGENTS.md) have no hook layer.

The ladder still applies, one rung lower: CI and linters carry the

hard guarantees, prose carries judgment, and the "hard guarantees in

prose" gap is covered by a pre-commit hook in git itself, which every

setup has.

Our kits ship this split pre-built: prose for judgment, hooks and validator rules for guarantees, in AgentConfig Studio. Try the approach on Next.js first: free sample kit (MIT).

── more in #ai-agents 4 stories · sorted by recency
── more on @agentconfig studio 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/config-files-vs-hook…] indexed:0 read:2min 2026-09-22 ·