--- name: writing-agents-md-files description: Use when creating or updating AGENTS.md context files for projects or subdirectories - covers top-level vs domain-level organization, capturing architectural intent and contracts, and mandatory freshness dates --- # Writing AGENTS.md Files Read `writing-agent-directives` first, for the underlying guidance on token efficiency, compliance techniques, and directive structure. ## Core Principle `AGENTS.md` files bridge an agent's statelessness. They preserve context so humans don't re-explain architectural intent every session. **Key distinction:** - **Top-level**: HOW to work in this codebase (commands, conventions) - **Subdirectory**: WHY this piece exists and what it PROMISES (contracts, intent) ### Cross-platform Support Treat `AGENTS.md` as canonical. Preserve host-specific companion files only when the repository already uses them or the user explicitly requests them; do not duplicate the instructions. ## File Hierarchy Agents read context files from the current directory up to root: ``` project/ ├── AGENTS.md # Project-wide: tech stack, commands, conventions └── src/ └── domains/ ├── auth/ │ ├── AGENTS.md # Auth domain: purpose, contracts, invariants │ └── oauth2/ │ └── AGENTS.md # OAuth2 subdomain (rare, only when needed) └── billing/ └── AGENTS.md # Billing domain: purpose, contracts, invariants ``` **Depth guideline:** Typically one level (domain). Occasionally two (subdomain like `auth/oauth2`). Rarely more. ## Top-Level `AGENTS.md` Focuses on project-wide WHAT and HOW. ### What to Include | Section | Purpose | |---------|---------| | Tech Stack | Framework, language, key dependencies | | Commands | Build, test, run commands | | Project Structure | Directory overview with purposes | | Conventions | Naming, patterns used project-wide | | Boundaries | What agents can and cannot edit | ### Template ```markdown # [Project Name] Last verified: [DATE - use `date +%Y-%m-%d`] ## Tech Stack - Language: TypeScript 5.x - Framework: Next.js 14 - Database: PostgreSQL - Testing: Vitest ## Commands - `npm run dev` - Start dev server - `npm run test` - Run tests - `npm run build` - Production build ## Project Structure - `src/domains/` - Domain modules (auth, billing, etc.) - `src/shared/` - Cross-cutting utilities - `src/infrastructure/` - External adapters (DB, APIs) ## Conventions - Functional Core / Imperative Shell pattern - Domain modules are self-contained - See domain `AGENTS.md` files for domain-specific guidance ## Boundaries - Safe to edit: `src/` - Never touch: `migrations/` (immutable), `*.lock` files ``` ### What NOT to Include - Code style rules (use linters) - Exhaustive command lists (reference package.json) - Content that belongs in domain-level files - Sensitive information (keys, credentials) ## Subdirectory `AGENTS.md` (Domain-Level) Focuses on WHY and CONTRACTS. The code shows WHAT; these files explain intent. ### What to Include | Section | Purpose | |---------|---------| | Purpose | WHY this domain exists (not what it does) | | Contracts | What this domain PROMISES to others | | Dependencies | What it uses, what uses it, boundaries | | Key Decisions | ADR-lite: decisions and rationale | | Invariants | Things that always hold | | Gotchas | Non-obvious traps | ### Template ```markdown # [Domain Name] Last verified: [DATE - use `date +%Y-%m-%d`] ## Purpose [1-2 sentences: WHY this domain exists, what problem it solves] ## Contracts - **Exposes**: [public interfaces - what callers can use] - **Guarantees**: [promises this domain keeps] - **Expects**: [what callers must provide] ## Dependencies - **Uses**: [domains/services this depends on] - **Used by**: [what depends on this domain] - **Boundary**: [what should NOT be imported here] ## Key Decisions - [Decision]: [Rationale] ## Invariants - [Thing that must always be true] ## Key Files - `index.ts` - Public exports - `types.ts` - Domain types - `service.ts` - Main service implementation ## Gotchas - [Non-obvious thing that will bite you] ``` ### Example: Auth Domain ```markdown # Auth Domain Last verified: 2025-12-17 ## Purpose Ensures user identity is verified exactly once at the system edge. All downstream services trust the auth token without re-validating. ## Contracts - **Exposes**: `validateToken(token) → User | null`, `createSession(credentials) → Token` - **Guarantees**: Tokens expire after 24h. User objects always include roles. - **Expects**: Valid JWT format. Database connection available. ## Dependencies - **Uses**: Database (users table), Redis (session cache) - **Used by**: All API routes, billing domain (user identity only) - **Boundary**: don't import from billing, notifications, or other domains ## Key Decisions - JWT over session cookies: Stateless auth for horizontal scaling - bcrypt cost 12: Legacy decision, migration to argon2 tracked in ADR-007 ## Invariants - Every user has exactly one primary email - Deleted users are soft-deleted (is_deleted), never hard deleted - User IDs are UUIDs, never sequential ## Key Files - `service.ts` - AuthService implementation - `tokens.ts` - JWT creation/validation - `types.ts` - User, Token, Session types ## Gotchas - Token validation returns null on invalid (doesn't throw) - Never return raw password hashes in User objects ``` ## Referencing Files You can reference key files in `AGENTS.md`: ```markdown ## Key Files - `index.ts` - Public exports - `service.ts` - Main implementation ``` **Avoid host-specific import syntax** such as `@./service.ts`; it may force-load files and is not portable. Name files normally so an agent can read them when needed. ## Heuristics: Top-Level vs Subdirectory | Question | Top-level | Subdirectory | |----------|-----------|--------------| | Applies project-wide? | ✓ | | | New engineer needs on day 1? | ✓ | | | About commands/conventions? | ✓ | | | About WHY a component exists? | | ✓ | | About contracts between parts? | | ✓ | | Changes when the domain changes? | | ✓ | **Rule of thumb:** - Top-level = "How to work here" - Subdirectory = "Why this exists and what it promises" ## When to Create Subdirectory `AGENTS.md` Create when: - Domain has non-obvious contracts with other parts - Architectural decisions affect how code should evolve - Invariants exist that aren't obvious from code - New sessions consistently need the same context re-explained Don't create for: - Trivial utility folders - Implementation details that change frequently - Content better captured in code comments ## Updating `AGENTS.md` Files When updating any `AGENTS.md`: 1. **Verify contracts still hold** - read the code, check invariants 2. **Remove stale content** - better short and accurate than long and wrong 3. **Keep token-efficient** - <300 lines top-level, <100 lines subdirectory ## Common Mistakes | Mistake | Fix | |---------|-----| | Describing WHAT code does | Focus on WHY it exists, contracts it keeps | | Missing freshness date | Always include; obtain the real date from the environment | | Using host-specific imports for files | Name files normally and let the agent read them on demand | | Too much detail | Subdirectory files should be <100 lines | | Duplicating parent content | Subdirectory inherits parent; don't repeat | | Stale contracts | Update when domain changes; verify dates | ## Checklist **Top-level:** - [ ] Tech stack listed - [ ] Key commands documented - [ ] Project structure overview - [ ] Freshness date (from `date +%Y-%m-%d`) **Subdirectory:** - [ ] Purpose explains WHY (not what) - [ ] Contracts: exposes, guarantees, expects - [ ] Dependencies and boundaries clear - [ ] Key decisions with rationale - [ ] Invariants documented - [ ] Freshness date (from `date +%Y-%m-%d`) - [ ] Under 100 lines