DEV Community

Cover image for How I Manage Claude Code Context Across 20+ Repositories
Glenn Gray
Glenn Gray

Posted on • Originally published at graycloudarch.com

How I Manage Claude Code Context Across 20+ Repositories

This post was originally published on graycloudarch.com.


Every new Claude Code session starts cold. Claude doesn't know your
naming conventions, your Terraform state backend configuration, your
Jira workflow, or the architecture decisions you made six months ago. It
doesn't know you prefer Terragrunt over raw Terraform, that your AWS
accounts follow a specific naming scheme, or that your team's PR
descriptions follow a particular format.

You either re-explain everything at the start of each session, or you
watch Claude suggest patterns that don't fit your environment.

I run Claude Code daily across a 6-account AWS platform monorepo, a
personal consulting site, homelab infrastructure, and a handful of side
projects. After six months of experimentation, 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:

  • Global preferences get mixed with project specifics. Your "use snake_case for variable names" preference shouldn't live next to your Terraform state bucket configuration.
  • Credentials and account IDs end up in files you accidentally commit. Put AWS account IDs in a shared CLAUDE.md, and someone will eventually push it.
  • You can't share patterns across repos without duplication. Every new repo gets a fresh copy of the same conventions, and updates never propagate.
  • Multi-employer context creates conflicts. Your consulting client's Jira workflow shouldn't contaminate your personal project sessions.

The fix is to separate context by scope and load each layer
automatically.

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
Enter fullscreen mode Exit fullscreen mode

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.

Implementation: Symlinks from Dotfiles

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/
Enter fullscreen mode Exit fullscreen mode

install.sh wires these automatically:

::: {#cb3 .sourceCode}

# 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
Enter fullscreen mode Exit fullscreen mode

:::

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
Enter fullscreen mode Exit fullscreen mode

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.

::: {#cb5 .sourceCode}

## 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
Enter fullscreen mode Exit fullscreen mode

:::

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
Enter fullscreen mode Exit fullscreen mode

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:

::: {#cb7 .sourceCode}

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

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

## 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
Enter fullscreen mode Exit fullscreen mode

:::

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:

::: {#cb8 .sourceCode}

## Current State
- Branch: feat/IN-89-adstack-dev-ecr
- Active ticket: IN-89 — ECR in workloads-dev
- Next: IN-90 — ECS task definition

## Architecture Decisions
- ECR in workloads-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 infra-prod DNS zone creation before cutover can proceed
Enter fullscreen mode Exit fullscreen mode

:::

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).

Content Location Committed?


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
Enter fullscreen mode Exit fullscreen mode

A command file is just the prompt Claude should execute:

::: {#cb10 .sourceCode}

# 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.
Enter fullscreen mode Exit fullscreen mode

:::

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 dotfiles integration is worth setting up early --- it takes 30
minutes and means you never have to rebuild the context hierarchy when
you get a new machine or start working in a new environment.

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.

Top comments (0)