From afterthought to infrastructure: how AI config evolves in a real project
506 commits. 407 files. 8.6% of all repo activity. How AI config evolved from afterthought to infrastructure over 9 months on a real production codebase.
Written by Florian Bruniaux
AI Founding Engineer at MΓ©thode Aristote, 13 years scaling engineering teams from developer to CTO. Builds open-source developer tools, see what else I've shipped.
TL;DR
| What | Details |
|---|---|
| Project | MΓ©thode Aristote EdTech platform, 9 months (Aug 2025 β Apr 2026) |
| Total AI config commits | 506, 8.6% of all repo commits |
| Current scale | 407 files in .claude/, 34 rules, 15 hooks, 36 skills, 57 commands, 17 agents |
| Distribution | 23% in first 5 months, 77% in last 4 months |
| 5 phases | Afterthought β Documentation β Infrastructure β Engineering Practice β Compound Engineering |
| Context Diet | Apr 2026: always-on context 2,518L β 646L (-74%), ai:score 85 β 125/145 |
| The big bang | Jan 6, 2026: 86 files created in a single day (commit 1421e863) |
| Key insight | AI config doesnβt get designed upfront, you figure out what it needs by running into the friction. |
This is a post-mortem of AI configuration evolving over 9 months of serious use on a production codebase, rather than a guide to a perfect CLAUDE.md.
The data is real: I ran git log --all --format="%ad" --date=format:"%Y-%m" -- CLAUDE.md .claude/ on the repository and categorized 506 commits touching AI configuration files. The pattern surprised me, and so did the final number: 8.6% of all commits in this repository touch AI config. CLAUDE.md alone has been committed 149 times.
506 configuration commits over nine months
Commits AI-config per month (506 total, 9 months)
Aug 2025 ββ 5
Sep 2025 ββββββββ 24
Oct 2025 βββββββββββ 34
Nov 2025 βββββββββ 27
Dec 2025 βββββββββ 27
Jan 2026 ββββββββββββββββββββββββββββββββββββββββββββββ 138 β Big Bang (86 files in 1 day)
Feb 2026 βββββββββββββββββββββββββββ 81
Mar 2026 βββββββββββββββββββββββββββββββββββββββ 116 β ACE pipeline
Apr 2026 ββββββββββββββ 43 (partial)
|βββ 23% (117) ββββ|βββββββββββββ 77% (378) ββββββββββββββββ|
AugβDec JanβApr
| Month | AI-config commits | % of total |
|---|---|---|
| Aug 2025 | 5 | 1.0% |
| Sep 2025 | 24 | 4.7% |
| Oct 2025 | 34 | 6.7% |
| Nov 2025 | 27 | 5.3% |
| Dec 2025 | 27 | 5.3% |
| Jan 2026 | 138 | 27.3% |
| Feb 2026 | 81 | 16.0% |
| Mar 2026 | 116 | 22.9% |
| Apr 2026 | 43 | 8.5% (partial) |
| Total | 506 | 100% |
Two spikes, not one. January 2026 (month 6) and March 2026 (month 8). Together they represent 50.2% of all AI config activity. Both were triggered by specific structural decisions, not by gradual accumulation.
Phase 1: Config as Afterthought (Aug-Sep, 29 commits)
The first AI config file. August 22, 2025, commit a48d5017b. CLAUDE.md, 282 lines, shipped in the first release.
The content was minimal. Project identity, the T3 stack (Next.js, tRPC, Prisma), basic conventions. A starting point, not a system.
Aug 22 βββ CLAUDE.md (282 lines) ββββββββ Born: AI config exists
Sep 05 βββ .claude/ directory ββββββββββββ Dedicated structure
Sep 11 βββ .claude/commands/ βββββββββββββ First slash commands
At this stage the mental model was basic: CLAUDE.md as a context file, you write down what the AI needs to know. Useful the way documentation is useful, better than nothing, but not yet a system.
The AI had the obvious stuff: project stack, naming conventions, basic architecture intent. Everything that mattered day-to-day was missing, meaning the business domain, the patterns weβd already established, the reasoning behind specific decisions, and what it should refuse to do.
24 commits in September added the .claude/ directory structure and first slash commands. Basic namespacing: tech:commit, tech:PR, tech:review. Useful shortcuts for repetitive operations.
At this point, one person maintains AI configuration informally, changing it whenever something breaks or feels missing. It is still a file someone cares about, rather than a system.
Phase 2: Config as Documentation (Oct-Dec, 88 commits)
Phase 2 is where the AI starts needing business context, not just technical context.
Oct 15 βββ .claude/agents/ (v0.8.0) ββββββ First custom agents
Oct 23 βββ knowledge-base.md (v0.10.0) βββ Business rules codified
Nov 04 βββ MCP Serena (v0.14.0) βββββββββββ Persistent memory
Nov 21 βββ CLAUDE.md -50% tokens ββββββββββ First optimization pass
October 23: doc/knowledge-base.md created. This is when the configuration started encoding business knowledge rather than just technical setup. Session mechanics (supervised vs autonomous, 15-minute tolerance, doublet/triplet offsets). User lifecycle rules. Tutor compensation logic. The glossary of French terms that appeared in the code.
Without this, the AI was technically capable but business-ignorant. It could write a repository method but didnβt know that a βsessionβ in this codebase meant something specific (SUPERVISED: 1h with a tutor, or AUTONOMOUS: 30min solo), with a lifecycle of SCHEDULED β STARTED β COMPLETED.
November 4 (v0.14.0): MCP Serena integration. Persistent memory across sessions. The AI could now remember architectural decisions made in previous sessions without restating them every time.
November 21 (v0.15.6): CLAUDE.md optimized, 50% token reduction. The file had grown organically and accumulated noise. First deliberate compression pass.
By Phase 2 the mental model had shifted: AI configuration as onboarding documentation, the kind youβd write for a new senior hire. Business rules, conventions, architectural decisions, the βwhyβ behind the patterns.
Phase 3: Config as Infrastructure (Jan, 138 commits, 27.3%)
January 2026 is the first turning point. The configuration stops being a file and becomes a system, faster than any planned migration would have allowed.
January 6, 2026. Commit 1421e863. 86 files created in a single day.
Jan 06 βββ 12 agents + 5 hooks + settings.json βββ Big Bang (86 files, 1 day)
Jan 09 βββ .claude/rules/ ββββββββββββββββββββββββ Guardrails formalized (21 files)
Jan 16 βββ grepai MCP ββββββββββββββββββββββββββββ Semantic code search
Jan 19 βββ Pre-push security hooks βββββββββββββββ Defense at commit level
Jan 26 βββ Tasks API (450 lines doc) ββββββββββββββ Multi-session management
Jan 26 βββ Perplexity MCP, Jam.dev MCP ββββββββββββ Expanded context sources
Jan 29 βββ SonarQube MCP βββββββββββββββββββββββββ Real-time quality analysis
Jan 29 βββ 283 tests added βββββββββββββββββββββββ TDD enforcement in practice
Jan 29 βββ RTK enforcement hook βββββββββββββββββββ Token optimization mandatory
What triggered the explosion was team growth. Augustin was joining, and the configuration that worked for one developer (me, on macOS, with a specific workflow) now had to cover multiple people on different setups, tools, and levels of experience. A single monolithic CLAUDE.md couldnβt absorb that, so a system had to.
Skills: 12 agents and the first skills created on January 6, growing to 36 skills today. Loaded on-demand rather than burning context permanently. TDD methodology, security playbooks, database patterns, accessibility rules, all available on trigger and silent otherwise.
Hooks: 5 hooks created on January 6 in a single commit: dangerous-actions-blocker.sh, security-gate.sh, activity-logger.sh, auto-format.sh, notification.sh. Pre-push security checks, token optimization enforcement (RTK mandatory for all CLI operations). These run automatically without requiring the developer to remember to run them. For a full breakdown of hook events and what each can deterministically block, see Claude Code Under the Hood.
Rules: First 3 rule files on January 9, growing to 34 today. Guardrails that fire during coding sessions. Silent catches, hidden fallbacks, and unvalidated nullable access are out. A failing test before implementation code is mandatory, hence the blunt version of the rule: βWrite code before the test? Delete it and start over.β
6 MCP servers integrated in 3 weeks: Serena (persistent memory), grepai (semantic code search), Perplexity (web search with citations), Jam.dev (bug recording), SonarQube (code quality), Postgres read-only (direct production queries for context).
By Phase 3, AI configuration has its own PRs, review process, and maintenance burden. It is infrastructure in practice. You optimize it, test it, and measure the impact when changes land.
Phase 4: Config as Engineering Practice (Feb, 81 commits, 16.0%)
81 commits in 28 days = 2.9 commits per day on AI configuration alone.
Feb 03 βββ .cursor/ config ββββββββββββββββ Cursor support (Augustin)
Feb 05 βββ profiles/ + modules/ YAML ββββββ Modular system
Feb 09 βββ Zod validation + CI ββββββββββββ Config has tests
Feb 11 βββ Cross-editor sync ββββββββββββββ Claude + Cursor synchronized
Feb 13 βββ Memory compression -6.2K tokens β Ongoing optimization
February 5 (PR #598): The modular system. Instead of one CLAUDE.md that everyone reads, a generation pipeline:
- 5 YAML profiles (one per developer)
- 14 modules (composable content blocks)
- A TypeScript pipeline that assembles them with Zod validation
- Generated outputs: CLAUDE.md (703 lines for Florian, Claude Code, all modules) and .cursorrules (289 lines for Augustin, Cursor, minimal modules)
February 9 (PR #614): The generated outputs have their own tests. The pipeline validates that no placeholder remains unresolved. The CI catches configuration regressions.
The AI configuration now has the properties we expect from production code:
- Version controlled (source files, not generated outputs)
- Validated (Zod schema with 7 fields, 5 valid tone values, 6 valid feature modules)
- Tested (pipeline tests, CI checks)
- Reviewed (PRs for configuration changes, same process as feature PRs)
- Documented (450 lines of documentation for the Tasks API alone)
Phase 5: Config as Compound Engineering (Mar, 116 commits, 22.9%)
March 2026 produced more AI config commits than January, which wasnβt in any plan.
Mar 04 βββ ACE pipeline + 12 ADRs ββββββββ Commit 3fc8c14f (43 files)
Mar 04 βββ Compound engineering patterns ββ Architecture decisions codified
Mar ββββββ multi-agent-coordination.md ββββ Agent orchestration rules
Mar ββββββ research-output.md βββββββββββββ Structured research protocol
Mar ββββββ retex-review.md ββββββββββββββββ Post-task retrospective system
Commit 3fc8c14f contained the ACE pipeline complet, 12 Architecture Decision Records, compound engineering patterns, and 43 files. The configuration had matured enough to start encoding how to evolve itself.
Phase 5 goes past βmore rulesβ. The configuration starts capturing meta-patterns: how to coordinate agents, how to structure research before implementation, how to extract learnings after each task. The system began codifying its own methodology.
April 2026: The Context Diet
The next inflection wasnβt a spike in commits. It was a deliberate reduction.
By April 2026, the configuration had grown to 23 always-on rules loaded into every Claude session, regardless of what you were working on. 2,518 lines of guardrails firing unconditionally, whether you were touching a React component or a Prisma migration. The system worked, but it was eating 14% of a 200K context window before any code was read.
The branch fix-improve-context ran in 5 phases over a single week.
Phase 0, baseline. I built a scoring script (scripts/ai/score-ai-context.ts) before touching anything, because βbetterβ needed to mean something measurable. 85/100, grade A. Thatβs the number you optimize from, not a vague intuition.
Phase 1, triage. Every rule classified against one question: does Claude need this without being asked? Three categories emerged. CONSTRAINT means always-on, non-negotiable. PROCEDURE means step-by-step workflows that load on demand. HYBRID is a short directive plus a long protocol. Of 23 always-on rules, 13 turned out to be procedures or hybrids masquerading as constraints.
Phase 2, extraction. Nine procedural rules converted to skills: code-duplication.md became /tech:dupes, defensive-code-audit.md became /tech:audit, implementation-checklist.md became /tech:checklist. Each always-on version got replaced by a 5-to-15 line stub keeping the directive, while the protocol itself moved on-demand. A smart-suggest.sh pattern was added to every extracted skill so Claude surfaces it when relevant context appears, without loading it permanently.
Phase 3, compression. Rules that belonged in always-on but were too verbose got trimmed. rtk-enforcement.md disappeared entirely since RTK already lives in the global CLAUDE.md, making the per-project copy redundant. debugging-methodology.md dropped from 112L to 43L, with three more rules cut alongside it. Net result, 2,518L down to 646L in always-on context, a 74% reduction.
Phase 3+, Cursor parity. The .cursorrules file had grown into a 703L monolith. Converted to a 133L stub (metadata plus pointers) with 23 .cursor/rules/*.mdc path-scoped rules carrying the real content. Cursor now loads rules only when file paths match, so the same economy applies to Claude.
Phase 4, machine-readable index. Three new generated files landed in machine-readable/:
ai-config.yaml(~270L): structured index of all 27 rules, 36 skills, 59 commands, 16 agents, 15 hooks, module list, profile list. One@reference answers βwhatβs available?β in a new session without grep.llms.txt(~50L): standard llms.txt format for LLM crawlers and context injection.llms-full.txt(~4,500L): full content concat of all rules, modules, and skeletons, for offline/no-tools fallback.
All three generated by pnpm ai:sync. Three new canary checks (C18-C20) were added, worth +10pts to the quality scorer.
The final numbers:
Always-on context: 2,518L β 646L (-74%)
.cursorrules: 703L β 133L (-81%)
ai:score: 85/100 β 125/145 (+B grade, +10pts machine-readable)
Canary checks: 17/17 β 20/20
The January and March spikes followed the same pattern. Friction made the cost visible, measurement made the improvement verifiable, and the tooling (scoring script, canary checks, generated index) catches the next drift before it compounds. The grade records one checkpoint; the scoring script, canary checks, and generated index catch the next accumulation before it becomes a cleanup sprint.
Why two spikes appeared
Thereβs no planning failure here. You canβt write the rules for problems you havenβt hit yet.
Day one, you donβt know what your AI configuration needs to be. You find out by running into the friction.
The January spike was team-driven. Rules that prevent silent catches showed up after we caught AI-generated code doing exactly that. The TDD enforcement rule landed after a stretch of shipping code without tests. The profile system appeared once a second developer with a different setup needed the configuration that had been tuned for one person. Guardrails encode lessons, and you canβt write those down until youβve hit the problem theyβre solving.
The March spike was scale-driven. The system had become complex enough to require architectural governance. The 12 ADRs codified decisions that had been made implicitly over months. Compound engineering patterns emerged from observing what worked across 1,100 commits. The configuration caught up with the maturity of the codebase.
Team size shapes the investment curve too. Phase 1-2 configuration works fine for a solo developer. Phase 3-4 becomes necessary once someone else joins and the monolithic setup stops fitting their machine or context. Collaboration is what eventually forces the systematization, while solo use rarely asks for it.
Lessons from the commit history
If I were starting from scratch today, I wouldnβt try to skip to Phase 3. Those abstractions encode lessons I didnβt have yet. The rules describe problems that hadnβt happened. Start with a CLAUDE.md that honestly reflects what you know: stack, conventions, the business domain youβve figured out so far. The rest shows up when it needs to. That climb from a plain file to versioned, tested infrastructure is the ladder the six-level context engineering guide lays out one level at a time. This article is that ladder playing out in one repo over five months; the guide is the version without the commit archaeology.
The things I would track earlier are hook execution rates and token counts. A score turns βbetterβ into something more than a feeling. 713 lines versus 289 lines is a real cost difference. Once I had the scoring script, optimization became verifiable instead of intuitive. I later built ccboard to watch exactly that: hook activity, per-session cost, and MCP health in one view. That is the instrumentation I wish Iβd had in this phase.
The 77% back-loaded distribution shows how an investment curve behaves when you build a system while using it at the same time. In this repository, the systemβs needs became visible when friction appeared.
The real number is this: 8.6% of all commits in this repository touch AI configuration. On a 5,820-commit project, thatβs 506 commits dedicated to improving how the AI works alongside the humans. More than most business logic files received. If that feels like a lot, consider that the alternative is a stale CLAUDE.md and an AI that drifts from the codebase itβs supposed to understand. The factual half of that drift, the paths and scripts and version numbers that quietly stop matching the code, is what ctxharness checks automatically, so the stale-CLAUDE.md case gets caught instead of noticed months later.
This dataset gives a concrete answer on timing: later than any upfront plan would suggest, and then much faster than expected once the teamβs complexity makes it unavoidable.
Beyond the two-person team
This dataset is one project, two developers, one stack. The friction that shaped the 506 commits was scoped to that size: a second dev joining, one monorepo to cover, one set of conventions to encode.
At organizational scale, the friction shifts shape. Across multiple repos, the same rule ends up duplicated in N CLAUDE.md files and drifts the moment someone updates one without the others. Across stacks, a rule about TypeScript Result types does not translate to a Rust repo using anyhow::Result. Once multiple teams are in the mix, profiles proliferate from 5 YAML profiles to 50, most of that variance with legitimate reasons behind it.
A likely pattern is a dedicated AI config repository as the source of truth, consumed by downstream projects. A few shapes this can take:
- Git submodule: the config repo is pinned at a commit, reproducible across machines, stack-agnostic. The cost is submodule UX, which is real but manageable with a wrapper script.
- Published package (npm, cargo, pip): versioned with semver, distributed through existing release workflows. Works well when your org is stack-homogeneous, less well when a TypeScript team and a Rust team both need the same base rules. Itβs the shape I used for a narrower slice of the same problem, reusable hooks and templates rather than full org config: claude-code-plugins ships 181 of them as installable plugins, versioned and pulled in per project.
- Shared config CLI that fetches + assembles (think Terraform modules or a dotfiles manager): purpose-built, cross-stack, but itβs another tool to maintain.
Whichever shape, the mental model is the same: org modules + team modules + project modules, composed by a pipeline. The modular system that emerged at Phase 4 for one project is the same shape, scaled up one level.
I havenβt run this setup myself. The projection rests on the principle that made Phases 3-4 work: systematize when collaboration demands it, not before. At org scale, that demand jumps from repo-internal to cross-repo. The investment curve likely mirrors what happened here, a long slow accumulation followed by a spike once a second repo needs the same rules that had been tuned for one.
If youβre in that situation, the prediction is concrete: youβll resist the central repo for months because your team-level configs feel fine, and then youβll build it in two weeks because version drift across four repos became impossible to manage.
If youβve already hit that inflection point at org scale, Iβd be curious to hear what shape it took.
Single project (this article) β CLAUDE.md + .claude/ scoped to one repo
Multi-repo org (logical next step) β Shared AI config repo + per-project override
506 commits, no upfront blueprint
AI configuration grew from one informally maintained file into a system with tests, a generation pipeline, and its own PR review process. The 506 commits on this project came from measuring the tooling and responding to friction as it appeared. Each phase encoded a problem we had already hit. Start with a CLAUDE.md that reflects what you know, then instrument hook execution rates, token counts, and a scoring script early enough to see the next source of friction. In this repository, the investment curve back-loaded itself.
The modular AI instruction system described here (YAML profiles, modules, generation pipeline with Zod validation) is documented in the Claude Code Ultimate Guide. Source data from the MΓ©thode Aristote repository git history (5,820 commits, v0.1.0 β current). The archaeology command: git log --all --format="%ad" --date=format:"%Y-%m" -- CLAUDE.md .claude/ | sort | uniq -c.
YSNK
(You should now know)
- The two spikes (January and March) together account for 50.2% of all AI config activity, and neither was gradual: one was team-driven, the other was scale-driven
- Classifying every always-on rule against one question, does Claude need this without being asked, found that 13 of 23 rules were actually procedures or hybrids masquerading as constraints
rtk-enforcement.mddisappeared entirely during the cleanup because it duplicated a rule that already lived in the global CLAUDE.md, redundant the moment someone checkedpnpm ai:syncnow also generates a machine-readable index (ai-config.yaml,llms.txt,llms-full.txt), so a new session can answer βwhatβs available?β with one reference instead of grepping the repo- At org scale, the same friction repeats one level up: a rule duplicated across N CLAUDE.md files drifts the moment one gets updated without the others, which is why a dedicated shared config repo becomes the next inflection point
Go further
If this topic interests you and you want to move from understanding to practice, I created two free guides for different profiles.
Related appearances
Live appearances and podcast episodes about this article.
Related articles
Claude is my second contributor: what real Git stats show
6 contributors in our git history. One is an AI. What the commit patterns actually look like after months of Claude Code, beyond the marketing claims.
UVAL: the protocol I built to stop accepting code I don't understand
Jeremy Twei coined it. Addy Osmani popularized it. Margaret-Anne Storey extended it to teams. Here's what I built to fight all three.
AI velocity is bidirectional
Everyone talks about shipping 10x faster with AI. Nobody talks about accumulating debt 10x faster. 7 months of production data from a real EdTech platform.
Go deeper
Step-by-step guides that put this into practice.
Claude Code security: the attack surface nobody audits
Hooks are shell scripts with your user permissions. MCP servers are third-party code with access to your credentials. Both run before the model reasons.
Claude Code setup, level by level
Three levels of configuration, each with a concrete result. From a 10-line CLAUDE.md to an agent that remembers your project across sessions.
Context engineering: the L0-to-L5 playbook
A step-by-step playbook to move from a 50-line CLAUDE.md (L0) to versioned, CI-enforced context (L5), with the concrete failure mode each level fixes.