# Writing AGENTS.md files that actually work

After shipping AI-assisted features in dozens of repos, these are the patterns that move the needle.

## 1. Lead with constraints, not capabilities

Bad: "You are a helpful expert in TypeScript."
Good: "Use TypeScript strict mode. Never use `any`. Prefer `unknown` + narrowing."

Agents respond to constraints. Praise is filler.

## 2. Tell the agent what NOT to do

Most production bugs from AI agents come from things you forgot to forbid. Always include:

- "Do not add npm packages without approval."
- "Do not modify migrations once committed."
- "Do not add comments explaining the change."
- "Do not write tests for code you didn't change."
- "Do not run destructive commands (rm -rf, git push --force, db drop)."

## 3. Pin the versions

"Use Next.js 15 App Router" — not "Use Next.js." The agent might pull patterns from Next.js 12 docs otherwise.

## 4. Specify the test command

Agents will guess. Tell them exactly:

```
Run tests with: pnpm test
Run a single test with: pnpm test -- path/to/file.test.ts
```

## 5. Specify the directory layout

```
src/
  app/        # Next.js App Router pages and layouts
  components/ # Shared React components (PascalCase files)
  lib/        # Pure functions, no React imports
  server/     # Server-only code, db access, never imported by client
```

## 6. Style is policy

Lint rules are not enough. State the policy in prose:

- "Function components only. No class components."
- "Server Components by default. Add `'use client'` only when required."
- "No default exports except for Next.js page/layout files."

## 7. Forbid silent fallbacks

- "Throw on missing env vars at startup, never default to empty string."
- "If a fetch fails, throw. Don't swallow."

## 8. Match the agent to the task

Long-running tasks (Claude Code, Copilot agent mode):
- Add a planning section: "Before writing code, list the files you'll touch."
- Add a verification section: "After the change, run tests and report the result."

Short edits (Cursor inline, Copilot completion):
- Keep `.cursorrules` short. Cursor injects it on every prompt.
- Move the long prose to `AGENTS.md` which Cursor reads on demand.

## 9. Update after every regression

Every time the agent ships a bug, ask: "What rule would have prevented this?" Add it.

## 10. Test the file itself

Open a fresh chat, paste the AGENTS.md, ask the agent to summarize the rules. If it gets them wrong, the file is wrong.
