Auditors don't want a picture; they want a control. "We say the domain layer must never call the API layer" is a policy. "Our build fails if it ever does, and here is the exact line it caught last time" is a control. py-code-visualizer enforces the rule at the call-graph level — stricter than an import linter, because an import can sit unused while a call edge is a real runtime dependency.
The fixture below (examples/scenarios/soc2_audit) is a billing service split
into three layers — api → domain → infra — with one deliberate boundary
violation, so the output here is exactly what you'll see on your own code.
Turn a policy into a failing build
Declare the layers and the forbidden dependency. The gate walks every resolved call edge and fails the moment one crosses the line — pointing at the precise call site.
No ambiguity, no "somewhere in the domain package." The offending method, the function it illegally reached, and the line number. Fix it or justify it — either way it's on the record.
Prove the clean state passes
A control that never passes is noise. Once the boundary is respected (or for a rule the code already honors), the same command exits clean.
In production you'd put the rules in [tool.pyvisualizer.rules] in
pyproject.toml so CI runs a single flag-less
py-code-visualizer check.
Commit the diagram as dated evidence
The output is deterministic — byte-identical across runs on unchanged code. That's the property that turns a diagram into an audit trail: a CI job regenerates and commits it, so git history becomes a dated, attributable architecture change-log. And because the HTML is a single self-contained file with zero network requests, it's safe to hand to an auditor or run in an air-gapped review environment — the code never leaves the machine.
The committed architecture.html at any past commit shows exactly what the
architecture was on that date — no reconstruction, no "we think it looked like this."
What you got. A layering policy converted into an
enforced, call-graph-level control that fails CI with an exact file:line;
a clean-state pass to prove the control works; and deterministic, air-gap-safe diagrams
that make git history your dated architecture evidence. That's a SOC 2 control narrative
you can actually stand behind.
Output shown verbatim from running the commands against
examples/scenarios/soc2_audit; the absolute path in the violation is
abbreviated here as …/ for width. Determinism and the zero-network-request
property are verified in the benchmarks and reproducible
with python benchmarks/bench.py.