Your LLMs need a
crossing guard.

Monitor and control native sessions and tool calls in Claude Code, Codex and OpenCode, with deterministic policies or AI agents.

Open source, built in the open.

The framework source is on GitHub under the Apache 2.0 licence, and you build it yourself with Go. Crossing Guard runs every day on our own Claude Code, Codex and OpenCode sessions. The tutorials show what it does, with the version and date behind each fact. The agent conversation above is an example. The command output further down is copied from a build of the published source.

Works with the agents you already use — and says exactly how well

CC Claude Code Allow · ask · deny
CX Codex Allow · ask · deny
OC OpenCode Deny on 1.18.0
CU Cursor Deny only

One binary connects to each agent at its own extension point: hook entries for Claude Code, Codex and Cursor, and a plugin for OpenCode. Claude Code and Codex can allow a tool call, hold it for you, or deny it. Codex skips a hook until you trust it once in its /hooks screen. OpenCode blocks only on the version we verified (1.18.0) and records on any other. Cursor denies, and a rule that would ask is denied too. Read the installers →

A registered hook is not a firing hook. crossing-guard verify and doctor report the hook events they have seen on your machine.

What it does

01

One memory

Project memory is plain Markdown on your disk, one file per record, with no vendor store. Claude Code and Codex read the same files: a session-start hook adds the records for the repository you are in. See the store →

crossing-guard — memory
crossing-guard attach claudecrossing-guard attach codexls ~/.crossing-guard/memory api-retry-policy.md release-checklist.md recall-log.jsonl (file names are examples)
rules.safety-starter.json — one rule
{ "id": "git-force-push", "action": "ask", "message": "force push can discard published history for everyone", "backstop": "remote-branch-protection", "if": { "tag": "command", "matches": "\\bgit\\s+push\\b.*(--force\\b|…)" }}

02

One rulebook

A rule is JSON: an id, an action and a condition. The actions are deny, ask, allow, observe and redact. A fresh install selects no rules. Opt in to the five starter rules with crossing-guard rules select safety-starter, or point it at your own file. Command matching is best-effort, so keep your branch protection. Read the starter rules →

03

Every agent, one file

The same rule document is evaluated for every connected agent, by one evaluator. crossing-guard check shows what a command would get before any agent tries it. This output is from a build of the published source with the starter rules.

crossing-guard check — dry run
crossing-guard check "git push --force origin main"ASK git-force-push "git push --force origin main"crossing-guard check "git status"allow (no rule matched) "git status"

How it works

1

Build & connect

Build the binary from source. crossing-guard init --dry-run lists every change first, and init then asks per agent before it writes a hook.

2

Pick your rules

Select the starter rules or your own JSON file. Nothing is asked or denied until you do.

3

Watch it work

crossing-guard console opens the local console: Sessions, Memory, Skills and Governance, with approvals waiting for you.

build from source — Go 1.26 or later, macOS
git clone https://github.com/crossing-guard/crossing-guardcd crossing-guardgo build -mod=readonly -o bin/crossing-guard ./cmd/crossing-guard./bin/crossing-guard init --dry-run

Full build notes on GitHub →

4 agents connected
Claude Code · Codex · OpenCode · Cursor
1 rule document
5 actions, one evaluator
1 local daemon
loopback address by default, a token on every API call
Read the source →

Proof of work instead of a user count.

Never get stuck

Your usage limit resets in five hours.
Your deadline doesn't.

When one agent hits the wall mid-task, the next one starts with the same memory and the same rules. The console drafts a handoff note from the stalled session, you edit it, and it is written into the repository for the next agent to read. How the handoff is built →

How limits work →

When the meter runs out (example)

At limit Claude Max · resets 4h 51m

Continue in Codex → same memory, same rules, plus your handoff note.

For whoever has to answer for it

Honest governance, not a checkbox

A person in the approval

An ask rule holds the tool call in a local approvals inbox. If nobody can be reached, the call is denied. Source →

A record you can check

Each session's event log carries a sha256 hash chain. crossing-guard chain verify recomputes it. Source →

Run it yourself

One binary and one folder, ~/.crossing-guard, on your own machine. uninstall removes the hooks and keeps your data unless you ask it to purge.

We didn't put Open in the name. We put it in the license.

Side by side

Choosing between agents? We ran the same thing on each.

Each tutorial names the versions it ran on and the date it was last verified.

What we ranOn
Hooks and plugins: what fires, and whenClaude Code · Codex · OpenCode
One MCP server, and how each agent reports a broken oneClaude Code · Codex · OpenCode
One skill: where each agent looks, and how to tell it loadedClaude Code · Codex · OpenCode

See all tutorials →

Put a guard at the crossing.

See how it hooks into the agents you already use.