architecture-drift-guard
Skill1 starsChanged 59 days agoApache-2.0View on GitHub
Detect and block architecture drift in CI by comparing a codebase's actual Python import graph against a declared C4 component model. Use this whenever the user wants to enforce architecture in CI/CD, fail builds on undocumented dependencies, keep C4/Mermaid diagrams in sync with code, set up architecture tests or fitness functions, prevent layering violations, or guard/lint/gate their architecture — even if they don't name C4 or Mermaid explicitly. Also use it to bootstrap an architecture manifest from an existing repo or to remediate a failing drift check.
- Installs packages
In this repository39 other files it gives its agents.
- agent-core/AGENTS.mdAGENTS.md
- .agents/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- behavioral-regression/AGENTS.mdAGENTS.md
- claude-foundation/AGENTS.mdAGENTS.md
- config/AGENTS.mdAGENTS.md
- corpora/AGENTS.mdAGENTS.md
- demo/AGENTS.mdAGENTS.md
- docs/AGENTS.mdAGENTS.md
- examples/AGENTS.mdAGENTS.md
- experiments/AGENTS.mdAGENTS.md
- flow-corpus/AGENTS.mdAGENTS.md
- flow-protocol/AGENTS.mdAGENTS.md
- openspec/AGENTS.mdAGENTS.md
- scripts/AGENTS.mdAGENTS.md
- skills/AGENTS.mdAGENTS.md
- tests/AGENTS.mdAGENTS.md
- claude-foundation/CLAUDE.mdCLAUDE.md
- merge-gate-auditorSkill
- update-executive-reportSkill
- update-executive-reportSkill
- commonSkill
- corpus-guardianSkill
- dataset-lintSkill
- deploySkill
- e2e-matrix-sentinelSkill
- eval-corpus-forgeSkill
- hierarchical-recursive-brainstormSkill
- model-benchSkill
- openai-judgeSkill
- openspec-implementation-reviewSkill
- openspec-peer-reviewSkill
- openspec-quality-planSkill
- pre-pr-gateSkill
- project-setupSkill
- quality-gateSkill
- refactoring-decomposerSkill
- repo-invariant-reviewSkill
- test-completeness-guardSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 11
Keep a codebase's real structure honest against its documented architecture and fail CI when they diverge.
- Distinctive: line 31
If any precondition fails the runner stops and reports it (exit 2) — it does not improvise around a broken manifest.
- Very specific: line 58
1 when an undocumented edge exists (drift), 2 on a manifest/extraction error.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Architecture Drift Guard — E2E Action Skill
Keep a codebase's real structure honest against its documented architecture and
fail CI when they diverge. The architecture is declared once in a manifest
(architecture.yaml); the Mermaid C4 diagram and the CI gate are both derived
from it. The blocking gate is deterministic code — a model is never in its
decision path. Same inputs always yield the same exit code; that
reproducibility is the entire value.
Scope: this enforces the C4 Component level (packages/modules and their edges) for Python (grimp parses Python imports). Edges are direct, not transitive. Context (L1) and Container (L2) are human-defined and not derivable from code — do not promise drift detection there.
1. Preconditions (input contract)
- An
architecture.yamlmanifest exists withschema_version,root_packages, andcomponents;dependenciesmay be empty when bootstrapping. - The
root_packagesare importable — installed, or reachable via the manifest'ssys_pathentries (which the runner prepends tosys.path). grimpandpyyamlare installed (pip install grimp pyyaml).
If any precondition fails the runner stops and reports it (exit 2) — it does not improvise around a broken manifest.
2. Procedure (the E2E steps)
Deterministic work lives in scripts/; the library is scripts/adguard/ and the
two thin entrypoints call it.
- Bootstrap the declared edges from reality, then review them WITH the user
(undocumented edges are exactly the drift to surface — don't launder them):
Paste the reviewedpython scripts/drift_check.py --manifest architecture.yaml --emit-actualdependencies:block into the manifest. - Generate the diagram and commit both files:
python scripts/mermaid_gen.py --manifest architecture.yaml -o architecture.mmd - Gate in CI — run both checks on every PR:
python scripts/drift_check.py --manifest architecture.yaml # drift gate python scripts/mermaid_gen.py --manifest architecture.yaml --check -o architecture.mmd # freshness gate
3. Output contract (postconditions — what "done" means)
drift_check.pyexits 0 when every actual component edge is declared, 1 when an undocumented edge exists (drift), 2 on a manifest/extraction error. Undocumented edges are printed by name; declared-but-unused edges are a[warn]only and never fail.mermaid_gen.py(no--check) writes a deterministic C4 Component diagram. With--checkit exits 1 iff the committed diagram differs from a freshly rendered one (after whitespace/newline normalisation).--emit-actualprints a deterministic, round-trippabledependencies:block to stdout and exits 0.
4. Failure handling
- Drift (exit 1): classify the new edge WITH the user. If the dependency is
intended, add it to
dependencies, regeneratearchitecture.mmd, commit both. If it is a mistake, the code changes, not the manifest — the gate did its job. Never silence the gate by editing the manifest reflexively. - Stale diagram (exit 1 on
--check): regenerate and commitarchitecture.mmd. - Error (exit 2): the manifest is missing/malformed or a root is not importable; fix the precondition. The runner leaves no partial artifacts.
5. Validation gate (before declaring success)
You are not done until this exits 0:
python scripts/validate_skill.py --skill . --tier structural,behavioralThe bundled library also has a full unit suite (run from the skill dir):
python -m pytest tests --cov=adguard --cov-report=term-missing --cov-fail-under=906. Examples
Example 1 (clean): a manifest whose declared edges match the code →
drift_check.py exits 0 with "matches the manifest".
Example 2 (drift, edge case): code has a core -> api back-edge the manifest
omits → drift_check.py prints core -> api and exits 1, naming the
undocumented dependency rather than silently passing.
Optional: directional rules via import-linter
Graph-equality catches "an edge appeared that isn't declared." It does not express
"this layering must never invert." If the user wants named directional rules, add
import-linter as a second, separate gate alongside this one — it complements,
not replaces, the drift check.
Files
scripts/drift_check.py— the drift gate (also--emit-actualfor bootstrap).scripts/mermaid_gen.py— manifest → Mermaid C4, with--checkfreshness mode.scripts/adguard/— reusable library;extractor.pyis the only grimp-bound module, so a future non-Python extractor is an additive change.references/manifest-schema.md— full manifest field reference.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

