Put the recurring decisions in the project
You should not have to explain the same price format, test command, or file boundary every time you open Claude Code. Put those decisions in a project-root CLAUDE.md that your team can review alongside the code.
This is project instructions, not auto memory. You write the former. Claude maintains the latter as it learns from work. A CLAUDE.md is not a transcript of your last session, a guarantee of compliance, or a replacement for tests.
The official memory documentation describes how Claude Code loads instructions from the working directory and its ancestors. A file deeper in the tree can load when Claude works there. Start in the project you intend to change, and check which files actually loaded rather than relying on the filename alone.
Try it without touching your real project
Use a new empty folder, Claude Code, and Node.js 24. Do not run the example inside a customer repository. Read downloaded files before running them.
-
Create a small, reviewable project contract. This adds
CLAUDE.mdin the example folder. It does not change your global Claude configuration. If the folder already contains that file, stop and choose a fresh folder rather than overwriting it.+# Quote calculator conventions + +- Money is integer cents. Do not convert to decimal dollars. +- Export `quoteTotal(items)` from an ES module. +- Each item has `unitPriceCents` and `quantity`, both nonnegative safe integers. +- Return `{ totalCents, currency: "USD" }`, including for an empty list. +- Reject invalid inputs or an unsafe total with `RangeError`. +- Do not add dependencies.The plus signs mark additions in this diff; do not put them in the file. You can instead save the example instruction file as
CLAUDE.md.Check: open your saved file. It names the input fields, output shape and failure behavior without describing unrelated projects. Never put passwords or customer data in instructions.
-
Start a fresh Claude Code session in that folder. This starts a new conversation; it does not resume an old one. Use
/contextand check the Memory files section for this project’sCLAUDE.md./memoryhelps you find and edit memory locations, but a model saying “I read it” is not the same as seeing the loaded-file entry.Check: the actual example file appears in the loaded context. If it does not, stop here. Do not paste the missing rules into the prompt and call that automatic loading. Bare mode and safe mode intentionally skip instruction discovery.
-
Ask for one small implementation. This adds
quote.mjsin the example folder. Ask:Write the quoteTotal function for this project. Save it as quote.mjs. Do not add dependencies or change CLAUDE.md. Show me the diff.
Check: review the diff. It exports
quoteTotal, acceptsunitPriceCents, returnstotalCentswithcurrency: 'USD', and does not add taxes, discounts or other features the contract never requested. Treat generated code as code to review, not a command to run blindly. -
Test the behavior separately. Save the four-check test file beside
quote.mjs, inspect it, then run:node --test quote.test.mjsCheck: all four tests pass: an ordinary two-line quote, an empty quote, malformed inputs or invalid item values, and arithmetic that exceeds JavaScript’s safe integer range. The ordinary quote must total 4,498 cents, not 44.98 dollars. Do not edit the expected results to fit the implementation.
-
Repeat with another new session. Keep
CLAUDE.md; preserve the first implementation elsewhere inside your disposable folder and ask a fresh session to write a newquote.mjs. Review that diff and rerun the same test file.Check: you did not repeat the pricing rules in the prompt or resume the earlier conversation. This checks an ordinary project workflow, not an isolated instruction experiment: a new session can still read earlier code and tests. A passing run is evidence for that run, not a promise about the next one.
PASS: the project’s instruction file is listed as loaded, and the implementation from each fresh session passes the unchanged four-check file. If either condition fails, the card has not passed.
What we measured, including the misses
On 2026-10-03, we made six fresh automated Sonnet 5.5 requests on one Linux workstation. Each used the same six-rule file and the same prompt: “Write the quoteTotal function for this project. Return only the complete JavaScript ES module source, without Markdown fences or explanation. Do not use tools.” The four test cases were written before the requests and kept outside the model’s project folder. During verification, deliberate mutations exposed missing assertions for a fractional quantity whose product is an integer and malformed input containers or items returning the wrong error class. We strengthened the input case and rechecked all six saved outputs with the final downloadable checks; the table reports those results. We did not repair any generated implementation or relax an expected result.
| Launcher | First session | Second session | Project file confirmed loaded? |
|---|---|---|---|
| Restricted, tool-free | 0/4 checks | 0/4 checks | Not recorded |
| Tool-free, empty settings-source selection | 0/4 checks | 1/4 checks | Not recorded |
| Tool-free, project settings-source selected | 4/4 checks | 4/4 checks | Yes, both startup receipts |
The first two outputs expected unitPrice or price, not unitPriceCents, and returned dollars. They were plausible answers to a generic quote-calculator request, not answers to this project’s contract.
For the final pair, we used --setting-sources project and a temporary InstructionsLoaded observer passed through --settings. It recorded only this example’s instruction-file path, memory_type: Project, and load_reason: session_start, not file contents. The observer supplied no instructions to the model. Built-in tools and MCP servers were unavailable; each -p invocation used a distinct session, without continue, resume or session persistence. No saved user settings were changed.
Both final outputs matched the reference implementation, apart from quote formatting in the published copy. They were identical to each other. These are two small successful runs, not independent evidence of a general success rate. The launcher and observation setup changed during diagnosis, so this is not a controlled benchmark isolating one flag’s causal effect.
We did not capture load receipts for the failed runs. They therefore do not prove that Claude ignored instructions it had received. The useful lesson is narrower: confirm the project file loaded, then test the resulting behavior. Do not declare success because a file exists or because the model says it read it.
What you will see
Expected values to be strictly deep-equal:appeared when the empty quote returned a number or a different object instead of{ totalCents: 0, currency: 'USD' }. Inspect the actual and expected values. This can be an output-contract mismatch, not bad addition.unitPrice must be a finite numberappeared when generated code expectedunitPrice, but the project and test usedunitPriceCents. Check the field names before changing the inputs. It can look like missing data when the implementation is using the wrong contract.
Neither message alone proves an instruction-loading defect. A loaded-file check and the generated diff distinguish missing context from implementation mistakes.
What this doesn’t show
This is a deliberately small quote example on one Linux workstation, not a checkout, tax engine, memory benchmark, or productivity study. The test checks four behaviors; it is not a security audit and cannot establish that every instruction was followed.
The initial failed trials used Claude Code 2.1.288, the reported model claude-sonnet-5-5, and Node.js 24.12.0. We did not test macOS, Windows, competing instructions, large repositories, or auto-memory recall. A new session may produce different code.
Claude Code’s instruction guidance says these files provide context, not enforced configuration. Use tests for output contracts and permissions for actions that must be blocked. Keep your real project’s existing instructions; add the smallest concrete rules that prevent work you actually repeat.