Team AI Instructions Management
Team AI Instructions Management
Section titled “Team AI Instructions Management”Manage AI instructions (CLAUDE.md, .cursorrules) across a team without fragmentation.
Pattern: Profile-Based Module Assembly — shared modules + per-dev profiles + automated assembler.
When to use: Team 5+ developers, multiple AI tools (Claude Code + Cursor/Windsurf), mixed OS. Skip if: Solo developer, homogeneous team (same tool, same OS), short project (<3 months).
The Problem: N x M x P Fragmentation
Section titled “The Problem: N x M x P Fragmentation”When a team grows, AI instructions fragment fast:
| Factor | Values | Example |
|---|---|---|
| N developers | 5-20 | Alice, Bob, Charlie… |
| M tools | 2-4 | Claude Code, Cursor, Windsurf, Copilot |
| P operating systems | 2-3 | macOS, Linux, WSL |
Total variants: N x M x P = 5 x 3 x 2 = 30 possible configurations.
Without a system, what happens:
Week 1: Team agrees on shared CLAUDE.mdWeek 3: Alice adds TypeScript strict rules locallyWeek 5: Bob copies Alice's file, removes half the rulesWeek 8: New hire Charlie gets Bob's outdated copyWeek 12: 5 developers, 5 different CLAUDE.md files, nobody knows what's canonicalRoot cause: CLAUDE.md is treated as a monolithic file instead of a composed configuration.
Architecture Overview
Section titled “Architecture Overview”profiles/ modules/├── alice.yaml ├── core-standards.md├── bob.yaml ├── git-workflow.md├── charlie.yaml ├── typescript-rules.md│ ├── test-conventions.md│ ├── macos-paths.md│ ├── linux-paths.md│ ├── cursor-rules.md│ └── communication-verbose.md│├── skeleton/│ └── claude-skeleton.md ← Template with {{MODULE:name}} placeholders│└── sync-ai-instructions.ts ← Reads profile → injects modules → writes output │ ▼output/├── alice/CLAUDE.md ← Generated (read-only)├── bob/CLAUDE.md└── charlie/CLAUDE.mdFlow: Profile (YAML) + Skeleton (template) + Modules (fragments) → Assembler → Generated CLAUDE.md
Phase 1: Audit Your Current CLAUDE.md
Section titled “Phase 1: Audit Your Current CLAUDE.md”Goal: Classify every line as universal, conditional, or personal.
# Audit template
## Universal (all devs, all tools)- Architecture: hexagonal- Tests: must pass before PR- Naming: kebab-case for files
## Conditional (depends on tool or OS)- Cursor: use @filename syntax → module: cursor-rules- macOS paths: /opt/homebrew → module: macos-paths- Linux paths: /usr/local → module: linux-paths
## Personal (individual preference)- Style: verbose explanations → profile preference- Language: French comments → profile preferenceCommand to measure:
wc -l CLAUDE.md # Total lines before modularization# Tag each line with [U]niversal, [C]onditional, [P]ersonal# Count by category to estimate module splitTypical result: 60% universal, 25% conditional, 15% personal.
Phase 2: Extract Modules
Section titled “Phase 2: Extract Modules”Goal: One .md file per thematic group.
Recommended structure:
modules/├── core-standards.md # Architecture, naming, patterns (all devs)├── git-workflow.md # Git conventions (all devs)├── typescript-rules.md # TS strict config (if TypeScript)├── test-conventions.md # Testing patterns (all devs)├── macos-paths.md # macOS-specific paths (if macOS)├── linux-paths.md # Linux paths (if Linux)├── cursor-rules.md # Cursor-specific rules (if Cursor)└── communication-verbose.md # Verbose explanation style (if preferred)Module format (each module is a standalone Markdown fragment):
## TypeScript Rules
- Use strict mode: `"strict": true` in tsconfig- Prefer `type` over `interface` for unions- No `any` — use `unknown` + type guards- Zod for runtime validation at boundariesGuidelines:
- Keep modules self-contained (no cross-references between modules)
- 15-50 lines per module is the sweet spot
- Name modules for their domain, not their audience
- One module = one reason to change
Phase 3: Create Developer Profiles
Section titled “Phase 3: Create Developer Profiles”Goal: One YAML per developer, listing their modules.
name: "Alice"os: "macos"tools: - claude-code - cursorcommunication_style: "concise"modules: core: - core-standards - git-workflow - typescript-rules - test-conventions conditional: - macos-paths # auto-included when os: macos - cursor-rules # auto-included when cursor in toolspreferences: language: "english"Profile rules:
coremodules: included for every dev (team standards)conditionalmodules: included based onosandtoolsfieldspreferences: personal settings injected into skeleton variables
Template for new team members: See profile-template.yaml
Phase 4: Write the Assembler Script
Section titled “Phase 4: Write the Assembler Script”Goal: Script that reads profile, injects modules, outputs CLAUDE.md.
// sync-ai-instructions.ts (simplified ~30 lines)import { readFileSync, writeFileSync, mkdirSync } from 'fs';import { parse } from 'yaml';import { join } from 'path';
const profile = parse(readFileSync(`profiles/${process.argv[2]}.yaml`, 'utf8'));let skeleton = readFileSync('skeleton/claude-skeleton.md', 'utf8');
// Collect modules from profileconst modules = [...profile.modules.core, ...profile.modules.conditional];
// Replace each placeholder with module contentfor (const mod of modules) { const content = readFileSync(`modules/${mod}.md`, 'utf8'); skeleton = skeleton.replace(`{{MODULE:${mod}}}`, content);}
// Remove unused placeholdersskeleton = skeleton.replace(/\{\{MODULE:\w+\}\}/g, '');
// Write outputconst outDir = `output/${process.argv[2]}`;mkdirSync(outDir, { recursive: true });writeFileSync(join(outDir, 'CLAUDE.md'), skeleton);console.log(`Generated ${outDir}/CLAUDE.md (${modules.length} modules)`);Run:
npx ts-node sync-ai-instructions.ts alice # Single devnpx ts-node sync-ai-instructions.ts --all # Generate all profilesnpx ts-node sync-ai-instructions.ts --check # Verify no driftFull template: sync-script.ts
Phase 5: CI Drift Detection
Section titled “Phase 5: CI Drift Detection”Goal: Catch when output files are out of sync with profiles/modules.
name: AI Instructions Drift Checkon: push: paths: - 'modules/**' - 'profiles/**' - 'skeleton/**' schedule: - cron: '0 9 * * 1-5' # Weekdays at 9am
jobs: check-drift: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npx ts-node sync-ai-instructions.ts --check - name: Fail if drift detected run: | if git diff --quiet output/; then echo "No drift detected" else echo "::error::AI instructions are out of sync!" git diff output/ exit 1 fiWhat it detects:
- A module was edited but the assembler wasn’t re-run
- A profile was added but no output CLAUDE.md exists
- A dev manually edited their generated CLAUDE.md
Policy: Generated files are read-only. All changes go through profiles/modules, then re-run the assembler.
Phase 6: Onboarding New Developers
Section titled “Phase 6: Onboarding New Developers”Goal: New dev gets their CLAUDE.md in under 5 minutes.
# 1. Clone repogit clone <repo>
# 2. Copy profile templatecp examples/team-config/profile-template.yaml profiles/dave.yaml# Edit: name, os, tools, modules
# 3. Generatenpx ts-node sync-ai-instructions.ts dave
# 4. Installcp output/dave/CLAUDE.md .claude/CLAUDE.mdCLAUDE.md placement reminder:
- Project-wide:
project/CLAUDE.md(committed, for team conventions) - Personal overrides:
.claude/CLAUDE.md(gitignored, for individual preferences)
Troubleshooting
Section titled “Troubleshooting”| Problem | Cause | Fix |
|---|---|---|
| Generated file too long | Too many modules included | Review profile: remove rarely-used modules |
| Module missing in output | Placeholder typo in skeleton | Check {{MODULE:name}} matches filename |
| CI drift alert | Output not regenerated after module edit | Run sync-ai-instructions.ts and commit |
| Dev A has rules Dev B doesn’t | Expected — it’s the point | Verify profile is correct for that dev |
| Stale output after merge | Merge didn’t trigger regeneration | Run assembler post-merge (add git hook) |
Scaling Thresholds
Section titled “Scaling Thresholds”| Team size | Approach |
|---|---|
| 1-2 devs | Shared CLAUDE.md + precedence rules (Section 3.4) |
| 3-5 devs, same tools | Optional: modules only, no profiles |
| 5+ devs or multi-tool | Profile-Based Module Assembly (this workflow) |
| 20+ devs | Consider a CLAUDE.md config server + PR-based module changes |
Measured Results
Section titled “Measured Results”From a production team (5 developers, 3 tools, 2 OS):
| Metric | Before | After |
|---|---|---|
| Lines per CLAUDE.md | ~380 (monolithic) | ~185 (assembled) |
| Token reduction | — | 59% less context consumed |
| Modules extracted | 0 | 12 |
| Onboarding time | ”copy someone’s file” | 5 min (template + generate) |
| Drift incidents | Weekly | 0 (CI catches) |
Related
Section titled “Related”- Section 3.5 Team Configuration at Scale — Concept overview and measured results
- Section 3.4 Precedence Rules — How Claude reads multiple CLAUDE.md files
- profile-template.yaml — Profile template
- claude-skeleton.md — Skeleton template
- sync-script.ts — Full assembler script