Two Ecosystems: Claude Code and OpenAI Codex

CLAUDE.md: Standing Guidance for Claude Code

How to design, place, verify and maintain a short CLAUDE.md file so Claude Code carries stable project guidance across sessions, and when a different…

Chapter 29Two Ecosystems: Claude Code and OpenAI Codex

Picture a small booking service. After several rounds of changes, the agents keep forgetting the same two agreements: creating a reservation must stay idempotent, and checks are run through the project's package manager. The team wants to write this down once so that Claude Code takes the rule into account in every future session. CLAUDE.md can do that job: it is a plain text file that holds persistent context about the project.

In this unit, Application Programming Interface (API) means the interface through which other programs talk to a service. We will look at how to design a short instruction file specifically for Claude Code, where to put it, how to confirm it is actually loaded, and how to keep it current. The unit builds on the ideas already covered in context as a limited resource, sources of truth, handoffs between agents and sessions, repository knowledge architecture and the instruction hierarchy, which explains the difference between loading, precedence and technical enforcement. Here we focus on working with the file itself.

All examples are illustrative and invented. They do not describe a real service, a real environment or a real test run. The unit contains no exercises for the reader.

What CLAUDE.md is for

Claude Code reads CLAUDE.md as human-written context for a project, for your personal work, or for an organisation. It is the way to pass along information that is worth taking into account across many sessions: a verified command for running the project, a critical invariant, where a contract's source lives, or a rule for how to report checks. The file is loaded into the model's context. It shapes how Claude makes decisions, but it does not by itself block access to any tool, file, network or command.

Add a rule when there is a recurring reason for it: an agent has already missed a required document twice, reviewers keep finding the same mistake, or every new team member has to have a shared convention explained to them. Phrase the rule so a person can check whether it was followed. "Write quality code" names no observable action. "When changing reservation transitions, read the lifecycle description and update its tests" gives a precise action and a precise scope.

Claude Code is a distinct agent product with its own mechanisms for context, tools and settings. The fact that the ordinary Claude chat, or some other integration, can read a Markdown file does not mean that it loads CLAUDE.md automatically. For any other product, check that product's own documentation.

Where Claude Code finds instructions

Location determines whom a file applies to. The table lists the most common locations. In the current documentation, the organisation-wide policy file lives at a different system path on each platform.

Scope Location Typical purpose
Organisation macOS: /Library/Application Support/ClaudeCode/CLAUDE.md; Linux and Windows Subsystem for Linux (WSL): /etc/claude-code/CLAUDE.md; Windows: C:\Program Files\ClaudeCode\CLAUDE.md Shared standards rolled out by the organisation
User ~/.claude/CLAUDE.md Personal preferences that apply across projects
Project ./CLAUDE.md or ./.claude/CLAUDE.md Team conventions stored with the project
Local project ./CLAUDE.local.md Personal notes for this clone only; add the file to .gitignore

When Claude Code starts in a project directory, it loads CLAUDE.md and CLAUDE.local.md from that directory and from its parent directories. The contents of the files it collects are combined into the context: files higher up the directory tree come first, files lower down come later. Within a single directory, the local file is added after the team file. This describes the order in which the model sees the text. It is not a technical blocking mechanism, and it is not a general rule for other products.

Instruction files in subdirectories do not necessarily enter every session at startup. Claude Code adds them when it works with files in those subdirectories. So place a local rule as close as possible to the code it concerns, or use a separate path-scoped rule file. Do not assume a file is active just because it exists in the repository.

Compatibility with AGENTS.md

AGENTS.md is the name of an instruction file used by some other development tools. In its default mode, Claude Code reads AGENTS.md in place of the project CLAUDE.md when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working directory or above it. The files ~/.claude/CLAUDE.md, the organisation-wide CLAUDE.md and .claude/rules/ do not affect this check.

The Project instructions setting is opened with the /config command. Depending on the selected mode, Claude Code can read one kind of file or both:

Mode Which project instructions it picks
claude-md-or-agents-md CLAUDE.md or AGENTS.md; by default it looks for the compatible file under the condition described above.
claude-md-and-agents-md Both kinds: CLAUDE.md and AGENTS.md.
claude-md Only CLAUDE.md.
managed-only At startup, only the managed organisation-wide CLAUDE.md and auto memory.

