Skip to content

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 17 Jul 16:22
· 256 commits to main since this release

First stable release. The public Python API — the symbols exported from
scpn_phase_orchestrator.__all__ — is now covered by semantic-versioning
guarantees; future backward-incompatible changes to it will bump the major
version.

Added

  • The spo --version option, which reports the installed package version.
  • The full text of the GNU Affero General Public License v3
    (LICENSES/AGPL-3.0-or-later.txt), so the distribution conveys its licence in
    full alongside the grant notice in LICENSE.
  • A canonical Control Engineer onboarding notebook
    (notebooks/21_control_engineer_onboarding.ipynb): a ~15-minute guided golden
    path over the public Python API — validate a shipped binding spec, sweep the
    coupling strength to see the synchronisation transition (coherence R responds
    to the control knob), then audit and replay a run and verify its SHA-256
    hash-chain integrity and bit-exact determinism. Runs on the pure-Python path
    from a bare pip install scpn-phase-orchestrator; listed in the notebook
    execution matrix and the notebooks-and-demos gallery, and executed by the CI
    notebook suite.
  • A machine-readable validation_tier on every domainpack binding spec
    (scaffold, partial, or externally_validated; see VALID_VALIDATION_TIERS
    in binding.types), recording how much external evidence a binding scaffold
    carries — distinct from safety_tier (the deployment risk class). A binding is
    a reusable scaffold, not a validated detector, so scaffold is the honest
    default: the loader defaults an undeclared spec to it and the validator rejects
    any unknown tier. All 36 shipped domainpacks declare validation_tier: scaffold
    — none carries an independent end-to-end validation trail. The resolved binding
    summary surfaces the tier, and a new binding.gallery module
    (select_specs_by_validation_tier, group_specs_by_validation_tier) lets a
    Studio Hub filter or group packs by tier so a broad gallery is never mistaken
    for a broad set of validated solutions. Documented in the Domainpack validation
    tiers
    guide and the binding API reference; guarded by
    tests/test_binding_validation_tier.py and per-pack drift guards in
    tests/test_domainpack_validation.py.
  • A machine-readable monitor validation-status registry
    (monitor.validation_status) recording, per monitor family, how much external
    evidence it carries: EXTERNALLY_VALIDATED (external), SYNTHETIC_ONLY
    (synthetic-only), or RESEARCH (research). It restates the README
    §Evidence status verbatim in structured form — only the grid modal-growth
    detector and its streaming form are externally validated; the generic
    early-warning suite is synthetic-only; the remaining monitors are research. The
    package exports MonitorValidationStatus, MonitorValidationRecord,
    MONITOR_VALIDATION, validation_record, monitors_by_status, and
    validation_summary, documented in the Monitor validation status guide and
    API reference. A drift guard fails closed if a new public monitor module is left
    neither classified nor explicitly excluded, so the honest posture cannot rot.
    Guarded by tests/test_monitor_validation_status.py and
    tests/test_docs_monitor_validation_status.py.
  • A Module Federation studio remote under studio-web/ (Vite +
    @module-federation/vite) that builds remoteEntry.js for the SCPN Studio
    Hub. It exposes ./SpoStudioPanel, a pure renderer of the committed
    evidence-coverage snapshot — how each of SPO's six assurance evidence
    categories contributes to EU AI Act, ISO/IEC 42001 and ANSI/UL 4600 clauses,
    at the honest addressed / partially_addressed boundary; a malformed
    snapshot renders as a loud unverifiable block. The Python
    studio.federation_manifest now declares the remote through ui_module, a new
    studio.panel_data producer is the single source of truth for the snapshot
    (regenerated by tools/build_studio_panel_data.py, drift-guarded in CI), and a
    studio-web CI job typechecks, tests (100% coverage), and builds the remote.
  • assurance.build_twin_confidence_evidence maps a serialised
    TwinConfidenceScore into a twin_confidence evidence item, closing the one
    assurance-case evidence category that the clause map referenced but no producer
    emitted. The spo assurance-case / certification-evidence commands gain a
    repeatable --twin-confidence-file option that surfaces it for the
    drift-monitoring clauses (EU AI Act Articles 9/15/72, ISO/IEC 42001 Clause 9 /
    A.8, UL 4600 metrics-conformance). Guarded by
    tests/test_assurance_twin_confidence_evidence.py and
    tests/test_cli_assurance.py.
  • A control_envelope assurance evidence category and a run-derived
    control-safety-envelope evidence item. assurance.build_run_evidence now emits
    a run-control-envelope item (control mode, applied-action and
    boundary-violation totals, final regime) when a run record has the closed-loop
    policy feedback active, mapped to EU AI Act Articles 9/14/15, ISO/IEC 42001
    Clause 8, and UL 4600 safety-case/risk-analysis clauses. The
    spo assurance-case / certification-evidence --run-result path surfaces it
    automatically. Guarded by tests/test_assurance_run_evidence.py and
    tests/test_cli_assurance.py.
  • bench/honest_dataset_audit.py is a reusable honest-audit harness that
    generalises the CAP/Sleep-EDF audit pattern. It accepts a dataset manifest, a
    detector registry, and a domain-specific loader/label-extractor, then emits
    sealed audit records, per-recording summaries, an aggregate comparison JSON,
    and a data-driven recommendation. bench/cap_multichannel_n3_vs_wake.py is
    refactored to use the harness utilities (run_audit, compute_aggregate,
    write_aggregate, file_sha256) and still reproduces the committed CAP
    sealed-audit hashes exactly. Guarded by
    tests/test_honest_dataset_audit.py.
  • bench/synthetic_honest_audit_demo.py,
    docs/studies/synthetic_honest_audit_demo.md, and
    examples/real_data/synthetic_honest_audit_demo/ demonstrate the harness on a
    deterministic synthetic corpus (AR(1) events vs white-noise nulls). The
    autocorrelation detector beats chance at matched false-alarm 0.10 while the
    window-mean control does not, showing the harness generalises beyond sleep EEG.
    Guarded by tests/test_synthetic_honest_audit_demo_evidence.py.
  • bench/cap_multichannel_n3_vs_wake.py and
    docs/studies/cap_multichannel_n3_vs_wake.md extend the honest sleep-staging
    audit to a true multi-channel EEG corpus, the PhysioNet CAP Sleep Database.
    Three detectors — normalized delta-band Hilbert envelope (multi-channel mean),
    multi-channel delta-phase Kuramoto order parameter, and an SNR-weighted
    Kuramoto variant — are audited at the same matched false-alarm operating
    point (target_false_alarm = 0.10) on a four-recording panel (controls
    n1/n2, bruxism brux2, narcolepsy narco2). Sealed audit records,
    summaries, a manifest, an aggregate comparison JSON, and a data-driven
    detector recommendation are committed under
    examples/real_data/cap_multichannel_staging/ and guarded by
    tests/test_cap_multichannel_staging_evidence.py.
  • bench/cap_kuramoto_diagnostic.py and
    docs/studies/cap_kuramoto_diagnostic.md diagnose why the multi-channel
    delta-phase Kuramoto detector wins on n2 but under-performs on the other
    CAP recordings. Per-epoch signal properties (delta SNR, phase circular
    variance, artifact proxies, Kuramoto R statistics) are correlated with the
    detector gap; the committed cap_kuramoto_diagnostic.json recommends an
    SNR-weighted Kuramoto variant as the next refinement. Guarded by extended
    tests in tests/test_cap_multichannel_staging_evidence.py.
  • The recommended SNR-weighted delta-phase Kuramoto detector is implemented in
    bench/cap_multichannel_n3_vs_wake.py and honestly audited on the same CAP
    panel. The sqrt-softened per-epoch SNR weights do not improve over the simple
    mean-R Kuramoto detector (mean detection rate 0.175 vs 0.184 at matched
    false-alarm 0.10), so the aggregate recommendation is to stop refining this
    exact spatial-R feature and consider a different direction such as adaptive
    channel selection or temporal-stability criteria. The new artefacts and
    updated documentation are pinned by tests/test_cap_multichannel_staging_evidence.py.

