The ten contracts and how data moves between layers
Ten versioned contracts carry data between the layers, and repos may depend on nothing else. The two you will touch first are EvidenceLayer contract for detector output (direction; as built: Finding finding.json 1.2.0), from L3 to L4, and PrescriptionWhat to do, why, who, check plan (direction; as built: prescription.json 1.0.0 / card-proposal), from L4 to L5. All of them travel inside the Envelope header.
How to read it.
- Read top to bottom: state and evidence, then the decision, then what happened and what it was worth.
- Prescription is the payload L5 receives. ClosureState is the lifecycle of the card L5 makes from it. A WriteRequest needs both a Prescription and a granted AutonomyPolicy; without the policy there is no write.
- The dotted return arrow is how autonomy is earned: ValueRecords showing same-condition wins feed the policy.
Build now: Evidence, Prescription and ClosureState for the slow loop. Later: PlantState, WriteRequest and AutonomyPolicy for the fast loop.
View Mermaid source
flowchart TB
%% house-style: tour-contracts
subgraph state["State and evidence: L2 and L3"]
direction LR
lot["Lot and genealogy"]
ps["PlantState"]
evi["Evidence"]
end
subgraph decide["Decision: L4"]
direction LR
rx["Prescription"]
end
subgraph act["Action and value: L5 and the writer"]
direction LR
cs["ClosureState"]
wr["WriteRequest"]
a["Action"]
vr["ValueRecord"]
end
pol{{"AutonomyPolicy"}}
env["Envelope: header on every message, with episode_id"]
lot --> evi
ps --> evi
evi -- "L3 to L4" --> rx
rx -- "L4 to L5, becomes a card" --> cs
rx --> wr
pol --> wr
cs --> a
wr --> a
a --> vr
vr -. "same-condition wins" .-> pol
classDef govc fill:#fff4d6,stroke:#c99a2e,color:#000
classDef agentc fill:#e8f0ff,stroke:#5b7bd5,color:#000
classDef loopc fill:#eef7ee,stroke:#4f9a4f,color:#000
class pol,env govc
The ten, briefly#
| Contract | Carries | Produced by | Consumed by |
|---|---|---|---|
| PlantState | Estimated state of an asset, with uncertainty | L3 estimators, Plant Box twin | L4, writer, safety filter |
| Evidence | A typed claim and its support | L3 | L4, agents, ledger |
| Prescription | What to do, why, by whom, how it will be checked | L4 | L5 cards, safety filter |
| Action | What actually happened, by a person or the writer | L5, writer | Ledger |
| ValueRecord | One ledger row per action and KPI | L5 verification | Customer, registry, autonomy |
| AutonomyPolicy | A grant of authority | A person at the plant, through L5 | Safety filter, writer |
| Lot and genealogy | Which lots and parts passed which assets, with link confidence | L2 linkers | L3, ledger |
| WriteRequest | A request to change one set point | L4 or a person | Safety filter, writer |
| ClosureState | The card lifecycle, 11 states | L5 card machine | L6, analytics |
| Envelope | The header around all of them | Every producer | Every consumer |
What exists today#
Three of these have older ancestors in the code, and you will meet them. The L3 to L4 hop runs on FindingAs-built L3 detector output admitted to L4 (finding.json 1.2.0) 1.2.0, which forces every finding to carry a kWh and rupee estimate even when the loss is scrap. Evidence replaces it with a value vector. The L4 to L5 hop runs on the card proposal next to prescription.json 1.0.0, and L5 reads both. closure/action-intent.json is retired in favour of WriteRequestPlant Box write path request (direction; closure/action-intent.json retired) for the request and Action for the record.
Two vocabularies for how sure we are#
Evidence and ValueRecord carry a contract tier: measured, confirmed, modeled or unknown. Each quantity inside carries an evidence label: Measured, Estimated, Assumed or Unknown, plus calibrated or uncalibrated (D13, decided). A claim takes the weakest label among the quantities it rests on, and only a passed check raises it to confirmed. Confirmed is still not verified; that word is kept for counterfactual M&V that passed its checks.
Versions#
All ten are drafted in SE as 0.x, marked experimental (D2). While a contract is 0.x, a minor bump may break, so consumers pin the minor version. The first plant that uses a contract in production moves it to 1.0.0; after that, removing or renaming a field is a major change with a migration note. Consumers ignore unknown fields and reject messages missing required ones at the seam, never filling in defaults.
Go deeper: data contracts · Evidence and the tier mapping · versioning
Page history: last 1 change
- docs(technical): architecture tour and page summaries
79c8ea3