The Green-Light Brake example shows the soft brake — the agent reasoning its way to a stop. This example shows the hard brake: theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/quitohooded/keel-skills/llms.txt
Use this file to discover all available pages before exploring further.
PreToolUse hook (enforce-policy.cjs) intercepting a tool call and stopping it regardless of what the model decided. Two layers, defense in depth. The difference matters in one sentence: the soft layer depends on the model choosing to comply; the hard layer doesn’t.
The Setup
The project’sAGENT_POLICY.md contains a machine-readable block that the hook parses at runtime:
These entries refine the SPEC §4 defaults — they don’t replace them. The hook always enforces the defaults (
git push, deploy, rm -rf, schema changes, outward MCP calls) even with no block at all. A project that omits the block entirely still gets full default coverage.Call-by-Call Decisions
Every tool call is inspected before it runs. The hook emits a decision —allow, ask, or deny. When the verdict is ask, the agent surfaces an explicit human-approval prompt: that’s the request for a green light.
Headless Mode — No Human, No Pass
Run the same push in a non-interactive context — CI, a headless agent, a scheduled job — triggered byCI=true or KEEL_NONINTERACTIVE=1. There is no one to give a green light, so ask cannot be answered. The hook denies outright:
CI=true or KEEL_NONINTERACTIVE=1), there is no one to give a green light, so ask automatically becomes deny. This is the case the reasoning layer fundamentally cannot cover: when the agent runs unattended, “stop and ask” has to mean stop, because asking goes nowhere.
The Audit Trail
Every decision lands in.keel/audit.jsonl — so after the fact you can answer “what did the agent try, and what did we stop?”
Honest Scope — Backstop, Not Sandbox
The hook catches accidents, drift, and hallucinated actions — a large lift in assurance. It does not contain an adversarial or jailbroken agent: shell command matching can be routed around (g=push; git $g), and an agent with real credentials can still do real damage.
Why Both Layers
Both layers are necessary. Neither is sufficient on its own.| Soft layer (skills) | Hard layer (hook) | |
|---|---|---|
| What it is | The agent applies the four-step check itself | Deterministic code intercepts the call |
| Strength | Context-aware, smart, explains itself | Fires regardless of the model’s choice |
| Weakness | Depends on the model complying | Only catches concrete, pattern-matchable cases |
| Covers headless? | No (assumes a human is present to be asked) | Yes — denies when no human present |