Architecture
Stop and resume
A person's stop on agents. It shows the files chock stop and chock stop --everywhere write, the hooks that read them, and the log lines a stop leaves.
A stop is a file a person writes and every chock hook reads. While it is in force, the pre-tool stop check, the git dispatcher and the MCP gateway refuse the next action of an agent in scope, and each refusal is logged. Only a person at a terminal lifts it.
Diagram
- Engine code
- Generated file
- Local log
Select a box to read its card below.
Select a box to read its card here.
Components
chock stopEngine codeA person stops agents in one repository: it writes .chock/stop.json (scope, reason, who as git user.email, when) and an entry in the machine registry. An agent's shell is refused, and the refusal is logged.
Source: chock/src/chock/stop.py @ 5a4b6287a46e
stop --everywhereEngine codeA person stops every agent on the machine: it writes ~/.chock/stops/_everywhere.json. The --agent flag is refused with it: the scope is every agent.
Source: chock/src/chock/stop_everywhere.py @ 5a4b6287a46e
chock resumeEngine codePerson-only: it refuses an agent's shell, needs stdin and stdout to be a TTY, and asks for the repository's name to be typed. With --everywhere it asks for the word everywhere and lifts only the machine-wide stop.
Source: chock/src/chock/stop.py @ 5a4b6287a46e
.chock/stop.json Generated file
The repository's stop. Not committed, so a worktree has no copy of its own: the main checkout's stop reaches it.
Source: chock/src/chock/gate/runner/halt.py @ 5a4b6287a46e
Machine registry Generated file
~/.chock/stops/<sha256 of the repository's realpath>.json (0o600), for a hook whose client names no project root for the session: it refuses every call of an agent in scope while any entry is in force.
Source: chock/src/chock/gate/runner/halt.py @ 5a4b6287a46e
_everywhere.json Generated file
~/.chock/stops/_everywhere.json. A file there that is not a regular file, or cannot be read or parsed, refuses too.
Source: chock/src/chock/gate/runner/halt.py @ 5a4b6287a46e
Stop reader Engine code
Reads every stop. A file that exists but cannot be read or parsed refuses every agent. Stdlib only: gate.py and every runtime carry it.
Source: chock/src/chock/gate/runner/halt.py @ 5a4b6287a46e
Pre-tool stop check Engine code
The chock sync command wires one --stop-check entry per client, with no matcher, so the stop sees every tool call, reads included. A refused call reads stopped: <reason>. 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: chock/src/chock/gate/repo_stop.py @ 5a4b6287a46e
Git dispatcher Engine code
Refuses an agent's commit or push while a stop is in force. A person's commit or push passes. Only the main checkout's .chock/bin/gate.py tells an agent from a person.
Source: chock/src/chock/hooks/data/dispatcher.sh @ 5a4b6287a46e
MCP gateway Engine code
Refuses each tools/call while a stop reaches it, as an MCP error. It forwards initialize, tools/list and every other method.
Source: chock/src/chock/gateway/stop.py @ 5a4b6287a46e
Decision log Local log
Each refused call is a block line with reason stopped. The chock stop and chock resume commands each write one chock-stop line: event repo_stop or repo_resume, with scope, who and when.
Source: chock/src/chock/gate/decision_log.py @ 5a4b6287a46e
Connections
chock stop→ .chock/stop.json: Writeschock stop→ Machine registry: Registersstop --everywhere→ _everywhere.json: Writeschock resume→ .chock/stop.json: Removeschock resume→ _everywhere.json:--everywhere- .chock/stop.json → Stop reader: Reads
- Machine registry → Stop reader: Reads
- _everywhere.json → Stop reader: Reads
- Stop reader → Pre-tool stop check: Tool call
- Stop reader → Git dispatcher: Commit, push
- Stop reader → MCP gateway:
tools/call - MCP gateway → Decision log: Refusal
- Pre-tool stop check → Decision log: Refusal
Main path
The flow this diagram is about, in order:
chock stop- .chock/stop.json
- Stop reader
- Pre-tool stop check
- 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
Built from engine 5a4b6287a46e and catalog 1e60d211c1bb.