Skip to content

Changelog

[0.16.0] — 2026-03-13

Added

  • Phase 3 — Frontier physics (10 modules in core/):
  • gyrokinetic_transport.py — quasilinear TGLF-10 instability spectrum (ITG/TEM/ETG growth rates and mode identification from local plasma parameters)
  • ballooning_solver.py — second-order ODE eigenvalue solver in s-alpha geometry; binary-search marginal-stability finder; full stability diagram computation
  • current_diffusion.py — parallel current evolution PDE with neoclassical resistivity (Sauter-Angioni), ohmic heating, and bootstrap source
  • current_drive.py — ECCD, NBI, LHCD auxiliary current-drive models with absorption efficiency and radial deposition profiles
  • ntm_dynamics.py — modified Rutherford equation for neoclassical tearing modes (2/1, 3/2); ECCD stabilization factor; NTM controller with mode-tracking
  • rwm_feedback.py — resistive wall mode n=1 feedback with active coils, Galerkin gain computation, and passive-wall eigenvalue analysis
  • sawtooth.py — Porcelli-like trigger (shear at q=1), Kadomtsev reconnection crash model, density/energy conservation, SawtoothCycler with crash history
  • sol_model.py — two-point SOL model (upstream-to-target), Eich heat-flux width scaling (Goldston heuristic), sheath-limited and conduction-limited regimes
  • rzip_model.py — linearised tokamak vertical stability model (RZIp plant); eigenvalue-based growth rate; passive structure model
  • integrated_scenario.py — full integrated scenario simulator coupling transport, current diffusion, current drive, sawteeth, NTM, and SOL models; ships with ITER baseline, ITER hybrid, and NSTX-U preset scenarios
  • Phase 4 — Absolute control (10 modules in control/):
  • nmpc_controller.py — nonlinear MPC with SQP over 20-step horizon; state/input box constraints and slew-rate limits on Ip, beta_N, q95, li, Te, nbar
  • mu_synthesis.py — D-K iteration for structured robust control; D-scaling optimization minimising structured singular value mu; MuSynthesisController
  • realtime_efit.py — streaming equilibrium reconstruction from partial measurements; coil-current-to-psi mapping; sub-10ms latency target
  • gain_scheduled_controller.py — PID gains scheduled on operating regime (Ip, beta_N); automatic interpolation with hysteresis-aware regime detection
  • shape_controller.py — plasma shape feedback via divertor/shaping coils; boundary-geometry Jacobian; x-point and separatrix tracking
  • safe_rl_controller.py — PPO wrapper with MHD constraint checker; vetoes actions violating stability limits; Gymnasium-compatible
  • sliding_mode_vertical.py — sliding-mode controller for vertical stability; continuous control law with dead-band saturation; configurable sliding surface
  • scenario_scheduler.py — shot timeline manager for startup→ramp→flattop→ rampdown; actuator scheduling with power budgets; scipy.optimize trajectory
  • fault_tolerant_control.py — sensor/actuator fault detection via innovation monitoring; reduced-rank operation under faults; stuck-sensor reconstruction
  • control_benchmark_suite.py — standardised benchmark scenarios (step tracking, disturbance rejection, noise resilience) with JSON+Markdown report generation

Fixed

  • np.trapzscipy.integrate.trapezoid across all files (numpy 2.x compat)
  • Ballooning test hardened (alpha 0.9→1.5) for cross-platform robustness
  • 46 mypy errors fixed across 17 files (no-any-return, attr-defined, assignment)
  • scipy event function pattern refactored to class-based callable

Changed

  • 2,786 tests (178 files), 100% coverage, 26 CI jobs
  • Version bump: v0.15.0 → v0.16.0

[0.15.0] — 2026-03-11

