Featured image of post House rules

House rules

I’ve had a Gemini Pro subscription for about eighteen months. In that time it has researched a leisure battery and a diesel heater for the campervan conversion, generated a truly stupid number of pictures of my pets in hats, and helped me build out a homebrew setting for a D&D campaign that my players still haven’t finished. NotebookLM is genuinely brilliant. The Workspace integration means it can rummage through my own documents without me copying and pasting half of them into a chat box. Money well spent.

Three pets in chef’s hats wrecking a kitchen, with a proverb on a sign behind them

Read the sign on the wall of that kitchen. It says “too many cooks on broth”. Not “spoil the broth”. It’s very nearly a proverb, it’s rendered beautifully, and it is wrong, and I didn’t notice for a good few seconds because it looked exactly like the thing it was supposed to be. Hold that thought, because this whole post is about it.

For writing code, though, it never quite cut the mustard.

That’s not entirely fair, and it’s worth being precise, because there’s a version of this post that’s just a man being rude about a product he pays for. About a year ago I was using the Antigravity IDE, back when I still had a proper desktop to sit at, and it was massively formative. Not because the code it wrote was better than anything else, but because it was the first tool that taught me to work with an agent rather than at a very enthusiastic autocomplete. That shift, from “finish my line” to “here’s a task, go and do it, tell me what you did”, is the whole game. I learned that in Antigravity.

Then I gave the work laptop back. The new job’s replacement laptop isn’t mine to do personal work on, quite rightly, so my primary environment became a headless dev server I reach over SSH. No desktop, no IDE, no window to drag things around in. And in a terminal, Claude Code turned out to be the thing that fit. It became my daily driver almost by accident, having barely used it before.

So: a Gemini subscription I still pay for and use every week, and a Claude subscription doing the actual engineering. Two tools, cleanly separated, no conflict.

Then I ran out of tokens.

Reaching for what you’ve already paid for

A week without quota is a long time. Long enough that I stopped waiting for the reset and looked at what was already sitting in my account, which is when I noticed Google had shipped agy, a CLI in the same shape as Claude Code, riding the subscription I’d been paying for since before I owned a campervan.

It was disappointing. It made mistakes. Some were the sort you catch on the next line, and some sat there waiting until I bothered to look.

Now some of that is the models. Gemini gives me two that matter, 3.5 Flash and 3.1 Pro, and Google will happily tell you 3.5 Flash is the strongest coding model they’ve got. Read that again though. The strongest they’ve got. It beats 3.1 Pro, which is a very different sentence from “it beats what everybody else shipped this month”. Coding has never been where Gemini lives.

And some of it is me. I’d picked up a brand new CLI and driven it exactly like the one I already knew, because it looked like the one I already knew, and at no point did I open its documentation to find out what it could actually do or how to point it at the right model for the job I was giving it. RTFM. I have said that to other people, out loud, more than once. I got round to taking my own advice about a week later, by which time I’d spent a fair while blaming the tool for a decent share of my own idleness.

Lesson learned. Again.

Where it does earn its keep, mind, is ideation. I set it loose on krites, my photo culling tool, and told it to dream up features and redesign the interface. I wasn’t after accuracy. I wanted creative flair, and Gemini’s multimodal chops made that quick and clean. It came back with thirty-three feature ideas and eight interface concepts in an evening. Most of them were wrong. Several very much weren’t. That’s a respectable evening by anyone’s measure, and it’s the job agy does around here now.

Which left me with no tokens for Claude, and an agent I’d just adopted that couldn’t move the actual projects along. So I had a punt on codex. Twenty dollars, on the strength of what people had been saying about GPT-5.5, and because Anthropic’s Max plan is a number I can’t look at with a straight face for what is, after all, a hobby. It was the right call. Claude is still the daily driver, tokens permitting. But codex is a proper fallback now, and more useful than that, a second opinion. It reviews Claude’s work. Claude reviews its work right back.

Three agents. One repository.

Three guests, one hallway

The problem, when it came, had nothing to do with the models.

Every one of these tools wants to be told how the project works. What the commit conventions are. That we use just and not make. That specs live in docs/development/specs/ and you don’t write code until one is approved. That there is no AI attribution in commit messages, ever, because the human who approves the commit owns it entirely. That we’re pre-1.0, so a BREAKING CHANGE: footer will cause the release automation to cheerfully cut a v1 we are not ready for.

That’s 243 lines of hard-won house style. I had it in a CLAUDE.md, where Claude reads it. And now two more agents had walked through the door with no idea about any of it.

You know the sign. The one in the front hallway of a certain kind of house, usually wooden, usually in a font somebody’s aunt chose.

  1. Take off your shoes
  2. Clean up after yourself
  3. Mum is always right

Nobody hands each guest a personalised laminated rulebook on the doorstep. There’s one sign, everyone reads it, and the rules are the rules whether you’re family or you’ve come to fix the boiler. Standardisation is the only thing that makes a house with guests in it survivable.

