How evidence becomes a governed product — the entities the platform actually runs on, and how they relate. Each entity links to the working surface that implements it. This is the model, not a diagram of intent.
Four stages — Sources, Decision control, Execution, Products — expressed as entities and relationships.
erDiagram
SOURCE ||--o{ ASSUMPTION : feeds
DOMAIN ||--o{ ASSUMPTION : governs
SCENARIO }o--o{ ASSUMPTION : "selects bands"
MODEL }o--o{ ASSUMPTION : consumes
RUN }o--|| MODEL : executes
RUN }o--|| SCENARIO : under
RUN ||--o{ OUTPUT : produces
SOURCE { string provider string type date accessed }
DOMAIN { string name string steward string cadence }
ASSUMPTION { string key string value string unit string source float confidence date valid_to }
SCENARIO { string name string bands string review_status }
MODEL { string repo string sector string status }
RUN { string model_version string assumptions_commit string scenario string who datetime at }
OUTPUT { string artifact string provenance_json }
Read it as the pipeline: a governed ASSUMPTION (sourced, confidence-scored, governed by a DOMAIN steward) is banded by a SCENARIO and consumed by a MODEL. Stages 1–2 are live today. Stage 3 (RUN) is Layer 2 — a lightweight audit record of every execution, pinning the assumptions_commit, scenario, who and when. Stage 4 needs no separate registry: every OUTPUT artifact carries a provenance.json that embeds those same fields.
A model is born bottom-up (it defines its own assumptions) and matures top-down (it consumes governed ones). Maturity is one journey: an assumption goes local → governed → consumed. Which way you build depends on whether the registry already covers your domain.
Coverage decides what’s even possible: a thin or empty domain forces bottom-up — the model becomes the thing that defines what the registry should hold; a rich governed domain lets you go top-down from day one.
A 25-year railway feasibility model pulling 12 governed assumptions across 4 domains at runtime. Every input is sourced, confidence-scored, and owned. The model never touches a spreadsheet cell directly — it reads the registry.
| Assumption | Domain | Value (medium) | Unit | Confidence | Source |
|---|---|---|---|---|---|
| CapEx — total project | rail | R 79.0 bn | ZAR | V2 base case | |
| Tariff escalation | rail | 4.6% | pa | V2 base case rail tariff escalation | |
| Debt ratio | rail | 70% | gearing | V2 base case gearing | |
| Cost of debt | rail | 7.0% | pa nominal | V2 base case cost of debt | |
| Asset life | rail | 27 years | years | Engineering estimate | |
| WACC — pipeline assets | financial | 12.0% | pa | Governed hurdle rate | |
| GDP growth — SA base | macro | 2.2% | pa | Macro committee | |
| Iron ore — SA base production | mining | 37.7 MTPA | MTPA | DMRE / Kumba |
The 1% difference between high and medium tariff escalation (5.5% vs 4.6%) moves NPV by R20bn. That one governed assumption is the swing factor. If it lives in a spreadsheet cell, two analysts will disagree on it — silently. In the registry, there is one value, one owner, and one source document.
The model is not a picture. Every entity is a running surface in this intranet.
| Entity | What it is | Status | Open it |
|---|---|---|---|
| DOMAIN | 13 governed domains, each with a named steward and cadence. 5 live, 4 wiring pending. | Live | Operating manual → |
| ASSUMPTION | 550+ governed fields — sourced, confidence-scored, valid_to set, banded by scenario. | Live | The registry → |
| SCENARIO | 6 named scenarios (3 reviewed, 3 draft). Every model run picks one; bands resolve to concrete values. | Live | In the registry → |
| SOURCE | Provider, source_date and confidence on every assumption. No separate table — lives on the field. | Live | Download CSV → |
| MODEL | Sector decision models in external repos — they read the API at runtime. | External | Decision tools → |
| RUN | Audit record of every model execution — assumptions_commit, scenario, who, when. Closes the governance loop. | Layer 2 | In the roadmap |
| Output provenance | provenance.json written alongside every artifact — embeds run_id, assumptions_commit, scenario, model_version. No separate registry needed. | Layer 2 | Template → |