Fixed

  • GS* stencil sign bug: east/west coefficients in Jacobi, SOR, multigrid, and JAX solvers had the 1/(2R·dR) sign swapped — implementing the cylindrical Laplacian (∂²ψ/∂R² + (1/R)∂ψ/∂R) instead of the correct GS* operator (∂²ψ/∂R² − (1/R)∂ψ/∂R). Python now matches Rust sor.rs. Verified via Solov'ev exact solution (< 1% error on 33×33 grid).
  • beta_N formula (TokamakEnv): replaced dimensionally incorrect sqrt(Ip) expression with Troyon scaling β_N = c·T/Ip, calibrated to ITER baseline
  • gain_margin_db misnomer: renamed to stability_margin_db (eigenvalue-based, not Bode gain margin); backward-compat alias retained
  • MPC docstring: states clearly this is gradient-based trajectory optimization, not Rawlings-Mayne MPC
  • Physics citations: Braginskii tau_eq, Martin L-H threshold, Troyon beta_N, Wesson q95 — all hardcoded constants now cite source
  • H-infinity Y Riccati tolerance: tightened from 1.0 to 0.01
  • IPB98(y,2) RMSE gate: tightened from 200% to 80%

Added

  • Solov'ev analytic equilibrium test (GS solver vs exact ψ)
  • Crank-Nicolson CN-vs-Euler convergence test and pure diffusion decay test
  • validate-rmse CLI command (full RMSE dashboard)
  • 16 analytic regression tests in test_p0_regression.py

Changed

  • 2,420 tests, 0 failures, 105 skipped
  • Version bump: v0.14.1 → v0.15.0

[0.14.1] — 2026-03-11

Fixed

  • Jacobi step: add 1/R toroidal stencil (was Cartesian Laplacian, affecting fallback solver path)
  • Vacuum field: multiply coil current by turns (was ignoring multi-turn coils)
  • JAX GS boundary: use ψ_bdry=0.0 Dirichlet BC (was reading corner value)
  • UPDE Rust fast-path: return "Psi_global" key (was "Psi", breaking downstream code when Rust backend active)
  • Green's function: divide by k² not k in toroidal formula
  • Bootstrap current: use minor radius a, not domain extent R_max−R_min
  • lyapunov_v docstring: range is [0, 2] not [0, 1]
  • Neural transport docstring: honest about MLP architecture (not full QLKNN-10D)

Added

  • 13 analytic regression tests (test_p0_regression.py): Jacobi toroidal stencil, vacuum field turns scaling, UPDE key parity, GS boundary conditions, 2-oscillator Kuramoto exponential convergence, sub/supercritical phase transition thresholds
  • tutorial-smoke CI job (tutorials 01, 04, 05)
  • [all] optional-dependency group in pyproject.toml

Changed

  • MG parity tolerance widened (Rust multigrid uses Cartesian smoother)
  • 2,417 tests, 99.99% coverage, 26 CI jobs

[0.14.0] — 2026-03-10

Added

  • PPO 500K cloud training on JarvisLabs RTX5000 (3 seeds x 500K timesteps)
  • PPO reward=143.7 beats MPC (58.1) and PID (-912.3), 0% disruption rate
  • Reproducible: 3 seeds yield consistent +-0.2 mean reward
  • Per-seed weights: ppo_tokamak_seed{42,123,456}.zip
  • Benchmark report: benchmarks/rl_vs_classical.json
  • Cloud training script: tools/train_rl_upcloud.sh (multi-seed, best-select)
  • JarvisLabs automation: tools/jarvislabs_train.py

[0.13.0] — 2026-03-10

Added

  • JAX-differentiable Grad-Shafranov solver (jax_gs_solver.py): full Picard iteration via jax.lax.fori_loop with damped Jacobi inner sweeps
  • jax.grad through the complete equilibrium solve — closes autodiff depth gap with TORAX (JAX) and FUSE (Julia AD)
  • jax_gs_solve() public API with NumPy fallback
  • jax_gs_grad_Ip() convenience function for d(psi)/d(Ip) gradient
  • 20 JAX GS tests: NumPy parity, boundary conditions, symmetry, autodiff (finite, nonzero, sign, beta_mix, finite-difference agreement)
  • examples/quickstart.py — 30-second Python demo (equilibrium + transport + SNN compile + autodiff)
  • README "Python in 30 Seconds" quickstart block

