Pulsed-Shot FSM¶
MIF-004 implements the local, upstream-pending eight-state pulsed-shot lifecycle finite-state machine. The state graph is:
Each transition is guarded by plasma telemetry and capacitor-bank telemetry, and every transition is recorded as a timestamped audit entry.
Guards¶
| From | To | Guard |
|---|---|---|
idle |
ramp_up |
bank.energy_J >= min_precharge_energy_J |
ramp_up |
flat_top |
abs(plasma.coil_current_A) >= ramp_current_A |
flat_top |
burn |
phase error, spatial error, and burn temperature within thresholds |
burn |
expansion |
minimum burn dwell and fusion power threshold reached |
expansion |
dump |
radial expansion velocity threshold reached |
dump |
recharge |
bank energy is at or below dump floor |
recharge |
cool_down |
bank voltage fraction reaches recharge threshold |
cool_down |
idle |
plasma temperature and coil current are below cool-down thresholds |
Timestamps must be non-negative and strictly increasing after the first sample.
Python API¶
pulsed_shot_fsm
¶
Eight-state pulsed-shot lifecycle finite-state machine for MIF-004.
ShotState
¶
Bases: StrEnum
Canonical pulsed-shot lifecycle states.
SchedulerAction
¶
Bases: StrEnum
Command action emitted for the active lifecycle state.
PulsedShotSpec(min_precharge_energy_J, ramp_current_A, phase_tolerance_rad, spatial_tolerance_m, burn_temperature_eV, min_fusion_power_W, expansion_velocity_m_s, dump_energy_floor_J, recharge_voltage_fraction, cooldown_temperature_eV, cooldown_current_A, min_burn_duration_s=0.0)
dataclass
¶
Guard thresholds for the pulsed-shot lifecycle.
__post_init__()
¶
Validate pulsed-shot FSM threshold parameters.
PlasmaState(coil_current_A, temperature_eV, phase_lock_error_rad, reference_error_m, fusion_power_W, radial_velocity_m_s)
dataclass
¶
Plasma telemetry consumed by lifecycle transition guards.
__post_init__()
¶
Validate plasma-state telemetry used by shot scheduling.
BankTelemetry(voltage_V, voltage_max_V, energy_J)
dataclass
¶
TransitionRecord(t_s, from_state, to_state, reason)
dataclass
¶
Single lifecycle transition audit entry.
to_json()
¶
Return the stable JSON-serialisable audit representation.
SchedulerCommand(t_s, state, action, reason, transition, dwell_s)
dataclass
¶
Command emitted by one lifecycle FSM step.
PulsedShotFSM(spec)
¶
Eight-state pulsed-shot lifecycle finite-state machine.
audit_log
property
¶
Return immutable transition audit entries.
reset()
¶
Return to idle and clear timestamp and audit state.
transition_to(next_state, t_s, reason)
¶
Perform a validated manual adjacent transition.
step(t_s, plasma, bank)
¶
Evaluate lifecycle guards at t_s and emit the active-state command.
audit_log_jsonl()
¶
Return the transition audit log as newline-delimited JSON.
Dispatch¶
Use scpn_mif_core.lifecycle.dispatched_pulsed_shot_fsm(...) for the fastest
available measured runtime backend:
The pure Python PulsedShotFSM remains available for deterministic debugging
and tests. The Lean surface proves adjacency determinism, absence of
self-looping adjacent transitions, and the minimal eight-step cycle; it is not
a runtime benchmark backend.
Acceptance¶
The committed acceptance campaign traverses all eight states in order, verifies strictly increasing audit timestamps, checks JSONL audit serialisation, rejects duplicate or backwards timestamps, rejects non-adjacent manual transitions, and verifies that flat-top waits when either phase or spatial lock is missing. Additional guard tests cover low precharge energy, minimum burn dwell, and dump-floor energy holds.
Python/Rust parity tests cover the full state sequence and the Rust-backed
dispatch path. Lean builds SCPNMIF.PulsedShot.eight_step_cycle,
SCPNMIF.PulsedShot.adjacent_transition_deterministic, and
SCPNMIF.PulsedShot.idle_cycle_minimal.
Benchmarks¶
Measured on the local i5-11600K rig using Python 3.12.3 and Rust 1.85.0.
| Group | Backend | Mean | Result |
|---|---|---|---|
campaign_8 |
Rust | 2.57 us | fastest |
campaign_8 |
Python | 19.68 us | 7.7x slower than Rust |
Raw summary: bench/results/pulsed_shot_fsm.json.
Ownership¶
SYNC-STATE: upstream-pending applies to all MIF-004 implementation surfaces.
SCPN-MIF-CORE owns the local pulsed-shot FSM until SCPN-CONTROL receives the
reusable pulsed_scenario_scheduler_v2 surface targeted for the 0.21.0 lane.