danbauer.net / two-handed-estate

The two-handed estate

Several model families, one set of rules, and a routing table that evidence rewrites.

How I run Claude, Codex, Gemini, a local model and Jev as one estate: how they share rules, how work is routed between them, and where it's headed. Companion to governed agent operations, which covers the gates every lane ends in.

FIG 01 · ONE SET OF RULES, SEVERAL READERS

Every model needs the same rules: what may leave the machine, how secrets are handled, what counts as done. Today they live in a file only Claude reads. There are three ways to share them, and they stack.

flowchart LR
    share_V[("Vault: canonical rules, in git")] --> share_CMD["Global CLAUDE.md"]
    share_CMD --> share_CL["<b>Claude Code</b>"]
    share_O1["Option 1: copy the shared rules<br/>to Codex's global AGENTS.md"] --> share_CX["<b>Codex</b>"]
    share_O2["Option 2: Codex falls back<br/>to each repo's CLAUDE.md"] --> share_CX
    share_RP[("Repo CLAUDE.md files")] --> share_O2
    share_RP --> share_CL
    share_O3["Option 3: one AGENTS.md in the vault,<br/>linked for Codex, imported by CLAUDE.md"] --> share_CX
    share_O3 --> share_CL
    share_V --> share_O3
    class share_V,share_RP store
    class share_CMD,share_O1,share_O2,share_O3 rail
    class share_CL,share_CX core
    classDef core fill:#EAF2FB,stroke:#1667b8,stroke-width:1.5px,color:#16324f
    classDef rail fill:#FFFFFF,stroke:#1667b8,stroke-width:1.2px,stroke-dasharray:5 4,color:#16324f
    classDef gate fill:#0e7a4e,stroke:#0e7a4e,stroke-width:1.5px,color:#FFFFFF
    classDef check fill:#F2FAF6,stroke:#0e7a4e,stroke-width:1.5px,color:#16324f
    classDef store fill:#FFFFFF,stroke:#5b7288,stroke-width:1.2px,color:#16324f

Option 1 now, because no model should run without the publishing and secrets rules. Option 2 on trial, with a log of every time Codex trips on a Claude-only instruction. Option 3 the first time the copies disagree. The single source lives in the git-backed vault, since Codex's own folder isn't backed up.

DWG 02 · THE THREE OPTIONS
OPTION 1 · GLOBAL COPY
OPTION 2 · FALL BACK TO CLAUDE.MD
OPTION 3 · ONE SOURCE
What changes
Codex's global AGENTS.md holds the shared rules.
One config line tells Codex to read CLAUDE.md wherever no AGENTS.md exists.
The shared rules move into one file both tools read.
What Codex gains
The global rules, everywhere.
Each project's rules as well.
Same as option 1, and the copies can't drift.
Cost
Two copies that drift the first time one is edited.
Codex reads instructions written for Claude's tools and may try to follow them.
A one-time refactor of the most important file in the estate.
Risk
Silent drift: Codex follows last month's rules.
Mostly harmless confusion. The project files total under 9 KB against a 32 KB limit.
Claude's own rules fail to load if the import path is wrong.
Undo
Delete one file.
Delete one config line.
Revert one commit.
Effort
Minutes.
One line.
About an hour, plus a test that both tools load the rules.
DWG 03 · ROUTING, IN THEORY

A packet carries its destination; a prompt doesn't. Routing work across models is always two steps: classify the request, then forward it. The forwarding table is the easy part. The classifier has an accuracy number, and when it's wrong nothing errors. The wrong model just answers, fluently.

Data first, then task, then cost. The first question is where the data may go. Private data has two lanes: Claude on this machine, or the local model. Task shape picks a lane after that, and cost picks a tier inside the lane.
The cheapest classifier that's accurate enough. Most routing is a rule: which repo, which file type, a keyword. Next comes Jev, a small model from TypeSafe that returns a typed label or score instead of prose. A frontier model deciding where work goes is the core router working the front desk.
The default row escalates. A request that fits no class goes to Claude with a person watching. On the wire, a packet with no route is dropped and reported. Here, a request forced into the nearest class gets delivered and looks like success.
A second model family is an independent check. Two reviewers from the same family share blind spots. A different family fails differently, so cross-family review catches the quiet misses. That's the strongest reason to run two hands at all.
FIG 04 · THE ROUTING TABLE AS A DECISION PATH
flowchart TB
    route_R["Request"] --> route_D{"Where may this data go?"}
    route_D -- "private" --> route_P{"Task shape"}
    route_D -- "public, or code I'd publish" --> route_T{"Task shape"}
    route_P -- "judgment, writing, rules, ops" --> route_CL["<b>Claude Code</b>"]
    route_P -- "short offline draft" --> route_OL["Local model on CPU"]
    route_T -- "design, writing, or unclear" --> route_CL
    route_T -- "specified build with a test" --> route_CX["<b>Codex</b>"]
    route_T -- "bulk or parallel mechanical" --> route_CC["Codex cloud tasks"]
    route_T -- "free third opinion" --> route_AG["Antigravity free tier"]
    route_T -- "classify, rank, dedupe" --> route_J["<b>Jev</b><br/>typed judgments"]
    route_T -- "fits nothing" --> route_ESC["Claude plus a person:<br/>escalate, don't guess"]
    route_CX --> route_X["Cross-family review"]
    route_CL --> route_X
    route_X --> route_G{{"<b>Gates</b><br/>review squad, human release,<br/>sandbox"}}
    class route_CL,route_OL,route_CX,route_CC,route_AG,route_J core
    class route_X check
    class route_ESC rail
    class route_G gate
    classDef core fill:#EAF2FB,stroke:#1667b8,stroke-width:1.5px,color:#16324f
    classDef rail fill:#FFFFFF,stroke:#1667b8,stroke-width:1.2px,stroke-dasharray:5 4,color:#16324f
    classDef gate fill:#0e7a4e,stroke:#0e7a4e,stroke-width:1.5px,color:#FFFFFF
    classDef check fill:#F2FAF6,stroke:#0e7a4e,stroke-width:1.5px,color:#16324f
    classDef store fill:#FFFFFF,stroke:#5b7288,stroke-width:1.2px,color:#16324f

