Working with AI on a codebase you didn't write

CLAUDE.md, context files, repo conventions. How to teach an agent your codebase so it stops hallucinating its way through your patterns.

7 min read·Updated Apr 28, 2026

AI is great at writing idiomatic code. Your codebase is not idiomatic, it's specific. The model writes for the public average, and your repo is a thousand small deviations from that average. Closing that gap is the difference between AI as a teammate and AI as an annoyance you have to clean up after.

The whole skill of using AI in a real repo is teaching it the deviations.

The mental model

Think of the AI as a fast, talented engineer who joined your team yesterday. They will write good React, good Python, good Go. They will not write your team's React, Python, or Go. Not yet. They don't know that fetch is wrapped in a custom client, that errors are returned not thrown, that there's a useFeatureFlag hook nobody uses anymore but the model keeps suggesting because Stack Overflow loves it.

Your job for the first week of working with them is to teach. Same as any other new hire, except this one forgets everything between sessions unless you write it down.

CLAUDE.md and context files

The single highest-leverage move is a plain-text file at the root of your repo that the AI reads first. Cursor calls it .cursorrules, Claude Code reads CLAUDE.md, Cody has its own variant. Same idea everywhere.

What goes in it:

  • The frameworks and major libraries you use, and the ones to never propose. ("We're on TanStack Query v5. Do not suggest SWR or RTK Query.")
  • Conventions: how you handle errors, how you log, where tests live, how files are named, how routes are organized.
  • Patterns to copy: pointers to two or three exemplary files in the repo. "When writing a new API route, follow src/api/users.ts. When writing a new component, follow src/components/InvoiceCard.tsx."
  • Things to never do: no custom client wrappers around our HTTP client, no console.log in production code, no direct DB queries from route handlers.
  • One paragraph on the architecture, with file paths.

A real one is short. Something like:

# This codebase

Next.js 15 App Router, TypeScript strict, Postgres via Drizzle.
Auth lives in `src/lib/auth.ts`. Never roll your own.

Conventions:
- API routes return Result<T, ApiError>, never throw.
- Logging via `src/lib/log.ts`, structured fields only.
- Tests next to source as `*.test.ts`, run with `bun test`.
- Tailwind only. No CSS modules, no styled-components.

Reference patterns:
- New endpoint: src/api/invoices/route.ts
- New page: src/app/(dashboard)/invoices/page.tsx
- New table: src/db/schema/invoices.ts

Never:
- Add new client wrappers around `apiClient`.
- Use `useEffect` for data fetching, use TanStack Query.
- Touch `src/legacy/`. That code is being deleted.

Fifteen lines. Saves you from fifty bad suggestions a week.

Context window strategy

Even with a million-token window, you can't paste the whole repo and expect good results. Pick the right files: the one you're editing, the test file next to it, the most relevant utility, plus CLAUDE.md. Cursor and Cody surface this for you. Claude Code does it natively the moment you reference filenames in your prompt.

The trick is being specific. "Look at src/api/users.ts and the new endpoint we're discussing" beats "look at the codebase." The model is better at focused reading than skim-the-whole-repo synthesis.

Repo conventions in prompts

Always ground a request in an existing file. The cheapest, most reliable upgrade to your prompts.

Bad: "Write me an endpoint for invoices."

Good: "Write a new POST endpoint at src/api/invoices/route.ts for creating invoices, following the same pattern as src/api/users.ts. Same error type, same logging, same test file structure."

You'll get something that actually fits the repo on the first try, instead of a generic Express handler you have to translate.

The retraining loop

When the model writes something off-pattern, don't just fix it in place. Update CLAUDE.md so it doesn't make the same mistake next session. The doc compounds. Every correction you write down once is a correction you don't make ten more times. Every banned library you list is a banned library that stops appearing in suggestions.

Treat CLAUDE.md the way a tenured engineer treats their personal notes file: living, append-only, slightly embarrassing in the older entries.

For larger codebases

If you're past a hundred thousand lines, raw context isn't enough. Cody by Sourcegraph indexes the whole repo with semantic search and answers cross-cutting questions in seconds. Cursor's @codebase mode does most of the same work from the editor. Claude Code's repo awareness handles the middle ground well. Pinecone or your own vector store is overkill for almost everyone, skip it until you have a specific reason.

Make it a team thing

Don't make CLAUDE.md a one-person side project. Land it in the repo, get two teammates to push commits to it in the first week, and treat it like any other doc that needs maintenance. A stale CLAUDE.md is worse than none, the model will confidently follow the wrong rules. Review it the same way you'd review an outdated README.

Closing Pillar 3

This is the last guide in Build with AI. You've gone from vibe-coded prototypes to debugging the weird stuff to teaching the model your team's dialect. Pillar 4 is where building turns into shipping: picking a host, owning your stack, and getting changes from your laptop to production without a platform team in the way.