What you will be able to do
- Choose the right CLAUDE.md scope (managed, user, project or local) for an instruction, based on who should receive it
- Predict whether Claude Code reads AGENTS.md, CLAUDE.md or both in a given repository
- Tell apart behavioural guidance, which belongs in CLAUDE.md, from hard boundaries, which belong in managed settings
- Design a JSON schema for structured outputs and explain what the SDKs do with constraints the API does not support
Key concept
Layered instruction scope — Claude does not get its standing instructions from the prompt alone. They come from files at several scopes: organisation, user, project and local. Where an instruction lives decides who receives it and when it loads.
1.Where Claude Code gets its standing instructions
When you build on Claude Code, the text you type in a turn is only part of what Claude reads. Every session also loads persistent context from two places. The first is CLAUDE.md files, which you write. The second is auto memory, which Claude writes itself from your corrections. So the first design question is not what to say. It is where to put it, because the location decides who receives the instruction.
| Scope | Location | Shared with |
|---|---|---|
| Managed policy | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS), /etc/claude-code/CLAUDE.md (Linux and WSL) | All users in organization |
| User instructions | ~/.claude/CLAUDE.md | Just you (all projects) |
| Project instructions | ./CLAUDE.md or ./.claude/CLAUDE.md | Team members via source control |
| Local instructions | ./CLAUDE.local.md | Just you (current project) |
Local instructions are for personal, project-specific details such as sandbox URLs or preferred test data. You add the file to .gitignore so it never reaches teammates. Auto memory is different in two ways: Claude writes it, and it is scoped per repository and shared across worktrees. Only its first 200 lines or 25KB load into each session. Whatever the scope, write concrete instructions. The docs contrast "Use 2-space indentation" with "Format code properly", and "Run npm test before committing" with "Test your changes".
In the project CLAUDE.md (./CLAUDE.md or ./.claude/CLAUDE.md). It is team-shared and committed to source control. ~/.claude/CLAUDE.md would reach only you, and CLAUDE.local.md is gitignored, so it would reach only you as well.
Sources1
2.AGENTS.md and path-scoped rules
Many repositories already have an AGENTS.md. Claude Code can read it, but by default it treats AGENTS.md as a fallback, not an addition. If a CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in your working directory or any directory above it, Claude reads the CLAUDE.md files and skips AGENTS.md. A CLAUDE.md that imports AGENTS.md pulls it in through the import. Three files never count against AGENTS.md: your user file, the managed file, and rules files.
It reads their CLAUDE.md files only, because CLAUDE.local.md counts as one of them. To load both, set the instructionFiles option to claude-md-and-agents-md. Each directory's CLAUDE.md files then load first and its AGENTS.md after them. Other values are claude-md (never AGENTS.md) and managed-only. Some files are never read at all: AGENTS.local.md, AGENTS.override.md, and anything under a .agents/ directory. Subagents that skip project instructions also skip AGENTS.md.
To keep instructions from spreading into unrelated work, use .claude/rules/. A rule file can carry a paths field of glob patterns, so it applies only to matching files:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation commentsSources1
3.Content boundaries: guidance versus enforcement
A CLAUDE.md tells Claude how to behave. It is not a lock. When an organisation needs a boundary that holds, such as a tool Claude may not use or an isolated sandbox, the docs send that concern to managed settings, not to the managed CLAUDE.md.
| Concern | Configure in |
|---|---|
| Block specific tools, commands, or file paths | Managed settings: permissions.deny |
| Enforce sandbox isolation | Managed settings: sandbox.enabled |
| Environment variables and API provider routing | Managed settings: env |
| Login method and organization restrictions | Managed settings: forceLoginMethod, forceLoginOrgUUID |
| Data handling and compliance reminders | Managed CLAUDE.md |
| Behavioral instructions for Claude | Managed CLAUDE.md |
Boundaries also work in the other direction: they can keep instructions out. In a monorepo, claudeMdExcludes takes glob patterns, such as another team's CLAUDE.md or its .claude/rules/ folder, so their conventions don't load into your sessions.
Sources1
4.Schema design with structured outputs
An application that parses Claude's output needs output it can trust. Prompting alone can still produce invalid JSON, missing required fields or inconsistent types. Structured outputs address this with constrained decoding, and they come as two features you can use separately or together in one request. JSON outputs, set with output_config.format, shape the response. Strict tool use, set with strict: true, validates tool names and inputs.
output_config={
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"plan_interest": {"type": "string"},
"demo_requested": {"type": "boolean"},
},
"required": ["name", "email", "plan_interest", "demo_requested"],
"additionalProperties": False,
},
}
},The response comes back as valid JSON in the text content block. You don't have to write raw schemas by hand. In Python, client.messages.parse() takes a Pydantic model and returns parsed_output. In TypeScript, zodOutputFormat() does the same job for Zod schemas. The API supports only part of JSON Schema, so the Python, TypeScript, Ruby and PHP SDKs rewrite your schema before sending it. They remove unsupported constraints such as minimum, maxLength and similar, and restate each one in the field's description. They also add additionalProperties: false to every object and drop string formats the API doesn't support. Then they validate the response against your original schema. A Pydantic field with minimum: 100 reaches Claude as a plain integer whose description says "Must be at least 100".
Your code does, through the SDK. It validates the response against the original schema, constraints included. Claude sees a simplified schema plus a description hint.
A multi-tenant SaaS product runs one Agent SDK session per end-user conversation and must reliably return to a specific user's conversation later, even when it isn't the most recently active session on the server and even after the process restarts. Which session-handling approach fits this requirement?
Correct answer: A — Capture each session's ID from the result message and store it per user, then pass that specific ID to `resume` when the user returns, rather than relying on `continue`
- A. Correct. `resume` takes a specific session ID and is required when there are multiple sessions (for example, one per user) or when returning to a session that isn't the most recent; capturing and storing the ID per user is exactly the documented use case for this option.
- B. Incorrect. `continue` finds only the most recent session in the current directory with no ID tracking; in a multi-tenant server handling many users concurrently, that will resume the wrong user's session whenever another session is more recent.
- C. Incorrect. Fork creates a new, independent session copied from an original at a point in time; it is for branching to explore alternatives, not for repeatedly returning to and continuing a specific user's ongoing session.
- D. Incorrect. The SDK explicitly supports resuming a specific past session by ID; re-sending the full transcript as prompt text is unnecessary and discards the SDK's built-in session persistence and context accumulation.
Sources2
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Adding "never run rm -rf" to the managed CLAUDE.md reliably blocks that command for everyone in the organisation.Why is that wrong?
The managed CLAUDE.md carries behavioural guidance. Blocking tools, commands or file paths is a managed-settings concern, configured with permissions.deny.
2.Claude Code always loads AGENTS.md next to any CLAUDE.md in the repository.Why is that wrong?
By default, AGENTS.md loads only when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working directory or above it. To load both, set instructionFiles to claude-md-and-agents-md.
Covered in AGENTS.md and path-scoped rules
3.Constraints such as minimum or maxLength in a Pydantic model are enforced by constrained decoding, so the SDK doesn't need to check them.Why is that wrong?
The SDK removes unsupported constraints before sending the schema and restates them in the field descriptions. It then validates the response against the original schema, so the enforcement happens in your code.
Covered in Schema design with structured outputs
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://code.claude.com/docs/en/memoryOfficial docs
“Auto memory: notes Claude writes itself based on your corrections and preferences”
↩︎ Where Claude Code gets its standing instructions“Personal project-specific preferences; add to .gitignore”
↩︎ Where Claude Code gets its standing instructions“Don’t count, and keep loading alongside AGENTS.md: your ~/.claude/CLAUDE.md, your organization’s managed CLAUDE.md, and .claude/rules/ files”
↩︎ AGENTS.md and path-scoped rules“Not read: AGENTS.local.md, AGENTS.override.md, or anything under a .agents/ directory”
↩︎ AGENTS.md and path-scoped rules“Glob patterns that scope the rule to matching files.”
↩︎ AGENTS.md and path-scoped rules“Enforce sandbox isolation | Managed settings: sandbox.enabled”
↩︎ Content boundaries: guidance versus enforcement“CLAUDE.md files: instructions you write to give Claude persistent context.”
↩︎ Key concept“Block specific tools, commands, or file paths | Managed settings: permissions.deny”
↩︎ Exam trap 1“An AGENTS.md and a CLAUDE.md or CLAUDE.local.md in your working directory or above it | Your CLAUDE.md files only”
↩︎ Exam trap 2 - 2.
“Structured outputs constrain Claude's responses to follow a specific schema, ensuring valid, parseable output for downstream processing.”
↩︎ Schema design with structured outputs“Strict tool use (strict: true): Guarantee schema validation on tool names and inputs”
↩︎ Schema design with structured outputs“Remove unsupported constraints (for example, minimum, maximum, minLength, maxLength)”
↩︎ Schema design with structured outputs“This means Claude receives a simplified schema, but your code still enforces all constraints through validation.”
↩︎ Exam trap 3