Geometry-Neutral Replay¶
Geometry-neutral replay is the SCPN Control evidence surface for replaying a bounded controller scenario without tying the report to one tokamak, stellarator, or pulsed FRC geometry. It records the scenario, trace, metrics, thresholds, manifest digests, and limitations needed to admit a replay as a bounded repository artefact.
The report is useful for three jobs:
- Compare a controller policy across magnetic-configuration contracts without rewriting the replay harness.
- Bind acceptance metrics and trace digests into a deterministic manifest.
- Preserve claim boundaries so synthetic replay evidence is not mistaken for a plant, HIL, or measured-shot admission.
Schema versions¶
scpn-control.geometry-neutral-replay.v1 is the original replay schema. It
contains the deterministic replay trace, scenario declaration, geometry
contract, acceptance metrics, thresholds, limitations, and manifest digests.
scpn-control.geometry-neutral-replay.v1.1 extends the same base report with
optional pulsed-shot context fields and digest-bound AER admission metadata. A
v1 report remains loadable while the v1.1 schema bundle is installed, so
existing replay artefacts do not need migration.
The v1.1 optional fields are:
| Field | Type | Validation |
|---|---|---|
pulse_id |
UUID string | Must parse as a canonical UUID. |
capacitor_state_initial_J |
number | Must be finite and non-negative. |
trigger_timestamp_ns |
integer | Must be non-negative. |
energy_recovered_J |
number | Must be finite and non-negative. |
shot_phase_log |
list of objects | Entries must be sorted by t; each row needs finite non-negative t, non-empty state, and non-empty reason. |
frc_diagnostics.s_parameter_at_burn |
number | Must be finite and non-negative when present. |
frc_diagnostics.mrti_peak_amplitude_m |
number | Must be finite and non-negative when present. |
frc_diagnostics.tilt_growth_rate_s_inv |
number | Must be finite when present. |
aer_admission |
object | Optional AER ingress evidence built from SpikeBuffer.admission_report() and digest-bound into manifest.aer_admission_digest. |
The AER admission object records the decode strategy, decode window,
feature-normalisation mode, feature count, strict-monotonic policy, overflow
state, retained event count, monotonic latch, and out-of-order event count.
When require_monotonic=True, validation fails if the replay attempts to admit
non-monotonic AER input. If aer_admission is present,
manifest.aer_admission_digest must equal the SHA-256 digest of the canonical
AER admission payload; otherwise the replay is rejected.
Python API¶
from scpn_control.scpn.geometry_neutral_replay import (
SCHEMA_VERSION_V1_1,
assert_v1_replay_loadable_under_v1_1_schema_bundle,
attach_aer_admission_metadata,
build_aer_admission_metadata,
generate_report,
load_geometry_neutral_replay_report,
register_v1_1_schema,
save_geometry_neutral_replay_report,
validate_report,
)
from scpn_control.scpn.observation import AERControlObservation, SpikeBuffer, SpikeEvent
report = generate_report(steps=12, seed=314159)
bench = report["geometry_neutral_replay"]
bench["schema_version"] = SCHEMA_VERSION_V1_1
bench["pulse_id"] = "123e4567-e89b-12d3-a456-426614174000"
bench["capacitor_state_initial_J"] = 18250.0
bench["trigger_timestamp_ns"] = 500000
bench["energy_recovered_J"] = 7350.25
bench["shot_phase_log"] = [
{"t": 0.0, "state": "precharge", "reason": "bank voltage admitted"},
{"t": 0.0005, "state": "trigger", "reason": "ignitron trigger issued"},
{"t": 0.0010, "state": "burn", "reason": "FRC burn window entered"},
]
bench["frc_diagnostics"] = {
"s_parameter_at_burn": 1.42,
"mrti_peak_amplitude_m": 0.0032,
"tilt_growth_rate_s_inv": -8.5,
}
buffer = SpikeBuffer(capacity=8)
buffer.extend([
SpikeEvent(neuron_id=0, timestamp_ns=10),
SpikeEvent(neuron_id=1, timestamp_ns=30),
SpikeEvent(neuron_id=1, timestamp_ns=50),
])
observation = AERControlObservation(
timestamp_ns=100,
spike_stream=buffer,
decode_window_ns=100,
decode_strategy="rate",
n_features=4,
require_monotonic=True,
)
admission = build_aer_admission_metadata(
admission_report=observation.admission_report(),
decode_strategy="rate",
decode_window_ns=100,
n_features=4,
require_monotonic=True,
feature_vector=observation.to_features(),
)
report = attach_aer_admission_metadata(report, admission)
register_v1_1_schema()
validate_report(report)
path = save_geometry_neutral_replay_report(report, "validation/reports/replay.json")
loaded = load_geometry_neutral_replay_report(path)
assert loaded == report
For existing v1 reports:
Runtime and benchmark impact¶
The v1.1 AER admission change is metadata admission, digest binding, and schema validation. It does not change the control loop, Rust data plane, solver hot path, transport layer, or replay numerics. No new performance benchmark is required for this schema lane. If a future change wires these fields into runtime scheduling, capacitor-bank control, AER transport egress, FRC state estimation, or actuator commands, the matching Python/Rust/PyO3 benchmarks must be rerun and documented with the hardware context.
Claim boundary¶
A geometry-neutral replay report is repository evidence for deterministic scenario replay. It is not a measured-shot cross-validation, public P-EFIT admission, HIL campaign, real-time PCS certification, or facility safety case. Those claims remain blocked until their own artefacts are produced, digested, reviewed, and admitted.