Changed

  • Raised the supported Python floor to 3.11 — the versions CI actually exercises
    (3.11, 3.12, 3.13). The previously advertised but untested 3.10 support was
    removed from requires-python and the packaging classifiers.
  • Removed the REUSE-compliant README badge: the repository is not yet fully
    REUSE-compliant (reuse lint still reports uncovered files), so the claim was
    unearned. The full licence text is now shipped under LICENSES/ regardless.
  • spo doctor and the install guide now describe the PyPI-availability boundary
    honestly (external-validation finding E0.1). When the Rust backend is absent,
    the doctor previously advised "install the 'rust' extra (spo-kernel)", but
    spo-kernel is not on public PyPI (it is the project's own in-repo Rust
    acceleration), so an outsider could not follow that hint. The doctor now states
    that the acceleration is not on public PyPI — build it from the in-repo
    spo-kernel/ workspace with maturin or obtain the commercial wheel — and that
    the pure-Python path is used automatically. The Install Profiles guide gains a
    PyPI availability boundary section listing the three extras (rust, fusion,
    scpn-all) that depend on packages not on public PyPI, so the boundary is
    explicit rather than discovered at install time. A new
    tests/test_docs_install_profiles.py drift guard derives the private-backed
    extras from pyproject.toml and fails if the guide stops naming any of them.
  • The V&V report and testing guide now publish the measured coverage
    (94.34% line, 93.22% branch, from the CI coverage lanes) and the real gate — a
    per-domain no-decrease ratchet enforced by tools/coverage_guard.py — in
    place of the misleading "gated at 60%" framing, which was only the floor held
    during the dedicated-test-surface rebuild (audit finding SPO-G04). A new
    tests/test_docs_coverage_report.py drift guard ties the published floors to
    coverage_guard_thresholds.json / coverage_guard_branch_thresholds.json, so a
    raised ratchet forces the docs to be updated rather than silently going stale.
  • runtime.simulate now fails closed by default on a broken audit
    event-stream (audit finding SPO-T01). When the audit logger owns a protobuf
    event stream whose close-time integrity check fails, simulate raises
    AuditError instead of returning a result carrying an unenforced
    audit_event_stream_integrity field — a tampered or corrupted run can no longer
    return a green result. A normal run (whose freshly written stream always
    verifies) is unaffected; pass the new keyword strict_audit_integrity=False to
    restore the advisory-attach behaviour. Guarded by tests/test_simulation_core.py.