Why CLAUDE.md Is Not Enough to Protect Your Architecture A developer built ArchLint, an open-source CLI that enforces architecture rules by checking Git diffs, aiming to prevent architectural drift in AI-assisted coding. The tool supports deterministic rules like forbidden dependencies and import boundaries, integrates with GitHub Actions, and does not require an LLM or API key. Files such as CLAUDE.md and AGENTS.md are useful for explaining a project to coding agents. They can describe decisions like: The problem is that these are still instructions, not enforcement. An agent can understand a rule and still violate it during a large change. The generated code may compile and pass its tests while quietly introducing an architectural dependency that the project was supposed to avoid. Humans do this too. The problem is not specifically AI-generated code. AI agents simply make it easier to produce larger changes faster, which makes architectural drift easier to miss. I wanted the most important architecture decisions to behave more like lint rules. That led me to build ArchLint https://github.com/errrt/archlint , a small open-source CLI that checks Git changes against architecture rules stored in the repository. The basic flow is: AI agent or developer changes code ↓ Git diff ↓ ArchLint ↓ PASS or BLOCKED ArchLint does not need to know whether the change came from Claude Code, Codex, Cursor, or a human contributor. It evaluates the resulting Git diff. A project can define its rules in .archlint.yml : version: 1 rules: - id: no-firebase type: forbidden dependency packages: - firebase message: "Use Supabase Auth only." - id: db-boundary type: import boundary from: - "src/components/ " deny: - "src/db/ " message: "UI components must not access the database directly." - id: protect-auth type: protected path paths: - "src/auth/ " severity: warning These rules express three different decisions: The configuration lives beside the code, so it can be reviewed and versioned like any other architectural decision. From the root of a Git repository: npx archlint-ai init npx archlint-ai check The first command creates a starter configuration. The second checks staged, unstaged, and untracked changes. No account, API key, dashboard, or global installation is required. A successful check looks like this: ✓ 3 rules passed NO ARCHITECTURE DRIFT DETECTED When a rule is broken, ArchLint reports the rule, file, evidence, and message: no-firebase src/auth/firebase.ts:1 Use Supabase Auth only. Evidence: firebase Severity: ERROR The same check can run in GitHub Actions: name: ArchLint on: pull request: jobs: archlint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - run: npx archlint-ai check --base origin/${{ github.event.repository.default branch }} If a pull request introduces an error-level violation, the command exits with a non-zero status and the check fails. At that point, the team has two choices: .archlint.yml because the architecture decision itself has intentionally changed.The second option is important. Architecture rules should not be permanent by accident. They should be explicit and reviewable. ArchLint primarily checks additions in the current diff rather than scanning the entire repository. This has two practical benefits: It also keeps the tool focused on one question: Did this change make the architecture worse? An LLM could review a diff and decide whether it violates an architectural principle. That may become useful for rules that cannot be expressed structurally. However, many important constraints do not require an LLM: For these rules, deterministic checks are faster, cheaper, easier to understand, and produce repeatable results. ArchLint v0.1 therefore focuses on deterministic rules. It defines an experimental provider-neutral interface for future semantic checks, but the current package does not send repository code to an LLM. ArchLint is still an early release. The current dependency and import checks focus on JavaScript and TypeScript syntax. Import-boundary rules are path-based, and the project does not yet attempt to understand every framework or programming language. That is intentional. I wanted to start with a small tool that solves a clear problem before expanding the rule system. The next rules should be driven by real projects rather than guesses. ArchLint is not intended to replace CLAUDE.md , AGENTS.md , architecture decision records, or code review. Those documents explain the reasoning and help agents make better choices. ArchLint handles the smaller set of decisions that are important enough to enforce automatically. A useful separation is: Documentation explains the architecture. ArchLint protects its critical boundaries. Code review handles context and judgment. The project is available on GitHub: https://github.com/errrt/archlint https://github.com/errrt/archlint It can be tried with: npx archlint-ai init npx archlint-ai check I would especially like feedback from developers using coding agents on real repositories: Which architecture rule would you want to enforce first?