tabench.edoc

The EDOC-1 substrate: the external-dynamic-engine observational certificate (adr-036/037). The canon, the frozen-field replay agent, and the engine-pin assertions that certify equilibrium rows for engines with no static latency law.

EDOC-1 substrate: the external-dynamic-engine observational certificate.

Design: docs/design/adr-036-external-dynamic-observational-certificate.md.

The shared substrate for the dynamic-external engine rows (sumo-duaiterate first, then matsim / dtalite-simulation): the versioned canonicalization module (canon), the frozen EdocScenario family, the occupancy-aware frozen-field builder + per-first-edge origin-wait profiles (field), the certifier-owned label-correcting time-dependent shortest path (tdsp), the pinned-engine replay-harness types (replay), and the P8 macrorep + bootstrap-CI harness for the stochastic track (macrorep, adr-036 R5). The certificate itself (gates G0-G4 + the RG_D1 frozen-field best-response gap) lives in tabench.metrics.edoc_gaps.

class tabench.edoc.EdocScenario(name, edge_ids, edge_tail, edge_head, edge_fftt, edge_lanes, agent_ids, agent_origin, agent_dest, agent_depart, engine, engine_version, seed, semantic_config, dt, n_intervals, departure_quantum, backlog_bound, separation_factor, floor_seconds, replay_deadline_s, canon_speed_mps=13.89, r3_tolerance_s=15.0, field_semantics='raw', completion_rule='occupancy_aware', origin_wait_convention='profile', walk_bound=8, walk_count_bound=200000, seed_list=(), family='')[source]

Bases: object

A frozen external-dynamic instance. Topology is an explicit directed edge graph (SUMO edge IDs are strings); demand is a fixed per-agent trip table (agent id, origin node, destination node, scheduled departure time).

Parameters:
  • name (str)

  • edge_ids (tuple[str, ...])

  • edge_tail (tuple[str, ...])

  • edge_head (tuple[str, ...])

  • edge_fftt (ndarray)

  • edge_lanes (ndarray)

  • agent_ids (tuple[str, ...])

  • agent_origin (tuple[str, ...])

  • agent_dest (tuple[str, ...])

  • agent_depart (ndarray)

  • engine (str)

  • engine_version (str)

  • seed (int)

  • semantic_config (str)

  • dt (float)

  • n_intervals (int)

  • departure_quantum (float)

  • backlog_bound (float)

  • separation_factor (float)

  • floor_seconds (float)

  • replay_deadline_s (float)

  • canon_speed_mps (float)

  • r3_tolerance_s (float)

  • field_semantics (str)

  • completion_rule (str)

  • origin_wait_convention (str)

  • walk_bound (int)

  • walk_count_bound (int)

  • seed_list (tuple[int, ...])

  • family (str)

out_edges()[source]

Adjacency: node -> outgoing edge ids (certifier TD-SP input).

Return type:

dict[str, list[str]]

length_of()[source]

Canonical SUMO edge length: fftt * canon_speed (free-flow time = fftt).

Return type:

dict[str, float]

content_hash()[source]

SHA-256 over every scored-outcome-bearing field, domain-separated and length-framed (adr-036 MAJOR-5 hash-everything). A hash-coverage test (test_edoc) mutates each field and asserts the digest moves.

Return type:

str

class tabench.edoc.EmittedBundle(plans, experienced, engine_version, seed)[source]

Bases: object

What a model emits (adr-036 artifact contract): plans P (per-agent route + scheduled departure), the experienced record X, and provenance (engine version + seed, gated at G0, never the engine’s self-reported convergence).

Parameters:
  • plans (dict[str, tuple[tuple[str, ...], float]])

  • experienced (dict[str, ReplayAgent])

  • engine_version (str)

  • seed (int)

class tabench.edoc.FrozenField(dt, n_intervals, fftt, traveltime, occupancy, semantics='raw')[source]

Bases: object

Per-edge interval-mean experienced traversal-time field Ĉ with occupancy-aware completion (R2). traveltime[edge][k] is the measured mean cost on edge in interval k; occupancy[edge][k] is its occupancy signal (a standing-queue witness for completion). fftt[edge] is the free-flow traversal time used for never-loaded edges and zero-occupancy gaps.

Parameters:
  • dt (float)

  • n_intervals (int)

  • fftt (dict[str, float])

  • traveltime (dict[str, dict[int, float]])

  • occupancy (dict[str, dict[int, float]])

  • semantics (str)

is_loaded(edge)[source]

An edge is loaded if the replay put any occupancy or measured cost on it in any interval; a never-loaded edge is at free flow everywhere.

Parameters:

edge (str)

Return type:

bool

traversal_time(edge, entry_time)[source]

The frozen cost of entering edge at entry_time (R2).

Parameters:
  • edge (str)

  • entry_time (float)

Return type:

float

class tabench.edoc.MacrorepResult(per_seed, metrics)[source]

Bases: object

