Four read-only endpoints over the audited CR141 corpus. No Ethereum RPC call, no database, no credentials at request time — the API reads frozen artifacts and answers in milliseconds.
| Item | Status |
|---|---|
| OpenAPI specification | Available — /openapi.json, OpenAPI 3.1, 4 paths, 19 schemas |
| Schema examples | Available — every model carries a captured, reproducible example |
| Docker deployment | Available — docker compose up -d, then http://localhost:8000/docs |
| Public API endpoint | Not yet available — no public host is bound. cr141.com serves the static dashboard only. |
| Authentication | None. There is no key, no token and no account. |
The distinction matters: the contract is public and stable, the host is not. An agent or a developer can read the spec, generate a client and understand every model without issuing a single request. Only execution needs the container.
Returns the frozen audit status for CR141-001, derived from the audited corpus of 28 proposals and 141 collateral factor changes. Answers: is the audit closed, how many proposals matched exactly, predicted versus observed transitions, gate results.
Reads a pre-computed status document; it does not re-run the audit on request.
Returns the audited impact record for one governance proposal: execution block, markets with their collateral factor before and after, analyzed population, targets, predicted and observed transitions, and whether the sets matched exactly.
{"pid": 301, "targets": 5468, "predicted_flips": 65, "observed_flips": 65,
"exact_set_equality": true, "n_markets": 9}
Returns every predicted and observed account state transition for the proposal, with
market-level attribution when attribution=true: which market contributed to the
buffer change, by how much, and whether no single market alone would have flipped the
account.
Runs counterfactual governance analysis against the audited contribution model: given a proposal and an alternative collateral factor, returns the affected population and the newly flipped and healed accounts. The block state is held fixed; nothing is sent to the chain.
request : {"changes": [{"pid": 71, "market": "cETH", "cf_after": 0.70}]}
response: {"affected": 5309, "newly_flipped": 56, "healed": 0, "invalid": false}
Generated from openapi.json, which is generated from the running FastAPI app. Every 200 response is a declared Pydantic model, so these tables are the contract rather than a description of it. Field names and types below cannot drift from the code: the page is rebuilt from the same document a client generator would consume.
GET /evidence/statusIs the audit closed? Returns the frozen audit status for CR141-001. Derived from the audited corpus of 28 proposals and 141 CF changes. This is the evidence surface: audit_closed is true only when all eight gates pass, and exactness states the falsification measurement — predicted vs observed flip counts across the whole corpus (474 / 474, difference 0, exact set equality 28/28). Those numbers are measured from the verdicts, never asserted from a criteria document. cache says where the gate status came from: frozen: true means it was pre-measured at image build time and no evaluator is running in this deployment; null means an evaluator ran during this request. A consumer that needs to know how old the verdict is should read cache.generated_utc rather than assume audit_closed was measured just now. reproducible_package points at the offline rerun kit: the audit can be re-verified on a machine with no network access.
No parameters.
200 response: EvidenceStatus (8 fields)
| Field | Type | Example value |
|---|---|---|
audit | string | CR141-001 |
audit_closed | boolean | True |
events_measured | integer | 28 |
gates | object | … |
exactness | Exactness | … |
reproducible_package | ReproduciblePackage | … |
cache | StatusCache | null | … |
generated_utc | string | 2026-11-11T07:07:02Z |
{
"audit": "CR141-001",
"audit_closed": true,
"cache": {
"age_seconds": 68297.6,
"frozen": true,
"generated_utc": "2026-11-10T12:08:45Z",
"note": "pre-measured at image build time; evaluator not present in this deployment",
"source": "audit_status_cache.json",
"stale": false
},
"events_measured": 28,
"exactness": {
"difference": 0,
"exact_set_equality": "28/28",
"observed_flips": 474,
"predicted_flips": 474
},
"gates": {
"G0_bug_classes": {
"note": "manual registry in CR141-AUDIT-CLOSURE.json",
"pass": true
},
"G1_integrity": {
"pass": true
},
"G2_coverage": {
"pass": true
},
"G3_reproducibility": {
"note": "44/56/133 identical pre/post; 66 post-fix only",
"pass": true
},
"G4_prediction": {
"pass": true
},
"G5_corpus": {
"pass": true
},
"G6_operations": {
"pass": true
},
"G7_postmortem": {
"pass": true
}
},
"generated_utc": "2026-11-11T07:07:02Z",
"reproducible_package": {
"command": "cd rerun_package && python3 verify_hashes.py",
"network_required": false,
"path": "rerun_package/"
}
}Schema EvidenceStatus and all nested models are in openapi.json.
GET /proposal/{pid}One proposal: targets, population, predicted vs observed flips. Returns the audited impact record for a governance proposal. markets lists every CF change the proposal executed (before/after in both wei and decimal). population is every account the proposal could reach; targets is the subset that entered a changed market; predicted_flips and observed_flips are the engine's prediction and the chain's outcome, and exact_set_equality says whether the two sets are identical — not merely equal in size. density_pct is flips per 100 targets. route_a_b is an object on purpose. It reports how often Route A and Route B agree on a *numerator*, and how often they disagree — but disagree_is_artefact is true and the reference is CR141-INV-001: the disagreements come from nested-floor truncation and coexist with identical flip sets. A bare integer here would invite a consumer to read 1,105 disagreements as an error rate. They are not errors. block is the execution block and block_evaluated is the block the engine read (block - 1 by contract).
| Parameter | In | Type | Required | Example |
|---|---|---|---|---|
pid | path | string | yes | — |
200 response: Proposal (15 fields)
| Field | Type | Example value |
|---|---|---|
pid | integer | 301 |
block | integer | 20519734 |
block_evaluated | integer | null | 20519733 |
markets | array | … |
population | integer | null | 8353 |
targets | integer | 5468 |
predicted_flips | integer | 65 |
observed_flips | integer | 65 |
exact_set_equality | boolean | True |
density_pct | number | null | 1.189 |
route_a_b | RouteAB | … |
cf_before_zero_route_b_only | integer | null | 0 |
rpc_failures | integer | 0 |
completion_rate | number | null | 100.0 |
predicted_subset_of_entered_changed | boolean | null | True |
{
"block": 20519734,
"block_evaluated": 20519733,
"cf_before_zero_route_b_only": 0,
"completion_rate": 100.0,
"density_pct": 1.189,
"exact_set_equality": true,
"markets": [
{
"cf_after": 0.18,
"cf_after_wei": "180000000000000000",
"cf_before": 0.28,
"cf_before_wei": "280000000000000000",
"ctoken": "0xe65cdb6479bac1e22340e4e755fae7e509ecd06c",
"delta_rel": -0.35714285714285715,
"exec": 20519734,
"symbol": "CAAVE"
},
{
"cf_after": 0.845,
"cf_after_wei": "845000000000000000",
"cf_before": 0.855,
"cf_before_wei": "855000000000000000",
"ctoken": "0x39aa39c021dfbae8fac545936693ac917d5e7563",
"delta_rel": -0.011695906432748537,
"exec": 20519734,
"symbol": "CUSDC"
},
{
"cf_after": 0.1,
"cf_after_wei": "100000000000000000",
"cf_before": 0.2,
"cf_before_wei": "200000000000000000",
"ctoken": "0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407",
"delta_rel": -0.5,
"exec": 20519734,
"symbol": "CZRX"
}
],
"observed_flips": 65,
"pid": 301,
"population": 8353,
"predicted_flips": 65,
"predicted_subset_of_entered_changed": true,
"route_a_b": {
"agree": 2156,
"artefact_reference": "CR141-INV-001",
"disagree": 1105,
"disagree_is_artefact": true,
"flip_sets_agree_exactly": true
},
"rpc_failures": 0,
"targets": 5468
}Schema Proposal and all nested models are in openapi.json.
GET /proposal/{pid}/flipsFlipped accounts, optionally with driver-market attribution. Returns all predicted/observed flip accounts, optionally including driver attribution. One row per account whose predicted buffer goes negative. predicted_wei is the engine's buffer and observed_wei the chain's, both as signed wei strings (JSON numbers would lose precision above 2^53); margin_wei is the distance to the zero crossing and agrees says whether prediction and observation land on the same side. With ?attribution=true each row gains driver_market — the market with the largest negative contribution — plus its wei delta and the full contributions breakdown. driver_is_heuristic is true because the driver is chosen by largest contribution, not proven by counterfactual; joint_cause is true when no single market alone flips the account. Without attribution those fields are absent, not null (exclude_none): null would read as 'asked, and there is no driver', which is a claim this endpoint refuses to make. For the same reason next_cursor disappears on the last page — its absence means end of set. Attribution needs the per-market CONTRIB-*.json sidecar. A pid without one returns 501 with the exact command to regenerate it, rather than a silently empty driver field.
| Parameter | In | Type | Required | Example |
|---|---|---|---|---|
pid | path | string | yes | — |
attribution | query | boolean | no | — |
limit | query | integer | no | — |
cursor | query | string | null | no | — |
200 response: FlipPage (5 fields)
| Field | Type | Example value |
|---|---|---|
pid | integer | 301 |
total | integer | 65 |
next_cursor | string | null | MQ== |
attribution | boolean | True |
flips | array | … |
{
"attribution": true,
"flips": [
{
"account": "0x00b466c41109eda7be12406d06b017f77732f065",
"agrees": true,
"contributions": [
{
"cf_after": 0.1,
"cf_before": 0.2,
"delta_wei": "-18397842767644137056",
"market": "0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407",
"symbol": "CZRX"
},
{
"cf_after": 0.35,
"cf_before": 0.4,
"delta_wei": "-3693106226491475269",
"market": "0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e",
"symbol": "CBAT"
},
{
"cf_after": 0.845,
"cf_before": 0.855,
"delta_wei": "-576901220158309656",
"market": "0x39aa39c021dfbae8fac545936693ac917d5e7563",
"symbol": "CUSDC"
}
],
"driver_delta_wei": "-18397842767644137056",
"driver_is_heuristic": true,
"driver_market": "CZRX",
"joint_cause": false,
"margin_wei": "22667850214293921981",
"markets_touched": [
"CUSDC",
"CBAT",
"CZRX"
],
"n_markets": 3,
"observed_wei": "-11781305311049840994",
"predicted_wei": "-11781308056272734877"
}
],
"next_cursor": "MQ==",
"pid": 301,
"total": 65
}Schema FlipPage and all nested models are in openapi.json.
POST /simulateWhat would happen if a collateral factor were different? Runs a counterfactual simulation using the audited contribution model. This is the only endpoint that answers a question the corpus cannot: it takes a collateral factor the governance proposal did not execute and recomputes every account's buffer as if it had. The arithmetic is the audit's own — an account's buffer is buffer_before + sum(contribution over markets), and a CF change replaces exactly that market's term — so no approximation is introduced and multiple simultaneous changes simply add. Runs entirely on frozen artifacts (CONTRIB-*.json). No RPC call is made, which is why a full-population sweep over 5,309 affected accounts returns in tens of milliseconds. Request shape: changes is a list of {ctoken, new_cf_wei}. ctoken accepts a 0x address or a symbol (cETH, cUSDC); new_cf_wei accepts a wei string or a decimal. Supply pid or block — a simulation with neither is not reproducible and returns 400. Reading the result: affected_accounts is every account whose computed buffer moves at all; newly_flipped and healed are the directional changes; potential_flips is the total count whose buffer ends negative. If invalid is true an RPC call failed and the numbers must not be trusted — the API says so rather than returning plausible garbage. borrow_impact_wei is always 0 by construction: a CF change moves collateral, not debt.
No parameters.
Request body: SimulateRequest — SimulateRequest
| Field | Type | Example |
|---|---|---|
pid | integer | null | 71 |
block | integer | null | — |
changes | array | … |
scope | Scope | — |
200 response: SimulateResult (17 fields)
| Field | Type | Example value |
|---|---|---|
pid | integer | 71 |
block | integer | null | 13699346 |
block_evaluated | integer | null | 13699345 |
changes | array | … |
affected_accounts | integer | 5309 |
potential_flips | integer | 57 |
newly_flipped | integer | 56 |
healed | integer | 0 |
collateral_impact_wei | string | -617013926818452361212894412 |
borrow_impact_wei | string | 0 |
borrow_impact_note | string | a CF change moves collateral, not debt;… |
flips | array | … |
flips_truncated | integer | 56 |
invalid | boolean | False |
rpc_failures | integer | 0 |
runtime_ms | integer | 22 |
model | string | only the named markets' CFs change; eve… |
{
"affected_accounts": 5309,
"block": 13699346,
"block_evaluated": 13699345,
"borrow_impact_note": "a CF change moves collateral, not debt; borrow balances are unchanged",
"borrow_impact_wei": "0",
"changes": [
{
"cf_actual": 0.8,
"cf_before": 0.75,
"cf_hypothetical": 0.7,
"ctoken": "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5",
"symbol": "CETH"
}
],
"collateral_impact_wei": "-617013926818452361212894412",
"flips": [
{
"account": "0xa3d2bcce78e3edec1e655a1195540efc920805cb",
"buffer_wei": "701344199785325811852558",
"delta_wei": "-4198139075632086142103617",
"new_buffer_wei": "-1397725338030717259199251",
"was_flipped": false
}
],
"flips_truncated": 56,
"healed": 0,
"invalid": false,
"model": "only the named markets' CFs change; every other market keeps its actual cf_after",
"newly_flipped": 56,
"pid": 71,
"potential_flips": 57,
"rpc_failures": 0,
"runtime_ms": 22
}Schema SimulateResult and all nested models are in openapi.json.
build_pages.py from dashboard_data.json; no JavaScript, no network at read time.