This choice does not switch off loading of nested CLAUDE.md files, .claude/rules/ or path-scoped rules when Claude reads the files they belong to. Check the project's actual setting, especially if the repository contains both kinds of file or a personal local CLAUDE.local.md.

Three version-related facts, checked between 23 and 26 September 2026, need to be kept apart:

  • The current documentation says that reading AGENTS.md directly is supported in Claude Code from version 2.1.277 onward. Some sessions may not do it: those with feature-flag collection disabled, those running through a third-party provider, or those with the built-in module disabled. The first session after an update may also fail to load the file.
  • In the official release list, version 2.1.283, published on 25 September, was already the newest as of 26 September. An earlier research snapshot that showed 2.1.278 as the newest version became outdated after the subsequent releases.
  • In versions before 2.1.280, the /memory and /context commands did not show an AGENTS.md that Claude had read directly. So in an older version, the file's absence from that list does not, on its own, prove that it was not loaded.

For CLAUDE.md files, the documentation suggests running /context and checking the list of Memory files. After you change an instruction, the most reliable approach is to start a new session and check the list again. There is one documented re-read point: after /compact, Claude Code reads the root project CLAUDE.md from disk and adds it to the context again; nested CLAUDE.md files and rules with paths: are loaded when Claude reads the files they belong to. This does not mean that any edit to any already-loaded instruction automatically and immediately changes the current context. If the behaviour matters, check the file that was actually loaded, either in a new session or at a documented refresh point.

Imports

When you need the text of another file to be added to the context unconditionally, Claude Code supports imports written as @path/to/file. An import is expanded at load time. A relative path is resolved from the file that contains the import, not from the current directory. Imports can be nested at most four hops deep. Absolute paths are allowed. The first import from a project file that reaches outside the working directory requires the user's approval.

An import is not just a reference: the entire content goes into the context and uses up its capacity. For example, @docs/reservation-policy.md includes that file in every relevant session, while writing `docs/reservation-policy.md` merely names the place Claude should go when it needs to. For a detailed reference or a long procedure, a short pointer is usually enough. Do not add an import just to make sure the file "definitely gets found".

What belongs in the file

The root file should be a short guide to the stable rules that apply to almost any work in the repository. Typically that means:

  • what the project does and where its boundaries lie;
  • two or three important directories or contract sources that an agent is unlikely to guess;
  • commands for running or checking the project, verified against the project's current files;
  • a critical invariant that is easy to break and genuinely has to hold across many changes;
  • a document that must be read before a particular kind of change;
  • the expected shape of the report on changed files and checks performed.

For every command, name where it was verified: the manifest file, the repository's instructions, or continuous integration (CI), the process that runs automated checks on changes. If a command has not been verified yet, mark it as an assumption or find out first. A command name mentioned in an old chat is no proof that it still works.

Do not duplicate whole sections of README.md, the architecture description, or every decision in the changelog. For routing, it is enough to say which document answers which question: for example, README.md for first-time setup, docs/reservation-lifecycle.md for permitted transitions, and docs/decisions/ for recorded architecture decisions. If an entry in CLAUDE.md contradicts these current sources, verify each statement, agree on it with the project owner, and fix the source where the error actually lives.

Some things do not belong in a persistent file at all: secrets, keys, tokens, incidental personal data, full conversation histories, a list of every task completed, the current sprint status, or unverified commands. Secrets do not become safe because the file is called "local". For a task, an incident or a temporary plan, use the source that belongs to that work, such as its Jira issue or the current handoff, rather than copying it into the team's memory. A stable rule can stay; short-lived state should be dated and kept wherever its owner updates it.

A statement is easier to check when it names an action, a scope and a criterion for the result. Where it matters, add the reason or an exact reference:

  • Vague: "Test thoroughly."
  • Checkable: "After changing reservation transitions, run pnpm test -- reservation; the package defines this command in package.json. In your summary, list the results and any parts left unchecked."
  • Too broad: "Don't change the API."
  • Scoped: "If an endpoint's external behaviour changes, update openapi.yaml and the test that pins down the new contract."

Anthropic recommends aiming for no more than 200 lines per CLAUDE.md file: a large file consumes context and can reduce how well the rules are followed. This is a guideline for practical compactness, not a threshold that determines quality by itself. There is a separate technical limit: the current documentation says Claude Code skips a CLAUDE.md file larger than 4 MiB. Imported files also add text to the context, so splitting one encyclopaedia into ten automatically imported parts does not reduce its cost.

