Context & the Single Source of Truth
One short file decides what your agent knows — and every line in it is paid for again in every session.
write a project memory file that actually changes agent behaviour, and a master prompt that carries everything the file should not
Бұл бет әлі аударылмаған, сондықтан ағылшынша нұсқасы көрсетіліп тұр.
Your agent starts every session knowing how to program and nothing about your project. Not the test command. Not the rule you explained three times yesterday. There is one file that fixes this, and almost everyone overfills it.
Overfilling is not a small mistake. Claude Code’s guide names “over-specified CLAUDE.md” as one of its five common failure patterns: bloat makes the agent ignore rules that are sitting right there in the file. The fix is counter-intuitive — the file that changes behaviour most is the short one. The docs set the target at under 200 lines. (best practices, memory)
Context is a budget you spend, not a container you fill
In September 2025 Anthropic published the post that renamed the whole discipline. Context engineering is the work of choosing which tokens occupy the window at the moment the model answers. Attention is finite. Every token you add spends some of it, and recall drops as the window fills — the effect the post calls context rot. (Effective context engineering for AI agents)
That reframes your memory file. It is not a folder of documentation. It is a standing charge against a budget, loaded at the start of every session, paid for again in every session — including the ones about a file it has nothing to do with.
The same post gives the target for how a standing instruction should read: the “right altitude”. Specific enough to steer the model, general enough to work as a heuristic. Not brittle if-else rules that break on the first case you did not imagine. Not vague vibes like “write good code”. A rule at the right altitude sounds like this: all database access goes through src/lib/db, with no Supabase calls inside components.
Prompt engineering was about the sentence you type. Once an agent runs in a loop — reading files, running commands, reading the output, deciding again — your sentence is a small fraction of what the model sees. The post positions context engineering as the successor: what matters is every token in the window, including the files that got read, the output that got dumped in, and what your memory file is still charging you for. A perfect prompt in a polluted window loses to an ordinary prompt in a clean one.
What belongs in the file, and what quietly poisons it
The docs give an include list and an exclude list. They are worth memorising, because most bad memory files are made entirely of the second one.
- A tour of every folder in the repo
- Long pasted API documentation
- “Write clean, maintainable code”
- Standard language conventions the model already knows
- Anything readable from the code itself
- Fast-changing facts (the current sprint, today’s bug)
- Commands the agent cannot guess: install, dev server, typecheck, how to run one test file
- Style rules that differ from the defaults
- Repo etiquette: branch names, never push to
main, PR expectations - Architecture decisions specific to this project
- Environment quirks and gotchas that have already bitten someone
- Pointers — file paths and links — instead of pasted content
Two rules keep it short. To add: write a line when the agent makes the same mistake twice. To cut: for every line ask whether removing it would cause a mistake. If the answer is no, delete it. Run /doctor on a file you have already committed and it proposes cuts for you. And if the agent is ignoring a rule that is definitely in the file, the file is probably too long — emphasis words like IMPORTANT only work when one or two lines carry them. (memory, best practices)
Three things must never go in, for different reasons:
Secrets. The project file is committed. Put the shape of your config in it (.env.local is required, see .env.example) and never a value. A Read(./.env) deny rule helps, but the docs are blunt that these rules are convenience, not a security boundary: the deny covers cat and head in Bash, and not a script that opens the file itself. (permissions)
A style manifesto. Platitudes are on the official exclude list. They cost tokens in every session and change nothing, because “write clean code” gives the model no decision it could not already make.
“Read all the docs before starting.” This is the opposite of how a good agent works. Anthropic’s context post calls the alternative just-in-time retrieval: keep lightweight identifiers — paths, queries, links — and let the agent load the data at runtime. Claude Code already does this, using grep and glob instead of indexing everything up front. Your file should hand it addresses, not cargo.
CLAUDE.md, AGENTS.md, and which one your tool actually reads
AGENTS.md is the open standard version of the same idea: plain Markdown, no required fields, a predictable place for build commands, test commands, style, security notes and PR rules. Its own site describes it as a “README for agents”. (agents.md)
It is no longer one company’s format. On 9 December 2025 the Linux Foundation announced the Agentic AI Foundation, with three founding projects: MCP from Anthropic, goose from Block, and AGENTS.md from OpenAI. Platinum members include AWS, Anthropic, Block, Bloomberg, Cloudflare, Google, Microsoft and OpenAI. Today the file is read by Codex, Cursor, GitHub Copilot, Aider, Zed, VS Code, JetBrains Junie, Jules, Warp, Devin and more.
Claude Code reads it too, with one rule you have to know. Since v2.1.277 it reads AGENTS.md natively when there is no CLAUDE.md in or above the working directory. If a CLAUDE.md exists, only CLAUDE.md is read, unless you set project instructions to claude-md-and-agents-md. And in some sessions — Bedrock, or telemetry disabled — native reading is not available at all. (memory#agents-md)
So the portable move — the one that survives switching tools and switching versions — is this: make AGENTS.md the single source of truth, and put exactly one line in CLAUDE.md:
@AGENTS.md
Now every tool in the room reads the same file, and there is only one file to keep honest.
ТереңірекMonorepos, Codex paths, and scoped rules
In a monorepo the nearest AGENTS.md to the edited file wins, and an explicit instruction in chat overrides any file. OpenAI’s own main repo is cited as carrying 88 of them.
Codex reads a global ~/.codex/AGENTS.md, then every directory from the git root down to your current one, with a combined cap set by project_doc_max_bytes (32 KiB by default). (Codex agent configuration)
Claude Code has the matching trick for large repos: subdirectory CLAUDE.md files load on demand when Claude reads files there, and .claude/rules/*.md with a paths: frontmatter load only when a matching file is touched. That is how you keep a rule about migrations from costing anything on a CSS task.
Where the file lives decides who it binds
The same file name exists at four levels, from broad to specific. Picking the wrong one is how a good rule ends up in the wrong place: stuck on your laptop, or pushed onto every project you open.
| Scope | Where it lives | Who it binds |
|---|---|---|
| Managed policy | C:\Program Files\ClaudeCode\CLAUDE.md (Windows), /etc/claude-code/CLAUDE.md (Linux/WSL), /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) |
everyone in the organisation — set centrally, not by a repo |
| User | ~/.claude/CLAUDE.md |
you, in every project you open |
| Project | ./CLAUDE.md or ./.claude/CLAUDE.md |
everyone who clones the repo — commit it |
| Local | ./CLAUDE.local.md |
you, in this project only — add it to .gitignore |
There is a second memory system running beside yours: Claude keeps its own notes in ~/.claude/projects/<project>/memory/, with the first 200 lines or 25 KB of MEMORY.md loaded each session. Saying “remember that I prefer short answers” writes there. Saying “add this to CLAUDE.md” writes to your file. Use /init to generate a starter, /memory to open and edit, and /context to confirm what actually loaded. (memory)
A memory file is not a PRD
Module 4 gave you a PRD: what we are building, for whom, and what “done” means. It answers a question once. Your memory file answers a different question — how this repository works — and it answers it forever, in every session, including the ones that have nothing to do with the feature you specced. Paste the PRD into CLAUDE.md and you will pay for a finished feature’s user stories in every future session about an unrelated CSS bug. Link the PRD from the memory file instead.
There is one more reason the file matters, and it is the one that convinces experienced developers. A project-root CLAUDE.md survives /compact: it is re-read from disk. Instructions you only said in chat do not. When the window fills and Claude Code summarises the conversation away, your file is the part of the context that comes back. (memory)
A working AGENTS.md you can steal
Around 40 lines, and nothing in it is a fact the agent could read out of the code. Note the last two sections: a compaction instruction, and pointers instead of pasted docs.
# AGENTS.md — qairu-signup
## What this is
Next.js 15 (App Router) + TypeScript + Tailwind + Supabase. UI strings in EN and KK.
## Commands
- Install: `pnpm install`
- Dev server: `pnpm dev` (http://localhost:3000)
- Typecheck: `pnpm typecheck` Lint: `pnpm lint`
- One test file: `pnpm vitest run path/to/file.test.ts` All tests: `pnpm test`
- E2E: `pnpm e2e` (needs dev server running)
## Workflow
- For anything bigger than a one-line change: explore, write a plan, wait for approval.
- After a series of edits run typecheck + the related tests. Show the output.
- Small commits, message = what and why. Never push to `main`; open a PR.
- If you have been corrected twice on the same thing, stop and ask.
## Code rules that differ from defaults
- Server Components by default; add "use client" only when state or effects are needed.
- All DB access goes through `src/lib/db/*`. No Supabase calls inside components.
- Every user-facing string goes through `t()` with keys in `messages/en.json` and `messages/kk.json`.
- No new dependencies without asking.
## Gotchas
- `.env.local` is required (see `.env.example`). Never print or commit secrets.
- Supabase row-level security is ON; new tables need a policy or queries return empty.
- Kazakh text: test with long words; do not truncate with fixed widths.
## Do not touch
- `supabase/migrations/*` that are already applied — add a new migration instead.
- `src/generated/*` (generated types).
## When compacting
Keep: the list of modified files, the current plan step, and the test commands.
## More detail (read only when relevant)
- Architecture: docs/architecture.md - API conventions: docs/api.md - Release steps: docs/release.md
Read it against the exclude list. There is no folder tour, no pasted documentation, no “write clean code”. Every line would cause a mistake if you removed it — which is exactly the test.
The master prompt carries what the file cannot
Your memory file holds what is always true. Your prompt holds what is true today. Beginners fail by trying to make one do the other job: a prompt that re-explains the stack every time, or a memory file stuffed with this week’s task.
A master prompt has an anatomy, and every line does one job. The mission and the reason for it, so the agent can make trade-offs on its own. The context it must read first, including an existing file whose shape it should copy. The constraints, including what is out of scope. A phased process where each phase has an exit. A definition of done that a command can prove. What to do when it gets stuck. And the shape of the answer you want back.
GOAL [one sentence: what should be true when you are done]
WHY [who needs it / what it unblocks — helps the agent make trade-offs]
CONTEXT Read first: @[file], @[file]. Pattern to follow: [existing example file].
Docs: [URL]. Relevant history: [issue / PR / commit].
CONSTRAINTS Stack: [..]. Do not change: [..]. No new dependencies. Out of scope: [..].
PROCESS 1) explore and summarise 2) plan and wait for OK 3) implement in small steps
4) verify 5) commit. Use subagents for broad searches.
DONE MEANS [runnable check: `command` exits 0 / test names pass / screenshot matches]
Show evidence: command + output (or screenshot).
IF STUCK After two failed attempts at the same thing: stop, explain what you tried,
propose options. Ask instead of guessing on anything ambiguous.
OUTPUT Short summary: what changed, where, how verified, what is left.
LIMITS [max turns / budget / time], then stop and report.DONE MEANS is the line that separates this from a wish. If the finish condition is not something a command can prove, the agent’s only signal is that the work looks done — and then you are the test suite.
IF STUCK mirrors a rule from the docs themselves: after two failed corrections on the same issue, stop. A clean session with a better first prompt beats a long polluted one.
When the answer is a subagent, not a longer file
Sometimes the knowledge does not fit in a standing file and does not belong in the main conversation either. Anthropic’s context post names three techniques for long-running work: compaction (summarise and restart the window), structured note-taking (the agent writes notes to a file outside the window), and sub-agent architectures.
That third one is the daily habit. A subagent is a helper with its own context window, its own system prompt and its own tool list. It does the noisy work — searching a large codebase, reading a log file, comparing three libraries — and returns a condensed summary to the lead. The raw material never enters your window. In Claude Code, “use subagents to investigate X” is enough to start one. (subagents)
The trade is real: you get the summary, not the evidence. So ask for what you will need inside it — file paths, line numbers, the exact failing command. And know the failure it prevents. Infinite exploration is another of the guide’s five named failure patterns: an unscoped “investigate the codebase” fills the window before the real work starts.
Give QAIRU Event Sign-up a single source of truth
Create AGENTS.md in your project root, and a CLAUDE.md containing one line: @AGENTS.md.
Fill in four sections only, using the example above as the shape: Commands (install, dev server, how to run one test), Workflow (plan before non-trivial changes, show test output, never push to main), Code rules that differ from defaults (at least the bilingual-strings rule — every user-facing string exists in Kazakh and English), and Gotchas (what a new person would get wrong in the first hour).
Then prove it works. Start a fresh session, run /context and find your file in the memory list. Ask for a small change — a new field on the sign-up form — and watch whether it comes back bilingual, with test steps, and without a new dependency. If it does not, your file is too long or your rule is not concrete enough. Cut, sharpen, try again.
Finally, paste the master-prompt skeleton into docs/prompt-template.md and commit both files. Module 7 will run a real agent against them.
The 40-line memory file, the include/exclude test, and the master prompt — ready to paste into your own repo.