Six agents, one repo, and the 225 KB file that kept tripping them
I run four to six Claude Code sessions against this repo at once, from my phone. They kept crashing, burning tokens, and concluding they were 2–3 commits behind main. The diagnosis surprised me: the agent instructions file itself had become a 55,000-token tax and the #1 merge hotspot. A build log about the annoyance, the diagnosis, and the three boring fixes that ended it.
Lately I run this site from my phone. Four, five, sometimes six Claude Code sessions at once from the Android app — one getting a plan approved, one pushing a PR, one whose PR I just merged from the couch. It is genuinely fun, a little absurd, and it worked great right up until it didn't: sessions started stalling mid-task, burning tokens on nothing visible, and then — after a long, expensive pause — proudly announcing they were 2–3 commits behind main. This is a build log about why that kept happening and what finally fixed it.
The annoyance
Main on this repo moves fast — twenty-seven commits a day on average, sixty-three in one recent twenty-four-hour stretch, nearly all of it merged Claude branches. Run several sessions in parallel against that and a pattern emerges. A session branches off main, works for an hour, opens its PR — and discovers the world moved. Then comes the expensive part: instead of shrugging, the session treats "behind main" as an emergency. It rebases, hits the same conflict again, re-fetches, tries again. The git history started filling with merge commits like "resolve ADDON_CATEGORIES conflict: keep both" — two PRs that had each appended one entry to the same registry file, colliding on adjacent lines while being completely unrelated. Meanwhile other sessions were quietly dying a different death: long sessions would slow down, compact their context, slow down again, and eventually fall over. Crashes, token burn, and stale branches looked like three problems. They were one.
The diagnosis
The culprit was the agent guide itself. CLAUDE.md — the instructions file every Claude Code session loads before doing anything — had grown the way these files grow: every shipped surface appended its own deep-dive section, and nothing ever left. By last week it was 2,879 lines, about 225 KB — roughly 55,000 tokens. Every session paid that toll at startup. Worse, every time a long session compacted its context, the whole file got injected again. That was the "crashing": context exhaustion with a paperwork smell.
And the same file was the number-one merge hotspot. Because every feature PR appended a section to it, any two concurrent PRs conflicted there — on adjacent lines, about unrelated features. The registry files (NavMenu rows, the command palette list, the add-ons catalog, the redirects) were hotspot number two, and their conflicts resolved the same way every single time: keep both. The third finding was softer but just as real: being behind a fast-moving main is physics, not failure. Nothing had ever told the sessions that.
The fix, in three moves
The manual went on a diet. Twenty-four per-surface deep-dives moved verbatim — byte-diff-verified, nothing rewritten — into docs/surfaces/<name>.md, and the env-var table into its own file. CLAUDE.md is now a 256-line core: the stack, the commands, the guardrails, and a domain map where every route points at its doc. Sessions read the deep-dive for the surface they are actually touching, on demand. The context tax dropped about ninety percent, and the convention going forward is the part that keeps it fixed: a new surface documents itself in a new file plus one table row. Nobody appends to CLAUDE.md anymore, so concurrent PRs stopped having anything to fight over there.
Sessions sync themselves now. A SessionStart hook fires on startup, resume, and compaction: it fetches origin/main, and if the working tree is clean it just merges it in. On conflict it aborts and names the files; if the tree is dirty it reports how far behind you are and which hotspot files moved upstream, then gets out of the way. Up to date means total silence — zero context spent. Sessions start fresh instead of discovering staleness at PR time, which was the most expensive possible moment to find out.
The physics got written down. The new core has a short "Concurrent sessions & branch hygiene" section: behind-but-mergeable is normal — merge origin/main once, right before opening the PR, and never loop rebases mid-task. Registry conflicts are almost always two PRs appending entries: resolve keep-both and move on. It is maybe fifteen lines, and it converts a panic spiral into a one-step routine.
It tested itself on the way in
The PR carrying all this got to demonstrate the problem it was solving, live, three times. The hook — running for the first time in the very session that wrote it — auto-merged ten commits that had landed under me before I'd finished the branch. Then, in the few hours the PR was open, four other PRs merged sections into the old CLAUDE.md, conflicting with the split twice. Both times the resolution was exactly the recipe now documented in the repo: keep the slim core, move the upstream additions verbatim into their surface doc, verify byte-for-byte that nothing was lost. The third conflict was resolved from a phone screenshot of GitHub's "branch has merge conflicts" banner. If you wanted proof the old file was a contention point, the PR that deleted it collected three conflicts in one afternoon.
What I deliberately did not build
A few tempting options lost on purpose. A bot that auto-updates open PR branches when main moves sounds great until it pushes to a branch a live session is mid-push on — then they fight, and you have more reconciliation churn, not less. A .gitattributes union merge driver would "solve" the keep-both conflicts by silently producing broken JavaScript — duplicate keys, missing commas — which is worse than the conflict. And GitHub's merge queue is the grown-up answer for repos like this, but it is deferred: the three changes above may make it unnecessary, and I would rather measure first. The boring fixes — make the shared file small, sync early, write the norms down — were the whole game.
Get the next one
An occasional note when something genuinely new ships here — essays, free tools, projects. No schedule, no filler, easy out.
Need something like this built?
I design and ship AI tools, full-stack apps, and data pipelines — end to end, to production. Tell me the problem in a sentence; I'll give you an honest read on fit within a day.
Work with me →