Module 2: Agent Memory and Scopes

3. Sharing Memory Across Subagents

3. Sharing Memory Across Subagents

Description

In the previous capsule you configured memory in three scopes: user, project, and local. Each subagent has its own MEMORY.md in its own directory. This solves individual amnesia — the reviewer remembers patterns, the implementer remembers conventions. But it creates a new problem: independent memories that can contradict each other.

The reviewer records "the project uses camelCase for functions." The implementer, in another session, observes snake_case in a different module and records "the convention is snake_case." When the reviewer reports "naming inconsistency" and the implementer "fixes" it according to its own memory, the result is code that follows two different conventions. Individual memory without coordination produces exactly the kind of inconsistency that memory should prevent.

This capsule teaches you strategies to share context between subagents in a controlled way: complementary memory, shared conventions, CLAUDE.md as the source of truth, and practical patterns for systems of 3+ subagents. By the end, you'll know how to design a memory strategy that scales without contradictions — the prerequisite for capsule 05.


The Problem: Isolated Memories

Why individual memory isn't enough

When you enable memory: project on the reviewer and the implementer, each one has its own directory:

.claude/agent-memory/
├── reviewer/
│   └── MEMORY.md       ← the reviewer reads and writes here
└── implementer/
    └── MEMORY.md       ← the implementer reads and writes here

They're two independent files. No subagent reads the other's MEMORY.md by default. Each one builds its own version of the truth:

reviewer/MEMORY.md:
  "Team uses repository pattern for all DB access"
  "Error handling: raise HTTPException directly in routes"

implementer/MEMORY.md:
  "DB access through direct SQLAlchemy queries in routes"
  "Error handling: custom AppError hierarchy with middleware"

Both observed real patterns, but from different modules or different moments. Without coordination, the implementer applies conventions that the reviewer will flag as inconsistent.

The cost in a multi-agent flow

reviewer → "routes/orders.py: uses direct queries,
            should use repository pattern per convention"

implementer → reads its own memory, not the reviewer's
           → "my memory says direct queries are the convention"
           → doesn't fix the issue

tester → runs tests, everything passes
       → the anti-pattern stays in the code

The pipeline completed without errors, but the architectural inconsistency survived because the agents work with different versions of reality.


Strategy 1: Complementary Memory

The concept

Instead of each subagent keeping an independent copy of the truth, you assign complementary memory roles. The reviewer specializes in remembering certain aspects, the implementer in others. Neither duplicates the other's information.

reviewer/MEMORY.md    → Codebase patterns, issues, design decisions
implementer/MEMORY.md → Code conventions, library patterns, file map
tester/MEMORY.md      → Test results, flaky tests, coverage trends

Implementation: specialized system prompts

Reviewer's system prompt — specialization in observations:

## Memory Management — Specialization: Observations
Your MEMORY.md tracks:
- Architecture patterns observed across the codebase
- Design decisions found in code comments or PR descriptions
- Recurring issues and their resolution status
You DO NOT track:
- Code conventions (implementer's responsibility)
- Test results (tester's responsibility)

Implementer's system prompt — specialization in conventions:

## Memory Management — Specialization: Conventions
Your MEMORY.md tracks:
- Naming conventions observed and enforced
- Library-specific patterns (how the project uses SQLAlchemy, etc.)
- Implementation patterns that should be consistent
You DO NOT track:
- Architecture decisions (reviewer's responsibility)
- Test results (tester's responsibility)

Cross-reading: reading other agents' memory

The key: each subagent reads the others' memory at startup, but only writes to its own.

## Cross-Memory Reading

Before starting your work, read other agents' memories:
1. Read `.claude/agent-memory/reviewer/MEMORY.md` for architecture
   decisions and known issues
2. Read `.claude/agent-memory/implementer/MEMORY.md` for code
   conventions and library patterns

Use this context to inform your work, but ONLY write to YOUR
memory directory: `.claude/agent-memory/[your-name]/`

Complete subagent with cross-reading

---
name: implementer
description: Implements code changes following project conventions
tools: Read, Glob, Grep, Write, Edit, Bash
model: sonnet
maxTurns: 30
memory: project
---

## Role
You are a senior developer implementing code changes in src/.

## Cross-Memory Reading
Before implementing, read context from team agents:
1. Read `.claude/agent-memory/reviewer/MEMORY.md` for:
   - Architecture decisions (inform your approach)
   - Known issues (avoid reintroducing fixed bugs)
2. Your own memory (auto-injected) provides:
   - Code conventions to follow
   - Library patterns to apply

## Memory Management — Specialization: Conventions
Update YOUR memory with:
- New conventions you observe during implementation
- Library usage patterns discovered
- File/module purposes clarified

Do NOT write architecture decisions — that's the reviewer's domain.
If you discover an architectural pattern, note it in your report
so the reviewer captures it in their next run.

## Constraints
- ONLY modify files inside src/
- NEVER modify other agents' MEMORY.md
- When conventions conflict between memories, prefer the reviewer's
  (broader project visibility)

## Output Format
### Implementation Report
**Cross-memory context applied:**
- From reviewer memory: [patterns/decisions applied]
- From own memory: [conventions applied]
**Changes made:**
1. **[file]** — Description
**Suggested memory updates for reviewer:**
- [architectural patterns observed that reviewer should capture]

Strategy 2: Shared Memory Directory

The concept

Instead of separate memories, a common directory with thematic files. It requires a designated curator who controls the writing:

.claude/agent-memory/reviewer/
├── MEMORY.md           ← the reviewer's own memory
├── architecture.md     ← reviewer writes, everyone reads
├── conventions.md      ← reviewer writes, everyone reads
└── known-issues.md     ← reviewer writes, everyone reads

Implementation

The reviewer acts as the primary curator:

## Shared Memory Management (Reviewer as Curator)
You are the PRIMARY writer of shared memory files:
1. Update `architecture.md` with architectural patterns observed
2. Update `conventions.md` with coding conventions confirmed
3. Update `known-issues.md` with new issues found or resolved

The other subagents read but don't edit these files:

## Cross-Memory Reading (for implementer)
Before implementing, read the shared memory files:
1. `.claude/agent-memory/reviewer/architecture.md`
2. `.claude/agent-memory/reviewer/conventions.md`
3. `.claude/agent-memory/reviewer/known-issues.md`

If you discover information for these files, include it in your
report under "Suggested memory updates" — the reviewer captures it.

When to use this strategy

  • ✅ Small teams (2-3 agents) where a natural curator exists
  • ✅ Projects where memory consistency is critical
  • ❌ Doesn't scale well with many agents — the curator is a bottleneck

Strategy 3: CLAUDE.md as the Source of Truth

The concept

CLAUDE.md is read by all agents, including subagents. Put the fundamental truth there and use memories for agent-specific context.

CLAUDE.md           → Shared truth: architecture, conventions, stack
MEMORY.md (reviewer) → Specific context: issues found, patterns
MEMORY.md (implementer) → Specific context: library patterns, file map
MEMORY.md (tester)   → Specific context: results, flaky tests

Implementation

CLAUDE.md — project truth:

# CLAUDE.md

## Architecture
- FastAPI + SQLAlchemy + Alembic + PostgreSQL
- Routes in src/routes/, models in src/models/
- Repository pattern for ALL database access

## Code Conventions
- Snake_case for all Python identifiers
- Type hints required on all public functions
- Custom AppError hierarchy for error handling (src/exceptions.py)

System prompt — hierarchy of truth:

## Context Hierarchy
Your sources of truth, in priority order:
1. **CLAUDE.md** — Project truth. NEVER contradict CLAUDE.md.
2. **Your MEMORY.md** — Your accumulated observations.
   Use for context that complements CLAUDE.md.
3. **Code inspection** — Current state.
   If code contradicts CLAUDE.md, report the deviation.

If your MEMORY.md contradicts CLAUDE.md, update your MEMORY.md
to align — the team source takes priority.

When to use this strategy

  • ✅ Any project with a well-maintained CLAUDE.md
  • ✅ Combines naturally with the other two strategies
  • ❌ Doesn't replace the need for agent-specific memory

Comparison: Memory Strategies

AspectIndividualComplementaryShared dirCLAUDE.md + memory
SetupMinimalMediumHighMedium
Contradiction riskHighLowMinimalMinimal
ScalabilityHighHighLowHigh
MaintenanceLowMediumHigh (curator)Low
ConsistencyLowHighVery highVery high
To get started✅
For mature teams✅

Practical recommendation

Combine Strategy 3 (CLAUDE.md as truth) with Strategy 1 (complementary memory):

CLAUDE.md → Shared truth (architecture, conventions)
                 ↑ all agents read

reviewer/MEMORY.md → Observations (issues, anti-patterns)
                       ↑ implementer reads at startup

implementer/MEMORY.md → Practical conventions (library patterns)
                          ↑ reviewer reads for context

tester/MEMORY.md → Test results (private, local scope)
                     ↑ only the tester reads/writes

Read-Only vs Read-Write: Ownership

The problem of writing without coordination

In different sessions, two subagents can reach opposite conclusions. If both write to shared files, the last one to run wins.

Pattern: clear ownership

Assign a single writer per file:

FileOwner (writes)Readers
reviewer/MEMORY.mdreviewerimplementer, tester
implementer/MEMORY.mdimplementerreviewer
tester/MEMORY.mdtesterreviewer

For the owner (read-write):

## Memory: MEMORY.md (OWNER)
You own your MEMORY.md. Keep it current and accurate.

For the readers (read-only):

## Cross-Memory: reviewer/MEMORY.md (READER)
Read `.claude/agent-memory/reviewer/MEMORY.md` for context.
You MUST NOT write to this file — the reviewer owns it.
If you discover relevant info, include it in your output
under "Suggested memory updates for reviewer."

The write tools activated by memory are scoped to the agent's directory. To read other agents' files, use Read (not restricted by memory scope).


Naming Conventions

Recommended rules

  1. The directory name = the name from the frontmatter (automatic)
  2. Additional files follow kebab-case: known-issues.md, library-patterns.md
  3. Context prefix when you have variants of the same agent:
name: reviewer-security    # → .claude/agent-memory/reviewer-security/
name: reviewer-performance # → .claude/agent-memory/reviewer-performance/
  1. Descriptive names, not generic ones:
✅ reviewer, implementer, tester, doc-generator
❌ agent-1, agent-2, helper, worker

What to Share vs What to Keep Private

Type of informationSharePrivateWhere
Project architecture✅CLAUDE.md or project memory
Code conventions✅CLAUDE.md or project memory
Recurring bugs✅project memory (reviewer)
Library patterns✅project memory (implementer)
Credentials and tokens✅local memory or .env
Personal preferences✅user memory
Local test results✅local memory (tester)

The simple rule

If a colleague sees this, does it help them or harm them?
→ Helps them: share (project scope or CLAUDE.md)
→ Doesn't matter to them: private (local scope)
→ Harms them or is risky: private (local scope)

Practical Patterns: 3-Agent System

Memory flow diagram

CLAUDE.md (project source of truth)
    ↑ everyone reads
    │
    ├── reviewer (memory: project)
    │   ├── MEMORY.md → Patterns, issues, decisions
    │   └── Reads: implementer/MEMORY.md for conventions
    │
    ├── implementer (memory: project)
    │   ├── MEMORY.md → Conventions, library patterns
    │   └── Reads: reviewer/MEMORY.md for architecture
    │
    └── tester (memory: local)
        ├── MEMORY.md → Test results, flaky tests, coverage
        └── Reads: reviewer/MEMORY.md for issues to verify

Information flow in the pipeline

Session 1 — reviewer runs:
  1. Reads CLAUDE.md (project truth)
  2. Reads its MEMORY.md (auto-injected)
  3. Reads implementer/MEMORY.md (conventions)
  4. Analyzes code
  5. Updates its MEMORY.md with findings
  6. Produces report

Session 2 — implementer runs:
  1. Reads CLAUDE.md
  2. Reads its MEMORY.md (auto-injected)
  3. Reads reviewer/MEMORY.md (issues and decisions)
  4. Implements fixes
  5. Updates its MEMORY.md with discovered conventions
  6. Produces report

Session 3 — tester runs:
  1. Reads CLAUDE.md
  2. Reads its MEMORY.md (auto-injected)
  3. Reads reviewer/MEMORY.md (issues to verify)
  4. Runs tests
  5. Updates its MEMORY.md with results
  6. Produces report with comparison vs previous session

System prompt template for cross-reading

Use this pattern in any subagent that needs to read other agents' memory:

## Cross-Memory Context

Before starting work, gather context from team memory:

### Required Reading
1. **CLAUDE.md** — Project truth
2. **Your MEMORY.md** — Auto-injected, your accumulated context
3. **`.claude/agent-memory/reviewer/MEMORY.md`** — Architecture,
   known issues, design patterns

### Priority Order (for conflicts)
1. CLAUDE.md wins (team-agreed truth)
2. Reviewer memory (broadest visibility)
3. Your own memory (your domain expertise)
4. Code inspection (current state)

### Report Conflicts
If sources contradict each other, include them in your output
under "Memory Conflicts Detected" for human resolution.

Connection to the Project

Toward capsule 05: Memory Hierarchy for 3 Subagents

In capsule 05 you'll implement the complete hierarchy:

CLAUDE.md → project truth (editable only by humans)
     ↓
reviewer  (project) → observations, issues, decisions
     ↕ cross-reading
implementer (project) → conventions, library patterns
     ↕ cross-reading
tester (local) → results, flaky tests, coverage

Capsule 05 will ask you to: configure the 3 subagents with memory, run the complete pipeline, close and reopen the session, run again and verify that memory influenced the results, and inspect the 3 MEMORY.md files to confirm consistency.


Troubleshooting

"The subagent doesn't read other agents' memory"

Cause: The cross-reading instructions aren't explicit or the path is wrong.

Fix: Verify that the subagent has Read in its tools (Read isn't restricted to the memory directory) and that the path in the instructions is correct: .claude/agent-memory/reviewer/MEMORY.md, not reviewer/MEMORY.md.

"The memories contradict each other"

Cause: Two agents observed different aspects of the codebase and drew opposite conclusions.

Fix: Implement the hierarchy of truth: CLAUDE.md > reviewer > implementer. The agent that detects the contradiction reports it in its output for human resolution.

"One subagent overwrites another's memory"

Cause: The subagent has Write enabled and doesn't know which directory is its own.

Fix: The write tools by memory are scoped to the agent's directory. But if it has Write in general tools (like the implementer), it can write to any file. Reinforce in the system prompt: "NEVER write to any memory directory except your own."

"One agent's MEMORY.md is empty but the others have content"

Cause: The subagent hasn't run yet, or its system prompt doesn't include memory instructions.

Fix: Run each subagent at least once to initialize its MEMORY.md. Add ## Memory Management to each subagent's system prompt.


Exercises

Exercise 1: Identify contradictions (Easy)

The reviewer noted "services use dependency injection" (it observed src/services/). The implementer noted "functions are pure, no injection" (it observed src/utils/). The implementer is asked to create a new service in src/services/. What contradiction arises?

See solution

The implementer would create the service without dependency injection because its memory says the project doesn't use it — but it only observed utils/ (which by nature are pure functions). The service would end up inconsistent with the others in src/services/.

Solution: Cross-reading — the implementer should read reviewer/MEMORY.md before implementing. Or better: the "services use DI" convention should be in CLAUDE.md.

Exercise 2: Design file ownership (Easy)

You have 3 agents and 5 types of information. Assign who writes and who reads each one:

  1. Architectural patterns
  2. Naming conventions
  3. Test suite results
  4. Known bugs and their status
  5. Library versions and compatibilities
See solution
InformationOwner (writes)Readers
Architectural patternsreviewerimplementer, tester
Naming conventionsreviewerimplementer
Test suite resultstesterreviewer
Known bugs and statusreviewerimplementer, tester
Library versionsimplementerreviewer

Exercise 3: Write cross-reading instructions (Medium)

Write the ## Cross-Memory Context section for a doc-generator that generates API documentation. It should read: reviewer (architecture), implementer (conventions), tester (verified endpoints). Define what it looks for in each memory and the conflict priority.

See solution
## Cross-Memory Context

Before generating documentation, gather context:

### Required Reading
1. **CLAUDE.md** — Project truth: architecture, stack, conventions
2. **Your MEMORY.md** — Documentation style, templates, glossary
3. **`.claude/agent-memory/reviewer/MEMORY.md`** —
   Module purposes, design patterns, architectural decisions
4. **`.claude/agent-memory/implementer/MEMORY.md`** —
   Endpoint signatures, response formats, library patterns
5. **`.claude/agent-memory-local/tester/MEMORY.md`** —
   Which endpoints have passing tests (mark as "verified")

### Priority for Conflicts
1. CLAUDE.md → 2. Reviewer → 3. Implementer → 4. Tester → 5. Code

### What to Extract
From reviewer: module purposes, architecture overview
From implementer: endpoint signatures, request/response schemas
From tester: verification status per endpoint

Exercise 4: Implement CLAUDE.md as the source of truth (Medium)

You have information scattered across 3 memories. Extract what should be in CLAUDE.md:

reviewer: "FastAPI 0.104, SQLAlchemy 2.0 async, repository pattern since abc123" implementer: "snake_case, type hints required, {data, error, meta} response format" tester: "pytest, test_[action]_[scenario] naming, 80% min coverage"

See solution
# CLAUDE.md

## Architecture
- FastAPI 0.104.0 + SQLAlchemy 2.0 (async)
- Repository pattern for ALL database access
- All API responses: {data, error, meta} format

## Code Conventions
- Snake_case for all Python identifiers
- Type hints required on all public functions

## Testing
- Framework: pytest
- Test naming: test_[action]_[scenario]
- Minimum coverage: 80%

What does not go in CLAUDE.md: "commit abc123" (implementation detail), specific test results (volatile).

Exercise 5: Resolve a contradiction (Hard)

The reviewer has: "Error handling: raise HTTPException directly." The implementer has: "Error handling: use AppError hierarchy, never HTTPException." Design a 4-step plan: investigate, decide, update sources, and prevent future contradictions.

See solution

Step 1 — Investigate:

grep -r "raise HTTPException" src/routes/
grep -r "raise AppError\|raise.*Error" src/routes/

Likely result: both patterns exist (old routes vs new).

Step 2 — Decide: Ask the team what the official standard is. Result: "AppError is the standard, HTTPException is legacy."

Step 3 — Update:

# In CLAUDE.md:
## Error Handling
- Use custom AppError hierarchy (src/exceptions.py)
- Legacy: some routes still use HTTPException — migrate when touched

# In reviewer/MEMORY.md:
- OFFICIAL: AppError hierarchy (confirmed with team)
- LEGACY: HTTPException in some routes — flag as WARNING

# In implementer/MEMORY.md:
- AppError is standard (confirmed in CLAUDE.md)
- Migrate old HTTPException routes to AppError when touched

Step 4 — Prevent:

## Conflict Prevention (add to all system prompts)
When you observe a pattern inconsistent with your memory or CLAUDE.md:
1. Do NOT update memory with the new pattern
2. Report it as "Potential convention conflict" in your output
3. Let the human resolve — only update memory after confirmation

Exercise 6: Design memory for 4 agents (Hard)

Project with 4 subagents: reviewer, implementer, tester, deployer (checks deploy readiness). Design: scope, categories, what it reads from others, and ownership.

See solution
CLAUDE.md (shared truth — only humans write)
    │
    ├── reviewer (project)
    │   ├── MEMORY.md → Architecture, issues, design decisions
    │   └── Reads: implementer, deployer memories
    │
    ├── implementer (project)
    │   ├── MEMORY.md → Conventions, library patterns
    │   └── Reads: reviewer memory
    │
    ├── tester (local)
    │   ├── MEMORY.md → Test results, flaky tests, coverage
    │   └── Reads: reviewer memory (issues to verify)
    │
    └── deployer (project)
        ├── MEMORY.md → Deploy checklist, env requirements
        └── Reads: reviewer, implementer memories
InformationOwnerReaders
Architectural patternsreviewerimplementer, deployer
Code conventionsimplementerreviewer
Test resultstesterreviewer
Bugs and statusreviewerimplementer, tester
Deploy configdeployerreviewer
Env var requirementsdeployerimplementer

Hierarchy of truth: CLAUDE.md > reviewer > deployer > implementer > tester.

The deployer uses project because deploy configuration is team knowledge. The tester is the only one in local because its results depend on the environment.


Summary

  • Isolated individual memories can contradict each other — each agent builds its own version of the truth
  • Strategy 1 (Complementary): Each agent specializes in a memory domain and reads the others' memories
  • Strategy 2 (Shared directory): A designated curator writes thematic files, the others read
  • Strategy 3 (CLAUDE.md + memory): CLAUDE.md is the shared source of truth; memories complement it with role-specific context
  • The recommended combination: CLAUDE.md as truth + complementary memories
  • Clear ownership avoids conflicts: each file has a single writer and multiple readers
  • Naming conventions: the frontmatter name = the directory, kebab-case for additional files
  • Share: architecture, conventions, decisions. Keep private: credentials, preferences, local results
  • The hierarchy of truth (CLAUDE.md > reviewer > implementer) resolves contradictions
  • Reporting conflicts is better than resolving them silently — the human decides
  • This coordinated strategy is the building block of capsule 05's project

Additional Resources

  1. Subagents — Persistent Memory (Anthropic Docs) — Official documentation of the memory field and scopes
  2. Create Custom Subagents — Complete YAML frontmatter reference
  3. CLAUDE.md Documentation — How CLAUDE.md works as a shared source of truth
  4. Claude Code Best Practices — Context and memory organization
  5. Prompt Engineering: System Prompts — Principles applicable to memory instructions
  6. Claude Code Tips and Tricks — Structuring context
  7. Git Best Practices — Versioning shared configuration like memory scopes
  8. Claude Code Overview — General context of the agent system

Next capsule: In capsule 04 you'll tackle Memory Management — how to curate MEMORY.md so it stays useful. A 200-line file full of noise is worse than an empty one. You'll learn content rotation, consolidation, prioritization within the 200-line limit, and strategies to keep memory clean over weeks of use.