Sensitivity, then task, then cost. Every lane ends in the same gates, drawn in full on governed agent operations.

DWG 05 · LANES
LANE
TAKES
NEVER TAKES
Claude Code
Anything private; design, writing, rules, homelab operations; the escalation row.
Nothing excluded. It's the default.
Codex
Builds where a test defines done; second-opinion review.
Private repos in cloud mode.
Codex cloud tasks
Parallel mechanical work on public repos.
Anything I wouldn't publish.
Antigravity, free tier
A third opinion on public code.
Private data. The free tier may train on prompts.
Local model
Short drafts that must not leave the machine.
Agent loops. It writes 7.4 tokens a second on this CPU, measured.
Jev (TypeSafe)
Classify, triage, rank, dedupe many items.
Open-ended writing; private data, since it's a cloud API.
FIG 06 · THE ENDGAME · FOUR PLANES, MODELS AS WORKERS

Model names change every few months, and prompt patches tuned to one model over-correct on the next. So the endgame is an estate where models are interchangeable workers, and everything durable lives in planes no vendor owns.

flowchart TB
    end_LAW["<b>Behavior plane</b><br/>one AGENTS.md, skills in a shared format"] --> end_W
    end_MEM["<b>Truth plane</b><br/>the notes vault, served to any model"] --> end_W
    end_GATE{{"<b>Guarantee plane</b><br/>review squad, human release,<br/>sandboxes, hooks"}} --> end_W
    end_W["<b>Work plane</b><br/>Claude, Codex, Gemini, local model, Jev"] --> end_OUT[("Changes, drafts, decisions")]
    end_OUT --> end_EV["<b>Evals</b><br/>planted-flaw suites across model families"]
    end_EV --> end_RT["Routing table rewritten<br/>from measured results"]
    end_RT --> end_W
    end_OUT --> end_GATE
    class end_LAW,end_MEM rail
    class end_W core
    class end_GATE gate
    class end_EV,end_RT check
    class end_OUT store
    classDef core fill:#EAF2FB,stroke:#1667b8,stroke-width:1.5px,color:#16324f
    classDef rail fill:#FFFFFF,stroke:#1667b8,stroke-width:1.2px,stroke-dasharray:5 4,color:#16324f
    classDef gate fill:#0e7a4e,stroke:#0e7a4e,stroke-width:1.5px,color:#FFFFFF
    classDef check fill:#F2FAF6,stroke:#0e7a4e,stroke-width:1.5px,color:#16324f
    classDef store fill:#FFFFFF,stroke:#5b7288,stroke-width:1.2px,color:#16324f
DWG 07 · WHAT CHANGES FROM TODAY
STEP
WHAT IT MEANS
STATE
One set of rules, many readers
Option 3 in place, with skills kept in a format both tools import.
DRAFTED
Memory any model can query
The recall tool exposed as a server, so Codex and Gemini get the same context Claude gets, with the same rule that retrieved notes are data, never instructions.
DESIGN
Gates that don't depend on the tool
Every control that must hold sits where no model can route around it. The push check works for every model because it sits at the git boundary.
RUNNING
A router that's a table
First a small script that suggests a lane from rules and logs the choice. Later, the table gets rewritten from eval results.
DESIGN
Evals as the scoreboard
A new model runs the planted-flaw suites before it gets a lane. It earns routing the way an agent earns autonomy: one narrow lane at a time, taken back on a miss.
DESIGN

Rules, memory, gates and evals are plain files in git. They outlast any vendor, and they let a new model earn trust in a week instead of a quarter. Codex, Antigravity and the local model were installed and tested 2026-10-22.