CLAUDE.md Is the Steering Wheel
One markdown file at the repo root turns scattered AI help into a fleet that stays on-rails. How CLAUDE.md encodes the house rules every agent reads before it touches a line.

Scattered AI help is a liability. Ask an agent to "add a query" ten times and you get ten styles, ten import conventions, ten guesses about where files live. The fix isn't a better prompt each time — it's one file the agent reads before every task. In this repo that file is CLAUDE.md, and it's the closest thing the build has to a steering wheel. This is part of the Building with AI series.
Standing orders, not a one-off prompt
A prompt is advice you give once. CLAUDE.md is advice the agent re-reads on every run, checked into the repo next to the code it governs. It lives at the root, and in a monorepo each app can add its own scoped file that layers on top. Mine is short and blunt — rules, not prose:
1# House rules (read before every task)
2
3- Package manager is **pnpm**. Never emit npm/yarn commands.
4- Data access goes through `packages/service`. Components never import
5 `@sanity/client` directly.
6- Types are generated (`pnpm typegen`) — never hand-write a type that
7 mirrors the schema.
8- Every new query gets a groqd schema and a test in the same PR.
9- Prefer the smallest diff that passes `pnpm turbo typecheck test`.None of these are clever. They're the decisions I got tired of re-explaining. Writing them down once turned "please use pnpm" from a thing I said into a thing the repo enforces.
Boundaries beat reminders
The rule that paid off most is the second one: components never touch the Sanity client. It sounds like style policing, but it's really an architectural boundary that keeps the dependency graph acyclic — the same idea I lean on hard in Layer Contracts. When the boundary is written down, the agent stops trying to be helpful in the wrong place.
A guardrail an agent reads every time beats a correction you give it once.
You can feel the difference in the diffs. Before the boundary was explicit, an agent "fixing" a page would reach straight into the CMS client to grab one extra field. After, it adds the field to the service query where it belongs, and the type flows out to the component for free.
Make the rules checkable
Rules the agent can verify are worth ten it can only nod at. So the last line points at a command, not a vibe. Every task ends the same way, and the agent isn't done until it's green:
1{
2 "scripts": {
3 "typecheck": "turbo run typecheck",
4 "test": "turbo run test",
5 "verify": "turbo run typecheck test lint"
6 }
7}pnpm verify is the sentence at the bottom of CLAUDE.md made executable. The agent runs it, reads the failures, and fixes them before handing back — which means most of what reaches me already compiles and passes. Reviewing that output honestly, with fresh context, is its own discipline: Nothing Merges on Vibes.
Treat it like code
CLAUDE.md isn't write-once. When an agent makes the same wrong assumption twice, that's a missing line, and I add it. When a rule stops being true — a package moves, a convention changes — I update it in the same PR as the change. It reviews like code, drifts like code if you ignore it, and pays off like code when you don't.
One file, re-read every task, is worth more than a hundred perfect prompts. The steering wheel doesn't make the car faster; it makes the speed safe to keep. Next: the first thing the agents and I actually designed together — Designing the Content Model by Conversation.
