# One memory, many harnesses: AGENTS.md, guard scripts, model router
> [!summary] TL;DR
> One `AGENTS.md` serves Claude Code, pi, and codex: `CLAUDE.md` is a symlink to it, pi reads `~/AGENTS.md` natively, codex reads a symlink at its config path, Claude Code imports it with one line, `@~/AGENTS.md`. One set of guard scripts enforces the same policy (no edits on `main` outside a worktree, ever) in all three. A model router with deep, cheap, and auto profiles decides which model does the work. The habits (plan first, fresh sessions, write it down) stay above any single harness.
## Key points
- `CLAUDE.md` is a symlink pointing at `AGENTS.md`. [AGENTS.md](https://agents.md) is an open convention ("a README for agents," stewarded under the Linux Foundation).
- Each agent gets the same file through its own door: [pi](https://pi.dev) reads `~/AGENTS.md` natively, codex reads a symlink at its own config path, Claude Code imports it from the global `CLAUDE.md` with a one-line `@~/AGENTS.md`.
- The rules live exactly once: coding style, security posture, git workflow, the worktree policy from [[resources/documentation/Agents/Agents - One Workstream per Task|Part 2]], and every correction I have caught myself making twice. The vendor-named file is an entry point, not a source of truth.
- At the top of `AGENTS.md` sits a five-clause working agreement, priority-ordered: ask don't assume, right-size the solution, stay in scope, flag uncertainty, suggest better ways.
- A small CLI called `recall` indexes the transcripts of Claude Code, codex, pi, and Claude Desktop into one searchable store: full text, BM25 ranking, a bias toward the recent. Three weeks in, the index holds 885 sessions and just under twenty thousand messages.
- The load-bearing guard: no edits on `main` or `master` outside a worktree, ever. Before the guard existed, a long agent session would occasionally land a commit on `main` by accident; one hook deleted the entire failure mode.
- In Claude Code the guard is a `PreToolUse` hook; in pi a small TypeScript extension that intercepts the write tools and shells out to the same script; in codex, the same script again. One law, three courthouses. The guard scripts have their own tests, because a broken hook blocks all three agents simultaneously.
- pi has no permission popups by design, so the guard script is not a second layer of defense there; it is the layer.
- Claude Code is batteries-included (plan mode, permission prompts, compaction, subagents, skills, a diff panel). pi ships almost none of that on purpose: no built-in MCP, no subagents, no plan mode, no permission popups; you add what you need as TypeScript modules, and what you don't add doesn't exist.
- `af` treats the harnesses as interchangeable providers behind one interface (ADR-043). Claude launches with a deterministic `--session-id` and has a skip-permissions flag only allowed inside sandboxes; pi launches bare, resumes with `--continue`, and has no such flag at all.
- codex is a retired key: still configured, still symlinked into the shared memory, last used as a driver in May; it survives as a cross-model second opinion behind an MCP server.
- The model router runs three profiles (deep, cheap, auto). Keywords escalate: "security" or "deploy" routes deep, "typo" or "lint" routes cheap. A per-session budget caps spend at ten dollars. On rate limits it degrades to local models under Ollama: slower, free, always on.
- Subagents are tiered: planners and reviewers get the big model, workers the middle one, scouts the small one.
- The router has no loyalty: pi's default model is not an Anthropic one, while heavy review work still routes to Claude models.
- Logs: fifty-one plan-mode approvals in the last week, and the single most common opening prompt across history is, verbatim, "Implement the following plan:".
## One memory: AGENTS.md and the recall index
The `CLAUDE.md` symlink exists out of plain laziness: maintaining three copies of "don't commit to main" in three vendor dialects was never going to happen. Each agent gets the same file through whatever door it prefers:
- pi reads `~/AGENTS.md` natively
- codex reads a symlink at its own config path
- Claude Code imports it from the global `CLAUDE.md` with a one-line `@~/AGENTS.md`
The rules live exactly once: coding style, security posture, git workflow, the worktree policy from [[resources/documentation/Agents/Agents - One Workstream per Task|Part 2]], and every correction I have caught myself making twice. [[resources/documentation/Agents/Agents - Plan First, Fresh Sessions, Write It Down|Part 1]]'s rule about promoting repeated chat corrections into files applies across agents, not per agent. At the top sits a five-clause working agreement, priority-ordered: ask don't assume, right-size the solution, stay in scope, flag uncertainty, suggest better ways.
Memory also flows the other way. A small CLI called `recall` indexes the transcripts of all of it (Claude Code, codex, pi, and Claude Desktop) into one searchable store: full text, BM25 ranking, a bias toward the recent. "What did I decide about the retry backoff" is one query across every agent it was ever discussed with, which is the point: the conversations belong to the user, not to whichever harness hosted them. Three weeks in, that index holds 885 sessions and just under twenty thousand messages.
## One set of guard scripts: no edits on main
The load-bearing policy holds no matter which agent is driving: no edits on `main` or `master` outside a worktree, ever.
The rule has a scar behind it: before the guard existed, a long agent session would occasionally land a commit on `main` by accident. One hook deleted the entire failure mode.
- In Claude Code, the guard is a `PreToolUse` hook calling a guard script.
- In pi, it is a small TypeScript extension that intercepts the write tools and shells out to the same script.
- In codex, the same script again.
One law, three courthouses. When the policy changes, one file of bash is edited and every agent obeys at once, which is also why the guard scripts have their own tests: a broken hook blocks all three agents simultaneously; that is production code whether anyone likes it or not.
This matters more for pi than for the others, because pi has no permission popups by design. The guard script is not a second layer of defense there; it is the layer.
## Claude Code vs pi: furnished apartment, well-plumbed empty one
Claude Code is batteries-included: plan mode, permission prompts, compaction, subagents, skills, a diff panel. pi ships almost none of that, on purpose. Its site says "There are many agent harnesses—but this one is yours," and the design language is primitives, not features: no built-in MCP, no subagents, no plan mode, no permission popups. You add what you need as TypeScript modules, and what you don't add doesn't exist.
Claude Code is a furnished apartment. pi is a well-plumbed empty one. Keys to both are kept.
`af` from [[resources/documentation/Agents/Agents - One Workstream per Task|Part 2]] treats them as interchangeable providers behind one interface (ADR-043), and the seams show exactly where the philosophies differ. Claude launches with a deterministic `--session-id` and has a skip-permissions flag only allowed inside sandboxes; pi launches bare, resumes with `--continue`, and has no such flag at all, because approvals are its own internal business. codex, the third key on the ring, is honestly a retired key: still configured, still symlinked into the shared memory, last used as a driver in May. It survives as a cross-model second opinion behind an MCP server rather than a seat at the table.
Real differences, all of them below the habit layer. Plan first, fresh sessions, write it down: none of that cares which binary is running.
## The model router: deep, cheap, auto
The pi setup runs a model router with three profiles: deep, cheap, and an auto mode that picks between them. Keywords escalate: "security" or "deploy" routes deep, "typo" or "lint" routes cheap. A per-session budget caps spend at ten dollars. When a provider rate-limits, the router degrades to local models running under Ollama: slower, free, always on. Subagents are tiered the same way: planners and reviewers get the big model, workers the middle one, scouts the small one.
The router has no loyalty. As of writing, pi's default model is not an Anthropic one, while the heavy review work still routes to Claude models. That is the point: habits stay put while providers rotate underneath them.
## Where each harness wins
- Engineering: Claude Code, running its plan-then-execute model split (a big model argues about direction, a cheaper one types), because plan mode plus the review loop is still the best thinking surface I have used.
- Vault synthesis, dotfiles work, and any day of changing how the harness itself behaves: pi, partly because open-ended questions like "what does my Q2 journal say about energy management" benefit from a different model's perspective, and partly because changing pi is a TypeScript file, not a feature request.
This division was earned the slow way. For a while all three agents ran the same kinds of tasks, and the context fragmented into three half-memories of every decision. One lane per agent fixed what no amount of configuration had.
A postscript that proves the theme: Part 1 of this series was drafted with Claude Code's Explanatory output style. Between drafting and publication, the standalone `/output-style` command was deprecated and removed (gone in v2.1.91; it is a settings field now). A post in this series aged out of a command before it aged into print, which is most of the argument for keeping habits one level above anyone's feature list.
## FAQ
### Can Claude Code and pi share one memory file?
Yes. Point `CLAUDE.md` at `AGENTS.md` (a symlink), import it from the global `CLAUDE.md` with a one-line `@~/AGENTS.md`, and let pi read `~/AGENTS.md` natively and codex read a symlink at its config path. The rules live exactly once.
### What is AGENTS.md?
An open convention for agent instructions, "a README for agents," stewarded under the Linux Foundation. It does not care which agent is reading it.
### How do you stop agents committing to main?
A guard script that blocks edits on `main` or `master` outside a worktree, wired in as a `PreToolUse` hook in Claude Code, a TypeScript extension intercepting write tools in pi, and the same script in codex. pi has no permission popups, so there the guard script is the only layer.
### What are the five clauses of the working agreement?
Priority-ordered: ask don't assume, right-size the solution, stay in scope, flag uncertainty, suggest better ways.
### How does the model router pick a model?
Three profiles: deep, cheap, and auto. Keywords escalate: "security" or "deploy" routes deep, "typo" or "lint" routes cheap. A per-session budget caps spend at ten dollars, and on rate limits the router degrades to local models under Ollama.
### How are subagents tiered by model?
Planners and reviewers get the big model, workers the middle one, scouts the small one.
### What happened to Claude Code's /output-style command?
It was deprecated and removed between drafting and publication of Part 1 of this series (gone in v2.1.91; it is a settings field now). Habits should stay one level above any single harness's feature list.
## Related
- [[resources/documentation/Agents/Agents Workflow|Agents Workflow]] (series hub)
- [[resources/documentation/Agents/Agents - Plan First, Fresh Sessions, Write It Down|Plan First, Fresh Sessions, Write It Down]] (part 1: the habits that run above the harness)
- [[resources/documentation/Agents/Agents - One Workstream per Task|One Workstream per Task]] (part 2: workstreams and ADR-043's one interface)
- [[resources/documentation/Claude Focus Workflow]]
## Sources
- [AGENTS.md](https://agents.md)
- [pi](https://pi.dev)
- [ADR-043: agent providers](https://github.com/kakkoyun/af/blob/main/docs/adr/043-agent-providers.md)