EP07 intermediate

From Temp Worker to Permanent Employee: Making Claude Code Remember

CLAUDE.md, settings.json, rules, memory, and hooks — the five systems that turn Claude Code from an amnesiac into a teammate.

Every fresh Claude Code session starts the same way: a blank slate. No memory of your coding standards. No awareness of your project structure. No idea that you hate semicolons, always use Prettier, and never want console.log left in production code.

This is the temp worker problem. You hire someone brilliant, but they forget everything the moment they leave the office. Next morning, you explain the same things again. And again.

The fix isn’t a single config file. It’s five interlocking systems that make Claude Code persistent across sessions. I’ll walk through each one.

System 1: CLAUDE.md — The Employee Handbook

CLAUDE.md is a markdown file that Claude Code reads automatically at the start of every session. Think of it as an employee handbook. Two layers exist:

Global (~/.claude/CLAUDE.md) — applies to every project on your machine:

# About Me
- Backend developer, 5 years experience
- Stack: Python, FastAPI, PostgreSQL
- Prefer functional patterns over OOP
- Run all code through Black formatter

# Work Rules
- Never use print() for debugging — use logging module
- Always type-hint function signatures
- Tests go in tests/ directory, mirror src/ structure

Project-level (./CLAUDE.md in your repo root) — overrides or extends the global file:

# Project: Invoice API
- Framework: FastAPI 0.115
- Database: PostgreSQL 16 via SQLAlchemy 2.0
- Auth: JWT tokens, no session cookies
- Deploy target: AWS Lambda via Mangum

# Conventions
- All endpoints return {data, error, meta} envelope
- Use Pydantic v2 model_validator for input validation
- Alembic for migrations, never raw SQL DDL

When both files exist, Claude Code loads the global one first, then the project one. Project-level wins on conflicts. This means your global file can set defaults (“always use Black”) and your project file can override them (“this project uses Ruff instead”).

Keep the global file under 200 lines. I’m serious. Every line costs tokens on every single message. A 500-line CLAUDE.md means you’re paying for 500 lines of context before you even ask your first question.

System 2: settings.json — The Permission System

CLAUDE.md tells Claude Code what you want. settings.json tells it what it’s allowed to do. Two locations again:

Global (~/.claude/settings.json):

{
  "permissions": {
    "allow": [
      "Bash(npm run *)",
      "Bash(python -m pytest *)",
      "Bash(git status)",
      "Bash(git diff *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force *)"
    ]
  },
  "env": {
    "ANTHROPIC_MODEL": "claude-sonnet-4-20250514",
    "UV_PYTHON": "3.12"
  }
}

Project-level (.claude/settings.json in your repo):

{
  "permissions": {
    "allow": [
      "Bash(docker compose *)",
      "Bash(alembic *)",
      "mcp__supabase__*"
    ]
  }
}

The allow list is where you stop the permission prompts. Without it, Claude Code asks “Can I run npm test?” every single time. After a while, you start clicking “Yes” without reading — which defeats the purpose of having permissions at all. Better to explicitly allow the safe commands and let the prompt catch only the dangerous ones.

The env block sets environment variables for the session. I use it to pin the model, set Python versions, and pass API endpoints that differ per project.

System 3: Rules — Coding Standards on Autopilot

Rules live in .claude/rules/ as markdown files. They’re like CLAUDE.md, but organized by concern and loaded automatically.

.claude/
└── rules/
    ├── coding-style.md
    ├── testing.md
    ├── security.md
    ├── git-workflow.md
    └── python/
        ├── fastapi.md
        └── sqlalchemy.md

Why separate from CLAUDE.md? Three reasons.

First, organization. A single 400-line CLAUDE.md is hard to maintain. Twenty focused rule files of 20 lines each are easy to scan, edit, and version-control independently.

Second, reuse. Your coding-style.md and security.md probably apply to every project. Copy them to ~/.claude/rules/ and they become global rules. Project-specific rules stay in the project’s .claude/rules/ directory.

Third, token efficiency. Claude Code loads all rules at session start, but you can structure them so language-specific rules only exist in projects that need them. Your Python project doesn’t need TypeScript linting rules eating context.