Worked example 1: a short file for the booking service

The repository below is invented. Assume its package.json contains a test script that runs vitest run, and that the CI configuration uses the same package manager and lockfile. The commands in the example are appropriate only under those conditions; in a real repository they would have to be checked.

# Reservation service

## Project map
- This repository runs the reservation API.
- `src/reservations/` owns reservation state transitions.
- `openapi.yaml` defines the public API contract.

## Local checks
- Install from the repository root: `pnpm install --frozen-lockfile`.
- Run unit tests: `pnpm test` (`package.json` maps `test` to `vitest run`).
- Report a check as passed only if you ran it and saw it succeed.

## Change guidance
- Before changing reservation states, read `docs/reservation-lifecycle.md` and `docs/decisions/ADR-004-idempotency.md`.
- Preserve idempotency: a repeated request with the same `Idempotency-Key` must not create a second active reservation.
- If public behavior changes, update `openapi.yaml` and the relevant tests.

## Final report
- List changed files, exact checks run, their outcomes, and checks you could not run.

The section headings describe their purpose, so that both the agent and a human can find a rule quickly. The first three lines give a small map of the repository and its real contract instead of a long copy of README.md. The checks block records the commands and where the test command comes from; when the manifest changes, this line has to change too. The change-guidance block points to detailed documents that are needed only for lifecycle work, and briefly restates the invariant. The final-report block requires the agent to distinguish between a check it ran and one it did not.

ADR in the file name stands for Architecture Decision Record, a written record of an architecture decision. Idempotency-Key is a key that helps the service recognise a repeat of the same request; in this invented example, a repeat does not create another active reservation. This explanation does not define a scheme for anyone else's project: the header name and the behaviour must be confirmed against your own service's contract.

The example deliberately leaves out a long installation guide, the full database schema and every release step. If the agent only needs those for a specific task, the instruction should point to the relevant document. There is also no secret environment value here: you can name a setting, but never write down its actual key or password.

Worked example 2: a task log that contradicts the README

Imagine an invented football statistics site that shows player profiles and changes to team rosters. Its root CLAUDE.md has grown into a copy of old chats and plans. One passage reads: "Install the package with npm install, the full test is npm test, the transactions importer lives in src/api/transactions/, and the calendar page rebuild is not finished yet." Meanwhile, the current README.md describes pnpm install --frozen-lockfile; package.json declares packageManager: [email protected]; pnpm-lock.yaml and the CI check match the new package manager; the src/api/ directory has been deleted, and the importer for official roster changes now lives in src/feeds/transactions/. The list of unfinished work was copied from last quarter. The reader does not need to know the rules of any particular kind of football: the example is only about code paths and the project's verified sources.

An agent that has read both documents may see incompatible commands and an outdated map of the tree. A rule such as "always obey CLAUDE.md" does not solve the problem: the file is a route to knowledge, not a guaranteed truth about the file system. Check each specific statement against the sources responsible for setup, scripts and the current location of the code. In this scenario, the manifest, the lockfile, CI and the directory tree all confirm the current picture; trying to bring them in line with an outdated log would be wrong.

The reworked persistent file keeps only what makes sense in future sessions:

# Football statistics service

## Start and tests
- For the current quickstart, follow `README.md`.
- Use `pnpm`; its pinned version is declared in `package.json`.
- Run the unit suite with `pnpm test` after confirming the script in `package.json`.

## Project map
- Official roster transaction adapters live in `src/feeds/transactions/`.
- Player profiles live in `src/players/`; roster history is specified in `docs/roster-history.md`.
- `openapi.yaml` is the public API contract.

## Read before changing roster history
- Read `docs/roster-history.md` and the relevant decision records.
- Keep documentation current when the public behavior or supported commands change.

In this fix, the author removes old tasks and historical status updates from CLAUDE.md. If the note about the old importer also survives in README.md, the author updates the map there through the normal review process. If the README is accurate, links to it remain the main briefing for getting started. package.json, the lockfile and CI help verify command names and versions. The stale note about the calendar is deleted rather than kept as if it were a live task: current work lives in up-to-date records maintained by the responsible team.

