Appendix B - 15. Model-driven codegen

The Structure of Model-driven codegen — its shape at a glance:

A generator reads the model and emits the artifact, stamping a provenance header. A freshness lint re-runs generation and fails when the committed artifact differs, and the provenance lint fails on a hand-edit that dropped the marker.

flowchart LR
  M[(Model)] --> Gen[Generator]
  Gen --> Art[/Artifact + provenance header/]
  Art --> Fresh{{Freshness lint}}
  M --> Fresh
  Fresh -->|differs| Fail([build blocked])

Accessible description: a generator reads the model and emits an artifact carrying a provenance header. A freshness lint regenerates from the model and blocks the build when the committed artifact differs, so a hand-edit or a stale output is caught.

Projected from the catalogue entry system-models / Model-driven codegen.

On this page: Intent · Motivation · Applicability · Structure · Sample Code · Consequences · Example use within DocAble · Related Patterns

Intent

Intent — Generate real artifacts from the models — NetworkPolicy, service catalog, env wiring, public-API docs, competitor catalog, wire-contract types, docker — each carrying a provenance header, so the model drives the system (not merely describes it) and hand-edits are caught.

Motivation

If the models only described the system, they would be optional — nice docs, easy to ignore, quick to drift. The failure this addresses is a model nothing depends on: nothing breaks if it's wrong, so nothing keeps it right. And separately: a generated artifact that someone hand-edits loses the edit on the next regen, silently.

Applicability

Structure

The Structure diagram appears at the top of this page.

Sample Code

The generator emits the artifact with a provenance header re-stamped every run. A freshness lint regenerates and fails when the committed file differs — so the model stays authoritative and a stray hand-edit is caught before it is lost.

import sys

HEADER = "# GENERATED from the model — edits are overwritten; change the model instead\n"

def generate(model: list[dict]) -> str:
    body = "\n".join(f"allow: {row['name']}" for row in model)
    return HEADER + body + "\n"          # provenance marker re-emitted every run

def freshness_lint(committed: str, model: list[dict]) -> list[str]:
    expected = generate(model)
    if committed != expected:
        return ["artifact is stale or hand-edited — regenerate from the model"]
    if not committed.startswith(HEADER):
        return ["provenance header missing — artifact was hand-authored"]
    return []

if __name__ == "__main__":
    # `load_model` reads the source-of-truth; `read_artifact` reads the committed output file.
    findings = freshness_lint(read_artifact(), load_model())
    for f in findings:
        print(f"STALE-ARTIFACT: {f}")
    sys.exit(1 if findings else 0)

Consequences

Example use within DocAble

Contents
© James C. Davis, 2026–present