All modulesModule 06
Act II · HowCycle step 3/911 min+70 XP

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.

After this module you can

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.

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.

200lines: the target the docs set for a memory fileClaude Code · memory ↗
60,000+open-source repos carrying an AGENTS.mdagents.md ↗
9 Dec 2025AGENTS.md becomes a founding project of the Agentic AI FoundationLinux Foundation ↗

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.

Go deeperMonorepos, 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)

Quick check

Your teammates keep letting the agent call the database straight from a component, instead of going through src/lib/db. Where does the rule belong?

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.

AGENTS.md builder10 rules

Your agent starts every session with no memory of your project. This file is the memory. Pick what goes in it — and notice which lines are traps.

What to include

CLAUDE.md
# qairu-event-signup

Astro + Tailwind, Supabase for data, deployed to Cloudflare Pages.

## Commands
- Install: `npm ci`
- Dev server: `npm run dev` (port 4321)
- Build: `npm run build` — must pass before every commit
- Test: `npm test` (Playwright). Run it after changing anything under src/pages.

## Conventions
- Components in src/components, one per file, named exports only
- Conventional Commits (feat:, fix:, docs:). Small and atomic.
- Every English string needs a Kazakh counterpart in src/i18n/ui.ts

## Guardrails
- Never commit .env or any key. Secrets live in the host dashboard.
- Never run migrations or destructive SQL against production
- If a requirement is ambiguous, ask instead of guessing

## Definition of done
Build passes, tests pass, no secrets committed, and the change is described in one commit message.

Save this as CLAUDE.md in your project root. Claude Code loads it automatically every session. Name it AGENTS.md and Codex, Cursor, Gemini CLI and others read it too.

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.

Master-prompt skeletonany agent · start of a task
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.

Running project · 06QAIRU Event Sign-up

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.

Take it with you · prompt-packCLAUDE.md / AGENTS.md starter + master-prompt skeleton

The 40-line memory file, the include/exclude test, and the master prompt — ready to paste into your own repo.