Chock.sh Build your plugin

Architecture

The life of a policy

One policy from its manifest in chock-catalog, through chock compile and an install, to a tool call, its verdict and the decision log.

A policy is written once, compiled into the files each hook point runs, and installed per agent. After that, every tool call the agent makes runs through the hook, gets a verdict, and leaves one line in a local log.

Diagram

Build: once per policy, once per install Each tool call, on your machine Read hook.gate ambient implementations/ --gate --guard Hook registered Event One line Decision Policy manifestchock-catalog chock compilechock gate.jsonchock Guard scriptchock-catalog Ambient rulechock Install per agentchock A tool callagentseam Verdictchock Back to the clientagentseam Decision logchock
  • Generated file
  • Engine code
  • The agent's client
  • Local log

Select a box to read its card below.

This diagram as JSON

Components

  1. Policy manifest Generated file

    A policy is a folder under chock-catalog's base/. Its manifest.yaml names the policy, its enforcement and its hook: a declarative gate, or a guard script in implementations/. This one declares a content gate on commit and on tool use.

    Source: chock-catalog/base/block-invisible-unicode/manifest.yaml @ 3e9d2d3e04cf

  2. chock compile Engine code

    Reads a policy folder and runs one emitter per hook point: the ambient rule, agent hooks, git hook, CI step, Claude managed settings and the MCP gateway. The output lands in .chock/compiled/<policy>/.

    Source: chock/src/chock/compile/compiler.py @ 39df00bbf764

  3. gate.json Generated file

    The manifest's hook.gate, resolved into one gate.json per hook point: before a tool runs, at the turn's end, in the git hook and in CI.

    Source: chock/src/chock/gate/build.py @ 39df00bbf764

  4. Guard script Generated file

    A policy's own program, for a check a pattern cannot express. The hook hands it the shell command (--guard) and reads its verdict. The cited one is block-destructive-commands.

    Source: chock-catalog/base/block-destructive-commands/implementations/block-destructive-commands.py @ 3e9d2d3e04cf

  5. Ambient rule Generated file

    Text the agent reads, as an AGENTS.md block. It blocks nothing on its own. The gate and the guard do.

    Source: chock/src/chock/compile/emitters/ambient.py @ 39df00bbf764

  6. Install per agent Engine code

    The chock sync command writes each agent's hook file in that agent's own format, and its runtime into .chock/bin/. The chock install command builds the same for one agent as a plugin (ask the user before running either). Each hook command names the gate.json or guard it runs.

    Source: chock/src/chock/hooks/in_agent_install.py @ 39df00bbf764

  7. A tool call The agent's client

    The agent's client runs the hook before the tool runs and passes the call on stdin. Agentseam's dispatcher reads it, and that agent's adapter turns the payload into one Event.

    Source: agentseam/src/agentseam/dispatch.py @ dd4f0a485a36

  8. Verdict Engine code

    Evaluates the compiled gate, caps the verdict by the rollout level in force, and concludes with an exit code: block, ask, warn or allow.

    Source: chock/src/chock/gate/runner/verdict.py @ 39df00bbf764

  9. Back to the client The agent's client

    The adapter speaks the Decision in the client's own dialect, and the client refuses or runs the tool. What a hook can do in each agent, and what happens when it cannot run, is agentseam's data, not ours.

    Agentseam's tier table at the release the engine pins, by fail mode:

    • No adapted pre-tool hook (10): Aider (none), Amp (unadapted), GitHub Copilot (Agent Plugins 1.0 marketplace bundle) (unadapted), DeepSeek Harness (dsh) (unadapted), Kilo Code (unadapted), Kiro (unadapted), OpenCode (unadapted), Replit Agent (unadapted), Roo Code (unadapted), Zed (none)
    • If the hook fails, the action goes through (14): Antigravity (block+rewrite), Claude Code (block+rewrite), Cline (block), OpenAI Codex CLI (block+rewrite), Devin (block+rewrite), Factory Droid (block), Gemini CLI (block+rewrite), Grok CLI (block), Junie CLI (block+rewrite), Kimi Code CLI (block), OpenHands (block), Tabnine CLI (block+rewrite), GitHub Copilot (VS Code agent mode / CLI) (block+rewrite), Windsurf (Cascade) (block)
    • What a failed hook does can be configured (3): Cursor (block+rewrite), goose (block), Mistral Vibe (block+rewrite)

    Source: agentseam/src/agentseam/contract.py @ dd4f0a485a36

  10. Decision log Local log

    One line per hook call, in a local file. With repo hooks it is <repo>/.chock/log/gate-events.jsonl. With the plugin it is ~/.chock/log/<agent>/events.jsonl. Writing it never changes the decision, and the hook sends nothing over the network.

    Source: chock/src/chock/gate/decision_log.py @ 39df00bbf764

Connections

  • Policy manifest → chock compile: Read
  • chock compile → gate.json: hook.gate
  • chock compile → Ambient rule: ambient
  • Policy manifest → Guard script: implementations/
  • gate.json → Install per agent: --gate
  • Guard script → Install per agent: --guard
  • Install per agent → A tool call: Hook registered
  • A tool call → Verdict: Event
  • Verdict → Decision log: One line
  • Verdict → Back to the client: Decision

Main path

The flow this diagram is about, in order:

  1. Policy manifest
  2. chock compile
  3. gate.json
  4. Install per agent
  5. A tool call
  6. Verdict
  7. Decision log

Pinned sources

Every box cites a file at these commits. CI fails the build if a cited path is missing at its commit.

Built from engine 5a4b6287a46e and catalog 1e60d211c1bb.