Architecture
Lifecycle in a repository
The repo path from end to end. You author a policy, check it and sync it into hook files. Then each tool call, commit, push and CI run goes through the hook to a verdict and one log line.
A person authors and syncs once. After that, every agent tool call, every commit and push, and every CI run goes through the files chock sync wrote. The agent's hooks and the git hooks reach the same gate runner, so a policy means the same thing in the session and at commit.
Diagram
- Engine code
- Generated file
- The agent's client
- Local log
Select a box to read its card below.
Select a box to read its card here.
Components
Author a policy Engine code
The chock new policy <id> command writes a policy skeleton. A policy is one folder under .agents/policies/<id>/: a manifest, an optional deterministic script, and an eval suite. The policy-init skill writes one from an interview.
Source: chock/src/chock/scaffold/new.py @ 5a4b6287a46e
chock checkEngine codeRuns the repository's checks in order (validate, verify, evals, matrix, mechanisms, index, conflicts, baseline). The --only flag picks a subset.
Source: chock/src/chock/lifecycle.py @ 5a4b6287a46e
chock syncEngine codeRecompiles every installed policy, then writes each wired agent's hook file, the git hooks and INDEX.md. With --ci it also writes the CI workflow.
Source: chock/src/chock/scaffold/recompile.py @ 5a4b6287a46e
chock compileEngine codeRuns the emitter for each hook point on the policy and writes the output to
.chock/compiled/<id>/<surface>/. A hook point with no output gets no folder. It also writes a coverage report.Source: chock/src/chock/compile/compiler.py @ 5a4b6287a46e
Agent hook files Generated file
One entry per hook, in each agent's own file and format. Every entry runs the same committed launcher command.
Source: chock/src/chock/hooks/in_agent_install.py @ 5a4b6287a46e
Git hooks Generated file
A dispatcher in .git/hooks for pre-commit, pre-merge-commit and pre-push. It runs each policy's hook, which calls the vendored runner.
Source: chock/src/chock/hooks/data/dispatcher.sh @ 5a4b6287a46e
CI workflow Generated file
With --ci, chock sync writes .github/workflows/chock.yml. It runs the same runner with --event ci over a pull request's base...head range.
Source: chock/src/chock/scaffold/install_ci.py @ 5a4b6287a46e
Compiled gates Generated file
Loads hook.gate from manifest.yaml and bakes one gate.json per hook point.
Source: chock/src/chock/gate/build.py @ 5a4b6287a46e
Agent tool call The agent's client
Before a tool runs, and at a turn's end where wired, the client runs the hook with the call on stdin. Agentseam reads it as an Event and answers in the client's own dialect. What happens when a hook cannot run is agentseam's data, listed below.
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/dispatch.py @ 683f95b5f278
Launcher Engine code
Runs the first of git config chock.python, python3, python and py that runs Python 3.11+. With none it exits 2, never allow.
Source: chock/src/chock/hooks/data/launch.sh @ 5a4b6287a46e
Agent runtime Engine code
The file
.chock/bin/<agent>.pyholds agentseam's bundle plus chock's handler. A--guardcall runs the policy's script. A--gatecall asks the vendored gate runner.Source: chock/src/chock/gate/runtime_bundle.py @ 5a4b6287a46e
Gate runner Engine code
Evaluates a compiled gate, caps its verdict, and concludes with an exit code. It is assembled into .chock/bin/gate.py, the same runner the git hook and CI run.
Source: chock/src/chock/gate/runner/verdict.py @ 5a4b6287a46e
Decision log Local log
One line per hook decision. With repo hooks it is
<repo>/.chock/log/gate-events.jsonl. With the plugin it is~/.chock/log/<agent>/events.jsonl. It never raises, never changes the decision and never logs contents.Source: chock/src/chock/gate/decision_log.py @ 5a4b6287a46e
Connections
- Author a policy →
chock check: Manifest, evals chock check→chock sync: Thenchock sync→chock compile: Each policychock compile→ Compiled gates:gate.jsonchock sync→ Agent hook files: Per agentchock sync→ Git hooks: Git hookschock sync→ CI workflow:--ci- Agent hook files → Launcher: Runs
- Agent tool call → Launcher:
stdin - Launcher → Agent runtime: Python 3.11+
- Agent runtime → Gate runner:
--gate - Git hooks → Gate runner: Commit, push
- CI workflow → Gate runner:
--event ci - Compiled gates → Gate runner: Reads
- Agent runtime → Agent tool call: Verdict
- Gate runner → Decision log: One line
Main path
The flow this diagram is about, in order:
- Author a policy
chock checkchock sync- Agent hook files
- Launcher
- Agent runtime
- Gate runner
- 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.
- chock @ 5a4b6287a46e
- agentseam @ 683f95b5f278
Built from engine 5a4b6287a46e and catalog 1e60d211c1bb.