Changed

  • TokamakEnv reward: added survival bonus, progress shaping (Ng et al. 1999), increased disruption penalty — improves PPO learning speed
  • JOSS paper updated: 57 modules, ~22,900 LOC, 2,201 tests, JAX GS mention
  • Competitive analysis: equilibrium autodiff depth marked RESOLVED (5/6 gaps closed)

[0.12.0] — 2026-03-10

Added

  • QLKNN-10D trained neural transport model: 3-layer MLP (10→128→64→3) trained on synthetic critical-gradient data (5000 samples, van de Plassche et al. 2020 paradigm)
  • Training script tools/train_neural_transport_qlknn.py with --synthetic CI mode and --data-dir for real Zenodo dataset
  • Auto-discovery: NeuralTransportModel() loads weights from weights/ if present
  • PPO agent on TokamakEnv via stable-baselines3 (tools/train_rl_tokamak.py)
  • Gymnasium-compatible GymTokamakEnv wrapper with proper spaces.Box definitions
  • PID and 1-step MPC baseline controllers for comparison
  • RL vs classical benchmark (benchmarks/rl_vs_classical.py): PPO vs PID vs MPC
  • [rl] optional dependency group (stable-baselines3, gymnasium)
  • 20 QLKNN tests + 14 RL tests (weight loading, inference, training E2E, benchmark)

Fixed

  • NumPy 2.x deprecation: int(data["version"])int(data["version"].item())
  • TokamakEnv q95 formula: added elongation factor (q95 ≈ 3.0 at 15 MA, was 1.77)

[0.11.0] — 2026-03-10

Added

  • JAX-accelerated neural equilibrium (scpn_control.core.jax_neural_equilibrium): JIT-compiled PCA + MLP surrogate for Grad-Shafranov equilibrium with GPU dispatch, jax.grad for adjoint-based shape optimization, and jax.vmap batch inference
  • 13 new tests: JAX/NumPy parity, autodiff gradients, batched vmap, weight conversion
  • JAX neural equilibrium tests added to jax-parity CI job

[0.10.0] — 2026-03-10

Added

  • JAX-accelerated transport primitives (scpn_control.core.jax_solvers): Thomas tridiagonal solver, Crank-Nicolson diffusion operator, and batched transport via jax.vmap — all JIT-compiled, GPU-compatible, and differentiable via jax.grad for sensitivity analysis
  • Real DIII-D shot validation (tests/test_real_diiid_shots.py): 95 tests validating data integrity, physical ranges, disruption labels, phase-sync pipeline handling, and disruption-precursor feature extraction against 17 real DIII-D disruption shots (H-mode, VDE, beta-limit, locked-mode, density-limit, tearing, snowflake, negative-delta, high-beta)
  • CI Job: real-diiid — validates against real DIII-D shot data (25 CI jobs total)
  • CI: JAX solver parity tests added to jax-parity job
  • JOSS paper (paper.md, paper.bib): submission-ready for Journal of Open Source Software review
  • API docs: JAX transport primitives added to docs/api.md

[0.9.0] — 2026-03-10

Added

  • py.typed PEP 561 marker for downstream IDE type inference
  • [jax] optional dependency group (jax>=0.4.20, jaxlib>=0.4.20)
  • [loihi] optional dependency group (nengo>=4.0, nengo-loihi>=1.0)
  • CI Job 16: JAX backend parity (jax-parity) — validates jax_traceable_runtime.py
  • CI Job 17: Nengo Loihi test (nengo-loihi) — validates nengo_snn_wrapper.py
  • CI: Windows and macOS runners in python-tests matrix (Python 3.12)
  • API docs: 16 previously undocumented modules added to docs/api.md (neural_equilibrium, neural_transport, stability_mhd, hpc_bridge, adaptive_knm, plasma_knm, analytic_solver, bio_holonomic, digital_twin_ingest, director_interface, fueling_mode, halo_re, hil_harness, jax_traceable, neuro_cybernetic, torax_hybrid_loop)
  • VALIDATION.md: RMSE regression threshold table with sources

