Routing
Claude Code

A three-layer model for Claude Code governance: framework, personal, and repo. The framework installs into its own namespace so it never collides with Claude Code itself or with the user's own files.

Scroll
Series · Agent Governance for Claude Code
  1. Routing · this post · how layers compose and how docs get loaded
  2. Change rhythm · scratch plans, phase discipline, and ADRs as the only durable artifact
  3. Review and verify · auto-triggered self-review on every PR, verification gates, and deployment

Summary

This post defines the routing layer of a reusable Claude Code framework.

The framework is the shared process layer. It standardizes:

The core rule is simple: the framework owns process, the personal layer owns a user's cross-repo preferences, and the repo layer owns local truth. The framework installs into its own namespace so none of those layers collide.

The appendix contains the complete file skeletons for the routing layer. Part 2 covers the change-rhythm layer. Part 3 covers review, verification, and deployment.

Problem

Without a clear structure, Claude Code guidance tends to collapse into one of two bad states:

An earlier draft of this RFC proposed a two-layer split (global framework vs repo) with the framework's files planted directly under ~/.claude/. That shape had two concrete flaws.

Flaw 1: the framework squats on Claude Code's own directory

Claude Code natively uses ~/.claude/ for its own state: CLAUDE.md as user memory, commands/, skills/, agents/, hooks/, settings.json, projects/, plans/, and keybindings.json. Planting framework-owned files at ~/.claude/CLAUDE.md and ~/.claude/docs/agents/ invites three kinds of breakage:

Flaw 2: no user-level extension point

In a strict global-vs-repo model, a user who wants a preference that applies across all their repos has no place to put it. "Always prefer tabs over spaces in Go," or "no emoji in code comments," or "when writing commit messages, avoid marketing tone" are legitimate personal rules. With only two layers, the user must either edit the framework's own files (which breaks at enterprise scale where the framework is centrally managed) or copy the rule into every repo.

Both flaws share one root cause: the framework conflates user scope with framework scope. Namespacing the framework fixes both at once, because once ~/.claude/CLAUDE.md is no longer framework-owned, the user has somewhere to put personal preferences.

The framework also needs to avoid becoming a global dumping ground for frontend, backend, or infrastructure standards that only make sense inside a specific repo.

Goals

Non-Goals

Proposed Design

1. Three-Layer Hierarchy

The system has three layers:

The framework layer installs into its own namespaced subdirectory:

~/.claude/
├── CLAUDE.md                      # USER-owned. Imports framework + adds personal preferences.
├── commands/
│   └── agent-*.md                  # framework command shims. Claude Code's native commands dir.
├── personal/                      # optional: user's cross-repo docs tree
│   └── docs/agents/
│       ├── policy/
│       ├── playbooks/
│       ├── reference/
│       └── decisions/
└── agent-governance/              # framework-owned install
    ├── CLAUDE.md                  # framework root contract
    └── docs/agents/
        ├── router/
        ├── policy/
        ├── playbooks/
        ├── reference/
        └── decisions/

Two boundaries make this layout work:

Each repo extends the upper layers with local docs and optional local commands:

repo/
├── CLAUDE.md
├── .claude/commands/
└── docs/agents/
    ├── router/
    ├── policy/
    ├── playbooks/
    ├── reference/
    └── decisions/

The framework layer explains how work should happen. The personal layer carries one user's cross-repo preferences. The repo layer explains how that codebase works.

2. Root Contract

Two files form the root contract, with a deliberate separation of ownership:

A minimal user ~/.claude/CLAUDE.md looks like this:

@agent-governance/CLAUDE.md

## Personal preferences

- Prefer tabs over spaces in Go.
- No emoji in code comments.
- When suggesting commit messages, avoid marketing tone.

The @ prefix is Claude Code's native import syntax for CLAUDE.md. The framework contract loads first and establishes the shared process layer; personal preferences follow and override framework defaults where they conflict, subject to the authority order below.

$CLAUDE_HOME is the framework install directory. By default that is ~/.claude/agent-governance/. Every reference to $CLAUDE_HOME/docs/agents/... in framework docs or repo docs resolves under that path.

3. Components

The framework uses a typed docs tree so each category has a single job. During a typical change, they are encountered in this order:

Category Job
router/ Phase, capability, and workflow routing. Given a work description like "plan change" or "verify changes", the capability map resolves it to the canonical doc. The router also decides which policy and playbook to load based on the current phase and work type, and which layer owns a given rule.
policy/ Binding rules. Loaded early and checked throughout. Policies define what must be true, such as test requirements, spec completeness, and documentation discipline. They are not overridden by playbooks or references.
playbooks/ Ordered workflows. Playbooks sequence the steps for the current phase: what to do, in what order, and what to load next. They are the primary mechanism for driving work forward.
reference/ Deep detail. Loaded only when a playbook or policy needs deeper material on a specific topic, such as review triggers, audit checklists, or gate definitions. Not preloaded for every change.
decisions/ Durable rationale. Decision Records explain why a lasting architectural or workflow choice was made. They are not part of the normal flow; consulted on demand when a past decision is questioned. Part 2 defines when to write one.

In short: router selects, policy constrains, playbooks sequence, references deepen, and decisions explain why.

graph TD
    entry["~/.claude/CLAUDE.md
user composition · imports framework + personal prefs"]:::routing subgraph framework ["$CLAUDE_HOME (framework)"] fcontract["CLAUDE.md
framework root contract"]:::routing subgraph router ["router/"] phases["phases.md"]:::api capmap["capability-map.md"]:::api composition["composition.md"]:::api end policy["policy/*
binding rules"]:::data playbooks["playbooks/*
ordered workflows"]:::data reference["reference/*
deep detail"]:::onDemand decisions["decisions/*
durable rationale"]:::onDemand end entry --> fcontract fcontract --> phases fcontract --> capmap fcontract --> composition phases --> policy capmap --> policy composition --> policy policy --> playbooks playbooks --> reference playbooks -.-> decisions classDef routing fill:#5C3E14,stroke:#E8A849,color:#fff,stroke-width:1.5px classDef api fill:#1B3D3A,stroke:#4ECDC4,color:#fff,stroke-width:1.5px classDef data fill:#2A3054,stroke:#7B93DB,color:#fff,stroke-width:1.5px classDef onDemand fill:#3A2054,stroke:#B07CD8,color:#fff,stroke-width:1.5px

This avoids the common failure mode where one document mixes routing, rules, examples, and rationale without clear boundaries.

4. Authority Order

Three layers plus direct instruction create a resolution order. When sources conflict, higher beats lower:

  1. Direct user instructions for the current task
  2. Repo ./CLAUDE.md and repo docs/agents/*
  3. Personal ~/.claude/CLAUDE.md and ~/.claude/personal/docs/agents/*
  4. Framework $CLAUDE_HOME/CLAUDE.md and $CLAUDE_HOME/docs/agents/*
  5. Code and tests
  6. External memory or prior-session context

The order is intentional. Personal preferences sit above framework defaults because a user's own rules should win over shared defaults. But personal preferences sit below the repo layer because a codebase's own conventions are more specific than any individual's personal style.

Within each layer, the typed categories resolve in their own order: repo-specific policy beats repo-specific playbook, personal policy beats personal playbook, framework policy beats framework playbook, and so on.

5. Composition Contract

Ownership is strict:

Rules:

  1. $CLAUDE_HOME always means ~/.claude/agent-governance/. It does not mean ~/.claude, and it does not mean the repo root.
  2. Repo docs use repo-relative paths such as ./CLAUDE.md, docs/agents/..., and .claude/commands/....
  3. Personal docs use ~/.claude/personal/docs/agents/....
  4. The user's ~/.claude/CLAUDE.md begins with @agent-governance/CLAUDE.md (or equivalent import), then adds personal preferences.
  5. Repos extend with their own capability map for repo-specific routing and workflow names.
  6. Repo commands use distinct names, not agent-* shadowing.
  7. Commands in every layer stay process-oriented.

Routing Capabilities

The routing layer has three capabilities of its own: adopting the framework in a new repo, growing a repo's local routing, and repairing routing friction. Everything else (change bundles, verify, review, deploy) is scoped to parts 2 and 3.

Adopt

/agent-adopt is first-time repo onboarding. It reads the framework composition contract and produces the repo's local entrypoint, capability map, and initial docs/agents/ tree. It does not invent the repo's standards; it sets up the shape into which repo-specific policy, playbooks, and reference docs are later added.

Add Capability

/agent-add-capability is the wizard for growing an already-adopted repo. It should:

The same wizard can grow the personal layer: invoked with --scope=personal, it writes under ~/.claude/personal/docs/agents/ instead of a repo-relative path.

Improve

/agent-improve is for root-cause routing repair. When the framework routes to the wrong doc, or a playbook is unclear, or a user hits the same friction twice, this command diagnoses the underlying issue and patches the canonical typed docs. It is not a general-purpose refactor tool. Its job is to fix routing, not to rewrite opinions.

Decision Records as a doc category

decisions/ is a routing category, but the discipline around writing Decision Records lives in part 2, because a Decision Record is the durable artifact that a change produces. From the routing perspective all you need to know is that every layer has a decisions/ directory and that a Decision Record is consulted on demand, not preloaded.

Usage

Framework commands live under ~/.claude/commands/ and use the reserved agent-* namespace. This post covers the routing subset: three commands for exploring, adopting, and extending.

graph LR
  ADOPT["/agent-adopt
first-time repo onboarding"]:::routing ADDCAP["/agent-add-capability
extend repo or personal
policy, playbook, reference"]:::routing IMPROVE["/agent-improve
root-cause routing repair"]:::routing ADOPT --> ADDCAP ADDCAP --> IMPROVE classDef routing fill:#5C3E14,stroke:#E8A849,color:#fff,stroke-width:1.5px

These commands are process-oriented. They load canonical docs and guide the workflow. They are not the place for hidden repo-specific standards or arbitrary scaffolding logic. More specific commands should be repo-local.

Change lifecycle commands (/agent-plan-change, /agent-open-change, /agent-implement-change, /agent-close-change, /agent-record-decision) are defined in part 2. The auto-triggered review command (/agent-review-change) is defined in part 3.

Extension

Because the framework lives in its own namespaced subdirectory, the same install pattern works at every scale: solo, team, or enterprise. ~/.claude is the user's surface. ~/.claude/agent-governance/ is the install surface. The difference between scales is only who authors the install and how it is distributed.

Personal install

A solo user can clone or download the framework into ~/.claude/agent-governance/ directly, then add a thin ~/.claude/CLAUDE.md that imports the framework contract and adds personal preferences. No version manager is required, but the directory-per-install pattern means they can keep multiple versions around during a migration.

Team or enterprise install

For larger deployments, the framework should be owned in a versioned internal source repository or package and installed onto developer machines via a version manager that maintains a current pointer:

~/.claude/
├── CLAUDE.md                              # user composition
├── commands/
│   └── agent-*.md                          # thin shims, resolve against current
└── agent-governance/
    ├── current                             # symlink to the active version
    ├── 1.4.0/
    └── 1.5.0/

In this model:

This structure gives the organization:

The enterprise rollout should use five layers:

  1. enterprise policy memory for hard company-wide instructions
  2. enterprise managed settings for enforced permissions and configuration
  3. framework install at ~/.claude/agent-governance/ for the shared process runtime
  4. personal at ~/.claude/CLAUDE.md and ~/.claude/personal/docs/agents/ for one user's cross-repo preferences
  5. repo-local docs and commands for project-specific behavior

The framework should not rely on manual file copying at scale. Ship it through an internal installer or manager, for example:

company-claude install
company-claude update
company-claude doctor
company-claude adopt-repo

That tool installs the chosen framework version into ~/.claude/agent-governance/<version>/, updates the current pointer, verifies the effective runtime surface, and optionally bootstraps the minimal repo-local adoption files.

The framework may also integrate with MCP for dynamic company services such as service-catalog lookup or policy workflows, but MCP should not be the primary distribution mechanism for the core process docs. The base framework should still arrive through installed memory files and commands so it remains stable, inspectable, and versioned.

Example: Frontend Best Practices

If a repo wants frontend best practices, those rules belong in the repo layer, not in the framework.

A typical repo-local addition would look like this:

repo/
├── CLAUDE.md
├── .claude/commands/
│   └── frontend-change.md
└── docs/agents/
    ├── router/
    │   └── capability-map.md
    ├── policy/
    │   └── frontend.md
    ├── reference/
    │   └── frontend-best-practices.md
    └── decisions/
        └── DR-002-frontend-boundaries.md

In that design:

If the same user also wants a cross-repo rule such as "always scope new React state to the nearest route boundary," that belongs in the personal layer at ~/.claude/personal/docs/agents/policy/frontend.md, not in any repo and not in the framework. The personal rule applies everywhere unless a specific repo overrides it.

The framework owns the process for adding capabilities. The personal layer owns a user's cross-repo preferences. The repo owns the actual standards.

Tradeoffs

Benefits

Costs

These costs are acceptable because they buy a clearer separation of concerns, a safe install path that coexists with Claude Code's own evolution, and a first-class home for personal preferences that every engineer wants.

Recommendation

If your team uses Claude Code across multiple repositories and you want agents to follow a consistent, auditable process, adopt the routing layer described here:

Parts 2 and 3 of this series cover the change lifecycle and the review/verify/deploy discipline that sit on top of this routing layer.

Appendix: The complete routing-layer file skeletons are available in the implementation appendix.

Series: Part 2 · Change rhythm · Part 3 · Review and verify