CR141 API

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.

API status

ItemStatus
OpenAPI specificationAvailable — /openapi.json, OpenAPI 3.1, 4 paths, 19 schemas
Schema examplesAvailable — every model carries a captured, reproducible example
Docker deploymentAvailable — docker compose up -d, then http://localhost:8000/docs
Public API endpointNot yet available — no public host is bound. cr141.com serves the static dashboard only.
AuthenticationNone. 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.

Endpoints

GET /evidence/status

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.

GET /proposal/{pid}

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}

GET /proposal/{pid}/flips

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.

POST /simulate

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}

Contract — parameters and response fields

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/status

Is 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)

FieldTypeExample value
auditstringCR141-001
audit_closedbooleanTrue
events_measuredinteger28
gatesobject…
exactnessExactness…
reproducible_packageReproduciblePackage…
cacheStatusCache | null…
generated_utcstring2026-11-11T07:07:02Z
Captured response example
{
  "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).

ParameterInTypeRequiredExample
pidpathstringyes—

200 response: Proposal (15 fields)

FieldTypeExample value
pidinteger301
blockinteger20519734
block_evaluatedinteger | null20519733
marketsarray…
populationinteger | null8353
targetsinteger5468
predicted_flipsinteger65
observed_flipsinteger65
exact_set_equalitybooleanTrue
density_pctnumber | null1.189
route_a_bRouteAB…
cf_before_zero_route_b_onlyinteger | null0
rpc_failuresinteger0
completion_ratenumber | null100.0
predicted_subset_of_entered_changedboolean | nullTrue
Captured response example
{
  "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}/flips

Flipped 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.

ParameterInTypeRequiredExample
pidpathstringyes—
attributionquerybooleanno—
limitqueryintegerno—
cursorquerystring | nullno—

200 response: FlipPage (5 fields)

FieldTypeExample value
pidinteger301
totalinteger65
next_cursorstring | nullMQ==
attributionbooleanTrue
flipsarray…
Captured response example
{
  "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 /simulate

What 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

FieldTypeExample
pidinteger | null71
blockinteger | null—
changesarray…
scopeScope—

200 response: SimulateResult (17 fields)

FieldTypeExample value
pidinteger71
blockinteger | null13699346
block_evaluatedinteger | null13699345
changesarray…
affected_accountsinteger5309
potential_flipsinteger57
newly_flippedinteger56
healedinteger0
collateral_impact_weistring-617013926818452361212894412
borrow_impact_weistring0
borrow_impact_notestringa CF change moves collateral, not debt;…
flipsarray…
flips_truncatedinteger56
invalidbooleanFalse
rpc_failuresinteger0
runtime_msinteger22
modelstringonly the named markets' CFs change; eve…
Captured response example
{
  "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.

What the API does not do

CR141 — Governance Impact Verification. Static pages generated by build_pages.py from dashboard_data.json; no JavaScript, no network at read time.