Changed

  • mypy: disallow_untyped_defs = true, warn_return_any = true across all 54 modules (134 annotations added)
  • mypy: files simplified to ["src/scpn_control/"] (full package)
  • Codecov: fail_ci_if_error: true (was false with TODO)
  • Removed black from dev extras (redundant with ruff-format)
  • Cleaned 49 unused imports across 30+ test files (ruff auto-fix)
  • U-002 (Nengo Loihi) marked RESOLVED
  • U-006 (JAX CI) marked RESOLVED
  • All 7 UNDERDEVELOPED_REGISTER items now RESOLVED

[0.8.1] — 2026-03-10

Added

  • Rust H-inf: Padé(6,6) scaling-and-squaring matrix_exp replacing Euler discretization
  • Rust H-inf: zoh_discretize matching Python _zoh_discretize (exact ZOH via matrix exponential)
  • 6 new Rust tests for matrix_exp + ZOH (diagonal, nilpotent, large-norm, Euler agreement)
  • benchmarks/e2e_control_latency.py — honest E2E pipeline benchmark (sensor→equilibrium→transport→control→actuator)

Changed

  • README, pitch.md, use_cases.md, VALIDATION.md, competitive_analysis.md: honesty sweep
  • "formal verification" → "contract-based checking"
  • "DIII-D shot replay" → stated as synthetic mock data
  • Comparison table: kernel step ≠ full control cycle caveat
  • VALIDATION.md: Scope & Limitations table, "What does NOT exist" list
  • use_cases.md: added "Real tokamak data" and "Peer-reviewed papers" rows (both No)
  • U-001 marked RESOLVED in UNDERDEVELOPED_REGISTER
  • Stale doc counts: 2019 tests, 118 files, 54 modules

[0.8.0] — 2026-03-09

Added

  • Python fallback for rust_svd_optimal_correction(): truncated SVD pseudoinverse with singular-value cutoff (_python_svd_optimal_correction)
  • Python fallback for RustSPIMitigation: 3-phase disruption sim matching Rust spi.rs constants (Assimilation → ThermalQuench → CurrentQuench)
  • Python fallback for rust_multigrid_vcycle(): delegates to FusionKernel._multigrid_vcycle with isolated instance
  • require_bounded_float validator: arbitrary inclusive/exclusive bound checks
  • require_finite_array validator: ndim/shape constraints + finiteness
  • tests/test_rust_fallbacks.py — 16 tests (SVD, SPI, multigrid fallbacks)
  • Input validation on RustSPIMitigation.__init__() for both Rust and Python paths

Changed

  • h_infinity_controller.py: inline np.isfinite checks replaced with shared validators
  • disruption_predictor.py: 7 inline checks replaced with shared validators
  • advanced_soc_fusion_learning.py: 8 inline checks replaced with shared validators
  • U-003, U-004, U-005 marked RESOLVED in UNDERDEVELOPED_REGISTER
  • U-007 marked RESOLVED (shared validators in place, P1 modules converted)

[0.7.1] — 2026-03-09

Added

  • Enterprise root files: SUPPORT.md, GOVERNANCE.md, CONTRIBUTORS.md, NOTICE.md, ARCHITECTURE.md, VALIDATION.md, REUSE.toml, .gitattributes, .dockerignore, Makefile, requirements-dev.txt
  • Workflows: pre-commit.yml, codeql.yml, scorecard.yml, release.yml, stale.yml
  • .github/ISSUE_TEMPLATE/config.yml (Security Advisories + SUPPORT.md links)
  • _typos.toml domain allowlist (46 terms: physics, plasma, Rust identifiers)
  • 17 GitHub labels (dependencies, ci, security, performance, plasma-control, etc.)

Changed

  • ci.yml, docs-pages.yml, publish-pypi.yml: SHA-pinned all actions, permissions: {}, concurrency groups, SPDX headers
  • pyproject.toml: ruff UP/SIM rules, coverage exclude_lines, dev deps added
  • .pre-commit-config.yaml: check-toml + crate-ci/typos hooks
  • dependabot.yml: commit-message prefixes, dependency groups
  • FUNDING.yml: github sponsor link
  • SECURITY.md: Security Advisories as preferred reporting method
  • scorecard-action bumped v2.4.0 → v2.4.3
  • black bumped 25.1.0 → 25.11.0