So the instructions came out of CLAUDE.md and went into an AGENTS.md, which is the name codex and agy both look for without being asked. The sign went up in the hallway.

The adapter is not a wart

My first instinct was that CLAUDE.md should now die. One file, one truth, and Anthropic should get with the programme and read AGENTS.md like everybody else.

I’ve changed my mind, and the reason is sitting in the same repository, in a completely different refactor, that I was working on the same week.

We’re pulling go-tool-base apart. Not breaking it up, just loosening it, so the genuinely reusable bits can leave without dragging the entire framework out of the door behind them. So each package now owns a little typed struct that says, plainly, here is what I need in order to run: a timeout, an endpoint, a token. And the framework keeps a small file sitting next to it, config_adapter.go, whose whole job is to take the framework’s own sprawling config object and fill that struct in. The package holds the shared truth. The adapter is thin, it’s local, and it exists precisely so the package never has to know the framework is there at all.

Look again at what CLAUDE.md is now. AGENTS.md holds the shared truth. CLAUDE.md is a small local file that exists so I can give Claude an instruction the other two would only find confusing, without that instruction leaking into the shared file. Codex has somewhere to put its quirks. agy has somewhere to put its quirks.

It’s the same shape. Extract the core, leave a thin adapter at the border.

I’d love to tell you I saw that symmetry coming and designed it in. I didn’t. My head was in that space already, and the dots joined themselves while I was thinking about something else. That’s usually how it goes, and I’d rather admit it than pretend to a grand plan.

So no, the per-agent file isn’t a wart. It’s the adapter, and the other vendors should consider growing one.

The sign nobody read

There is a hole in this, and it’s mine.

I asked agy to leave CLAUDE.md behind as a pointer to AGENTS.md, with a file reference include, which I was fairly sure was possible. What it wrote was this:

> **Note:** The core agent instructions have been consolidated for use across all our
> AI tools (Claude, agy, codex).
> Please read and follow the instructions in [`AGENTS.md`](AGENTS.md) for all general
> development workflows, architecture guidelines, and commit conventions.

Which looks fine. Reads fine. It is, in fact, a polite request in prose with a hyperlink attached, and it is not an include of anything.

Too many cooks on broth.

Claude Code reads CLAUDE.md. It does not read AGENTS.md, and a markdown link is not a loading instruction, it’s a hint the model may or may not act on. There is a real import syntax, a bare @AGENTS.md on its own line, which expands the file into context when the session starts. I’d guessed right that it existed. It was documented the whole time. The agent didn’t use it, and I didn’t check.

RTFM, it turns out, is a lesson you get to learn twice in the same fortnight.

So for three days, agy and codex walked into the hallway and read all 243 lines of the sign, and Claude, the agent the original file was named after, walked in and read eight lines of a note telling it there was a sign somewhere.

I proved it in the end by asking a fresh session for a string that only exists in AGENTS.md. With the link: not found. With the import: found. One line, one merge request, and the guest can see the sign.

Now, I’ve written before that a CLAUDE.md is source code and the agent is its interpreter. I meant it as a warning about what an attacker could put in one. It cuts the other way too. If it’s source code, then a link where an import belongs isn’t a typo in a document, it’s a missing import statement at the top of a file. The program still runs. It just doesn’t have the thing it needed, and nothing tells you.

Only human

Whose fault?

Mine, of course. Not agy’s for writing plausible markdown. Not Anthropic’s, though I’d happily take an AGENTS.md read by default.

I have been caught out before by an agent’s confidence in its own ability, and I’ll be caught out again. It’s the same way you get caught out by a keen junior engineer: they tell you it’s done, they believe it’s done, they have every reason to think it’s done, and they are wrong in a way that only shows up later. The failure isn’t theirs. The failure is that I didn’t go and check the maths.

Except a junior is a senior who hasn’t happened yet. Give one two years and they’ll be checking your maths. This one won’t. Next week it will make the same class of mistake with exactly as much confidence, and the only thing standing between that and my main branch is whether I could be bothered to look.

Three agents in tandem takes a lot of oversight. There’s a lot of knowledge that has to move between them, and unguarded mistakes can and will happen. Standardisation is the only lever I’ve got, at least until the providers agree a common standard between themselves. Until then I make do, if only to avoid typing out the same instructions for every guest who walks in.

The thirteen I couldn’t import

I’ll leave you with the bit I haven’t solved.

The sign in the hallway says “read the house rules”, but it also says “and the detailed procedures are through there”. Those procedures are skills: how to draft a spec, how to verify before a merge request, how to write a conventional commit. I already publish them, as a plugin marketplace, because I’d rather write them once.

Claude can install them from there. agy and codex can’t reach it. So there are now fourteen skill files sitting inside the repository, thirteen of which are copies of something I already publish somewhere else, checked in so that the other two guests can read them.

I’ve spent a fortnight taking a framework apart so that its packages could be imported instead of carried around. And then, one floor up, I copied thirteen files into a repo because I had no way to import them.

I haven’t the faintest idea what the fix looks like yet.

Built with Hugo
Theme Stack designed by Jimmy