Skip to content

Skills carry intent, CLI tools mutate state, hooks enforce contracts — three layers, one job each, no bleed, and advisory prompting never substitutes for a hook that blocks.

Pattern

Layered Enforcement

The shape

Three layers. Each reads from below, enforces on above.

Layer 1

Skills

intent

  • Orchestrate workflows
  • Spawn agents
  • Read spec, write briefing

Does NOT

write code

enforce contracts

Layer 2

CLI Tools

state mutation

  • task_create / update / get
  • ADWState
  • Mutate task record + pipeline

Does NOT

make decisions

enforce contracts

Layer 3

Hooks

enforcement

  • Fire at tool boundaries
  • Read state from L2
  • Block or allow L1 actions

Does NOT

produce artifacts

mutate state directly

Layers read downward and enforce upward. Jobs don't overlap — and can't be swapped.

The anti-pattern

Advisory enforcement is a suggestion. The agent can override it.

Enforcement in the promptadvisory

lives in: L1 skill / agent prompt

"Before writing, make sure you've read every file listed in requiredReads."

Agent reads instruction ✓Agent intends to comply ✓Context pressure mounts…Write fires without all reads

The instruction was followed sometimes. It can be forgotten, misinterpreted, or skipped under pressure — no mechanism catches the miss.

Enforcement in a hookstructural

lives in: L3 hook (PreToolUse:Write)

context-gate.sh reads ledger. If requiredReads incomplete → exit 2.

Agent calls WriteHook fires, checks ledgerReads missing → BLOCKEDAgent reads, retries → ALLOWED

The rule can't be skipped. It's not about trusting the agent — it's about the reliability of the system. Structural enforcement doesn't depend on the agent remembering.

The invariants

Each hook enforces one cross-layer contract.

context-gate.sh

requiredReads were read before any Write

builder-product

planner-task-create-gate.sh

task created with --files-expected, --layer, --required-reads

/planning-products

product-spec-stop-verify.sh

filesExpected satisfied on disk + ledger at Stop

any builder task

subagent-context-check.sh

spawn prompt has all 5 required sections

any agent spawn

active-task-recorder.sh

active-task.json written on in_progress call

ledger precondition

Reliability comes from the structure — not from any individual agent doing the right thing.

Which layer?

Every new requirement maps to exactly one.

need

"Enforce that agents don't write to protected files."

↳Layer 3 · PreToolUse:Write hook

need

" Track which phase each task belongs to."

↳Layer 2 · CLI tool field

need

" Orchestrate a new 3-phase workflow."

↳Layer 1 · Skill

need

"Enforce that new workflows follow the 3-phase structure."

↳Layer 3 · Stop-event hook on the skill

Category errors are silent. Enforcement in L1 becomes advisory. State tracking in L3 becomes brittle and unqueryable. Classify first — the layer decides the mechanism.

The discipline

Advisory enforcement is not enforcement.

A hook that blocks a tool call cannot be overridden. A sentence in a prompt can. When you catch yourself writing "make sure you check X before Y," stop — that's a hook, not a paragraph. Pick the layer before you pick the mechanism.