Two humans and an agent
AstroAnsh v2 is a Vedic astrology platform: Next.js App Router, MongoDB, WhatsApp OTP auth through AiSensy, Cashfree for payments, images on Cloudflare R2, ISR deploys, and admin and super-admin dashboards. Two of us build it, and Claude Code sits in both our terminals. That last part is what forced the subject of this post into existence.
The drift
Solo habits do not survive a second person
Working alone I never needed conventions, because I was the convention. Every naming decision, every folder, every idea of what the agent could do without asking lived in my head, and my head was always in the room.
On v2 the drift showed up fast. One of us named route folders kebab-case, the
other PascalCased them. Data fetching split three ways: server components
fetching directly, a stray SWR hook, and one useEffect fetch that should
never have existed. Commit messages ranged from conventional-commits to a
single word.
Claude Code did not cause any of this. It amplified it. The agent learns the preferences of whoever it is pairing with that session and none of the previous person's, so it produced a faithful copy of each of our inconsistencies in turn, faster than we could.
The sharpest disagreement was autonomy. To me, the agent refactoring a component unprompted was the point of having it. To my teammate, watching it rewrite part of the Cashfree webhook handler on its own initiative was alarming — and they were right, because that file moves money and mine merely moved markup. We were not disagreeing about the agent. We were disagreeing about a line neither of us had ever drawn.
The doc we should have written on day one
The fix was boring: a CLAUDE.md-style conventions file at the repo root, read by the humans and loaded by the agent at the start of every session. Writing it was mostly transcription — every rule in it was something one of us had already said out loud, usually more than once.
It settled into five sections. File and folder structure, so a feature's route, components and server actions always land in the same places. Naming, which is three lines and ended the largest number of arguments:
- Route folders: kebab-case (app/kundli-report/)
- Component files: PascalCase, one component per file
- Server actions: verb-first, in _actions.ts beside the route
State and data fetching: server components fetch, mutations go through server
actions and revalidate their ISR path, and client state exists only for what
the browser genuinely owns. Git: conventional commits, branches named
feat/… or fix/…, and a PR describes behaviour rather than listing files.
And then the section that earned the whole file its keep.
The important part
The line between acting and asking
We wrote down, explicitly, where Claude Code should just do the work and where it must stop and confirm with a human first. This is the part of the doc I had never seen in anyone else's conventions, and the part I would now write first:
## Act, then mention it in the PR
- Component refactors with no behaviour change
- Copy and spelling fixes
- Moving a file to where the structure rules say it lives
## Stop and confirm with a human first
- Any schema change, including "just adding a field"
- Anything under payments/ — Cashfree webhooks, order state, refunds
- Auth and OTP flows, including the AiSensy templates
- Any new read or write of user data
If a change is local and reversible, act. If it touches money, identity or stored user data, ask.
An agent that asks about everything is a chatbot, and an agent that asks about nothing is a liability. The doc is where the team agrees on the boundary, once.
The payment-claim flow has its own post on this blog, and it is also the code I least want an agent quietly improving on a Friday evening. Writing the boundary down means none of us has to enforce a private version of it in every session.
What changed
The drift stopped, mostly because it stopped regenerating. The agent now produces the same shapes for both of us, so a diff no longer reveals whose terminal it came from.
Reviews got faster in a way I did not expect: with the style questions settled by the file, review comments are about the change itself, and there are fewer of them. We also stopped paying the re-explanation tax — sessions start from the doc rather than from ten minutes of describing how we do things here.
The doc turned out to have a lifecycle of its own. When a review comment gets made twice, it graduates into a line in the file and never needs saying again. Which is the thing I actually learned: the conventions file is not for the agent. It is the team's memory, written down at last — the agent just reads it faster than we do.
