AIClaude CodeLLMDeveloper ToolingDevOpsInfrastructure

How I Manage Claude Code Context Across 20+ Repositories

Every new Claude Code session starts cold. After 3 months of daily use across 20+ infrastructure repos, I built a three-tier context hierarchy that loads team patterns, project state, and infrastructure conventions automatically — no copy-paste, no ramp-up.

How I Manage Claude Code Context Across 20+ Repositories

Three months ago I was re-explaining my Terragrunt state backend to Claude for the third time in a week. Different session, same repo, same repo I’d worked in the session before. Claude had no idea I was even in the same project.

I run Claude Code daily across a 6-account AWS platform monorepo, a personal consulting site, homelab infrastructure, and a handful of side projects. Every session started with the same five minutes of “here’s the project, here are the conventions, here’s the Jira workflow” — and still ended with Claude suggesting patterns that didn’t fit the environment, because I’d inevitably forgotten to mention something.

After three months of broken symlinks and abandoned experiments, I landed on a three-tier context hierarchy that loads the right context automatically depending on which directory I’m working in — and I manage all of it from a single dotfiles repo.

The Problem with Single-File Context

Claude Code loads CLAUDE.md from the current directory (and parent directories, walking up to ~/.claude/CLAUDE.md). Most teams start with one file and put everything in it.

That breaks down quickly:

My first attempt at fixing this was a shared scripts directory. The three-tier hierarchy came later, after I figured out what was actually wrong with the simpler approach.

My First Attempt: A Shared Scripts Directory

Before landing on the three-tier system, I built something more obvious: a ~/shared-claude-infra/ directory containing a setup-project.sh script that initialized .claude/ context for each new repo.

The script created the directory structure and symlinked a rules/shared/ folder back to the shared repo:

mkdir -p "$PROJECT_DIR/.claude/rules"
ln -s ~/shared-claude-infra/rules "$PROJECT_DIR/.claude/rules/shared"

This worked for the first two repos I configured. Then the problems compounded:

When I eventually deleted the shared directory, a quick find confirmed broken symlinks scattered across every repo that had run the setup script. The approach was inherently fragile because it depended on every machine, every repo, and every workspace path staying synchronized manually.

The fix isn’t a smarter script. It’s inverting the relationship: instead of a script that runs once per project, use dotfiles that wire context automatically based on what directories exist.

The Three-Tier Hierarchy

~/.claude/CLAUDE.md              ← Global: preferences, style, git workflow
~/work/{employer}/.claude/       ← Org: team structure, AWS accounts, Jira workflow
~/work/{employer}/{repo}/.claude/ ← Project: repo architecture, active tickets

Claude Code walks up the directory tree loading CLAUDE.md files at each level. Each tier handles a specific scope:

Global tier (~/.claude/): Everything that applies across all work — communication style, git commit format, PR description templates, universal infrastructure patterns. No credentials, no account IDs, nothing employer-specific.

Org tier (~/work/{employer}/.claude/): Team structure, Jira project keys, AWS account layout, CI/CD pipeline conventions. Sensitive patterns (account IDs, VPC IDs, state bucket names) go in gitignored files within this directory. Reusable patterns (CI/CD templates, AWS patterns without specifics) go in committed files.

Project tier (~/work/{employer}/{repo}/.claude/): Architecture decisions for this specific repo, active tickets, ongoing work state. Always gitignored — this is ephemeral working context that changes frequently.

The hierarchy only works if it’s consistent across machines. I manage all context files from a dotfiles repo using symlinks:

dotfiles/claude/
├── global/          → symlinked to ~/.claude/
├── {employer}/      → symlinked to ~/work/{employer}/.claude/
└── {personal}/      → symlinked to ~/personal/.claude/

install.sh wires these automatically:

# Global context
ln -sf "$DOTFILES/claude/global" "$HOME/.claude"

# Per-employer context
for employer in "${EMPLOYERS[@]}"; do
  WORK_DIR="$HOME/work/$employer"
  if [ -d "$WORK_DIR" ]; then
    ln -sf "$DOTFILES/claude/$employer" "$WORK_DIR/.claude"
  fi
done

Any machine that runs install.sh gets the same context hierarchy. Changes committed to dotfiles propagate immediately.

What Each Level Contains

Global (~/.claude/)

~/.claude/
├── CLAUDE.md          # Preferences, active work summary
└── rules/
    ├── git-workflow.md
    ├── pr-patterns.md
    ├── infrastructure.md
    └── context-management.md

CLAUDE.md is short — preferences and a pointer to where active work lives. The heavy lifting goes in rules/ files that Claude loads as supplementary context.

## Communication Style
- Be direct and technical — I understand infrastructure concepts
- Explain the "why" behind decisions
- Provide specific file paths and line numbers

## Git Workflow
- Branch format: feat/TICKET-123-description
- Commit format: [TICKET-123] Brief summary\n\nWhy this change...
- Never add Co-Authored-By trailers

Org Level (~/work/{employer}/.claude/)

