CLAUDE.md, AGENTS.md, and Cursor rules: starter templates that actually bind
Download the pack (.zip of the actual files)
Most agent instruction files are scaffolding. A deterministic analysis of roughly 30,000 public repositories found only 27% of the average file does instruction work; the rest restates context the model already has. This page has four copy-ready starters that skip the scaffolding, plus the rules for keeping them that way.
Why most instruction files fail
A SCAM 2026 study cataloged configuration smells in the CLAUDE.md and AGENTS.md files of 100 popular public repositories. Only 9 of 100 were smell-free. Lint Leakage (style rules that belong in the linter) appeared in 62%, Context Bloat in 42%, Skill Leakage in 35%.
The files grow because the incentives point one way. The paper "Why Does CLAUDE.md Keep Growing?" analyzed 247,694 instruction lifetimes: appending a rule costs nothing, while safely deleting one means re-testing everything that might depend on it. Teams append, never delete, and the file decays. The same 30,000-repo analysis found 89.9% of files carry at least one rule that names no concrete construct, a "keep the code clean" line that reads fine to a human and binds nothing in the model.
The templates below follow five rules. Every line names a concrete construct (a command, a path, a package, a boundary). One concern per line. Nothing the model does by default. Nothing the linter already enforces. Under 60 lines, because a file the team can read in one screen is a file the team will actually prune.
AGENTS.md, the portable base
AGENTS.md is the cross-tool standard: Codex, Copilot coding agent, Cursor, and Jules read it. Claude Code reads CLAUDE.md, so the pointer pattern below keeps one source of truth.
# AGENTS.md
## Commands
- Install: `pnpm install`
- Test (single file): `pnpm vitest run path/to/file.test.ts`
- Full check before any commit: `pnpm check` (types + lint + tests)
- Never run `pnpm build` to validate changes; `pnpm check` is faster and sufficient.
## Boundaries
- Never edit files in `src/generated/` or `migrations/applied/`. Regenerate instead.
- Never add a dependency without stating why in the PR description.
- Never weaken CI: no test deletions, no `|| true`, no coverage threshold changes.
- Secrets come from `env.ts` accessors only. Never read `process.env` directly.
## Conventions the linter cannot see
- New API routes copy the shape of `src/api/health/route.ts` (validation, error envelope, logging).
- Database access goes through `src/db/queries/`. No inline SQL in route handlers.
- Feature flags: check `flags.ts`; never hardcode a flag name as a string.
## PR
- One concern per PR. If the diff mixes a fix and a refactor, split it.
- PR description states the user-visible behavior change in 2 sentences.
Read AGENTS.md and follow it. Claude-specific additions only below this line.
- Use plan mode for changes touching more than 3 files.
- When a test fails twice with the same fix attempted, stop and report instead of retrying.
CLAUDE.md for a TypeScript / Next.js app
# CLAUDE.md
## Commands
- Dev server: `pnpm dev` (assume it is already running; never start a second one)
- Typecheck: `pnpm tsc --noEmit`
- Test one file: `pnpm vitest run <path>` (never the full suite during iteration)
## Architecture facts the model will guess wrong
- App Router only. `pages/` is legacy and frozen; never add to it.
- Server components by default. Add `"use client"` only for event handlers or browser APIs, and say why in the PR.
- All fetches go through `src/lib/api.ts`. It handles auth headers and retries; raw `fetch` in components is a bug.
- Route handlers validate input with the zod schemas in `src/schemas/`. New endpoint = new schema first.
## Hard rules
- Never use `any` or `as unknown as`. If types fight back, the design is wrong; stop and explain.
- Never suppress with `eslint-disable` or `@ts-expect-error` without a linked issue.
- State lives in the URL or the database. Introducing client state libraries requires a human decision.
## Done means
- `pnpm check` passes, and the change is visible at a URL you name in the summary.
CLAUDE.md for a Python service
# CLAUDE.md
## Commands
- Env: `uv sync` (this repo uses uv, not pip; requirements.txt does not exist)
- Test one file: `uv run pytest tests/test_x.py -x -q`
- Lint + format: `uv run ruff check --fix . && uv run ruff format .`
## Architecture facts the model will guess wrong
- FastAPI routers live in `app/routers/`, one file per resource. Business logic lives in `app/services/`; routers stay thin.
- All DB access is async SQLAlchemy through `app/db/session.py`. Never create a second engine or session factory.
- Exceptions: raise the typed errors in `app/errors.py`. Bare `except Exception` that logs-and-continues is the number one bug pattern in this codebase; never add one.
- Background work goes through the task queue in `app/tasks/`. No `asyncio.create_task` fire-and-forget in request handlers.
## Hard rules
- Never edit `alembic/versions/` by hand. Schema change = new autogenerated migration, reviewed.
- Pydantic models are the only serialization boundary. No raw dicts across module edges.
- New third-party packages require a human decision; propose in the summary instead of installing.
## Done means
- `uv run pytest -x -q` passes and ruff is clean.
Cursor rules
Cursor reads AGENTS.md, and its own project rules live in .cursor/rules/ as scoped .mdc files. Scope is the point: a rule that only matters in one directory should only load there.
---
description: API route conventions
globs: ["src/api/**"]
alwaysApply: false
---
- New routes copy `src/api/health/route.ts`: zod validation, typed error envelope, request logging.
- Auth: call `requireUser()` first line of every handler except routes listed in `src/api/PUBLIC.md`.
- Response shapes change only with a version bump; breaking an existing field is never a refactor.
What to delete from the file you already have
- Everything the linter enforces. Quote style, import order, formatting. The 62% Lint Leakage finding is this. Move it to the linter config, where it is enforced instead of suggested.
- Restated defaults. "Write tests for new code," "use meaningful names," "follow best practices." The model does this without being told; the line costs context and binds nothing.
- Prose that describes the project. The model reads the code. A paragraph about what the company does is scaffolding, and scaffolding is 73% of the average file.
- Contradictions. When two rules conflict, current models follow one and silently drop the other, and the dropped rule reads as flakiness. Every rule added to fix "flaky" behavior should start with a search for the rule it contradicts.
- Anything nobody can trace to an incident. A rule that names no concrete construct and no one remembers adding is the 89.9% case. Delete it; if something regresses, the regression will name the real rule to write.
Instruction files steer the code that gets written. Reviewing what actually ships is the other half: Hyrax runs autonomous code review and fixing across the codebase and submits each fix as a PR that an engineer merges. There is a Free plan, and PR reviews in GitHub are free. hyrax.dev
Ship clean code.