{"course":{"slug":"building-apps-with-ai","title":"Building Apps with AI","url":"https://addaly.com/learn/building-apps-with-ai","level":"beginner","track":"build"},"lesson":{"slug":"the-rules-file-your-tool-reads","title":"The rules file, and what belongs in it","url":"https://addaly.com/learn/building-apps-with-ai/the-rules-file-your-tool-reads","position":8,"of":87,"minutes":8,"answer":"A rules file under two pages that names your stack, your file layout, your build command and the mistakes you have already made is the only text guaranteed to reach the model every turn.","keyIdea":"A rules file under two pages that names your stack, your file layout, your build command and the mistakes you have already made is the only text guaranteed to reach the model every turn."},"body":{"format":"markdown","text":"## One file, read every turn\n\nEvery serious tool now looks for a plain text file of project instructions and puts it into the context automatically: `CLAUDE.md`, `.cursorrules`, `AGENTS.md`, `.github/copilot-instructions.md`. Same idea, different filenames, and several tools read more than one.\n\nThis is the highest-leverage thing you can write. It is the only text that is present in every single request without you doing anything.\n\n## What belongs in it\n\nSix categories, and nothing else.\n\n**The stack, stated flatly.** \"Next.js app router, TypeScript, Postgres via Drizzle, Tailwind.\" Without this the model infers from whatever file it happened to read.\n\n**Where things live.** \"All database queries in `lib/queries.ts`. Route handlers in `app/api/`. Shared types in `types/`.\" This is what keeps a project navigable after two hundred generated files.\n\n**How to run it.** The commands. `npm run dev`, `npm run build`, `npm test`, `npm run db:migrate`. An agent that knows how to build can check its own work, which is worth more than any instruction about code style.\n\n**The rules that are yours.** The business constraints a model cannot infer. \"Prices are stored in paise, as integers, never floats.\" \"Invoice numbers restart on 1 April.\" \"Times are stored in UTC and displayed in the salon's local timezone.\"\n\n**The prohibitions.** \"No new dependencies without asking.\" \"Never edit files in `migrations/`.\" \"Do not change the database schema without telling me first.\" These are the ones that save whole afternoons.\n\n**The scars.** When a mistake happens twice, write the rule that prevents it. This is the section that makes the file yours rather than generic, and it is the section people never start.\n\n## What does not belong in it\n\n**Length.** Beyond about a page and a half, the file competes with itself for attention. If everything is important, the model prioritises for you, and it will not prioritise the way you would.\n\n**Praise and personality.** \"You are an expert senior engineer\" does approximately nothing for code quality in current models. The tokens are better spent on the fact that your dates are stored in UTC.\n\n**Anything already visible in the code.** The model can read `package.json`. It cannot read your intentions.\n\n**Stale rules.** A rule describing a file you deleted is worse than no rule; it sends the agent looking for something that is not there.\n\n## A worked example\n\n```markdown\n# Project rules\n\n## Stack\nNext.js app router, TypeScript, Postgres via Drizzle, Tailwind.\nDeployed to Cloudflare Workers. Node 20.\n\n## Commands\nnpm run dev · npm run build · npm test · npm run db:migrate\nAlways run `npm run build` before saying a change is finished.\n\n## Structure\n- Database queries: lib/queries.ts only\n- API routes: app/api/<name>/route.ts\n- Anything a browser component imports must not touch the database\n\n## Domain rules\n- Money is integer paise. Never a float.\n- Bookings cannot overlap for the same stylist.\n- Opening hours 09:00–19:00 local, stored UTC.\n\n## Do not\n- Add dependencies without asking\n- Edit anything in drizzle/migrations/\n- Refactor files I did not mention\n\n## Learned the hard way\n- The seed script wipes the dev database. Never run it to check something.\n- Two components are named BookingCard. The one in app/ is dead.\n```\n\nThat is under 200 words and it will prevent more failures than any prompt you write this month.\n\n## The line that pays for the file\n\n\"Always run `npm run build` before saying a change is finished.\"\n\nAn agent that verifies its own work catches the type errors, the missing imports and the broken build before you have opened the browser. It costs a few seconds per change and removes the most common form of false completion: a confident summary of a change that does not compile.\n\n## Keep it in git\n\nThe rules file belongs in the repository, committed like code. It is documentation that stays true, because unlike a README, something reads it every day and you notice when it is wrong.\n\nAnd when you hand the project to somebody else (a collaborator, a developer you hire, yourself in six months) this file is the fastest briefing that exists."},"check":{"question":"Which line in a project rules file does the most to stop an agent reporting work as finished when it is not?","options":[{"text":"\"You are a careful senior engineer who double-checks everything.\"","correct":false,"tempting":"Role framing changes tone rather than behaviour, and does nothing to introduce an observation the model can fail against."},{"text":"\"Always run npm run build before saying a change is finished.\"","correct":true},{"text":"\"Write clean, well-structured, maintainable code.\"","correct":false,"tempting":"States a quality goal with no way to check it; the model already believes its output meets this description."},{"text":"\"Explain every change you make in detail before making it.\"","correct":false,"tempting":"Produces more text about intended work, which is a second generation rather than evidence about the code on disk."}]},"prev":{"slug":"choosing-a-stack-and-stopping","title":"Choosing a stack, and then stopping","url":"https://addaly.com/learn/building-apps-with-ai/choosing-a-stack-and-stopping"},"next":{"slug":"autonomy-and-where-to-keep-your-hand","title":"Autonomy, and where to keep your hand","url":"https://addaly.com/learn/building-apps-with-ai/autonomy-and-where-to-keep-your-hand"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'The rules file, and what belongs in it', in Building Apps with AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/building-apps-with-ai/the-rules-file-your-tool-reads (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"The rules file, and what belongs in it","courseTitle":"Building Apps with AI","module":{"index":1,"slug":"the-machine-and-the-model","title":"The machine, and what the model can see of it"},"answer":null,"keyIdea":"A rules file under two pages that names your stack, your file layout, your build command and the mistakes you have already made is the only text guaranteed to reach the model every turn.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"one-file-read-every-turn","runs":[{"text":"One file, read every turn"}]},{"t":"p","runs":[{"text":"Every serious tool now looks for a plain text file of project instructions and puts it into the context automatically: "},{"text":"CLAUDE.md","code":true},{"text":", "},{"text":".cursorrules","code":true},{"text":", "},{"text":"AGENTS.md","code":true},{"text":", "},{"text":".github/copilot-instructions.md","code":true},{"text":". Same idea, different filenames, and several tools read more than one."}]},{"t":"p","runs":[{"text":"This is the highest-leverage thing you can write. It is the only text that is present in every single request without you doing anything."}]},{"t":"h2","id":"what-belongs-in-it","runs":[{"text":"What belongs in it"}]},{"t":"p","runs":[{"text":"Six categories, and nothing else."}]},{"t":"p","runs":[{"text":"The stack, stated flatly.","b":true},{"text":" “Next.js app router, TypeScript, Postgres via Drizzle, Tailwind.” Without this the model infers from whatever file it happened to read."}]},{"t":"p","runs":[{"text":"Where things live.","b":true},{"text":" “All database queries in "},{"text":"lib/queries.ts","code":true},{"text":". Route handlers in "},{"text":"app/api/","code":true},{"text":". Shared types in "},{"text":"types/","code":true},{"text":".” This is what keeps a project navigable after two hundred generated files."}]},{"t":"p","runs":[{"text":"How to run it.","b":true},{"text":" The commands. "},{"text":"npm run dev","code":true},{"text":", "},{"text":"npm run build","code":true},{"text":", "},{"text":"npm test","code":true},{"text":", "},{"text":"npm run db:migrate","code":true},{"text":". An agent that knows how to build can check its own work, which is worth more than any instruction about code style."}]},{"t":"p","runs":[{"text":"The rules that are yours.","b":true},{"text":" The business constraints a model cannot infer. “Prices are stored in paise, as integers, never floats.” “Invoice numbers restart on 1 April.” “Times are stored in UTC and displayed in the salon’s local timezone.”"}]},{"t":"p","runs":[{"text":"The prohibitions.","b":true},{"text":" “No new dependencies without asking.” “Never edit files in "},{"text":"migrations/","code":true},{"text":".” “Do not change the database schema without telling me first.” These are the ones that save whole afternoons."}]},{"t":"p","runs":[{"text":"The scars.","b":true},{"text":" When a mistake happens twice, write the rule that prevents it. This is the section that makes the file yours rather than generic, and it is the section people never start."}]},{"t":"h2","id":"what-does-not-belong-in-it","runs":[{"text":"What does not belong in it"}]},{"t":"p","runs":[{"text":"Length.","b":true},{"text":" Beyond about a page and a half, the file competes with itself for attention. If everything is important, the model prioritises for you, and it will not prioritise the way you would."}]},{"t":"p","runs":[{"text":"Praise and personality.","b":true},{"text":" “You are an expert senior engineer” does approximately nothing for code quality in current models. The tokens are better spent on the fact that your dates are stored in UTC."}]},{"t":"p","runs":[{"text":"Anything already visible in the code.","b":true},{"text":" The model can read "},{"text":"package.json","code":true},{"text":". It cannot read your intentions."}]},{"t":"p","runs":[{"text":"Stale rules.","b":true},{"text":" A rule describing a file you deleted is worse than no rule; it sends the agent looking for something that is not there."}]},{"t":"h2","id":"a-worked-example","runs":[{"text":"A worked example"}]},{"t":"code","lang":"markdown","label":"Markdown","text":"# Project rules\n\n## Stack\nNext.js app router, TypeScript, Postgres via Drizzle, Tailwind.\nDeployed to Cloudflare Workers. Node 20.\n\n## Commands\nnpm run dev · npm run build · npm test · npm run db:migrate\nAlways run `npm run build` before saying a change is finished.\n\n## Structure\n- Database queries: lib/queries.ts only\n- API routes: app/api/<name>/route.ts\n- Anything a browser component imports must not touch the database\n\n## Domain rules\n- Money is integer paise. Never a float.\n- Bookings cannot overlap for the same stylist.\n- Opening hours 09:00–19:00 local, stored UTC.\n\n## Do not\n- Add dependencies without asking\n- Edit anything in drizzle/migrations/\n- Refactor files I did not mention\n\n## Learned the hard way\n- The seed script wipes the dev database. Never run it to check something.\n- Two components are named BookingCard. The one in app/ is dead."},{"t":"p","runs":[{"text":"That is under 200 words and it will prevent more failures than any prompt you write this month."}]},{"t":"h2","id":"the-line-that-pays-for-the-file","runs":[{"text":"The line that pays for the file"}]},{"t":"p","runs":[{"text":"“Always run "},{"text":"npm run build","code":true},{"text":" before saying a change is finished.”"}]},{"t":"p","runs":[{"text":"An agent that verifies its own work catches the type errors, the missing imports and the broken build before you have opened the browser. It costs a few seconds per change and removes the most common form of false completion: a confident summary of a change that does not compile."}]},{"t":"h2","id":"keep-it-in-git","runs":[{"text":"Keep it in git"}]},{"t":"p","runs":[{"text":"The rules file belongs in the repository, committed like code. It is documentation that stays true, because unlike a README, something reads it every day and you notice when it is wrong."}]},{"t":"p","runs":[{"text":"And when you hand the project to somebody else (a collaborator, a developer you hire, yourself in six months) this file is the fastest briefing that exists."}]}],"check":{"question":[{"text":"Which line in a project rules file does the most to stop an agent reporting work as finished when it is not?"}],"options":[{"text":[{"text":"“You are a careful senior engineer who double-checks everything.”"}],"correct":false,"tempting":[{"text":"Role framing changes tone rather than behaviour, and does nothing to introduce an observation the model can fail against."}]},{"text":[{"text":"“Always run npm run build before saying a change is finished.”"}],"correct":true,"tempting":null},{"text":[{"text":"“Write clean, well-structured, maintainable code.”"}],"correct":false,"tempting":[{"text":"States a quality goal with no way to check it; the model already believes its output meets this description."}]},{"text":[{"text":"“Explain every change you make in detail before making it.”"}],"correct":false,"tempting":[{"text":"Produces more text about intended work, which is a second generation rather than evidence about the code on disk."}]}],"order":[2,3,1,0],"why":null},"prev":{"slug":"choosing-a-stack-and-stopping","title":"Choosing a stack, and then stopping","minutes":8},"next":{"slug":"autonomy-and-where-to-keep-your-hand","title":"Autonomy, and where to keep your hand","minutes":8}}}