~/work/{employer}/.claude/
├── {EMPLOYER}.md              # Team structure, Jira workflow — committed
└── rules/
    ├── cicd-patterns.md       # CI/CD conventions — committed
    ├── aws-patterns.md        # Account IDs, VPC IDs — GITIGNORED
    └── terraform-patterns.md  # State config, module paths — GITIGNORED

The privacy split matters. cicd-patterns.md contains reusable GitHub Actions patterns — fine to commit. aws-patterns.md contains actual account IDs — stays local.

A typical employer context file:

## Team Structure
- Platform team: 5 engineers, all in Jira project IN
- AWS accounts: dev, nonprod, prod (+ 3 infra accounts network, security, management)
- Monorepo: ~/work/{employer}/iac — Terragrunt, 78 components

## Jira Workflow
- IN project (infrastructure): transition IDs 3=In Dev, 8=Needs Review, 9=Done
- Prefix all commits: [IT-XXX]
- API: REST v2 only — v3 silently returns empty responses

## CI/CD
- GitHub Actions with OIDC to AWS (no long-lived credentials)
- PR requires: terraform plan output posted as comment
- Merge to main triggers auto-deploy to nonprod

The gitignored aws-patterns.md contains account IDs and specific ARNs that Claude needs for generating Terraform configurations accurately but shouldn’t be committed anywhere.

Project Level (~/work/{employer}/{repo}/.claude/)

Project context is ephemeral and always gitignored. It’s the working memory for an ongoing effort:

## Current State
- Branch: feat/IT-89-my-app-dev-ecr
- Active ticket: IT-89 — ECR in dev
- Next: IT-90 — ECS task definition

## Architecture Decisions
- ECR in dev only; cross-account pull policies for nonprod and prod
- Mutable tags in dev, immutable in nonprod/prod
- KMS key per environment, not per repository

## Blockers
- Waiting on network DNS zone creation before cutover can proceed

I update this file at the end of each session with current state so the next session loads instantly without re-explaining where things are.

The Privacy Model

The critical insight is that context files need two categories: committed (shareable) and local-only (sensitive).

ContentLocationCommitted?
Personal preferences~/.claude/CLAUDE.md
Git workflow rules~/.claude/rules/git-workflow.md
Team structure{employer}/.claude/{EMPLOYER}.md✅ sanitized
CI/CD patterns{employer}/.claude/rules/cicd-patterns.md
AWS account IDs{employer}/.claude/rules/aws-patterns.md❌ gitignored
VPC IDs, state config{employer}/.claude/rules/terraform-patterns.md❌ gitignored
Active ticket state{repo}/.claude/OVERRIDES.md❌ gitignored

The .gitignore at the dotfiles level handles this automatically by ignoring **/aws-patterns.md and **/terraform-patterns.md across all employer directories.

Custom Commands

Beyond context files, Claude Code supports custom /commands — reusable prompts stored as markdown files:

~/.claude/commands/
├── checkpoint.md       # Create context snapshot
├── sync-work.md        # Update active work status
└── pr-ready.md         # Generate PR description

A command file is just the prompt Claude should execute:

# checkpoint.md
Create a context checkpoint. Read the current git status across active repos,
summarize open PRs and their status, list active tickets with their current
state, and write a structured summary to ~/.claude/local.md. Include any
blocking issues and the next planned action.

Commands at the global level are available everywhere. Org-level commands handle employer-specific workflows like Jira transitions.

What This Solves in Practice

Before this system: every new Claude session started with “here’s the project, here are the conventions, here’s where things are.” Five minutes of ramp-up, inconsistent outputs because I’d forget to mention something.

After: I cd into a repo and Claude already knows the Jira workflow, the AWS account structure, the naming conventions, and where the active work stands. When I start a session mid-ticket, the project-level context tells Claude exactly what was in progress.

The bigger payoff is consistency. When Claude generates Terraform, it generates it with the correct state backend. When it writes commit messages, they follow the format reviewers expect. When it suggests architecture, it fits the actual account model rather than a generic AWS example.

Starting Point

If you’re starting from scratch, work tier by tier:

  1. Create ~/.claude/CLAUDE.md with your communication preferences and git conventions.
  2. Add a rules/ directory with patterns you want loaded consistently.
  3. Create an org-level directory when you start working with a specific employer or major project.
  4. Add project-level context when you start a multi-session effort.

Don’t try to build the whole system at once. The global tier alone eliminates most of the per-session ramp-up. The org and project tiers pay off as work gets more complex.

The thing that surprised me most wasn’t the time saved on ramp-up. It was how much the output quality improved. When Claude knows the actual state backend, the actual account IDs, the actual PR format your reviewers expect — the suggestions it makes fit your environment. That gap between “technically correct” and “actually usable” is where most of the friction in AI-assisted infrastructure work lives. The context hierarchy is mostly just closing that gap.


If you’re setting up Claude Code for a platform team and want to talk through the context design, I do advisory engagements for teams getting serious about AI tooling in their infrastructure workflow.

Working through a similar problem?

Fractional infrastructure architecture — 10–20 hrs/week for 3–6 months. No full-time headcount required.