Layer 1 — CLAUDE.md (The Memory Layer)

The question: How do I stop repeating the same context — our naming conventions, our VLAN plan, our vendor stack, our safety rules — at the start of every session?

The hierarchy

Claude Code reads CLAUDE.md files from multiple locations in a hierarchy. More specific files override more general ones:

~/.claude/CLAUDE.md               # Personal global — your defaults
./CLAUDE.md                        # Project root — your team's context
./terraform/CLAUDE.md              # Subdirectory — Terraform-specific rules
./playbooks/CLAUDE.md              # Subdirectory — Ansible-specific rules

A networking CLAUDE.md

Create CLAUDE.md in your project root:

# Network Automation Project — Operational Context

## Environment
- **Core/Distribution:** Arista 7280R3, EOS 4.32.2F
- **Access Layer:** Cisco Catalyst 9300, IOS-XE 17.12.04
- **Firewalls:** Palo Alto PA-5400, PAN-OS 11.2
- **Load Balancers:** F5 BIG-IP i5800, TMOS 17.1
- **SD-WAN:** Cisco Viptela, 20.14
- **Wireless:** Aruba Central, AP-635

## Naming Convention
Format: `{role}-{site}-{number}`
- Roles: core, dist, access, fw, lb, wan, wlc
- Sites: nyc, lax, ord, ldn, fra
- Example: core-nyc-01, fw-lax-02, access-ord-15

## IP Addressing Scheme
- Pattern: 10.{site_id}.{vlan_id}.0/24
- Site IDs: nyc=1, lax=2, ord=3, ldn=4, fra=5
- VLAN 10: User data
- VLAN 20: Voice
- VLAN 30: Printers/IoT
- VLAN 99: Management (always /24)
- VLAN 100: Native (no IP, never used for traffic)
- Loopbacks: 10.255.{site_id}.{device_id}/32

## Routing Design
- iBGP full mesh between core routers (AS 65000)
- OSPF Area 0 for inter-site backbone links and loopbacks
- Per-site OSPF areas for distribution/access (area = site_id)
- All BGP sessions use MD5 authentication
- Route-map naming: RM-{DIRECTION}-{PEER} (e.g., RM-OUT-TRANSIT-01)
- Prefix-list naming: PL-{PURPOSE} (e.g., PL-DEFAULT-ONLY)

## Safety Rules — Non-Negotiable
- NEVER apply configuration to a production device without explicit approval
- NEVER modify ACLs on management interfaces
- NEVER remove the last management access method from any device
- NEVER execute "write memory" or "copy run start" autonomously
- Always include rollback commands with any configuration change
- Always capture pre-change baselines: BGP summary, OSPF neighbors,
  interface counters, routing table size
- All changes require a ServiceNow ticket number

## Change Control
- Windows: Tuesdays and Thursdays, 22:00–02:00 UTC
- Emergency changes require VP-level approval
- Pre/post validation is mandatory, not optional

## Repository Structure
- configs/        — Running configs (pulled daily via Oxidized)
- templates/      — Jinja2 templates for config generation
- playbooks/      — Ansible playbooks
- terraform/      — IaC for AWS networking (Transit GW, VPCs)
- scripts/        — Python/Nornir operational scripts
- docs/           — Network diagrams, IPAM exports, runbooks

Every session now starts with Claude knowing your vendor stack, naming scheme, IP plan, routing design, change control process, and safety boundaries. When you ask it to generate a BGP neighbor config, it uses AS 65000, applies your route-map naming convention, includes MD5 authentication, and adds the rollback commands — without being reminded.

Subdirectory CLAUDE.md for context switching

Create playbooks/CLAUDE.md:

# Ansible Playbook Context

- Inventory source: NetBox dynamic inventory plugin
- Connection type: network_cli (not netconf unless specified)
- All playbooks must be idempotent
- Run ansible-lint with production profile before committing
- Vault password file: ~/.ansible/vault_pass
- Never hardcode credentials — use vault or env vars
- Always include a pre-task that captures running config backup
- Always include a rescue block with rollback logic

Create terraform/CLAUDE.md:

# Terraform Context

- Provider: AWS, pinned to ~> 5.0
- State backend: S3 + DynamoDB locking
- Workspace per environment: dev, staging, prod
- Module naming: mod-{function} (e.g., mod-transit-gw, mod-vpc)
- All resources tagged: Environment, Owner, CostCenter, ManagedBy=terraform
- terraform plan before any apply — no exceptions
- No inline security group rules — always separate resources

When Claude works in playbooks/, it reads both the root CLAUDE.md (vendor context, naming, safety rules) and the Ansible-specific context. When it works in terraform/, it picks up root context plus Terraform conventions. You never explain these again.

Knowledge check

Try it yourself