Skip to content

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 03:06
· 167 commits to main since this release

Fixed

  • Public NumPy, JAX, Julia, and Rust-backed UPDE/coupling boundaries now reject
    boolean, complex, numeric-string, malformed-cardinality, and non-finite
    payloads before conversion or publication while preserving valid real numeric
    object arrays.
  • Runtime twin and server metadata now preserve backend output contracts and
    report the installed package version instead of a stale hard-coded value.
  • Public documentation now matches the installed CLI and API, distinguishes
    simulation and review evidence from deployment validation, and removes
    unsupported latency, lead-time, certification, novelty, and market claims.
  • spo quickstart evidence now reads its sealed ISO-NE record from package data,
    so the README's zero-download pip install path works from an installed wheel
    rather than requiring a repository checkout. A byte-for-byte drift guard keeps
    the packaged record identical to the canonical evidence under examples/.

Added

  • Executable guards now validate the public learning inventory, documented CLI
    commands/options, release/version statements, capability claims, and
    evidence-boundary language.
  • The public architecture reference, role-based onboarding routes, tutorial/API
    navigation, and notebook execution inventory now form one discoverable and
    strictly built documentation path.
  • scpn_phase_orchestrator.meta.leave_one_domain_out: a leave-one-domain-out
    cross-domain transfer sweep. leave_one_domain_out_transfer() holds out each
    domain in turn, transfers the pooled remainder onto it via the honest
    audit_cross_domain_transfer calibration, and aggregates the per-fold verdicts
    under a rule that never upgrades: a single domain that is detectable
    within-domain yet receives no transfer skill refutes generality decisively
    (lodo_negative, the shape the recorded CHB-MIT cross-subject negative must
    produce), only an unbroken sweep of positive folds earns lodo_generalises, a
    sweep with no detectable target is lodo_untestable, and anything in between is
    lodo_inconclusive. Every arm is scored by the caller, so the sweep stays a
    pure deterministic aggregation with no hidden training step. Any positive
    domain-general claim from the harness remains CEO-gated.
  • CausalInterventionEngine now supports layer-scoped counterfactual
    interventions via an optional layer_membership mapping. A do(K, layer_<name>)
    action perturbs the within-layer coupling sub-block; layer_<name>.incident
    perturbs every coupling incident to a layer member (the set generalisation of
    the oscillator_ scope). The full scope string is preserved in the audit
    record so which semantics applied is always recoverable, and a layer-scoped
    action is rejected when no membership is declared, the layer is unknown, or the
    mode is not within/incident.
  • scpn_phase_orchestrator.monitor.conformal_alarm.ConformalAlarmStream: extends
    the split-conformal calibration of the twin-confidence gate to early-warning
    alarm streams. It learns an alarm threshold from a trusted nominal score window
    so the false-alarm rate on exchangeable nominal operation is bounded by a
    configured target (the conformal alpha), flags alarms on a live stream,
    reports the running empirical false-alarm rate over nominal ticks, and can
    adapt online by Adaptive Conformal Inference under drift (consuming only
    nominal ticks). The guarantee is the marginal split-conformal one; it makes no
    claim about detection power.
  • scpn_phase_orchestrator.runtime.stl_audit_chain: seals STLTraceResult
    verdicts into the SHA-256 hash-chained audit event stream and replays them.
    write_stl_results() / append_stl_result() write each STL verdict as a
    stl.trace_result event; read_stl_results() verifies the stream's payload
    digests, sequence continuity, hash chain, and signatures before reconstructing
    the records, so STL evidence is recovered from a tamper-evident log rather than
    trusted in memory. A bounded STL operator over a window past the trace end
    yields a vacuous ±inf robustness, which the JSON-backed stream cannot encode;
    this is rejected at the sealing boundary rather than silently coerced.
  • The builtin STLMonitor robustness backend now evaluates the bounded
    temporal operators always[a,b] and eventually[a,b] (integer discrete step
    window, 0 <= a <= b) over a conjunction of atomic predicates, so common
    bounded safety and liveness forms no longer require the optional rtamt
    dependency. The bounded reduction restricts the pointwise robustness to the
    window at the initial time, clamped to the trace end, and returns exactly what
    rtamt reports at time zero (a window past the trace end is a vacuous
    quantifier: +inf for always, -inf for eventually). until, nested
    temporal operators, and other syntax continue to route to rtamt and raise a
    clear ImportError when it is absent.
  • scpn_phase_orchestrator.monitor.stl.PHASE_FIELD_SPECIFICATIONS: a curated
    catalogue of named single-signal STL safety properties for Kuramoto-type
    phase fields — an order-parameter floor, a coupling-gain ceiling, a
    chimera-index ceiling, a Sakaguchi phase-lag bound, and a winding-stability
    bound. Each PhaseFieldSpecification renders a builtin-compatible STL formula
    (so it evaluates without rtamt) and carries a physical rationale and a
    soft/hard severity tier; the thresholds are documented engineering
    defaults, not empirically fitted constants. Look one up with
    phase_field_specification() and list the keys with
    phase_field_specification_names().
  • scpn_phase_orchestrator.nn.solve_ude_adjoint: a continuous-time adjoint
    integrator for the UDE-Kuramoto vector field built on diffrax. It replaces
    the memory-heavy explicit-Euler jax.lax.scan roll-out (which stores every
    step) with an adaptive solver (diffrax.Tsit5 by default) under a
    configurable adjoint — RecursiveCheckpointAdjoint for logarithmic
    checkpointing or BacksolveAdjoint for O(1)-memory reverse-mode gradients.
    Integration runs on the unwrapped phase (the coupling is 2*pi-periodic so
    the field is wrap-invariant, while an adaptive solver must not see the
    % 2*pi discontinuities the Euler map introduces); wrapping is applied once,
    to the returned states. The solver never mutates the global jax_enable_x64
    flag, so callers keep the float32 default of the rest of nn. Requires the
    diffrax dependency (the nn, jax, or full extra).
  • UDEKuramotoLayer.forward_with_trajectory and nn.trajectory_loss now accept
    backend="euler"|"diffrax". "euler" stays the default and calls the exact
    reproducible explicit roll-out unchanged (trajectory hashes and every existing
    layer keep working); "diffrax" routes the trajectory through
    solve_ude_adjoint, sampling the same n_steps grid so trajectory_loss
    trains the UDE layer through the checkpointed continuous adjoint at
    O(1)-memory gradient cost. The backend is validated outside the compiled
    region, so an invalid value fails fast with a plain error.
  • The nn and jax install extras now include diffrax>=0.5,<1.0, so the
    advertised Neural-ODE path (solve_ude_adjoint, backend="diffrax") is
    installable via pip install scpn-phase-orchestrator[nn] rather than only the
    full extra. solve_ude_adjoint gains a throw stiffness guard: a solve that
    exhausts max_steps raises by default rather than returning a silent
    non-finite result; throw=False recovers the incomplete solution for
    inspection.
  • scpn_phase_orchestrator.adapters.C37118SessionClient, build_command_frame,
    and read_frame: a live asynchronous IEEE C37.118.2 session client that reads
    synchrophasor frames from a PDC/PMU over TCP using only the standard library's
    asyncio (no new dependency). It issues the standard command frames (request
    CONFIG-2, data on, data off) — a benign protocol handshake that controls only
    the data stream and never actuates grid equipment (non_actuating) — and
    delegates decoding to SynchrophasorFrameCodec. The command-word values were
    verified at source against the pypmu CommandFrame table and the Wireshark
    synchrophasor dissector (standard Table 15).
  • scpn_phase_orchestrator.adapters.C37118PhaseBridge and PhasorBinding: a
    review-only bridge mapping decoded IEEE C37.118.2 PMU phasors to oscillator
    PhaseStates. A PMU phasor is already phase-resolved, so the bridge reads the
    angle directly (theta = rectangular atan2(imag, real) or floating-point
    polar angle) rather than running a waveform extractor; omega = 2*pi times
    the measured frequency, amplitude = the phasor magnitude in engineering
    units (integer components scaled by the PHUNIT factor now decoded by the
    codec), and quality derives from the STAT data-error/sync bits. Integer
    polar phasors raise rather than emit a fabricated angle. The bridge is
    non_actuating / execution_disabled.
  • SynchrophasorFrameCodec now decodes the per-phasor PHUNIT conversion factors
    into PmuConfiguration.phasor_units (a tuple of PhasorUnit), so integer
    phasor magnitudes can be scaled to engineering units.
  • scpn_phase_orchestrator.adapters.SynchrophasorFrameCodec and
    data_frames_to_frequency_series: a dependency-free decoder for IEEE
    C37.118.2-2011 synchrophasor CONFIG-2 and DATA frames from raw bytes (no
    network I/O). It recovers each PMU's measurement layout and decodes phasor,
    frequency (deviation from nominal — millihertz for the integer FORMAT, hertz
    for float), and analog/digital measurements, CRC-CCITT-validating every frame
    and raising a typed SynchrophasorFrameError subclass on malformed input.
    data_frames_to_frequency_series emits a (time_s, frequency_hz) series in
    the layout the PMU ringdown screener consumes, so a decoded stream feeds the
    existing hash-sealed ringdown evidence path. The byte layout and CRC
    parameters were cross-checked against the iicsys/pypmu and
    marsolla/Open-C37.118 reference implementations.
  • scpn_phase_orchestrator.adapters.to_nir_graph and NeuromorphicIRGraph: a
    dependency-free, deterministic, SHA-256-hashed export of a schedule's LIF
    populations and projections into a graph shaped like the Neuromorphic
    Intermediate Representation (neuromorphs/NIR). It is an honestly-labelled
    structural subset (conformance = "structural_subset") that carries only the
    LIF parameters the Abbott-rate model defines and lists the unmodelled NIR
    physical parameters (R, v_leak, v_reset) rather than fabricating them.
  • scpn_phase_orchestrator.adapters.check_openqasm3 and
    OpenQasm3ConformanceReport: a dependency-free structural conformance checker
    for OpenQASM 3 programs (version header, includes, qubit registers, custom
    gate declarations, and per-application parameter/qubit arity and register
    bounds). Its gate registry honestly separates the gates stdgates.inc defines
    from the two-qubit Pauli-rotation extensions (rxx/ryy/rzz/rzx) that
    Qiskit and PennyLane provide as builtins.

