Keep CLAUDE.md concise enough to remain useful
Keep CLAUDE.md focused on verified repository facts, distinguish written instructions from remembered notes, and remove stale guidance before it misleads a task.

For a developer working repeatedly in one repository, CLAUDE.md should preserve the facts that make the next task easier to execute correctly. Useful entries include the actual test command, a shared-module boundary, and a constraint that is easy to miss by reading one file. The document loses value when it becomes a transcript of every previous conversation. This lesson assumes you can read a package script and run Python with Node installed; it does not require a live Claude session.
The Claude Code memory documentation, retrieved on September 21, 2026, distinguishes instructions written by the project owner from automatic memory maintained by the tool. It also documents support for repository instruction files and scoped guidance. These mechanisms provide context; they should not be mistaken for an access-control system.
Give each fact an appropriate home
A repository-wide rule belongs in shared guidance. A local preference about output verbosity may belong in user-level configuration. A hypothesis from an unfinished debugging session belongs in a task handoff with an uncertainty label. Mixing these categories can make a tentative observation look like a permanent architectural rule.
Suppose a hypothetical project builds a desktop client and a shared TypeScript core. The core must remain independent of browser globals so it can run in both desktop and server-side tests. That constraint deserves a short, explicit instruction with a reason.
# Project context
The shared core runs in the desktop client and in Node-based tests.
Keep browser globals out of packages/core; pass platform adapters instead.
Run the package's documented test script after changing its public behavior.
Check package.json for the current command before copying an old task note.
Generated API types come from schema/api.yaml.
Edit the schema and use the generation script rather than editing output files.
The paths describe a teaching example. In a real repository, verify them before adding them. An instruction file full of plausible but nonexistent paths is more damaging than a missing file because it creates false confidence about where work belongs.
The figure separates durable repository rules from temporary task evidence. A failed test observation can be important without becoming a rule that every future task must repeat. Its value comes from the specific commit and environment where it occurred.
Keep commands tied to their source
Commands drift when scripts are renamed or packages are reorganized. A copied command can remain in memory long after the repository has moved to another test runner. Include the command’s directory and, where useful, the configuration file that defines it.
The Claude Code best-practices guide recommends concise, useful instructions and verification. Apply that advice by testing the file against a real task: can the agent locate the relevant command, identify the shared boundary, and explain what a successful check establishes?
A command that exits successfully may still run zero tests because a filter no longer matches. Read the output when maintaining the instruction file. The instruction should point to a meaningful check, not merely a shell command that returns zero.
Check whether a remembered command executes its intended test
The following self-contained experiment creates a temporary teaching repository, runs its commands and removes it afterward. Its schema file is only a path placeholder, not a validated API definition. The shared core has one actual string-label function and one named test. The marker is written inside that test, so the experiment can distinguish executing the test body from merely obtaining a successful process exit.
import json
import subprocess
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
root = Path(directory)
(root / 'packages/core').mkdir(parents=True)
(root / 'schema').mkdir()
(root / 'schema/api.yaml').write_text('openapi: 3.1.1\n')
scripts = {
'test:core': 'node --test core.test.mjs',
'test:empty': 'node --test --test-name-pattern=absent core.test.mjs'
}
(root / 'package.json').write_text(json.dumps({'scripts': scripts}))
core = root / 'packages/core/label.mjs'
core.write_text('export const label = name => name.trim();\n')
(root / 'core.test.mjs').write_text(
'import test from "node:test";\n'
'import assert from "node:assert/strict";\n'
'import {writeFileSync} from "node:fs";\n'
'import {label} from "./packages/core/label.mjs";\n'
'test("core label", () => { writeFileSync("ran.txt", "yes"); '
'assert.equal(label(" Ada "), "Ada"); });\n'
)
print('old script exists:', 'test' in scripts)
print('current script exists:', 'test:core' in scripts)
print('schema path exists:', (root / 'schema/api.yaml').is_file())
def inspect(script):
(root / 'ran.txt').unlink(missing_ok=True)
result = subprocess.run(
['npm', 'run', '--silent', script], cwd=root,
text=True, capture_output=True, check=False
)
print(script, 'exit:', result.returncode,
'body ran:', (root / 'ran.txt').is_file())
for line in result.stdout.splitlines():
if line.startswith(('# tests ', '# pass ', '# fail ', '# skipped ')):
print(line)
return result
inspect('test:core')
inspect('test:empty')
core.write_text('export const label = name => window.document.title;\n')
inspect('test:core')
inspect('test:empty')
The first three lines report that the remembered test script is absent, the current test:core script exists and the schema path exists. They establish discoverable repository facts. They do not establish that a command exercises useful behavior or that the schema is valid. The script then supplies the missing behavioral evidence.
In the local Python 3.12.3 and Node 22.23.2 run, the ordinary core test exits zero and writes its marker. The filtered command exits zero without writing the marker. After deliberately replacing the core function with a browser-global dependency, the ordinary test exits one and still writes the marker before its assertion fails. The filtered command remains green with no marker. A remembered command can therefore hide the precise regression the architectural note was meant to prevent.
This Node run also reports one pass in the filtered command’s summary: its test-file entry succeeds even though the named test body is excluded. Merely requiring a nonzero pass count would miss this case. Read which test ran and connect its assertion to the changed behavior. The marker is a teaching probe, not a proposal to instrument every real test with a file write.
The fixture establishes this one exercised core path’s Node behavior. It is not a static import analyzer, proof that the entire package avoids browser APIs, a schema generator test or an experiment in Claude instruction loading. Its subprocesses run only the two literal scripts created above. Do not turn it into a utility that executes arbitrary instructions copied from untrusted notes.
Anthropic’s Effective context engineering for AI agents, published September 29, 2025, recommends retaining a small set of useful context and using references to retrieve details when needed. Here, a short instruction can name the current test and its purpose while a linked report keeps exact command output. The article motivates context selection; this fixture does not measure model recall or claim that a shorter CLAUDE.md guarantees compliance.
Label remembered evidence honestly
A note such as “the export test fails because of timezone handling” may begin as a hypothesis. Before preserving it as a fact, inspect the failure and verify the cause. Otherwise, later tasks can inherit a confident diagnosis that was never established.
A useful handoff distinguishes observed facts, interpretations, and next checks. For example: the test fails for a date near midnight; the failure was observed on a specific commit; timezone conversion is a hypothesis; the next check is to compare the serialized value before and after the adapter. That structure lets a future session continue without treating speculation as authority.
Store sensitive data according to the repository’s policy. A memory note rarely needs an access token, customer message, or full production log. Prefer a redacted error signature and a controlled reference to the original evidence. Persistent context should not become an accidental archive of secrets.
Resolve contradictions at the source
If CLAUDE.md says to use one package manager while the lockfile and current setup documentation specify another, investigate before executing a broad installation. The contradiction is a maintenance issue. Ask which source is authoritative when the repository does not resolve it, and update the instruction only with evidence.
Local guidance can also conflict with a task’s explicit request. A general instruction to avoid generated files may still permit regenerating them through the documented script. Interpret the rule according to its purpose, and preserve the distinction between editing generated output manually and producing it from its source.
Do not turn every exception into another paragraph. If several rules contradict each other, rewrite the relevant section around the current contract. Accumulating patches to old wording can leave the agent with a list of mutually incompatible instructions.
Review memory as maintained documentation
After a meaningful architecture change, check whether the instruction file still names the right boundaries and commands. Remove finished-task details that no longer guide future work. Keep a link to a longer design note when the reasoning matters but would overwhelm the instruction file.
For a first maintenance pass, select three entries and verify each against the checkout: one command, one path, and one architectural constraint. Record any uncertainty rather than filling gaps from memory. This modest review can expose whether the file describes the project that exists or the project someone remembers.
The result should be useful to a new human contributor too. If an instruction only makes sense to the agent that wrote it, add the missing context or remove it. Persistent guidance earns its place when it helps the next reader make a correct decision with evidence they can inspect.


