Appendix B - 10. Executable source-of-truth models
The Structure of Executable source-of-truth models — its shape at a glance:
The typed model sits at the center. Agents read it to reason; the build generates artifacts from it; a drift gate holds it equal to reality. Because it is read and checked on every run, it cannot go stale.
flowchart LR
M[(Typed model<br/>imports nothing)] --> Agent[Agent reads]
M --> Gen[Generate artifacts]
M --> Gate{{Drift gate}}
Gate -->|diverges| Fail([build blocked])
Accessible description: one typed model that imports nothing feeds three consumers — an agent that reads it, generators that emit real artifacts from it, and a drift gate that blocks the build when the model diverges from reality. Continuous reads and checks keep it from staling.
Projected from the catalogue entry system-models / Executable source-of-truth models.
On this page: Intent · Motivation · Applicability · Structure · Sample Code · Consequences · Example use within DocAble · Related Patterns
Intent
Intent — Model the system as typed data that tools read on every run and generate real artifacts from. The model becomes executable documentation that cannot drift, and the codebase becomes operable by a context-bounded agent.
Motivation
A large codebase exceeds any agent's context window; no agent can hold 280 KLOC. Left to read the raw code, an agent gets lost, re-derives the architecture (badly), and drifts. Meanwhile the architecture itself lives only implicitly, scattered across the code, so humans re-derive it too. The failure is no shared, authoritative, compact representation of the system, which caps how large a codebase agents can operate on at all.
Applicability
- Typed models that import nothing. Data, not code, so anything can read them cheaply.
- Continuous consumption. The model must be read on real runs, or it is just another doc.
- A drift gate per model (drift-parity-gates). Without enforcement the "cannot drift" claim is a hope.
Structure
The Structure diagram appears at the top of this page.
Sample Code
The model is data, not code — a record set anything can load cheaply. One consumer reads it at run time and a drift gate checks it against reality, so the model is exercised on every run and cannot quietly fall behind the code it describes.
from dataclasses import dataclass
import sys
@dataclass(frozen=True)
class Node:
name: str
kind: str
# The model: typed data that imports nothing, so any tool loads it for free.
MODEL = [Node("web", "service"), Node("worker", "service")]
def consume() -> set[str]:
return {n.name for n in MODEL} # a real run reads the model, not a hardcoded copy
def drift_gate(reality: set[str]) -> list[str]:
model = consume()
findings = [f"model row '{n}' not in reality" for n in sorted(model - reality)]
findings += [f"'{n}' in reality, unmodeled" for n in sorted(reality - model)]
return findings
if __name__ == "__main__":
# `scan_reality` enumerates the real things the model claims to describe.
findings = drift_gate(scan_reality())
for f in findings:
print(f"DRIFT: {f}")
sys.exit(1 if findings else 0) # the model is checked every run, so drift can't hide
Consequences
- Upkeep is real. The models must be maintained and the drift gates satisfied on every change; this is exactly the tedium that stops humans, and the reason it needs agents.
- A wrong model is worse than none. An authoritative-looking model that has drifted misleads everything downstream; hence the drift gates are not optional.
- Modelling discipline up front. Deciding what to model, and in what dialect, is design work.
Example use within DocAble
- The model catalog (typed YAML/JSON + loaders; imports nothing).
- The preference order: a stable lint that reads the meta-file, over codegen, over a hand-rolled copy.
- Each model's doc-derived characterization pin.
Related Patterns
- Bridge — every model here couples an agent-side use (query/inject) to a product-side use (govern/generate); see the individual models below.
- Counterpart — drift-parity-gates: the hard mechanism that makes "cannot drift" true.
- See also — the six models: component-zone · synchronization · concurrency-contracts · service-flow · deployment-topology · domain-registries; and the mechanisms codegen · query-surface · consumption.