# Control-cycle trace: field glossary

Written by `audit/final_adversarial/harness.py` as gzip JSONL, one object per
line, to `artifacts/final-adversarial-audit/traces/<phase>/<scenario>_<arm>_<seed>.jsonl.gz`.
The trace is append-only within a run.

* **Times** are simulated seconds.
* **Junction IDs** are SUMO traffic-light IDs (`C00`–`C55`).
* **Vehicle IDs** are SUMO vehicle IDs. Ordinary vehicles are `v<n>`; the
  named emergency vehicles are `amb1`, `fire1` and `pol1`; random emergency
  vehicles are `ev<n>`.

The same IDs appear in the run summary (`trials/.../<seed>.json`) and in the
evidence manifest. They join a vehicle, a junction, a decision and an outcome.

## `header` (first line)

| field | meaning |
|---|---|
| `schema` | `vector-final-adversarial-trial/1` |
| `scenario`, `seed`, `arm` | the trial's identity |
| `network` | the SUMO network variant (`city36_static` or `city36_actuated_matched`) |
| `demand_sha256` | sha256 of the generated route file: the exact demand of this trial |
| `config_sha256` | sha256 of the scenario description (`AuditScenario.describe()`) |

## `decision`: one per controller call

Written only for controlled arms. The native arm commands nothing.

| field | meaning |
|---|---|
| `t` | simulated time of the decision |
| `j` | junction |
| `shown` | `{NS, EW}`: the queue counts the controller was shown, after the sensor model (`null` = NaN injected) |
| `truth` | `{NS, EW}`: SUMO's halting count at the same instant (end of the previous step) |
| `flags` | the sensor model's marks: `stale`, `dropout`, `delayed_s`, `spike` (approaches), `swapped`, `invalid` (approaches). Empty = exact |
| `phase`, `t_in` | the signal phase shown, and the time in it (from `SignalAdapter`) |
| `ev` | the emergency view given to the controller: `{vid, ap}`, or `null` |
| `request` | what the controller asked for (`NS`/`EW`) |
| `valid` | whether the request named an approach (else the adapter replaced it) |
| `effect` | what the adapter did: `green X`, `extend X`, `end X green (yellow)`, `max green: X terminated (yellow)` |
| `decide_ms` | wall time of `controller.decide()` in ms, including VECTOR's shadow stack |
| `reason` | VECTOR only: `control_logic`'s reason string (`VEHICLE_DEMAND (...)`, `EMERGENCY_OVERRIDE (0.95)`, `STARVATION_PREVENTION_LANE_n`, `NO_DEMAND_*`) |
| `belief` | VECTOR only: the QueueObserver's constrained queue per approach, as the law used it |
| `shadow` | `vector` arm only: the advisory stack's output for this cycle (below) |

`shadow` fields:

| field | meaning |
|---|---|
| `tier` | `SENTRY` / `PREDATOR` / `APEX`: the tier the orchestrator ran |
| `regime` | the StateEstimator's regime label |
| `esc` | escalation reasons |
| `invoked` | models invoked as *authorised* (none are; the gate holds all) |
| `skipped` | number of models skipped |
| `degraded` | `FULL`, `PREDATOR_ONLY` or `SENTRY_ONLY` |
| `fallback` | whether a tier failed and a simpler one ran |
| `disagreement` | relative spread of the shadow forecasts |
| `agreed` | whether its candidate matched the applied phase |
| `n_forecasts` | forecasts produced this cycle |
| `pred_total_8s` | their mean: the forecast total queue 8 s ahead |
| `ms` | its latency |
| `error` | present instead of the above if the shadow raised. The control decision is unaffected |

## `event`

| `event` | fields | meaning |
|---|---|---|
| `blockage_stalled` / `blockage_released` | `lane`, `vehicle` | the queue head held at speed 0 (verified each step afterwards), and its release |
| `speed_limit_set` | `edge`, `speeds` | a capacity cut applied or lifted, as read back from SUMO |
| `ev_inserted` / `ev_arrived` | `vid`, `vtype`, `route` | an emergency vehicle entering and leaving the network |
| `fault_injected` | `junction`, `what`, `t` | scenario M: VECTOR's forecasters or advisory orchestrator made to raise |

## `footer` (last line)

| field | meaning |
|---|---|
| `health_ok` | the trial's health gate |
| `signal_sequence_sha256` | hash of every junction's realised signal intervals, rebuilt only from states SUMO reported |

## Outcomes

Outcomes are in the run summary, not the trace. The summary holds per-vehicle
time loss, per-junction halting, spillback, every emergency vehicle's journey,
and safety counts. The summary's `traffic.network_halting_by_60s` is the
network-state series that a decision's consequences can be read against.
