Skip to content

Skills, hooks, agents, CI: what enforces what

Building with agents

A rule that lives only in a skill is a wish. It reads like policy (“never commit to main”, “always run the migration check”) but nothing makes it happen. The model may load it, may weigh it, may follow it. Anthropic’s engineering guidance on steering agents is blunt about the failure mode: advisory rules give way under pressure (a long session, a crowded context, a prompt injection), while hooks and permissions hold because they don’t ask the model’s opinion. So before you write another rule, ask: what enforces this?

There are five places a rule can live. They differ on one axis: the guarantee they give.

MechanismWhat it isGuarantee
Always-loaded conventionCLAUDE.md, AGENTS.md: standing instructions read at session startAdvisory. The model can ignore it
Skill / on-demand knowledgePackaged know-how, loaded only when judged relevantAdvisory, and conditional on being loaded at all
HookA script that fires at a lifecycle point, blocks or passesDeterministic. Always fires; exercises no judgment
AgentA fresh model with a mandate: review this diff, refute this claimJudgment. Catches what scripts can’t; guarantees nothing
CI / platform policyBranch protection, pipeline gates, permission boundariesReal enforcement. Binds human and agent alike

Read the table bottom-up and it’s a chain of custody: the further down, the less the outcome depends on anyone (human or model) behaving well.

  • Skill (on-demand) advisory
  • Convention (always loaded) advisory
  • Agent judgment, not a guarantee
  • Hook deterministic
  • CI / platform policy enforced

Standing instructions and skills are the same substance, text a model reads; they differ only in when they load. Conventions cost context on every turn; skills cost almost nothing until triggered. Both are the right home for knowledge: your stack, your naming, how deploys work here. Neither is enforcement. An advisory rule fails in four ordinary ways: it wasn’t loaded, it was crowded out, a conflicting instruction outranked it, or an injected prompt overrode it. None of these are exotic. All of them happen on normal Tuesdays.

A hook is code at a lifecycle point: before an action, after an edit, at the end of a turn. It fires every time, whatever the model believes. A pre-action hook can refuse any write to migrations/; a stop hook can run the test suite and refuse to end the turn until it’s green. This is the 12-factor agents principle of owning your control flow: a production agent is mostly deterministic code with model steps placed where reasoning is needed, not a model improvising the loop. The trade is symmetrical: a hook never forgets, and it never understands. It cannot tell a safe migration from a destructive one. It can only tell migrations/ from everywhere else.

Some rules can’t be checked by pattern-matching: “is this error message actually helpful?”, “does this change match the spec’s intent?” That’s judgment work, and a fresh reviewer agent that didn’t write the code is the right tool: it reads the diff without the author’s attachment to it. But be precise about what you bought. A model grading a model is a strong opinion, not a gate. It raises the odds of catching what a script can’t see, and guarantees nothing. Use agents as a net above your deterministic layer, never as the floor.

Branch protection, required pipeline checks, permission boundaries, deploy gates: these bind at the platform, so they don’t care who’s asking. A human at 23:00 and an agent in an unattended run hit the same wall. That symmetry is the point: any control that only worked because humans were slow was never a control. The research direction agrees. Written policy can be compiled into runtime guardrails rather than left as prose. Your “must never” rules belong here, stated once, enforced for everyone.

You needReach for
Knowledge the model should applyA skill (or standing instructions)
Something that must happen every timeA hook
A judgment call on ambiguous outputAn agent
A “must never”, whatever the actorCI / platform policy

Most real rules decompose across rows. “Migrations are reviewed before they ship” becomes: a skill explaining how migrations work here, a hook blocking direct writes to the folder, a reviewer agent reading the SQL, and branch protection making the human sign-off non-optional. Four layers, one rule, and only the last one is a guarantee.

Enforcement lives downstream of definition

Section titled “Enforcement lives downstream of definition”

Writing the rule is the cheap step. The decision that matters is where the rule lives: which row of the first table it lands on, and therefore what its violation costs. Audit your current rules against that axis. If everything sits in the top two rows, you don’t have a policy. You have a wish list with good formatting.

Rules are one half of what persists across sessions. The other half is memory, and most of it is not where you’d expect.