House Notes

Give Claude Code project instructions you don't have to repeat

Two fresh sessions passed all four quote-calculator checks after we confirmed the project instructions loaded. Four earlier attempts did not pass the full check. Touches: one CLAUDE.md and a disposable example, not global settings or saved memories. Undo: remove the example folder; in a real project, revert only your approved additions. Say to the agent: Write a short project contract, show the diff, then verify it in a fresh session without repeating its rules.

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.

  1. Create a small, reviewable project contract. This adds CLAUDE.md in 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.

  2. Start a fresh Claude Code session in that folder. This starts a new conversation; it does not resume an old one. Use /context and check the Memory files section for this project’s CLAUDE.md. /memory helps 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.

  3. Ask for one small implementation. This adds quote.mjs in 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, accepts unitPriceCents, returns totalCents with currency: '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.

  4. Test the behavior separately. Save the four-check test file beside quote.mjs, inspect it, then run:

    node --test quote.test.mjs

    Check: 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.

  5. 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 new quote.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 number appeared when generated code expected unitPrice, but the project and test used unitPriceCents. 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.

Reader poll

Self-selected, unverified responses. These counts describe this poll's responses.

JavaScript is needed to send an answer and load this poll's counts.

Enter the House