A universal rules file tells an agent how to behave. It can't tell it how your project works: which command runs the tests, where shared helpers live, or which folder it must never touch.
That's what a project rules file is for. In UNIVERSAL-AGENTS.md it's called AGENTS.project.md, and this post shows how to write a good one.
Section 23 of the universal rules sets the priority when instructions conflict:
AGENTS.md
Section 34.1 names AGENTS.project.md as the home for project rules. So the split is clean:
AGENTS.project.md holds everything specific to One exception: the safety rules (Sections 27, 28, 29, and 33) can't be loosened by project rules. Only an explicit instruction from the user can override them.
cp templates/AGENTS.project.template.md AGENTS.project.md
The template has ten sections. You don't need all of them. Delete what doesn't apply and keep the file short, because agents load it into their context window and every line costs something.
Here is a fictional project, an invoicing API in TypeScript. Adapt it to your stack.
## 1. Project overview
- **Name:** invoice-api
- **Purpose:** REST API for creating and sending invoices.
- **Languages / frameworks / runtimes:** TypeScript 5, Node 20, Fastify
- **Package manager:** pnpm
- **Repository type:** single project
## 2. Commands
| Task | Command |
|------|---------|
| Install dependencies | `pnpm install` |
| Build | `pnpm build` |
| Run locally | `pnpm dev` |
| Run all tests | `pnpm test` |
| Run a single test | `pnpm vitest run path/to/file.test.ts` |
| Lint | `pnpm lint` |
| Type-check | `pnpm tsc --noEmit` |
## 3. Architecture and layout
- **Entry points:** `src/server.ts`
- **Key directories:** `src/routes` (HTTP only), `src/services` (business logic), `src/db` (queries)
- **Layering rules:** routes never query the database directly.
- **Shared utilities live in:** `src/lib`. Search here before writing new helpers.
## 4. Conventions
- **Code style:** enforced by `eslint.config.js`.
- **Error handling:** throw `AppError` from `src/lib/errors.ts`; never throw plain strings.
- **Commit message format:** Conventional Commits.
## 5. Protected areas
Do not modify without explicit approval:
- `migrations/`: applied migrations must never be edited.
Generated files (never edit by hand):
- `src/db/types.generated.ts`: generated by `pnpm db:codegen`.
## 6. Approval required
Ask the user before:
- adding or upgrading dependencies
- creating or changing a database migration
- changing anything in `.github/workflows/`
## 7. Documentation to keep in sync
| When this changes | Update this |
|-------------------|-------------|
| A route's request or response | `docs/api.md` |
| An environment variable | `README.md` (Configuration section) |
## 8. Testing expectations
- **Required for:** every bug fix needs a regression test.
- **Test locations and naming:** next to the source, `*.test.ts`.
- **Do not run against:** any database other than the local Docker one.
## 9. Environment and secrets
- **Local config:** `.env`, based on `.env.example`.
- **Never log or print:** API keys, customer emails, card data.
## 10. Known pitfalls
- `pnpm test` is slow on a cold start; run a single test while iterating.
Commands. This is the highest-value section. Without it, an agent guesses npm test in a pnpm project, or runs the whole suite when one file would do. Exact commands also make the agent's verification report (Section 21) trustworthy.
Architecture and layering. Section 5 already tells the agent to reuse existing code before writing new code. Pointing it at src/lib tells it where to look, so it doesn't write a fourth date-formatting helper.
Protected areas. Section 8 says agents must not touch things outside the request. Naming migrations/ and generated files turns a general principle into a hard boundary.
Approval required. Dependencies, migrations, and CI changes are the changes people most regret not reviewing. Listing them means the agent asks first.
Documentation to keep in sync. Section 9 requires docs to match the code. A table of "when X changes, update Y" lets the agent do it reliably.
Testing expectations. This sharpens Section 19, which says to add tests only when asked or when project conventions require them. If your convention is "every bug fix gets a regression test", say so here and the agent will follow it.
Known pitfalls. One or two lines here can save a lot of wasted runs.
Section 34.2 covers this: the AGENTS.md closest to the file being changed takes precedence for that subtree, and any rules it doesn't mention still apply from the universal file. Put a small AGENTS.md in each package with its own commands and layout.
If your tool doesn't read AGENTS.md natively, copy the matching file from adapters/ (Claude Code, Gemini CLI, GitHub Copilot, Cursor). The adapters already tell the tool to read AGENTS.project.md as well. Check your tool's docs to confirm the file format it expects.
👉 https://github.com/NTDevLops/UNIVERSAL-AGENTS.md (MIT licensed)
What's the one line in your project that you wish every new contributor, human or AI, read first? Share it in the comments.