agentleFS
ianshankianshank/Agents/skills/architecture-drift-guard/SKILL.md

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

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
  1. Very specific:

    Keep a codebase's real structure honest against its documented architecture and fail CI when they diverge.

    line 11
  2. Distinctive:

    If any precondition fails the runner stops and reports it (exit 2) — it does not improvise around a broken manifest.

    line 31
  3. Very specific:

    1 when an undocumented edge exists (drift), 2 on a manifest/extraction error.

    line 58

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.yaml manifest exists with schema_version, root_packages, and components; dependencies may be empty when bootstrapping.
  • The root_packages are importable — installed, or reachable via the manifest's sys_path entries (which the runner prepends to sys.path).
  • grimp and pyyaml are 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.

  1. Bootstrap the declared edges from reality, then review them WITH the user (undocumented edges are exactly the drift to surface — don't launder them):
    python scripts/drift_check.py --manifest architecture.yaml --emit-actual
    Paste the reviewed dependencies: block into the manifest.
  2. Generate the diagram and commit both files:
    python scripts/mermaid_gen.py --manifest architecture.yaml -o architecture.mmd
  3. 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.py exits 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 --check it exits 1 iff the committed diagram differs from a freshly rendered one (after whitespace/newline normalisation).
  • --emit-actual prints a deterministic, round-trippable dependencies: 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, regenerate architecture.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 commit architecture.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,behavioral

The 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=90

6. 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-actual for bootstrap).
  • scripts/mermaid_gen.py — manifest → Mermaid C4, with --check freshness mode.
  • scripts/adguard/ — reusable library; extractor.py is the only grimp-bound module, so a future non-Python extractor is an additive change.
  • references/manifest-schema.md — full manifest field reference.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.