Designing Codebases Where AI Agents Hit the Ground Running
Imagine a repository where a brand-new team member can ship a meaningful change on day one. Most engineering organizations dream of this; few achieve it. Onboarding usually takes weeks. But for AI agents like Claude Code, those weeks can compress into ten minutes — under one condition. The codebase has to be designed knowing it will be read by an agent.
Over the past year, I've put Claude Code through dozens of large repositories, and the patterns of where agents stumble versus where they glide through have become unmistakable. This article distills those observations into design principles you can implement immediately.
Why "Designing for AI Agents" Is a New Engineering Discipline
Traditional codebase design assumes humans will maintain the code over months and years. Directory layouts, naming conventions, testing strategies — they all assume "you'll get used to it." The cost of getting up to speed has always been treated as a necessary tax.
But AI agents don't "get used to" anything. Every session is a cold start. The only information available to an agent is what's literally written in the repository at that moment. Tribal knowledge — the kind passed around in Slack threads and tap-on-the-shoulder conversations — is invisible to them.
This constraint is also a measuring stick. A codebase where an AI agent can grasp the architecture in ten minutes is, almost without exception, a great codebase for new human engineers too. Designing for agents ends up lifting productivity for the entire organization.
Principle 1: Place a Map at the Top Level
Place a CLAUDE.md file at the root of the repository. This is your first move. Claude Code reads this file automatically on startup — it's the agent's "first briefing."
But here's where many teams go wrong. They stuff CLAUDE.md with detailed API specs and per-class explanations. That's a mistake. CLAUDE.md is a map, not a dictionary.
A good map contains things like this:
- What problem this project exists to solve (one or two sentences)
- The role of each major directory (responsibilities of
src/,tests/,scripts/, etc.) - One-line build, test, and deploy commands (in executable form)
- Non-negotiable rules during development (breaking change constraints, mandatory tests)
- Pointers to deeper documentation (
_documents/and the like)
What it should not contain: detailed implementation of specific functions, frequently-changing API response shapes, or the changelog of past bug fixes. Those belong in separate files; CLAUDE.md should link to them.
# Project Name
## One-Line Summary
A SaaS platform that solves [specific problem] for [target users].
## Directory Roles
- src/api/ — REST endpoint definitions
- src/domain/ — Business logic (no external dependencies)
- src/infra/ — DB and external API adapters
- _documents/ — Design docs and operations guides
## Development Commands
- Start dev server: `npm run dev`
- Run all tests: `npm test`
- Type check: `npm run typecheck`
## Critical Rules
- src/domain/ must not depend on src/infra/ (dependency inversion)
- New endpoints require tests in tests/integration/
- Migration changes require updating _documents/MIGRATIONS.mdThe simplicity is the point. After reading CLAUDE.md, an agent should immediately know "where do I look next?"
Principle 2: Make Contract Boundaries Explicit
Write into the code itself which parts an AI agent can modify freely and which parts demand caution. I call these contract boundaries.
Concretely, combine these techniques:
Type System Boundaries
In TypeScript, isolate public APIs that must not change into a dedicated type file. Name it something like types/contracts.ts — let the filename carry intent. From the word "contracts," the agent infers: this file is depended on by external code, don't touch it casually.
// types/contracts.ts
// These types are part of the public API. Changes must go through the v2 branch with a phased rollout.
export interface UserPublicProfile {
readonly id: string;
readonly displayName: string;
readonly joinedAt: string; // ISO 8601
}Comments That Encode Intent
Wherever the intent isn't readable from the code alone, leave a comment. When an agent can't tell why something is written a certain way, that's exactly when it makes the worst changes.
// Intent: Not awaiting here is deliberate — we need to return immediately
// when rate limits hit. Parallel execution is the goal, not a bug.
results.forEach(item => fireAndForget(item));Per-Directory READMEs
Important directories like src/payment/ get a short README.md inside them. Three to five lines is enough: "what this directory is responsible for," "things to watch when modifying it," "external services it depends on."
Principle 3: Tests as Living Specifications
The most dangerous outcome of an agent-written change is "looks like it works, but it's actually broken." The only reliable defense is tests that function as specifications.
A test environment that's friendly to agents has clear traits.
First, a single command like npm test should run everything. Don't make agents memorize flags. Second, when tests fail, the test name alone should tell you what specification was violated. test('should return 400 when email format is invalid') reads like English. Third, tests must run quickly. Agents iterate. A five-minute test run kills their effectiveness.
I recommend a pyramid strategy: lots of unit tests at the bottom (under one minute), integration tests in the middle (under five), a small set of E2E tests at the top (under ten). Have agents run unit and integration; let CI handle E2E.
Principle 4: Provide Agent-Specific Scripts
What's obvious to a human engineer is invisible to an agent. So script the recurring operations.
# scripts/ai-onboarding.sh
# Commands a new AI session should run first
#!/bin/bash
echo "=== Repository status ==="
git status --short
echo ""
echo "=== Recent commits ==="
git log --oneline -10
echo ""
echo "=== Current branch ==="
git branch --show-current
echo ""
echo "=== Test status ==="
npm test --silent 2>&1 | tail -5Including a "survey the environment" script like this lets agents orient themselves quickly. Mention it in CLAUDE.md: "Run bash scripts/ai-onboarding.sh first."
Other handy scripts: templates for new files (scripts/new-endpoint.sh), database migration commands (scripts/migrate.sh), local environment reset (scripts/reset-local.sh). Agents will discover and call these.
Principle 5: Wire Guardrails into CI
CI is your last line of defense. Build a system where wrong changes from an agent get caught before they hit production.
Minimum checks to wire up:
# Key jobs in .github/workflows/ci.yml
# - lint: detect code style violations
# - typecheck: detect type errors
# - test: run all tests
# - build: confirm production build succeeds
# - secret-scan: detect leaked API keys
# - bundle-size: warn on bundle bloatSecret scanning is especially important. Agents sometimes write real-format API keys when they meant to write placeholders. Wire GitHub Secret Scanning or TruffleHog into CI to catch leaks before they reach the repo.
Bundle size checks matter too. Agents add dependencies casually. Monitor for sudden growth.
A Phased Rollout Roadmap
Don't try to implement all of this at once. Here's a sequence I've seen work:
Week one: clean up CLAUDE.md. This alone dramatically improves agent first-move quality. Weeks two and three: add per-directory READMEs and agent-specific scripts. Daily work gets noticeably smoother.
Month two: tackle contract boundaries and revise test strategy. This takes the longest but pays the highest dividends. Finally, harden the CI guardrails.
Each phase produces visible improvement, which makes it easy to keep organizational support.
Measuring Impact
Measure these metrics before and after:
Time from "give the agent a task" to "agent submits a PR." Often cuts in half. Single-pass merge rate of agent PRs (merged with no major review changes). Tends to climb from around 50% to 80%. Time for a new human engineer to land their first commit. Also drops significantly.
These metrics aren't only for AI agents. They reflect overall developer productivity. A codebase designed to be read benefits everyone.
Your Next Step
Now that you've read this guide, the first thing to do is review your repository's CLAUDE.md. Audit your existing CLAUDE.md (if you have one) against these three checks:
Can a reader understand each directory's role in three lines? Are dev commands written in directly executable form? Is there a clear pointer to deeper docs (_documents/, etc.)?
Just satisfying those three transforms how AI agents perform on day one.