Repository

  • Squash-only merge, delete-branch-on-merge, discussions enabled
  • 10 topic tags, homepage set to GH Pages docs URL
  • Dependabot PR triage: 1 merged (#21 black), 4 closed (incompatible Cargo bumps)

[0.7.0] — 2026-03-02

Added

  • tests/test_nengo_snn_wrapper.py — 14 mocked tests for the only untested module (389 LOC)
  • tests/test_e2e_compile_to_control.py — 5 E2E integration tests (compile → artifact → controller → step)
  • require_range validator in core/_validators.py
  • /// doc comments on 11 public Rust functions (mpi_domain.rs, vmec_interface.rs)
  • keywords and categories in all 5 Rust Cargo.toml files
  • Paper 27 Reviewer Integration page in mkdocs nav

Fixed

  • Public API typo: TokamakTopoloyTokamakTopology (deprecated alias retained)
  • print()logging in 13 control modules (58 call sites total)
  • Remaining Union[str, Path]str | Path in 3 files (eqdsk.py, realtime_monitor.py, artifact.py)
  • CLI hardcoded module/test counts → dynamic Path.rglob computation
  • Magic number b0=5.3 → named constant ITER_B0_VACUUM_T with citation
  • Stale doc counts across README, architecture, pitch, use_cases, CONTRIBUTING (53 modules, 115 files, 1969 tests, 15 CI)
  • Dead grid_index() function removed from Rust gmres.rs

Changed

  • Coverage gate ratcheted: fail_under = 6285
  • from __future__ import annotations added to core/__init__.py and scpn/__init__.py
  • 4 duplicate validators in halo_re_physics.py replaced with core._validators imports
  • ROADMAP.md rewritten: v0.6.0 moved to Shipped, unshipped items to v0.7.0+
  • 12 additional tests across 5 thin test files

[0.6.0] — 2026-03-02

Added

  • .editorconfig and .github/CODEOWNERS
  • Copyright headers on all 3 CI workflow files
  • repository field in all 5 Rust Cargo.toml files
  • tests/test_validators.py — 49 parametrized tests for core/_validators.py
  • tests/test_phase_properties_extended.py — 14 Hypothesis property tests (knm, upde, adaptive_knm)
  • Paper 27 citations on OMEGA_N_16 and build_knm_paper27 constants

Fixed

  • .zenodo.json license "MIT""AGPL-3.0-or-later" (matches pyproject.toml)
  • docs/api.md version stuck at "0.5.0""0.6.0"
  • print()logger.info() in spi_mitigation.py (3 sites)
  • Anti-slop: renamed unused param proposed_action_proposed_action, deleted 4 narration comments in cli.py
  • Flaky timing test: absolute 5s threshold → relative warmup baseline
  • Dead DEFAULT_GAIN constant removed from Rust optimal.rs

Changed

  • Typing modernization: from __future__ import annotations + Optional[X]X | None in 21 files
  • Shared test fixtures extracted to conftest.py (3 controller test files deduplicated)
  • pyproject.toml keywords + author email added

[0.5.2] — 2026-03-02

Fixed

  • Codecov fail_ci_if_error: falsetrue (matches v0.5.0 CHANGELOG claim)
  • Stale doc counts: architecture.md (17→21 modules, 1243→~1900 tests), pitch.md, use_cases.md
  • Bug report template version placeholder 0.3.0 → 0.5.x
  • Development.md release example v0.2.1 → vX.Y.Z
  • Magic number citations: ITER Physics Basis for SHOT_DURATION, TARGET_R, TARGET_Z, u_max
  • Anti-slop: "leveraging" → "using" (nengo), narration → TMR median voter (hil), dead pass block (eqdsk)

Changed

  • docs/changelog.md synced with root CHANGELOG (was frozen at v0.3.3)
  • ROADMAP.md rewritten for v0.5.x shipped state
  • require_non_negative_float added to core/_validators.py; scaling_laws and spi_mitigation use shared validators
  • control/__init__.__all__ includes normalize_bounds
  • Legacy typing imports replaced in 7 files (phase/ + scpn/): Optional→|None, List→list, Dict→dict, Tuple→tuple

[0.5.1] — 2026-03-02

Fixed

  • CITATION.cff DOI description said v0.4.0 (now v0.5.0)
  • docs/api.md version string stuck at 0.3.3 (now 0.5.0)
  • CONTRIBUTING.md stale test count (1243→~1900), coverage (50→62%), CI jobs (17→16)
  • docs/development.md stale coverage (55→62%) and release process (no longer uses __init__.py)
  • Two "Approximate" comments cleaned per anti-slop rule #4

Changed

  • require_int deduplicated: canonical core/_validators.py replaces 3 copies
  • deny.toml wildcards: "allow" → "deny"
  • Pre-commit: added check-merge-conflict, detect-private-key hooks
  • Paper 27 phase dynamics page added to mkdocs nav

Added

  • SECURITY.md responsible disclosure policy
  • CODE_OF_CONDUCT.md (Contributor Covenant v2.1)
  • U-007 in UNDERDEVELOPED_REGISTER (np.isfinite boilerplate)
  • GitHub issues gh-13, gh-14, gh-15 for U-003/004/005 Rust fallback gaps

[0.5.0] — 2026-03-02

Fixed

  • __version__ now derived from package metadata (PEP 621), was stuck at 0.3.3
  • Rust H-inf update_discretization TODO tracked as gh-10, param renamed _dtdt
  • README test/CI job counts updated to actual values

Added

  • 27 new tests: 9 Rust (h_infinity, xpoint, bfield, chebyshev) + 18 Python (rust_compat_wrapper)
  • cargo-deny supply-chain policy (deny.toml) + CI Job 15
  • ruff format --check CI gate + pre-commit hook
  • UNDERDEVELOPED_REGISTER.md tracking 6 known gaps
  • Python 3.13 in CI matrix

Changed

  • Coverage gate: 55% → 62% (actual: 93%)
  • Codecov fail_ci_if_error: true
  • Pre-commit: Rust hooks no longer gated to stages: [manual]
  • Removed unused proptest dev-dependency from 3 Cargo.toml files

[0.4.0] — 2026-03-01

Added

  • Real-time adaptive Knm engine driven by tokamak diagnostics (AdaptiveKnmEngine, DiagnosticSnapshot, AdaptiveKnmConfig)
  • Five adaptation channels: beta scaling, MHD risk amplification, coherence PI control, per-element rate limiting, Lyapunov guard veto
  • K_override parameter on UPDESystem.step(), .run(), .run_lyapunov()
  • RealtimeMonitor.from_plasma() constructor with adaptive engine support
  • Diagnostic kwargs (beta_n, q95, disruption_risk, mirnov_rms) on tick()
  • 46 new tests (1888 total)

Changed

  • .zenodo.json: complete Zenodo metadata (related identifiers, communities, notes)
  • CITATION.cff: version bump, date update

[0.3.3] — 2026-02-27

Changed

  • License: AGPL-3.0 → AGPL-3.0-or-later dual (137 files, zero AGPL remaining)
  • README: pip install -e "."pip install scpn-control (PyPI install path)
  • CONTRIBUTING: CI job count 14 → 17

[0.3.2] — 2026-02-27

Added

  • VectorizedSCLayer + Rust backend path in SNN compiler (512× real-time)
  • Two-tier import: v3.8.0+ preferred → legacy bit-ops → numpy float fallback
  • Test for v3.8 detection and VectorizedSCLayer forward-path benchmark
  • sc-neurocore listed first in optional deps table (crown jewel)

Changed

  • README: engine callout and dep table updated for sc-neurocore

[0.3.0] — 2026-02-27

Added

  • Ruff linter (E/F/W/I/B rules) — CI job + pyproject.toml config
  • Property-based tests for phase/ module (Hypothesis, 11 properties)
  • Gymnasium-compatible TokamakEnv (control/gym_tokamak_env.py, 10 tests)
  • IMAS/OMAS equilibrium adapter (core/imas_adapter.py)
  • CLI scpn-control info command (version, Rust status, weights, Python/NumPy)
  • Weight provenance manifest (reproduction commands, hardware, training config)
  • Paper 27 + H-infinity notebooks in CI smoke tests

Fixed

  • API docs: wrong snapshot keys (R→R_global, V→V_global, lambda→lambda_exp)
  • API docs: wrong UPDESystem constructor and LyapunovGuard API examples
  • README/CHANGELOG: "14 CI jobs" → actual count, test counts updated
  • _rust_compat.py: calculate_thermodynamics/vacuum_field now delegate to Python
  • 163 ruff auto-fixes (whitespace, import sorting, unused imports)
  • 26 manual ruff fixes (raise-from, unused variables, one-liners, E402)
  • Bandit now fails on medium+ severity (was --exit-zero)
  • TeX build artifacts (.aux/.log/.out/.toc) excluded from repo

Changed

  • Coverage threshold raised from 50% → 55% (actual: 61%)
  • CI: 12 → 13 jobs (added python-lint)
  • Test suite: 680 → 701 tests (50 test files)

[0.2.0] — 2026-02-26

Added

  • Paper 27 phase dynamics engine (src/scpn_control/phase/, 7 modules)
  • Kuramoto-Sakaguchi step with global field driver (kuramoto.py)
  • 16x16 Knm coupling matrix builder with calibration anchors (knm.py)
  • UPDE multi-layer solver with PAC gating (upde.py)
  • LyapunovGuard sliding-window stability monitor (lyapunov_guard.py)
  • RealtimeMonitor tick-by-tick UPDE + trajectory recorder (realtime_monitor.py)
  • PhaseStreamServer async WebSocket live stream (ws_phase_stream.py)
  • CLI scpn-control live command for real-time WS phase sync server
  • Streamlit WS client (examples/streamlit_ws_client.py)
  • Streamlit Cloud deployment (streamlit_app.py, .streamlit/config.toml)
  • Mock DIII-D shot generator (tests/mock_diiid.py)
  • E2E phase sync with shot data tests (tests/test_e2e_phase_diiid.py)
  • Phase sync convergence video (MP4 + GIF) and generator script
  • PyPI publish script (tools/publish.py)
  • Rust upde_tick() in control-math + PyRealtimeMonitor PyO3 binding

Changed

  • CI expanded from 6 to 12 jobs
  • Test suite expanded from 482 to 680 tests (680 passing, 94 skipped)
  • README updated with <video> MP4 embed, Streamlit Cloud badge
  • .gitignore updated to allow docs GIF/PNG and Streamlit config

[0.1.0] — 2026-02-19

Added

  • Initial extraction from scpn-fusion-core v3.4.0
  • 41 Python source files (minimal control transitive closure)
  • 5 Rust crates (control-types, control-math, control-core, control-control, control-python)
  • Slim PyO3 bindings (~474 LOC, control-only)
  • Clean __init__.py files (no matplotlib/GPU/ML import bombs)
  • Click CLI with 4 commands (demo, benchmark, validate, hil-test)
  • Streamlit dashboard (optional, [dashboard] extra)
  • CI workflow (6 jobs: python-tests, rmse-gate, rust-tests, rust-python-interop, rust-benchmarks, rust-audit)
  • 37 test files (482 passing, 122 skipped, 0 failures)
  • 16 disruption shot reference data files
  • 8 SPARC EFIT equilibria
  • 3 pretrained weight files
  • Validation scripts and tools
  • Stochastic Petri Net logic map header (docs/scpn_control_header.png)

Changed (vs scpn-fusion-core)

  • Required deps: numpy, scipy, click ONLY (was: numpy, scipy, matplotlib, streamlit)
  • matplotlib, streamlit, torch, nengo moved to optional extras
  • All imports renamed: scpn_fusion -> scpn_control, scpn_fusion_rs -> scpn_control_rs
  • Rust workspace reduced from 11 crates to 5
  • CI reduced from 13 jobs to 6
  • hpc_bridge.py relocated from hpc/ to core/ subpackage
  • Import guards added for excluded modules (stability_analyzer, global_design_scanner, imas_connector, diagnostics.forward, fusion_ignition_sim)