DobermanDocs
Menu

Architecture Coupling evidence

Coupling evidence

Doberman's architecture claims (a decoupled core, one decision path, no proxy reaching into policy) are measurable in a knowledge graph built over the repository. This page shows what that graph says.

View as Markdown

On this page

What the graph is#

The graph is built by running a code-graphing tool (graphify) over the Doberman codebase: every file, class, function, and symbol becomes a node, and every reference between them (a call, an import, a type use) becomes an edge. Each edge carries a provenance tag: EXTRACTED means it was parsed directly out of the code (an import statement, a function call); INFERRED means a model estimated the relationship and attached a confidence score. Treat a surprising INFERRED edge as a hypothesis to check, not a fact.

The current build measures 13,873 nodes and 33,207 edges, about two-thirds EXTRACTED and one-third INFERRED. The numbers on this page come from the 2026-08-25 build; the graph is regenerated from the repository, so rebuilding it is the way to check them against the current code.

Subsystem coupling#

The table below aggregates cross-subsystem edges: how many references point from one subsystem's code into another's, and what kind of reference dominates.

Subsystem pair Edges Dominant relation Reading
models ↔ turngate 206 uses the turn gate speaks the shared vocabulary
engine.rules ↔ models 202 uses rules consume, never redefine, the shared types
auth ↔ tests 146 uses, calls the challenge chain is directly exercised
storage ↔ tests 110 calls (80) the heaviest call-level test coverage in the repo
models ↔ proxy 96 uses the proxy depends on models, one-way
auth ↔ turngate 63 uses step-ups from the turn gate reuse the auth tier
models ↔ subjective 51 uses the subjective layer consumes the action vocabulary
cli ↔ policy 48 calls (47) the CLI is the drift gate's biggest caller
auth ↔ hosthooks 44 uses the host-hook deny path resolves AUTH through the shared chain
auth ↔ proxy 29 uses the proxy's _handle_auth uses the same chain
proxy ↔ policy core 0 imports none the boundary the import-linter contract enforces

Two facts a reader can check#

models is the hub. The shared vocabulary module (SecurityObject, Verdict, ReasonCode, Risk, ActionType, GuardrailResult, EvalContext, Decision) is the most-connected code in the graph. Every subsystem above imports and reads these types; almost none of them get redefined downstream. If you're reading the codebase for the first time, this is the file to start with: understanding these types tells you what every other module is passing around.

There is no proxy ↔ policy-core edge. The table's last row is zero because of the boundary described in the system atlas: the decision engine, roles, policy, storage, auth, the subjective layer, and the egress broker never import the proxy, the host hooks, or the dashboard. An import-linter contract enforces it and fails CI if anyone adds that edge.

Both facts can be re-checked by rebuilding the graph against the current commit and reading the same two rows.

Doberman v0.18.3 · Apache-2.0 · Defense-in-depth, not airtight.

navigate open esc close