babylon.engine.headless_runner.models

Pydantic entities for the headless simulation runner.

Spec: 064-headless-sim-runner (data-model.md §1)

All models are frozen Pydantic 2.x per project standard. The set:

Classes

AuditEntry(**data)

Projection of one row from spec-062 conservation_audit_log.

ExitReason(*values)

Run-terminal state discriminator.

PerformanceBreakdown(**data)

Wallclock attribution for SC-002 verification.

ScheduledBlocShock(**data)

Spec-102: exogenous, deterministic scheduled shock to a bloc's Φ inflow.

SimulationRunConfig(**data)

Frozen, hashable description of a single headless run.

SimulationRunResult(**data)

Return value of babylon.engine.headless_runner.run().

TraceRow(**data)

One row of trace.csv.

class babylon.engine.headless_runner.models.ExitReason(*values)[source]

Bases: StrEnum

Run-terminal state discriminator.

Mapped to CLI exit codes per contracts/cli_contract.yaml:

  • COMPLETED → exit 0

  • EARLY_TERMINATED → exit 0 (valid end-game)

  • USER_INTERRUPTED → exit 130

  • ERRORED → exit 1

COMPLETED = 'completed'
EARLY_TERMINATED = 'early_terminated'
USER_INTERRUPTED = 'user_interrupted'
ERRORED = 'errored'
class babylon.engine.headless_runner.models.ScheduledBlocShock(**data)[source]

Bases: BaseModel

Spec-102: exogenous, deterministic scheduled shock to a bloc’s Φ inflow.

Declares a level-set multiplier applied to that bloc’s external_nodes_phi entry starting at tick (inclusive) and persisting on all subsequent ticks until a later shock for the same bloc supersedes it (see _apply_due_shocks in runner.py). Pure exogenous scenario-authoring data — blocs never decide to shock themselves (R-AMEND, blocs stay Layer-0 register machinery).

tick must be >= 1: the tick loop only visits ticks 1..(config.ticks - 1) (tick 0 is a raw hex-state persist that never reads external_nodes_phi).

Parameters:
model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tick: int
bloc: str
phi_multiplier: float
class babylon.engine.headless_runner.models.SimulationRunConfig(**data)[source]

Bases: BaseModel

Frozen, hashable description of a single headless run.

Constructed from CLI flags + defaults; persisted into the manifest’s deterministic_inputs section.

Parameters:
model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

ticks: int
start_year: int
random_seed: int
scope_name: str
scope_fips: frozenset[str]
external_node_ids: frozenset[str]
sqlite_reference_path: Path
output_dir: Path
defines_overlay_path: Path | None
dry_run: bool
verbose: Literal['DEBUG', 'INFO', 'WARNING', 'ERROR']
strict: bool
liveness_gate: bool
endgame_detector: str | None
write_baseline_to: Path | None
shock_schedule: tuple[ScheduledBlocShock, ...]
class babylon.engine.headless_runner.models.PerformanceBreakdown(**data)[source]

Bases: BaseModel

Wallclock attribution for SC-002 verification.

Parameters:
model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

total_wallclock_sec: float
session_init_sec: float
hex_hydration_sec: float
tick_loop_sec: float
artifact_emission_sec: float
per_tick_median_ms: float
per_tick_p99_ms: float
per_tick_max_ms: float
per_system_ms: dict[str, float]
class babylon.engine.headless_runner.models.AuditEntry(**data)[source]

Bases: BaseModel

Projection of one row from spec-062 conservation_audit_log.

Parameters:
  • tick (int)

  • invariant_name (str)

  • severity (Literal['info', 'warning', 'error', 'critical'])

  • details (dict[str, Any])

model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tick: int
invariant_name: str
severity: Literal['info', 'warning', 'error', 'critical']
details: dict[str, Any]
class babylon.engine.headless_runner.models.TraceRow(**data)[source]

Bases: BaseModel

One row of trace.csv.

Column ordering matches contracts/trace_csv_schema.yaml and the SQL view view_runtime_trace_emission. CSV serialization writes "" for None per FR-008.

Parameters:
  • tick (int)

  • simulated_year (float)

  • entity_id (str)

  • entity_kind (Literal['county', 'external', 'national', 'hex_aggregate'])

  • v (float | None)

  • c (float | None)

  • s (float | None)

  • k (float | None)

  • p_acquiescence (float | None)

  • p_revolution (float | None)

  • ideology_r (float | None)

  • ideology_l (float | None)

  • ideology_f (float | None)

  • surveillance_coupling (float | None)

  • internet_access_pct (float | None)

  • biocapacity_stock (float | None)

  • energy_stock (float | None)

  • raw_material_stock (float | None)

  • profit_rate (float | None)

  • exploitation_rate (float | None)

  • population (int | None)

  • employment_proxy (float | None)

model_config: ClassVar[ConfigDict] = {'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

tick: int
simulated_year: float
entity_id: str
entity_kind: Literal['county', 'external', 'national', 'hex_aggregate']
v: float | None
c: float | None
s: float | None
k: float | None
p_acquiescence: float | None
p_revolution: float | None
ideology_r: float | None
ideology_l: float | None
ideology_f: float | None
surveillance_coupling: float | None
internet_access_pct: float | None
biocapacity_stock: float | None
energy_stock: float | None
raw_material_stock: float | None
profit_rate: float | None
exploitation_rate: float | None
population: int | None
employment_proxy: float | None
class babylon.engine.headless_runner.models.SimulationRunResult(**data)[source]

Bases: BaseModel

Return value of babylon.engine.headless_runner.run().

Parameters:
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'frozen': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

session_id: UUID
config: SimulationRunConfig
ticks_completed: int
exit_reason: ExitReason
end_game_tick: int | None
end_game_condition: str | None
wallclock_start: datetime
wallclock_end: datetime
performance: PerformanceBreakdown
conservation_audit: tuple[AuditEntry, ...]
trace_rows: Iterator[TraceRow] | None
artifact_dir: Path | None
events: tuple[dict[str, Any], ...]
final_world_state: Any