Reporting

June 22, 2026 · View on GitHub

Matplotlib-based visualisation for coherence analysis and phase dynamics. Requires the plot optional extra:

pip install scpn-phase-orchestrator[plot]

Purpose in operations

This is the production evidence surface for post-run understanding. CoherencePlot intentionally reads from the same audit records that operators and reviewers already use for compliance and replay, so every figure can be traced back to immutable records.

Use this API when:

  • you need trend evidence for safety gate review (coherence and regime trajectories),
  • you need a compact action audit before a change-control meeting,
  • or you need explainable outputs from a run that is already fully replayable.

The module is deterministic by construction: identical audit inputs produce identical plot assets and JSON summaries.

CoherencePlot

The reporting module provides a single class CoherencePlot that consumes JSONL audit log data and produces diagnostic figures.

CoherencePlot(log_data: list[dict])

The constructor accepts a list of parsed audit log records (from ReplayEngine.load() or direct JSON parsing). It filters to step records containing "step" and "layers" fields.

Available plots

MethodOutputDescription
plot_r_timeline(output_path)PNGPer-layer R over simulation steps
plot_regime_timeline(output_path)PNGRegime epochs as coloured horizontal bands
plot_action_audit(output_path)PNGR(t) with actuation event markers
plot_amplitude_timeline(output_path)PNGMean amplitude and subcritical fraction
plot_pac_heatmap(output_path)PNGPhase-amplitude coupling matrix

All methods return Path to the saved figure.

Regime colour conventions

RegimeColourHex
NOMINALGreen#2ecc71
DEGRADEDOrange#f39c12
CRITICALRed#e74c3c
RECOVERYBlue#3498db

Pipeline integration

AuditLogger.log_step() ──→ audit.jsonl


                       ReplayEngine.load()


                       CoherencePlot(log_data)

               ┌────────────────┼────────────────┐
               ↓                ↓                ↓
        plot_r_timeline  plot_regime_timeline  plot_action_audit
               │                │                │
               ↓                ↓                ↓
          r_timeline.png  regime.png        actions.png

The reporting module consumes audit log output. It does not connect to the engine directly — all data passes through the audit trail, ensuring that plots match the auditable record.

When the audit trail contains a run header, spo report --json-out includes the resolved binding_summary. N-channel runs also expose channel_algebra at the top level of the JSON report so downstream tools can read channel groups, derived channels, runtime evidence, and missing required channel evidence without re-parsing the binding spec.

The text report also prints a compact channel-algebra line when the audit header contains one, including required/optional/derived/delayed/uncertain counts and any missing required channel evidence.

If the audit stream includes passive integrated-information monitor records with monitor: integrated_information, the JSON summary includes an integrated_information block with latest Phi proxy values, normalised Phi values, series data, record count, and the claim boundary. The text report prints a compact line with the latest Phi proxy, normalised Phi, total integration, and number of monitor records.

Programmatic tools can use build_audit_report_summary() directly to get the same JSON-ready report payload as spo report --json-out.

Usage

from scpn_phase_orchestrator.runtime.replay import ReplayEngine
from scpn_phase_orchestrator.reporting.plots import CoherencePlot

# Load audit log
replay = ReplayEngine("audit.jsonl")
entries = replay.load()

# Generate diagnostic plots
plotter = CoherencePlot(entries)
plotter.plot_r_timeline("output/r_timeline.png")
plotter.plot_regime_timeline("output/regime.png")
plotter.plot_action_audit("output/actions.png")
plotter.plot_amplitude_timeline("output/amplitude.png")
plotter.plot_pac_heatmap("output/pac.png")

Internal extraction methods

MethodReturnsDescription
_extract_r_series(steps, n_layers, series)Per-layer R arrays
_extract_regime_epochs[(regime, start, end)]Regime change boundaries
_extract_actions(steps, r_global, knob_steps)Action event indices
_extract_amplitude(steps, amps, sub_frac)Amplitude time series
_extract_pac_matrix(n, matrix)PAC from last log record

::: scpn_phase_orchestrator.reporting.plots

Summary Builder

::: scpn_phase_orchestrator.reporting.summary

Explainability

Human-readable report helpers that translate audit and supervisor records into plain diagnostic summaries for notebooks, demos, and operator-facing reports.

::: scpn_phase_orchestrator.reporting.explainability

Operator copilot

reporting.operator_copilot turns an ExplainabilityReport into a grounded question-answering surface for a control-room operator. It renders the audit evidence — regime distribution, transitions, every control action with its recorded reason and evidence, the metric summary — into the prompt and instructs the language model to answer only from that evidence and to decline when it is silent, so the model explains and locates what the audit records rather than inventing control history or recommending actuation. The model is any provider with a complete(prompt) -> str method (a local HTTP model, or a deterministic stub for tests), so no network backend is required and the prompt is fully testable.

::: scpn_phase_orchestrator.reporting.operator_copilot