{"slug": "5-months-100-claude-code-zero-architectural-drift", "title": "5 months. 100% Claude Code. Zero architectural drift.", "summary": "A developer reports that after five months of using Claude Code to write 100% of the code for two projects, the architecture has not drifted. The key to preventing architectural drift is a system of locked files that agents cannot modify without human approval, enforced via GitHub push rulesets. The developer found that while AI agents propose changes to locked files frequently, only about two-thirds of those proposals are accepted, and the human gate prevents self-reinforcing drift.", "body_md": "In one web service project I have been building and maintaining for 5 months, every line of code has been written by Claude Code. In a second project, a macOS app in Swift built over 3 months, the same is true with Claude Code.\n\nThe architecture has not drifted.\n\nAI failures usually get described as catastrophic. The agent broke the build. Shipped a bug. Those happen, but they are not what wears down a long project.\n\nThe failure that does is much smaller:\n\nEach change is locally justified. None of them are globally correct. After five months, the codebase looks \"almost right everywhere\", and the architecture I started with is no longer what I have.\n\nBetter CLAUDE.md does not fix this. It works for one session, not five months.\n\nThe system has three parts working together:\n\nThe first two share the same enforcement mechanism: a file lock at the server. The third is a different kind of layer that runs after every implementation. The rest of this article covers each.\n\nThe model that has worked, on both projects, is to separate every piece of agent instruction into two categories based on who is allowed to change them. Everything outside these two categories is left to the agents.\n\nThe files that define how the agents themselves operate:\n\n```\nCLAUDE.md            # project-level Claude Code config\n.claude/agents/      # subagent definitions (architect, developer, validator)\n```\n\nAgents can read these and propose changes. They cannot push changes. Every modification goes through me.\n\nThe reason this category is locked is recursive. If AI can change the rules that constrain it, drift becomes self-reinforcing. The agent that is drifting becomes the agent that rewrites the rules to permit the drift. The human gate breaks the loop.\n\nThe system still has to improve. Agents propose changes to their own rules when they notice friction or a repeated mistake. The improvements that survive my review become permanent.\n\nThe files that define what the agents produce:\n\n```\ndocs/code-documentation/\n  architecture-overview.md      # system map, tech stack, data flow\n  architecture-backend.md       # service patterns, REST boundaries\n  architecture-frontend.md      # React structure, state boundaries\n  architecture-shared-types.md  # cross-package contracts\n  testing-guidelines.md         # test patterns, anti-patterns\n  git-workflow.md               # branch rules, commit conventions\n```\n\nSame mechanism. Agents read and propose. They cannot push.\n\nI enforce both categories with a single GitHub push ruleset. It restricts pushes to these paths:\n\n```\nCLAUDE.md\n.claude/agents/**\ndocs/code-documentation/architecture-*.md\ndocs/code-documentation/testing-guidelines.md\ndocs/code-documentation/git-workflow.md\n```\n\nOnly the repository admin role is on the bypass list. The AI agent pushes with its own token, tied to a non-admin identity, so it is not a bypass actor. Any push it attempts to a locked file is rejected at the server.\n\nWhen the agent wants to change a locked file, it surfaces the proposal as a Product Decision: situation, options, trade-offs, recommendation. I decide. If I approve, I make the file change myself.\n\nThe naming prefix matters. `architecture-*`\n\nis not only an organizational hint. It is also part of the access rule. A new architecture document added later inherits the lock by name.\n\nAcross both projects, the agents have proposed changes to locked files dozens of times. Reasonable proposals. About one in three I decline. Those implementations get rewritten within the existing rules, and the codebase does not gain the new pattern. The rest are genuine improvements, and I make those file changes myself.\n\nThe reason the architecture has not drifted is not that the agents stopped trying. It is that they cannot apply their proposals without going through me first.\n\nMy memory file currently has 50+ pitfall entries in each project. Many of them come from a drift attempt that was caught in review, recorded so the agent does not repeat it.\n\nThe whole setup works because of a final layer: independent validator agents that check every implementation against the locked architecture and code style documents. The validator sub-agents do not see the implementation reasoning. They get a fresh context, the code and the locked docs, and they verify the code conforms. Nothing else. If the validator reads the implementation's reasoning, it starts agreeing with it. That is rubber-stamping, not validation.\n\nBut not all of that validation is a judgment call, and that is on purpose. Before an implementation is even eligible for review, the compiler has to pass in strict mode, the test suite has to be green, and coverage has to clear an 80% threshold. A deterministic check cannot be talked into agreeing with the code the way an LLM can. The agent validators sit on top of that floor. They catch what the machine cannot: whether the code conforms to the locked architecture, not just whether it runs.\n\nI have written about the validator setup in more detail in an earlier article: [How I validate quality when AI agents write my code](https://dev.to/teppana88/how-i-validate-quality-when-ai-agents-write-my-code-481c). The two-category model in this article and the validation pipeline in that one are halves of the same system.\n\nAI will not destroy your architecture in one mistake. It will replace it with a better one, one reasonable change at a time. Preventing that is the developer's job. Our skill matters most when we know how to set up the system that does it. This is one model that worked.", "url": "https://wpnews.pro/news/5-months-100-claude-code-zero-architectural-drift", "canonical_source": "https://dev.to/teppana88/5-months-100-claude-code-zero-architectural-drift-i6e", "published_at": "2026-06-30 07:00:55+00:00", "updated_at": "2026-06-30 07:19:02.609501+00:00", "lang": "en", "topics": ["large-language-models", "ai-agents", "developer-tools", "ai-safety", "mlops"], "entities": ["Claude Code", "GitHub", "CLAUDE.md"], "alternates": {"html": "https://wpnews.pro/news/5-months-100-claude-code-zero-architectural-drift", "markdown": "https://wpnews.pro/news/5-months-100-claude-code-zero-architectural-drift.md", "text": "https://wpnews.pro/news/5-months-100-claude-code-zero-architectural-drift.txt", "jsonld": "https://wpnews.pro/news/5-months-100-claude-code-zero-architectural-drift.jsonld"}}