← all projects
[system] May 2026 Open Source

Archlint

Claude Code hook that catches architectural drift while the agent is writing code. Reads layer rules from CLAUDE.md, blocks or warns on import violations.

Archlint

Static analyzers run after the fact. Linters run at commit time. Archlint runs *inside the agent loop*. When Claude edits a file, archlint parses its imports against the layer rules you wrote in CLAUDE.md and surfaces drift before it compounds. A single Python file, no dependencies, language-agnostic for the four mainstream stacks. The blueprint is prose plus a fenced code block — the same document the agent already reads.

Features

terminal
Single-file Python
Around 630 lines, stdlib only. No virtualenv, no framework, no dependency to install. Drop into `.claude/hooks/` and it works.
rule
Architecture-as-prose
Layer rules live inside the project's CLAUDE.md, in a fenced `archlint` code block. The same document the agent already reads also constrains the agent. No second config file to forget.
speed
Hook-native, not CI-only
Runs on PostToolUse + Stop. Surfaces drift while the agent is still in the loop, before the architecture compounds out of shape across forty tool calls.
code
Multi-language
Python (AST), TypeScript, JavaScript, Go, Rust. Adding a language is a regex and two suffixes. External imports — npm, pip, stdlib — are ignored, so no false positives.
tune
Lenient by default, strict when it matters
Default mode surfaces drift to the model as context. Strict mode (`ARCHLINT_MODE=strict`) blocks the turn until the violation is gone. Same code, same rules in CI via `archlint check`.

Philosophy

Agentic code generation has a recovery loop human-only coding doesn't: the agent is still there mid-turn, and you can hand it a constraint cheaply. The right time to catch architectural drift is not after twenty edits have compounded — it's between edits. The agent makes one move; a hook reads it; the agent gets a short note about the violation and tends to self-correct on the next move. The loop is fast and the cost is paid early.

Archlint is the smallest version of that idea. One Python file, stdlib only, four languages supported out of the box. The blueprint is not yet another config file — it's a fenced code block inside the same CLAUDE.md the agent already loads on every session. Same source of truth for prose, agent context, and machine-enforced rules.

How it works

Architecture lives in CLAUDE.md (or ARCHITECTURE.md / SPEC.md — first one found wins). Inside an ## Architecture section, a fenced archlint block declares layers as globs, allowed dependencies as arrows, and forbidden dependencies as explicit prohibitions. The grammar is a dozen lines and reads close to English.

After every Write, Edit, or MultiEdit, archlint parses the touched file, extracts its imports, resolves them against the layer rules, and reports violations. External imports — npm packages, pip packages, the standard library — are ignored, so adding a new dependency never produces a false positive. At end of turn, archlint emits a checkpoint summary of any unresolved drift, giving the agent one last chance to fix it before declaring done.

Lenient mode (default) reports drift as additionalContext and trusts the model to self-correct. Strict mode raises drift to decision: block, which keeps the agent working until the violation is gone. The same engine runs as a CLI for CI and pre-commit hooks — archlint check — so the rules you write once protect both the live coding loop and the merge gate.

What's next

Archlint is MIT-licensed and lives at github.com/MKanhan/archlint. The single-file design is the point — features arrive only if they keep the script readable end-to-end in fifteen minutes. The likely additions, if usage proves them: an archlint init that asks Claude to draft an initial blueprint from the existing tree, support for Java/Kotlin/Swift/C#, and severity tiers (forbid! versus forbid) for projects that want graduated enforcement. Anything else is community-driven.

Tech Stack

Python Claude Code AST stdlib
GitHub