The row-level result of a P8 macrorep certification: the per-seed certified metrics (diagnostics, one dict per pinned seed) and the row metrics (feasible, mean RG_D1 + bootstrap CI, the row floor, and Tier-B backlog/delta aggregates).

Parameters:
  • per_seed (dict[int, dict[str, float]])

  • metrics (dict[str, float])

class tabench.edoc.OriginWaitProfile(dt, n_intervals, wait_mean, occupancy)[source]

Bases: object

Per-first-edge interval-mean origin (insertion) wait, built from the replay’s own departDelay samples with the same occupancy-aware completion as the link field (MAJOR-2). wait(edge, t) charges the measured entrance queue of edge for a departure in t’s interval; a never-used first edge admits immediately (0 wait — the deviation-optimistic default). The agent_symmetric convention is the optional family alternative (disclosed entrance-choice blindness); it is handled by the certifier, not here.

Parameters:
  • dt (float)

  • n_intervals (int)

  • wait_mean (dict[str, dict[int, float]])

  • occupancy (dict[str, dict[int, float]])

class tabench.edoc.ReplayAgent(agent_id, departure, arrival, route, experienced_time, depart_delay)[source]

Bases: object

One agent’s replayed experienced record: scheduled departure, arrival, the driven edge route, the door-to-door experienced time, and the off-network insertion (origin) wait depart_delay (INCLUDED in every cost, G3).

Parameters:
  • agent_id (str)

  • departure (float)

  • arrival (float)

  • route (tuple[str, ...])

  • experienced_time (float)

  • depart_delay (float)

class tabench.edoc.ReplayResult(canon_hash, agents, field_records, flows=<factory>, n_intervals=0)[source]

Bases: object

The parsed, canonicalized output of one pinned-engine replay. canon_hash is the object G1’s determinism double compares; agents is the replayed per-agent record (compared to the emitted X); field_records and flows are the model-blind material the certifier builds Ĉ and the G4 conservation checks from.

Parameters:
  • canon_hash (str)

  • agents (dict[str, ReplayAgent])

  • field_records (dict[str, dict[int, tuple[float, float]]])

  • flows (dict[str, dict[int, tuple[float, float]]])

  • n_intervals (int)

tabench.edoc.assert_engine_pin(installed_version, pinned_version)[source]

A ReplayRunner’s mandatory pre-replay check (G0 split): the engine actually installed on this box must equal the instance’s pinned engine_version.

A mismatch is a configuration error and RAISES ValueError eagerly (the adr-020 eager-config / adr-036 R6 crash-vs-censor map — an infra/config fault is never laundered into feasible=0). The certifier separately checks the emitted provenance (the model’s self-report); this is the runner verifying the box it is about to build the frozen field on, which is what the “read the installed version at certify time” clause of G0 actually requires.

Parameters:
  • installed_version (str)

  • pinned_version (str)

Return type:

None

tabench.edoc.build_field_from_records(records, fftt, dt, n_intervals, semantics='raw')[source]

Build a FrozenField from per-edge {interval: (traveltime, occupancy)} records (SUMO meandata, or a synthetic fixture). An interval present with traveltime populates traveltime[edge][k]; its occupancy populates occupancy[edge][k]. Missing intervals are gaps (completed at read time, R2).

Parameters:
  • records (dict[str, dict[int, tuple[float, float]]])

  • fftt (dict[str, float])

  • dt (float)

  • n_intervals (int)

  • semantics (str)

Return type:

FrozenField

tabench.edoc.build_origin_waits(departures, dt, n_intervals)[source]

Build a per-first-edge origin-wait profile from replay departure samples (first_edge, depart_time, depart_delay): the interval-mean departDelay per first edge, plus an occupancy witness (a nonzero mean wait in an interval marks a standing entrance queue there, so completion carries it forward across an interior gap; an interval with no departures has no witness → 0).

Parameters:
  • departures (list[tuple[str, float, float]])

  • dt (float)

  • n_intervals (int)

Return type:

OriginWaitProfile

tabench.edoc.canonicalize_dtalite(name, data)[source]

Canonicalize one DTALite artifact (adr-040): the IDENTITY plus the decompress rule — the engine is byte-deterministic at the pinned OMP=1, so no strip/sort is needed; idempotent and content-sensitive by construction. The 13/12 positional-parse necessity (R10’s founding spec) lives in the adapter’s trajectory PARSER, whose header-shape RAISE is the canon-version-bump trigger for upstream format drift.

Parameters:
  • name (str)

  • data (bytes)

Return type:

bytes

tabench.edoc.canonicalize_matsim(name, data)[source]

Canonicalize one MATSim artifact (adr-039): decompress (gzip frames carry volatile metadata), and — for events artifacts ONLY — sort same-timestamp event ties (the measured multithreading permutation surface; see the module docstring). Plans/network payloads pass through decompressed and untouched. Idempotent.

Parameters:
  • name (str)

  • data (bytes)

Return type:

bytes

tabench.edoc.canonicalize_sumo(name, data)[source]

