A practical configuration exercise — not coding a feature but building the environment that makes Claude Code behave correctly for every developer on the team. Covers the 3-level CLAUDE.md hierarchy, path-specific rules with YAML frontmatter, skills with context: fork and allowed-tools, and the team-vs-personal MCP split.
| Domain | Name | Weight | Coverage |
|---|---|---|---|
| D3 | Claude Code | 20% | Primary — CLAUDE.md hierarchy, path rules, skills, planning mode, @path syntax |
| D2 | Tool Use & MCP | 18% | Secondary — MCP config split, allowed-tools, team vs. personal servers |
The project-root CLAUDE.md — committed to version control. This is Level 2 in the hierarchy and is shared by every team member who clones the repo. Contains universal coding standards (Python 3.11+, type annotations, Google docstrings, naming conventions, async guidelines, commit format) plus planning mode decision guidance.
@path syntax to import 3 rules files: @./.claude/rules/api-conventions.md, @./.claude/rules/testing.md, @./.claude/rules/security.md@ must be immediately adjacent to the path (no space) or it is treated as literal text@path imports is 5 levels~/.claude/CLAUDE.md on one developer's machine. Fix: move to <project-root>/CLAUDE.md and commit. The project CLAUDE.md is the single source of truth for shared standards.Path-specific rule file loaded only when editing files under src/api/**/*. The YAML frontmatter paths: key triggers conditional loading. Without this file, a developer editing a CSS file would still load API rules — wasting context window tokens on irrelevant content.
# YAML frontmatter — triggers conditional loading --- paths: ["src/api/**/*"] ---
{"success": bool, "data": any, "error": str|null}dictexcept ExceptionTesting rule file with a multi-glob paths pattern. Test files can live anywhere in the project tree; this file targets them by naming convention rather than directory, ensuring the testing rules apply regardless of where the test is located.
--- paths: ["**/*.test.py", "**/test_*.py", "**/*_test.py"] ---
paths: glob when the rule follows a file type (test files scattered across dirs). Use a directory CLAUDE.md when the rule follows a location (everything in src/payments/).Security rule file that loads for both API and auth directories — multi-path frontmatter. Security rules apply wherever inputs enter the system and wherever tokens/credentials are handled.
--- paths: ["src/api/**/*", "src/auth/**/*"] ---
Depends(get_current_user)${ENV_VAR} syntax only — real values in .envallow_origins=["*"] in productionThe code-review skill invoked via /code-review src/api/. Uses context: fork to run in an isolated subagent — all intermediate work (reading files, running grep) happens in that subagent's context. Only the final report returns to the main session.
--- context: fork allowed-tools: ["Read", "Grep", "Glob"] argument-hint: "Path to file or directory to review" ---
The test-gen skill invoked via /test-gen src/api/users.py. Demonstrates why the allowed-tools list differs from code-review: test generation must create files, so Write is added. But Bash is still excluded — the skill writes tests but does not run them.
--- context: fork allowed-tools: ["Read", "Grep", "Glob", "Write"] argument-hint: "Path to source file to generate tests for" ---
Write vs. code-review — must create test fileBash — does not need to execute testsEdit — Write is sufficient for new file creationTeam-shared MCP server configuration. Committed to version control. Every developer who clones the repo gets these 3 servers automatically: GitHub (code search, PRs), PostgreSQL (team dev DB), Slack (notifications). Real credentials use ${ENV_VAR} placeholders — actual values in each developer's local .env file.
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
}
}
}
${ENV_VAR} is mandatory — real tokens in .mcp.json are permanently embedded in Git historygit filter-branch or BFG to remove from history → audit access logs~/.claude.json. Bob clones the repo. Bob can't access the postgres MCP tool. Root cause: personal file was never committed. Fix: move to .mcp.json with ${DATABASE_URL}, commit it.Template for the personal ~/.claude.json override file. Committed to VCS as a template so developers know what to set up, but the actual ~/.claude.json with real credentials is never committed.
~/.claude.json and fills in real values locallyThe compliant API file. Every element traces to a specific rule. Used to demonstrate what Claude Code should produce when all rules files are active.
| Code Element | Rule Satisfied |
|---|---|
async def create_user(...) | api-conventions: All endpoints must be async |
request: CreateUserRequest (Pydantic) | api-conventions: All inputs validated with Pydantic |
Depends(get_current_user) | security: Auth on every protected request |
return ok(UserResponse...) | api-conventions: Standard response wrapper |
except DuplicateEmailError: | api-conventions: Specific exceptions, not bare except |
| Google-style docstrings on all functions | CLAUDE.md: All public functions need docstrings |
UserResponse excludes password hash | security: Never expose sensitive data |
The intentional violations file. Run /code-review src/api/orders.py to see what the code-review skill catches. Contains 8+ violations across 3 endpoints.
| Violation | Rule Broken | Severity |
|---|---|---|
def get_order(order_id: int): | Synchronous handler | MEDIUM |
f"SELECT...WHERE id = '{order_id}'" | SQL injection (string-formatted SQL) | CRITICAL |
Missing Depends(get_current_user) | No auth on protected routes | CRITICAL |
logger.info(f"email: {email}") | Logs PII (email address) | HIGH |
Query inside for oid in order_ids: | N+1 query pattern | HIGH |
return orders | Missing response wrapper | MEDIUM |
except Exception as e: | Bare except | MEDIUM |
data: dict parameter | No Pydantic validation | MEDIUM |
Compliant test file demonstrating all testing conventions: GIVEN/WHEN/THEN docstrings, factory functions, real DB fixture (no mocking), class-based grouping.
make_user_payload(**overrides) factory — schema changes require updating ONE placedb_session fixture uses real TestAsyncSession + rollback for clean stateTestUserCreation, TestUserRetrievalSource: explanation Ex2.md