·3 min read

Claude Code config is a team asset, not a personal file

build-in-publicaiai-engineeringllmopscontext-engineeringengineering-culture|
PostLinkedIn
A diagram of the layered .claude/ setup: a lean root CLAUDE.md, path-scoped rules, per-service nested CLAUDE.md files, settings.json with permissions and hooks, and .mcp.json with a read-only Postgres server.

Claude Code config is a team asset, not a personal file

Most teams treat their AI coding agent's setup as a personal thing: each engineer tweaks their own instructions, and the repo's real conventions live in people's heads and in review comments. On the robbed monorepo — Solidity contracts, a TypeScript web app, an API, an indexer, a keeper, and a shared package — I wanted the opposite. A shared, version-controlled, enforced Claude Code setup, so that every engineer, and every AI coding agent working in the repo, follows the same conventions, guardrails, and ownership boundaries automatically.

It started from a real problem. All of the agent's context lived in one monolithic root CLAUDE.md. That meant the repo's rules were one giant blob where every task loads every rule in full (Solidity rules load while you edit the TypeScript indexer), and there was no clean way to say who owns what. So I restructured it into layers that live in git and load beside the code they govern.

Shared conventions, not tribal knowledge. The lean root CLAUDE.md plus .claude/rules/ encode the repo's rules once, checked in. Six rule files: two load every session (spec-authority, no-market-metrics) because they're universal; four are path-scoped — solidity-orbitcontracts/, lp-copy → web/shared/docs, anti-driftapps/ + packages/*, docs-placement → any .md. A new teammate, or a fresh agent run, gets the right rules automatically instead of learning them by breaking things in review. Ownership boundaries per service. Each workspace got its own nested CLAUDE.mdcontracts/, apps/web/, apps/web/e2e/, apps/api/, apps/indexer/, apps/keeper/, packages/shared/ — carrying that service's commands, spec sections, and gotchas. I also authored a dedicated subagent for the one service that lacked one, so the per-service convention is complete. The config now mirrors the team's ownership model: the boundaries in the repo match the boundaries in the setup. Guardrails everyone inherits. Enforcement moved into settings.json: permissions deny reads of real secret files (.env, keys, keystores, deployer.json) while keeping committed .env.example and build configs readable; safe build/test prefixes are allowed; forge script asks first. Two hooks back it up — a protect-secrets.sh PreToolUse guard that blocks secret reads, repo-wide rm -rf, and destructive psql, and a stop-typecheck.sh Stop hook that typechecks only the touched workspaces, with a loop guard. Same safety rules for every contributor and every agent run, human or AI — nobody accidentally reads a secret or leaves a workspace broken.

A couple of smaller things rode along: .mcp.json gained a read-only Postgres MCP server in restricted access mode, so anyone can inspect the schema without write access, and the contributor guide's authority chain and docs map were updated to match.

The takeaway: treat Claude Code config the way you treat CI, linters, and CODEOWNERS — a shared team asset checked into the repo, not a personal per-developer thing. I can't hand you a metric; the consistency and focus wins are qualitative. But as the team and the repo grow, the right context loading beside the right code, for everyone, is the property that scales.

Commit: https://github.com/robbed-fun/robbed/commit/65cfcfffc7291d564a041e424fa34b5696eb277c

Oleksandr Yusypenko

Oleksandr Yusypenko

Senior Full-Stack + AI Engineer. Building in public — AI agents, LangGraph, production systems.