Eliminate the Re-Explain Tax: How an Owned Repo Powers Efficient Coding Agents
A coding agent that can read your repo and edit it like a junior engineer with infinite patience was the enable we waited a decade for. Claude Code, Cursor, the long tail — they will rewrite a controller, write a migration, refactor a hook across forty files without breaking eye contact. The work that ate a Tuesday now fits between two espressos.
The friction is not in the agent. The friction is in the handoff. Every fresh session starts blind. You open a tab, paste your stack, paste your conventions, paste the three commands you actually run, paste the gotchas — and only then do you get a useful edit. Repeat tomorrow in a new branch, repeat next week on a new feature, and the meter is running the whole time you are typing what you have already typed.
That re-explain is not a bug. It is the absence of a layer.
The blind session, priced in tokens
A warm agent session with full repo context reads roughly fifty thousand to one hundred and fifty thousand tokens before the first reply. Most of that is your own code, your own config, and the implicit conventions your codebase already encodes. You paid for it once when you wrote the code. You are paying for it again every time you spin up a session.
The session that begins with you typing "schema lives in db/schema.ts, never write raw SQL, run migrations with bun db:migrate, the user table is the source of truth for auth" has already cost you two thousand to four thousand tokens of boot text before the agent has done a single useful thing. Multiply by the eight to twenty sessions a real engineer runs in a week, and the boot text alone is a meaningful fraction of your monthly spend.

The agent does not know any of this on its own. It is not supposed to. The repo knows. The repo is the only thing that survives the session.
What an owned repo does that a sandbox cannot
A sandbox — a chat tab, a one-off canvas, a Replit-style playground — is a session with amnesia. It has whatever you typed into it, the files it just touched, and nothing else. The moment you close it, the context evaporates. The next session starts at zero.
An owned repo is the opposite. It is persistent context. It carries the schema, the conventions, the scripts, the test commands, the deploy pipeline, and the gotchas that took you a quarter to learn — encoded in files that survive every session boundary. The agent does not need to be told. It can read.
The flip is small and it is everything. Instead of pasting two thousand tokens of boot text into a chat, you write a single file at the repo root that says the same thing — once — and the agent reads it on every session for free.
11 production screens. Login, database, payments — all wired.
The SaaS Dashboard Kit ships everything already connected. Nothing to set up. Live demo at saas.otf-kit.dev.
The four files that collapse the tax
A repo that boots warm for any agent, today, has four pieces in roughly the same place. None of them are exotic.
# 1. The repo brain — read by every agent, every session
CLAUDE.md
# 2. The Cursor-specific mirror (Cursor ignores CLAUDE.md by default)
.cursorrules
# 3. The prompt library — tested recipes the agent can pick from
ai/prompts/
# 4. The human-facing conventions doc — same content, prose form
docs/conventions.mdCLAUDE.md is the workhorse. It is plain markdown, lives at the root, and is the first file Claude Code reads on every session. A tight version is two to three thousand tokens and pays for itself in the first reply.
# Project brain
## Stack
- Bun runtime, TypeScript strict.
- Server: HTTP routes under `server/routes/`, one file per resource.
- DB: schema in `db/schema.ts`. Never write raw SQL. Migrations: `bun db:migrate`.
- Auth: session-cookie only, never JWTs. `server/auth/` is the source of truth.
- Tests: `bun test`. One test file per source file.
## Conventions
- All money is integer cents. Never floats.
- All times are unix ms in the DB, ISO strings at the API edge.
- Errors throw `AppError(code, message, status)`. Never return `{ error: ... }` directly.
- Every route exports a `zod` schema named `<route>Schema`.
## Gotchas
- Do not import from `src/`. Use the alias `@/`.
- The Stripe webhook is idempotent — never re-run side effects.
- Background jobs live in `server/jobs/` and use the queue in `server/queue.ts`.
## Commands I actually run
- `bun dev` — local server on :3000
- `bun db:migrate` — apply pending migrations
- `bun test` — full suite
- `bun typecheck` — strict tsc, no emitThat single file replaces the two-thousand-token boot paste. .cursorrules is the same content, JSON-wrapped, because Cursor ignores CLAUDE.md by default. Keep them in sync with a small script — the content is identical, only the wrapper changes.
A tested prompt beats an improvised one
ai/prompts/ is the recipe folder. Each prompt is a tested, named instruction for a recurring job: write a migration, scaffold a route, refactor a hook, generate a test, draft a release note. The agent reads the prompt, follows it, returns the diff. You are not inventing the instructions every session — you wrote them once, you ran them, you know they work.
<!-- ai/prompts/scaffold-route.md -->
# Scaffold a CRUD route
Given a resource name and a zod schema, generate:
1. `server/routes/<resource>.ts` — POST, GET, PATCH, DELETE handlers.
2. `<resource>Schema` exported and registered in `server/routes/index.ts`.
3. A test file at `server/routes/<resource>.test.ts` with the four happy-path cases.
4. A migration if the schema introduces a new table.
Constraints:
- Use `AppError` for every failure path.
- All money as integer cents.
- No raw SQL — go through `db/queries/<resource>.ts`.
Return: the diff. Do not explain.The agent picks this prompt by name. You wrote it once. The cost of running it is the cost of the diff, not the cost of re-negotiating the instructions.
What OTF puts in the box
SaaS Dashboard, Fitness, Booking — every paid kit ships the four files already populated, not as documentation but as load-bearing parts of the project. You own the code; the kit ships the CLAUDE.md, the .cursorrules, the docs/conventions.md, and twenty-plus tested prompts in ai/prompts/ that go with it.

The point is not that the kit knows how to talk to the agent. The point is that the kit is the context. When the model behind Cursor or Claude Code changes next month — and it will — the repo does not change. The conventions stay. The prompts stay. The four files stay. The next model reads them on the first reply and is warm by the time you have typed the first word of your request.
OTF is the durable layer underneath the tool churn. Use the agent — and the kit's context layer means the agent is warm before you are.
The loop, before and after

Before: open tab, paste stack, paste conventions, paste gotchas, paste commands, ask for the edit, wait. The agent is useful on reply three. The meter has been running since reply zero.
After: open tab, ask for the edit, wait. The agent reads CLAUDE.md on the way in. Reply one is useful. The meter starts when the work starts.
The savings are not in any single session. They are in the hundred sessions a real engineer runs in a quarter, every one of which now skips the two-thousand-token boot paste, skips the re-negotiation of conventions, skips the part where you explain for the fourth time this month that money is integer cents.
Closing
The re-explain tax is not the agent's fault and it is not your fault. It is the missing layer between them. A repo that encodes its own conventions in four files is the cheapest, most portable, most durable context layer we have — and it survives every model swap, every IDE change, every vendor pivot. Write the four files once. The agent reads them forever.
Ship the product, not the setup.
- 11 production screens — auth, billing, team, analytics, settings
- Real database, payments, and login — all wired on day 1
- AI configs pre-tuned so your agent extends instead of regenerates