Changed

  • CausalAttribution now reports trajectory_consistency in place of the
    misleadingly named confidence. The old value was min(1, |score|/threshold)
    — a magnitude-over-threshold ratio that clamped to 1.0 for any clear effect
    and implied a statistical confidence the deterministic single-trajectory
    rollout cannot provide. The new field is the fraction of the rollout horizon
    over which the per-step order-parameter delta holds the attributed sign (or, for
    a neutral verdict, stays within the |delta| <= threshold band) — an honest
    measure of how steadily the intervention acts, with no sampling-distribution or
    p-value implied. Effect magnitude remains available in
    score/delta_R_final/delta_R_mean. The to_audit_record() key changes from
    confidence to trajectory_consistency accordingly; the four domainpack
    causal-attribution demos now surface honest sub-unity consistency (e.g. the
    cardiac weak-signal case reports ~0.42, previously masked as 1.0).
  • QuantumControlBridge.build_quantum_compiler_manifest now validates its
    emitted OpenQASM 3 text with check_openqasm3, adding an openqasm_conformance
    record to the manifest and a qasm_parse_ok flag to the co-simulation parity
    evidence.
  • SNNControllerBridge.build_neuromorphic_schedule_manifest now embeds a
    NIR-structural graph (neuromorphic_ir) and its nir_sha256 digest.
  • upde.gradient_knm_jax is reimplemented on a diffrax continuous adjoint. It
    integrates the Kuramoto-Sakaguchi field with an adaptive Tsit5 solver under a
    RecursiveCheckpointAdjoint and differentiates the sync cost through it, in
    place of the previous hand-rolled explicit-Euler fori_loop. The function no
    longer mutates the process-global jax_enable_x64 flag (the previous version
    silently upcast every JAX array in the session), and the # pragma: no cover
    is removed — the path is now exercised by a gradient-agreement test against the
    finite-difference reference (cos ≥ 0.999, O(dt) convergence measured) plus
    a regression lock that asserts the global x64 flag is untouched.