Before merging, review the diff of the instruction file as carefully as a code diff: a new line can affect every agent session. The owner should check that it really is a shared convention, that no other instruction makes it false, and that the file has not quietly turned into a diary. If it is unclear which command is current, do not guess from the package name; trace the source or ask the owner.

Worked example 3: an outdated test command

Now take a separate change. The instruction file still says "run npm test", but after the project moved to pnpm, the command in README.md and in the checks workflow became pnpm test. Someone reports that the agent wasted time on missing dependencies or wrote the wrong command into its report. The symptom alone does not prove that CLAUDE.md is the root cause: the session may have started in the wrong directory, the file may have been missing from the context, or settings may have changed which instructions are loaded.

First, check loading and sources without touching any code:

  1. In Claude Code, run claude --version and confirm that the session is running the expected product and version.
  2. Run /context and check whether the Memory files list contains the expected CLAUDE.md. For an older version, the limitation described above about directly read AGENTS.md files should not be mistaken for the file itself being absent.
  3. Read the current README.md, package.json, the lockfile and the CI workflow. Compare the package manager, the declared script and the command the automated check actually uses.
  4. If these sources still contradict each other, identify the owner and find out what was intended. Do not change the README or the test command at random just because two texts disagree.
  5. Update CLAUDE.md with the verified command or, if simpler, remove the duplicated command and point the agent to the single current source.
  6. To verify, start a new session, check /context, and then ask Claude to state the current command and its source. This shows whether the instruction is visible and understood; by itself it does not prove that the test passes.

If the agreed command is pnpm test, the edited fragment might look like this:

## Tests
- Run the unit suite with `pnpm test`; the script is defined in `package.json`.
- Run it from the repository root with the lockfile-based install completed.
- In your report, say whether the command actually ran and include the result.

Here the first line can be checked against the manifest, the second explains the precondition, and the third prevents an instruction from being passed off as evidence of success. If the command was not run, both the document's author and the agent say so. Fixing the text does not run the test for anyone and does not mean the check succeeded.

Changes to team conventions are best made together with the code or configuration that caused them, and reviewed as a change in agent behaviour. For commands that change often, pointing to the README or the manifest is more stable than duplicating the list by hand in several places.

When a different mechanism is needed

The key question is simple: does the agent need a standing reminder, or does the team need a separate process, a conditional rule, automation, or a real restriction on actions? The answer decides whether CLAUDE.md is the right place.

Mechanism What to keep there Example of the boundary
CLAUDE.md Short, stable facts and habits that apply to a broad range of work in Claude Code "When changing a contract, keep the description and the test in sync"
.claude/rules/ Topic-specific instructions, especially those tied to particular paths or file types Detailed requirements for src/http/ only
Skill with SKILL.md A repeatable procedure, reference material or multi-step work that should be loaded when needed Reviewing a migration against a checklist
settings.json settings Model choice, environment variables, hooks and tool access Where to allow, ask about or deny a call
Hook Event-driven automation; PreToolUse can inspect a call before it is processed Stop a specific tool call when a condition holds
Project documentation Full contracts, decisions, setup instructions and detailed procedures for people README.md, the architecture description, a decision record

Rules in .claude/rules/ are kept as separate files in that directory, and individual rules can be made to apply only to specified paths. Their syntax and loading conditions are covered in Claude Code rules. A Skill is a SKILL.md file for knowledge and procedures that Claude Code can use when they are needed or when it is invoked directly; Claude Code skills covers it in detail. Do not move all of their content into the root file.

Claude Code settings are stored in JavaScript Object Notation (JSON, a text format for structured data) files such as ~/.claude/settings.json, .claude/settings.json or .claude/settings.local.json. Shared project settings are kept in Git; local settings are meant for a single clone and should be excluded from Git. The permissions.allow, permissions.ask and permissions.deny lists define access rules. A managed organisation-level policy layer can have a wider effect. The exact values and their scope must be checked against the current settings and permissions documentation.

Hooks are also defined in configuration, but they run on specific events. In particular, PreToolUse fires before a tool call is processed and can allow it, deny it, ask for confirmation, or defer it. An ordinary convention in CLAUDE.md has no such decision mechanism. The sentence "never delete the production table" reminds the model of the expected behaviour, but it is no guarantee that the action will be blocked. If an action must be technically impossible, you need a permissions setting or some other verified boundary in the environment, not a more forcefully worded sentence.

Checking quality and keeping it up