A good rule file is short and concrete:

# Testing Rules

- Minimum 80% test coverage
- Use pytest, never unittest
- AAA pattern: Arrange, Act, Assert
- Test file naming: test_{module_name}.py
- Fixtures go in conftest.py, not in test files
- Mock external APIs, never hit real endpoints in tests

Vague rules like “write clean code” waste tokens and change nothing. Specific rules like “functions under 50 lines, files under 800 lines” actually get followed.

System 4: Memory — Cross-Session Persistence

Memory is the system that turns Claude Code from a goldfish into a colleague. It stores facts that persist between sessions in ~/.claude/projects/<project-hash>/memory/.

Four memory types exist:

TypeWhat it storesExample
userPersonal preferences”Simon prefers tabs over spaces”
feedbackCorrections you’ve made”Don’t use any type — always be explicit”
projectArchitectural decisions”We chose Redis over Memcached for caching”
referenceExternal resources”API docs at https://docs.example.com/v3

Memory gets created two ways. Explicitly, when you tell Claude Code to remember something:

> Remember: we decided to use UUIDs for all primary keys, not auto-increment integers.

Or implicitly, when Claude Code detects a correction. If you say “No, don’t import from the barrel file — import directly from the module,” it can store that as feedback memory.

All memories funnel into a MEMORY.md index file that gets loaded at session start. The index is lightweight — just titles and links to individual memory files. So even 50 memories only cost a few hundred tokens at load time.

My rule of thumb: when in doubt, tell it to remember. You can always clean out stale memories later. Forgetting a hard-won decision is more expensive than storing a few extra lines.

System 5: Hooks — Automated Guardrails

Hooks are executable code (not prompts) that fire on specific events. The distinction matters: CLAUDE.md rules are suggestions that Claude Code usually follows. Hooks are code that always runs.

Six hook events:

EventWhen it firesUse case
PreToolUseBefore any tool runsBlock dangerous commands
PostToolUseAfter any tool runsAuto-format saved files
SessionStartSession beginsLoad project context
StopSession endsSave session summary
UserPromptSubmitYou send a messageInject reminders
PreCompactBefore context compactionPreserve key info

Hooks go in .claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "npx prettier --write $CLAUDE_FILE_PATH"
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "command": "echo $CLAUDE_TOOL_INPUT | grep -q 'rm -rf /' && exit 1 || exit 0"
      }
    ]
  }
}

The PostToolUse hook above runs Prettier on every file Claude Code writes or edits. No more “can you format that?” messages. No more forgetting to format. It just happens.

The PreToolUse hook blocks catastrophic rm -rf / commands before they execute. Hooks run outside the AI’s control — it can’t decide to skip them, override them, or argue about them.

Putting It All Together

Here’s what a well-configured project looks like:

my-project/
├── CLAUDE.md                    # Project handbook (50-100 lines)
├── .claude/
│   ├── settings.json            # Permissions + hooks + env vars
│   └── rules/
│       ├── coding-style.md      # Code conventions
│       ├── testing.md           # Test requirements
│       └── python/
│           └── fastapi.md       # Framework-specific rules
├── src/
├── tests/
└── ...

Plus your global config:

~/.claude/
├── CLAUDE.md                    # Global handbook (under 200 lines)
├── settings.json                # Global permissions
├── rules/
│   ├── security.md              # Universal security rules
│   └── git-workflow.md          # Commit message format
└── projects/
    └── <hash>/
        └── memory/
            ├── MEMORY.md        # Memory index
            ├── project_uuid_decision.md
            └── feedback_no_barrel_imports.md

The first session with a new project takes effort. You write the CLAUDE.md, set up rules, configure permissions. Maybe 30 minutes of work.

Every session after that? Claude Code opens knowing your stack, your conventions, your past decisions, and your pet peeves. It formats code your way, runs tests your way, and commits your way. No re-explaining.

That’s the difference between a temp worker and a permanent employee. The temp might be equally smart. But the permanent employee has context — and context is what makes speed possible.