Canonicalize one SUMO artifact: decompress, strip the generated on timestamp comment (all XML), and — for summary artifacts ONLY — strip the wall-clock duration attribute. Every simulation-state byte is left intact (tripinfo duration is untouched). Idempotent.

Parameters:
  • name (str)

  • data (bytes)

Return type:

bytes

tabench.edoc.certify_macroreps(base, emit, certify, *, b=10000, level=0.95)[source]

Emit + certify one macrorep per pinned seed and aggregate to the row.

emit produces the model’s bundle for one per-seed instance; certify is the row’s certification path (the row passes its own wrapper so R3 / separation vetting run per seed). Exceptions from either PROPAGATE (R6: infrastructure is never laundered); a certified feasible != 1 on ANY macrorep censors the WHOLE row (ruling 3). On an all-feasible row the score is mean(rg_d1) with the house percentile-bootstrap CI drawn on the reserved SOURCE_BOOTSTRAP stream at root_seed = seed_list[0] (deterministic in the pinned list alone — P8), and the row floor is the mean of the per-seed floor_gaps (ruling 2).

CONTRACT (adr-039, the N2 boundary): emit must be HARNESS-controlled — a fresh per-seed engine run keyed on sc.seed, as every shipped row’s score path wires it — never a model-supplied bundle: when an engine’s replay map is seed-independent, feeding one cherry-picked bundle to every macrorep would pass G1 per seed and void the N2 defense (a zero-width CI over a best-of-N emission), which no check here can detect.

Parameters:
Return type:

MacrorepResult

tabench.edoc.evaluate_route(field, origin_waits, route, depart_time)[source]

Door-to-door cost of the DRIVEN route from scheduled departure depart_time: the first edge’s origin-wait profile plus the time-dependent traversal of every edge on the frozen field (the same composition c_br minimizes over, so the driven route is in the min set).

Parameters:
Return type:

float

tabench.edoc.hash_dtalite_artifacts(artifacts)[source]

DTALite specialization of hash_artifacts() (adr-040’s row): the {trajectory.csv} allowlist surface + the identity-plus-decompress canonicalizer, same domain/version.

Parameters:

artifacts (Mapping[str, bytes])

Return type:

str

tabench.edoc.hash_matsim_artifacts(artifacts)[source]

MATSim specialization of hash_artifacts() (adr-039’s row): the allowlist surface + the tie-sorting canonicalizer, same domain/version.

Parameters:

artifacts (Mapping[str, bytes])

Return type:

str

tabench.edoc.hash_sumo_artifacts(artifacts)[source]

SUMO specialization of hash_artifacts() (adr-037’s first row).

Parameters:

artifacts (Mapping[str, bytes])

Return type:

str

tabench.edoc.is_hashed_artifact(name)[source]

SUMO hash surface (R10): simulation-state artifacts are hashed; engine/ driver logs are provenance and excluded. name may be a path or a basename.

Parameters:

name (str)

Return type:

bool

tabench.edoc.is_hashed_dtalite_artifact(name)[source]

DTALite hash surface (R10, adr-040): allowlist-only — exactly trajectory.csv; every other emission (sim_info.csv’s timestamp column, the debug/summary logs, the echoed inputs) is provenance. name may be a path or a basename.

Parameters:

name (str)

Return type:

bool

tabench.edoc.is_hashed_matsim_artifact(name)[source]

MATSim hash surface (R10, adr-039): allowlist-only — everything outside _MATSIM_HASHED_BASENAMES is provenance (census-measured; see the constant’s comment). name may be a path or a basename.

Parameters:

name (str)

Return type:

bool

tabench.edoc.per_seed_scenarios(base)[source]

Derive the macrorep instances from base: one per pinned seed, each pinning ITS OWN seed (so its content hash moves with the seed and the substrate’s per-emission G0 emitted.seed == sc.seed check applies unchanged per macrorep) while carrying the full hashed seed_list.

A deterministic-track instance (empty seed_list) on this stochastic API is a config error and RAISES ValueError (adr-036 R5).

Parameters:

base (EdocScenario)

Return type:

tuple[EdocScenario, …]

tabench.edoc.td_shortest_path(out_edges, edge_head, field, origin_waits, origin, dest, depart_time, walk_bound, walk_count_bound=200000)[source]

Minimum door-to-door cost from origin to dest for a departure at depart_time, over every walk of <= walk_bound edges (waiting-not- allowed; origin wait on the first edge only). Returns inf if the destination is unreachable within the bound. Raises RuntimeError if the walk count exceeds walk_count_bound — a certify-time infrastructure guard (adr-036 R6, prompt + bounded, never a censor), not a solution property; there is no construction-time pre-count.

Parameters:
  • out_edges (Mapping[str, Sequence[str]])

  • edge_head (Mapping[str, str])

  • field (FrozenField)

  • origin_waits (OriginWaitProfile)

  • origin (str)

  • dest (str)

  • depart_time (float)

  • walk_bound (int)

  • walk_count_bound (int)

Return type:

float