Judge the file against concrete work in the project, not by how many fashionable sections it has. These questions are useful in review:

  • Does Claude Code load the file from the directory where the session starts? Does /context show the path of the expected file?
  • Does every route point to a document that exists and is genuinely responsible for that statement?
  • Are the commands confirmed by the current manifest, README or CI?
  • Does every rule have a clear action and scope, and can the result be checked?
  • Are there leftover old tasks, contradictory names, duplicated documents or unsourced assumptions?
  • Is the file free of secrets and of data that should not be in shared context?
  • Is the rule needed in every session, or should it move to a document, a path-scoped rule, a Skill, or an enforcement mechanism?

Checking that a file is loaded and checking its quality are two different results. /context helps you see which files are included, but it does not prove that every command is correct or that the model will follow every instruction. Conversely, an agent may follow a needed rule even when the author has no evidence it was loaded. Check the source of the instruction, the outcome of the work, and the technical restrictions separately.

A useful example of a versioned change comes from the open-source repository crytic/slither. In a commit dated 20 January 2026, the authors narrowed an oversimplified rule in CLAUDE.md about traversing functions: instead of advising that the _declared suffix always be used, they distinguished three types of analysis. The commit description says the earlier wording had already caused incorrect comments during code review. This is a single historical example of how a rule can need a more precise scope and conditions; it is not statistical evidence that instructions are effective. Slither's rules themselves depend on that tool's internal types, so they should not be carried over to another project.

When code changes, review the related lines of CLAUDE.md: a command may have changed, a structure may have moved, an architectural invariant may have gained a new contract. When a rule is no longer needed, delete it rather than leaving it as historical reference. For changes that affect a wide range of sessions, state in the review why the change was made and where the new information came from.

Summary

CLAUDE.md works well as a compact, standing guide for Claude Code: important shared conventions, verified commands, critical invariants and links to fuller sources. Its location determines its scope; imports load additional text into the context; the /context command helps confirm that the file is present. Choice, configuration and technical blocking are handled by other mechanisms.

When an instruction conflicts with the README or with a command from the repository, establish which document is current for that particular fact and fix the place that is out of date. Do not turn the file into a task log, a store of secrets or a copy of the reference documentation. Check it the way you check an agent's behaviour: by source, by concrete scenario, and by evidence.

Sources and further reading

Claude Code features and versions were checked on 26 September 2026. The vendor pages consulted showed no separate publication date or revision number, so the date below is the access date. Claude Code is a fast-changing product: before relying on exact paths and modes, check the current documentation and the version you have installed.

  1. Anthropic, How Claude remembers your project, accessed 26 September 2026. Confirms where CLAUDE.md is located and how it is loaded, imports, the target size, rules, and the version-dependent differences in AGENTS.md support.
  2. Anthropic, Settings files and precedence, accessed 26 September 2026. Describes the scopes of Claude Code settings files and the purpose of managed settings.
  3. Anthropic, Extend Claude with skills, accessed 26 September 2026. Explains when to use SKILL.md and how skills differ from the persistent content of CLAUDE.md.
  4. Anthropic, Hooks reference and Configure permissions, accessed 26 September 2026. Confirm access boundaries and the event-driven behaviour of hooks, including the PreToolUse check.
  5. Anthropic, Extend Claude Code, accessed 26 September 2026. Maps persistent context, skills, hooks and other extensions to the tasks each is designed for.
  6. Anthropic, Claude Code v2.1.283, published 25 September 2026 and shown as the latest release on 26 September 2026. A reference point for the release state on the access date, not the date AGENTS.md support appeared.
  7. OpenAI, Custom instructions with AGENTS.md, accessed 26 September 2026. The official description of how Codex picks up AGENTS.md for its own surfaces. The original link to the Codex documentation redirects to this page. Its behaviour does not define Claude Code's semantics.
  8. crytic/slither, CLAUDE.md at a pinned revision and commit b4da3e93e82991590ead901d5a950a51a258b947, 20 January 2026, accessed 26 September 2026. The primary source for one example of refining a project instruction after an erroneous reviewer comment; not a recommendation to copy that repository's specific rules.

Limits of verification. This unit explains published documentation and one recorded example from public GitHub. No Claude Code setup was configured for it, no specific user account was checked, and the example commands were not run. The illustrative file is not a ready-made configuration for any other repository.