babylon.engine.headless_runner.run_summary
Build summary.json — terminal aggregates + audit log + performance.
Spec: 064-headless-sim-runner (T026).
The summary follows contracts/summary_json_schema.yaml. Top-level
keys:
schema_version— locked literal “1.0”run_metadata— session id, exit reason, ticks, year, seed, scopeterminal_state— aggregates at the final completed tickexternal_node_flows— per-external-node summed flow magnitudescounty_terminal_snapshot— per-county terminal state (delta-vs-init)conservation_audit— projection of conservation_audit_log rowsperformance— wallclock breakdownend_game_event(optional) — present when exit_reason == early_terminatederror(optional) — present when exit_reason == errored
The builder is decoupled from Postgres: callers feed it pre-shaped inputs. Postgres-backed runs query the relevant views/tables and pass the rows in; unit tests pass synthetic fixtures.
Functions
|
Spec-065 T057: aggregate boundary_flow_register rows per external node. |
|
Construct the summary payload as a plain dict. |
- babylon.engine.headless_runner.run_summary.aggregate_external_node_flows(*, pool, session_id)[source]
Spec-065 T057: aggregate boundary_flow_register rows per external node.
Reads the per-tick rows produced by
BoundaryFlowRegister.flush()that the bridge persists each tick, and computes per-external-node cumulative summaries:total_phi_inflow: SUM(magnitude) forflow_type='drain_edge'total_trade_inbound: SUM forflow_type='trade_edge'total_commute_outbound: SUM forflow_type='commute_out'tick_count_with_inflow: distinct ticks with at least one row
Spec-101 review fix #5: the external node plays a DIFFERENT structural role depending on
flow_type—DRAIN_EDGE/TRADE_EDGEput it onsource_node_id(babylon.engine.systems.phi_distribution,babylon.engine.systems.vol2_circulation), whileCOMMUTE_OUTputs it ondest_node_id. A singleGROUP BY dest_node_id(as this function used before the fix) is therefore WRONG for the only currently- live flow type: forDRAIN_EDGErowsdest_node_idis the receiving county FIPS, not the bloc —node_idin the returned rows was silently a county view, contradicting this function’s own name and ADR055/proof.md’s “per external node” framing. The corrected query picks whichever side carrieskind='external'per row, so the aggregation is genuinely per-bloc for every flow type (current and future).Returns one entry per external node id present in the register. Empty list when the engine has not yet integrated boundary flows.
- babylon.engine.headless_runner.run_summary.build_summary(*, config, session_id, exit_reason, ticks_completed, wallclock_start, wallclock_end, terminal_state, external_node_flows, county_terminal_snapshot, conservation_audit, performance, end_game_event=None, error=None)[source]
Construct the summary payload as a plain dict.
- Parameters:
config (
SimulationRunConfig) – The drivingSimulationRunConfig.session_id (
str) – UUID string for this run.exit_reason (
ExitReason) – How the run terminated.ticks_completed (
int) – Number of fully-persisted ticks (≤ config.ticks).wallclock_start (
datetime) – Run start time (UTC).wallclock_end (
datetime) – Run end time (UTC).terminal_state (
dict[str,Any]) – Aggregates at the final completed tick (counties_alive, total_population, total_v/c/s/k, mean ideology axes, etc.).external_node_flows (
list[dict[str,Any]]) – One entry per external node (canada, china, rest_of_usa) with summed inflows/outflows.county_terminal_snapshot (
list[dict[str,Any]]) – Per-county terminal row + delta-vs-initial.conservation_audit (
list[AuditEntry]) – Conservation-invariant violations from spec-062.performance (
PerformanceBreakdown) – Wallclock attribution model.end_game_event (
dict[str,Any] |None) – Present iff exit_reason == EARLY_TERMINATED.error (
dict[str,Any] |None) – Present iff exit_reason == ERRORED.
- Return type:
- Returns:
Dict ready to be JSON-encoded as summary.json.