Binding System¶
The binding system connects domain-specific signals to SPO's universal oscillator framework. A binding specification (YAML file) declares the complete interface between a domain and the phase dynamics engine.
Pipeline position¶
The binding system is the configuration layer of the SPO pipeline. It is loaded once at startup and configures all downstream subsystems:
binding_spec.yaml
│
↓
load_binding_spec()
│
↓
validate_binding_spec()
│
↓
BindingSpec
├── layers[] ──→ Oscillator Extractors (P/I/S)
├── coupling ──→ CouplingBuilder.build()
├── policy ──→ PolicyEngine rules
└── actuators ──→ ActuationMapper mappings
Without a valid binding spec, SPO cannot start. The spec declares what to observe, how to couple, when to intervene, and where to actuate.
Role in the Architecture¶
The binding system is the first stage of the SPO pipeline:
Domain Data ─► binding_spec.yaml ─► Loader ─► Validator ─► BindingSpec
│
Oscillator Extractors
Coupling Templates
Policy Rules
Actuator Mappings
Every domainpack ships a binding specification. When SPO starts,
the loader reads the YAML, the validator checks it against the schema,
and the resulting BindingSpec configures all downstream subsystems.
Specification Structure¶
A binding spec declares:
name: power_grid
version: "1.0"
layers:
- name: generator_phase
channel: P
extractor: hilbert
frequency_range: [49.5, 50.5]
- name: load_demand
channel: I
extractor: event_rate
coupling:
template: distance_decay
K_base: 0.47
decay_alpha: 0.25
policy:
rules:
- condition: R < 0.6
action: boost_K(0.1)
actuators:
- name: governor
knob: K
scope: layer_0
limits: [0.0, 2.0]
The schema is defined in docs/specs/binding_spec.schema.json and
enforced by the validator at load time.
Resolved Runtime Summary¶
validate/inspect/run commands rely on a resolved summary that is
produced from the YAML and includes inferred defaults (for example
control_interval_steps and engine_mode). The full contract is documented in
Resolved Runtime Defaults and exposed as a CLI summary plus audit metadata.
The summary now embeds channel_algebra, so audit consumers can read required
channels, optional channels, derived channels, group membership, coupling
participants, and missing required channel evidence from the same resolved
configuration record.
resolved ¶
Deterministic summaries of binding runtime choices.
Resolved binding records expose timing, engine mode, layers, families, channels, driver key names, objectives, actuators, and optional feature flags for CLI output and audit headers. Raw driver configuration values are deliberately omitted because production bindings may include endpoints or deployment-local identifiers that should not be copied into public logs.
Classes¶
Functions:¶
resolved_binding_config ¶
Build a deterministic, JSON-safe summary of binding runtime choices.
The summary intentionally exposes structural choices, enabled features, and driver key names only. It does not copy raw driver configuration values into audit metadata because production driver blocks may contain endpoints or deployment-local identifiers.
Parameters¶
spec : BindingSpec The binding specification whose resolved runtime choices are summarised.
Returns¶
dict[str, object] Deterministic, JSON-safe mapping of structural choices, enabled features, and driver key names; raw driver values are excluded.
Source code in src/scpn_phase_orchestrator/binding/resolved.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
format_resolved_binding_config ¶
Render a compact, human-readable summary for CLI output.
Parameters¶
summary : dict[str, object]
A mapping produced by :func:resolved_binding_config.
Returns¶
list[str] Formatted output lines suitable for printing to a terminal.
Source code in src/scpn_phase_orchestrator/binding/resolved.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 | |
N-Channel Algebra Summary¶
build_channel_algebra_report() produces a deterministic, JSON-safe view of
declared channels, required/optional status, derived channels, group
membership, supervisor visibility, coupling participation, and cross-channel
edges. It is intended for audit, replay, and reporting surfaces that need a
channel-count-agnostic view without re-parsing YAML.
The same report classifies delayed and uncertain channels from existing
role, metric_semantics, and replay_semantics metadata. This lets audit and
reporting surfaces expose delayed/uncertain policy evidence without changing
the binding schema.
The report also emits runtime policy records for every declared channel.
Delayed channels use hold_last_runtime_evidence, uncertain channels use
confidence_weight_runtime_contribution, missing required channels use
block_required_channel, and missing optional channels use
drop_optional_channel. This gives supervisor/runtime callers deterministic
handling semantics without adding new binding-schema fields.
ChannelRuntimeExecutor applies those delayed and uncertain policies during
spo run. Delayed channels contribute the previous tick's layer evidence once
available, with the first tick explicitly marked as current_tick_prime.
Uncertain channels scale their layer R contribution by a named-channel driver
confidence_weight or confidence value clamped to [0, 1]. The executed
layer states are the states consumed by supervisor decisions and boundary
observation, while the audit log records raw versus executed R and psi
values under channel_runtime.
from scpn_phase_orchestrator.binding import (
build_channel_algebra_report,
load_binding_spec,
)
spec = load_binding_spec("domainpacks/power_safety_nchannel/binding_spec.yaml")
report = build_channel_algebra_report(spec)
audit_record = report.to_audit_record()
This report is read-only. It complements validate_binding_spec() rather than
replacing validation gates.
channel_algebra ¶
Deterministic N-channel algebra summaries for binding specs.
Classes¶
ChannelCouplingEdge
dataclass
¶
JSON-safe cross-channel coupling edge.
Methods:¶
to_audit_record ¶
Return a serialisable coupling-edge record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ChannelCouplingEdge fields.
Source code in src/scpn_phase_orchestrator/binding/channel_algebra.py
ChannelRuntimePolicy
dataclass
¶
ChannelRuntimePolicy(
channel: str,
evidence_required: bool,
delay_policy: str,
uncertainty_policy: str,
missing_policy: str,
)
Runtime handling policy derived from channel metadata.
Methods:¶
to_audit_record ¶
Return a serialisable runtime-policy record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ChannelRuntimePolicy fields.
Source code in src/scpn_phase_orchestrator/binding/channel_algebra.py
ChannelAlgebraReport
dataclass
¶
ChannelAlgebraReport(
channels: tuple[str, ...],
declared_channels: tuple[str, ...],
required_channels: tuple[str, ...],
optional_channels: tuple[str, ...],
derived_channels: tuple[str, ...],
delayed_channels: tuple[str, ...],
uncertain_channels: tuple[str, ...],
runtime_evidence_channels: tuple[str, ...],
missing_required_channels: tuple[str, ...],
supervisor_visible_channels: tuple[str, ...],
coupling_participating_channels: tuple[str, ...],
replay_semantics: dict[str, str],
runtime_policies: dict[str, ChannelRuntimePolicy],
channel_groups: dict[str, tuple[str, ...]],
channel_membership: dict[str, tuple[str, ...]],
coupling_edges: tuple[ChannelCouplingEdge, ...],
)
Deterministic channel algebra view for audit, replay, and reporting.
Methods:¶
to_audit_record ¶
Return a serialisable channel algebra record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ChannelAlgebraReport fields.
Source code in src/scpn_phase_orchestrator/binding/channel_algebra.py
Functions:¶
build_channel_algebra_report ¶
Build a deterministic N-channel algebra report from a binding spec.
The report is a read-only structural view. It does not validate or mutate
the binding; callers should still run validate_binding_spec() for gates.
Parameters¶
spec : BindingSpec The binding specification to analyse.
Returns¶
ChannelAlgebraReport A read-only report of channels, coupling edges, and runtime policies derived from the spec.
Source code in src/scpn_phase_orchestrator/binding/channel_algebra.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | |
channel_runtime ¶
Runtime execution of delayed and uncertain N-channel policies.
Classes¶
ChannelLayerRuntimeEvidence
dataclass
¶
ChannelLayerRuntimeEvidence(
layer_index: int,
channel: str,
raw_R: float,
executed_R: float,
raw_psi: float,
executed_psi: float,
delay_policy: str,
uncertainty_policy: str,
evidence_source: str,
confidence_weight: float,
)
Per-layer evidence showing how a channel policy affected execution.
Methods:¶
to_audit_record ¶
Return a serialisable layer runtime-evidence record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ChannelLayerRuntimeEvidence fields.
Source code in src/scpn_phase_orchestrator/binding/channel_runtime.py
ChannelRuntimeExecution
dataclass
¶
ChannelRuntimeExecution(
layers: tuple[LayerState, ...],
evidence: tuple[ChannelLayerRuntimeEvidence, ...],
)
Executed layer states plus audit evidence for one runtime tick.
Methods:¶
to_audit_record ¶
Return a serialisable runtime execution record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ChannelRuntimeExecution fields.
Source code in src/scpn_phase_orchestrator/binding/channel_runtime.py
ChannelRuntimeExecutor ¶
ChannelRuntimeExecutor(
*,
layer_channels: tuple[str, ...],
report: ChannelAlgebraReport,
confidence_weights: dict[str, float],
)
Apply N-channel delay and uncertainty policies to layer diagnostics.
The executor is intentionally deterministic and non-actuating. It only transforms the layer diagnostics consumed by the supervisor and audit log: delayed channels contribute the previous tick's layer evidence when available, while uncertain channels scale their contribution by an explicit driver confidence weight.
Initialise an executor from resolved channel policy inputs.
Source code in src/scpn_phase_orchestrator/binding/channel_runtime.py
Methods:¶
from_spec
classmethod
¶
Build a runtime executor from binding channel metadata.
Parameters¶
spec : BindingSpec The binding specification supplying channel layer metadata.
Returns¶
ChannelRuntimeExecutor An executor configured with the spec's per-channel runtime policies.
Source code in src/scpn_phase_orchestrator/binding/channel_runtime.py
execute ¶
Apply delayed/uncertain channel policies to this tick's layer states.
Parameters¶
raw_layers : list[LayerState] Per-layer states observed for the current tick, one per binding layer.
Returns¶
ChannelRuntimeExecution The policy-adjusted layer states with per-layer runtime evidence.
Raises¶
ValueError
If raw_layers does not have one entry per configured binding
layer.
Source code in src/scpn_phase_orchestrator/binding/channel_runtime.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
Functions:¶
Digital-Twin Binding Contract¶
build_digital_twin_binding_contract() turns a validated BindingSpec into a
versioned, bidirectional contract for simulators, services, and hardware twins.
The contract is deterministic and transport-neutral: it describes timing,
layers, actuators, N-channel algebra, and allowed sync payload classes without
opening sockets or applying actuation.
from scpn_phase_orchestrator.binding import (
build_digital_twin_binding_contract,
load_binding_spec,
)
spec = load_binding_spec("domainpacks/digital_twin_nchannel/binding_spec.yaml")
contract = build_digital_twin_binding_contract(spec)
payload = contract.to_audit_record()
stable_json = contract.to_json()
The emitted contract_hash is computed over the contract payload before the
hash field is added, so replay systems can compare contract compatibility
without re-parsing YAML. Default sync capabilities cover state snapshots,
phase observations, proposed control actions, and audit replay.
Transport adapters should wrap payloads in DigitalTwinSyncEnvelope and run
validate_digital_twin_sync_envelope() before handing data to a runtime or
external twin. The validator checks contract-hash compatibility, declared
capability names, allowed directions, integer-only non-negative sequence
numbers, non-empty string-keyed payloads, and strict JSON-safe finite payload
values before serialization. It remains transport-neutral: REST, gRPC, Kafka, file, and
hardware adapters can all use the same validation record without this module
opening sockets.
from scpn_phase_orchestrator.binding import (
build_digital_twin_sync_envelope,
validate_digital_twin_sync_envelope,
)
envelope = build_digital_twin_sync_envelope(
contract,
capability="state_snapshot",
direction="twin_to_spo",
sequence=1,
payload={"layer": "machine_cells", "R": 0.91},
)
validation = validate_digital_twin_sync_envelope(contract, envelope)
For file-based replay or adapter smoke tests, the JSONL adapter writes one validated envelope shape per line and reads it back through the same contract gate:
from scpn_phase_orchestrator.binding import (
read_digital_twin_sync_jsonl,
write_digital_twin_sync_jsonl,
)
write_report = write_digital_twin_sync_jsonl("sync.jsonl", [envelope])
read_report = read_digital_twin_sync_jsonl(contract, "sync.jsonl")
The read report separates accepted envelope validations from malformed JSON, invalid envelope shapes, and contract-validation rejections. This is the reference behaviour concrete REST, gRPC, Kafka, file, and hardware adapters can mirror.
For runtime-facing tests that should not touch disk, use
DigitalTwinSyncMemoryAdapter. It validates submissions against the same
contract, queues accepted envelopes in order, and drops rejected envelopes while
returning the validation reason to the caller.
from scpn_phase_orchestrator.binding import DigitalTwinSyncMemoryAdapter
adapter = DigitalTwinSyncMemoryAdapter.for_contract(contract)
validation = adapter.submit(envelope)
accepted_batch = adapter.drain()
Adapter implementations can also publish a DigitalTwinAdapterManifest before
any runtime code is enabled. build_digital_twin_adapter_manifest() checks that
the adapter only claims contract-declared capabilities, that live transports
declare authentication, and that offline transports support replay.
from scpn_phase_orchestrator.binding import build_digital_twin_adapter_manifest
compatibility = build_digital_twin_adapter_manifest(
contract,
name="grpc-live",
transport="grpc",
sync_capabilities=("state_snapshot", "audit_replay"),
supports_replay=True,
requires_auth=True,
)
DigitalTwinSyncRestAdapter is the first concrete live boundary. It stays
dependency-free and does not open a socket; web frameworks call handle_post()
with parsed JSON and request headers, then map the returned HTTP-style status
and body to the framework response.
from scpn_phase_orchestrator.binding import DigitalTwinSyncRestAdapter
adapter = DigitalTwinSyncRestAdapter.for_contract(contract)
response = adapter.handle_post(
envelope.to_audit_record(),
headers={"authorization": "Bearer ..."},
)
accepted = adapter.drain()
DigitalTwinSyncGrpcAdapter follows the same pattern for decoded unary gRPC
requests. It avoids generated protobuf imports in the binding layer; a servicer
passes decoded fields and metadata into handle_unary() and maps the returned
gRPC-style status name to framework-native status handling.
from scpn_phase_orchestrator.binding import DigitalTwinSyncGrpcAdapter
adapter = DigitalTwinSyncGrpcAdapter.for_contract(contract)
response = adapter.handle_unary(
envelope.to_audit_record(),
metadata={"authorization": "Bearer ..."},
)
accepted = adapter.drain()
DigitalTwinSyncKafkaAdapter accepts decoded broker message records. It checks
the configured topic, auth header, decoded value envelope, contract hash, and
capability direction without importing Kafka clients or committing offsets.
from scpn_phase_orchestrator.binding import DigitalTwinSyncKafkaAdapter
adapter = DigitalTwinSyncKafkaAdapter.for_contract(contract)
response = adapter.handle_message(
{"topic": "spo.digital_twin.sync", "value": envelope.to_audit_record()},
headers={"authorization": "Bearer ..."},
)
accepted = adapter.drain()
DigitalTwinSyncHardwareAdapter accepts decoded device frames from a separate
hardware integration layer. It requires a registered device ID and explicit
safety interlock, and it always reports hardware_write_permitted=False; the
binding layer validates and queues envelopes but never writes to physical
devices.
from scpn_phase_orchestrator.binding import DigitalTwinSyncHardwareAdapter
adapter = DigitalTwinSyncHardwareAdapter.for_contract(
contract,
device_ids=("pynq-loopback-0",),
)
response = adapter.handle_frame(
{
"device_id": "pynq-loopback-0",
"safety_interlock": True,
"value": envelope.to_audit_record(),
},
headers={"authorization": "Bearer ..."},
)
accepted = adapter.drain()
digital_twin ¶
Transport-neutral digital-twin contracts derived from bindings.
This package turns a validated BindingSpec into deterministic contract hashes,
adapter manifests, sync capabilities, and envelope validation records for
simulators, services, and hardware twins, split into responsibility modules
(contract, envelope, evidence, and per-transport adapters) behind a stable
re-export surface. REST, gRPC, Kafka, JSONL, hardware, and in-memory helpers
validate decoded payloads only; they do not open sockets, spawn servers, or
apply live control actions.
Classes¶
DigitalTwinSyncGrpcAdapter
dataclass
¶
DigitalTwinSyncGrpcAdapter(
contract: DigitalTwinBindingContract,
compatibility: DigitalTwinAdapterCompatibility,
_queue: list[DigitalTwinSyncEnvelope],
)
Dependency-free gRPC boundary for digital-twin sync payloads.
The adapter does not start a gRPC server or import generated protobuf
classes. A real servicer can pass decoded protobuf fields into
:meth:handle_unary; this boundary then applies the same contract checks
as other transports before queuing accepted envelopes.
Methods:¶
for_contract
classmethod
¶
for_contract(
contract: DigitalTwinBindingContract,
*,
name: str = "grpc-sync",
sync_capabilities: Sequence[
str
] = _DEFAULT_SYNC_CAPABILITIES,
requires_auth: bool = True,
supports_replay: bool = False,
) -> DigitalTwinSyncGrpcAdapter
Create a gRPC adapter boundary for a digital-twin contract.
Parameters¶
contract : DigitalTwinBindingContract The digital-twin binding contract the adapter serves. name : str, optional Human-readable adapter name. sync_capabilities : Sequence[str], optional Sync capabilities the adapter advertises. requires_auth : bool, optional Whether the adapter boundary requires authentication. supports_replay : bool, optional Whether the adapter supports replay of past envelopes.
Returns¶
DigitalTwinSyncGrpcAdapter A new gRPC adapter boundary bound to the contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_grpc.py
handle_unary ¶
handle_unary(
request: Mapping[str, object],
*,
metadata: Mapping[str, str] | None = None,
) -> DigitalTwinSyncGrpcResponse
Validate one unary gRPC request and queue accepted envelopes.
Parameters¶
request : Mapping[str, object] The decoded unary gRPC request body. metadata : Mapping[str, str] or None, optional Optional request metadata (e.g. auth tokens).
Returns¶
DigitalTwinSyncGrpcResponse
The response; accepted envelopes are queued for :meth:drain.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_grpc.py
drain ¶
Return accepted gRPC envelopes in arrival order and clear the queue.
Returns¶
tuple[DigitalTwinSyncEnvelope, ...] The queued sync envelopes in submission order; the internal queue is left empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_grpc.py
to_audit_record ¶
Return gRPC adapter state without exposing payload contents.
Returns¶
dict[str, object] Deterministic, JSON-safe state of the DigitalTwinSyncGrpcAdapter (queue counters and status); no network surface or payload contents are exposed.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_grpc.py
DigitalTwinSyncGrpcResponse
dataclass
¶
DigitalTwinSyncGrpcResponse(
status_code: str,
accepted: bool,
reason: str,
message: dict[str, object],
)
gRPC-style response for a digital-twin sync boundary.
Methods:¶
to_audit_record ¶
Return a JSON-safe gRPC adapter response.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncGrpcResponse fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_grpc.py
DigitalTwinSyncHardwareAdapter
dataclass
¶
DigitalTwinSyncHardwareAdapter(
contract: DigitalTwinBindingContract,
compatibility: DigitalTwinAdapterCompatibility,
device_ids: tuple[str, ...],
_queue: list[DigitalTwinSyncEnvelope],
)
No-I/O hardware boundary for digital-twin sync payloads.
The adapter validates decoded frames from a hardware integration layer. It never opens device files, writes registers, toggles GPIO, or applies actuation; accepted envelopes are only queued for caller-controlled review.
Methods:¶
for_contract
classmethod
¶
for_contract(
contract: DigitalTwinBindingContract,
*,
device_ids: Sequence[str],
name: str = "hardware-sync",
sync_capabilities: Sequence[
str
] = _DEFAULT_SYNC_CAPABILITIES,
requires_auth: bool = True,
supports_replay: bool = True,
) -> DigitalTwinSyncHardwareAdapter
Create a no-I/O hardware boundary for a digital-twin contract.
Parameters¶
contract : DigitalTwinBindingContract The digital-twin binding contract the adapter serves. device_ids : Sequence[str] Identifiers of the hardware devices the boundary serves. name : str, optional Human-readable adapter name. sync_capabilities : Sequence[str], optional Sync capabilities the adapter advertises. requires_auth : bool, optional Whether the adapter boundary requires authentication. supports_replay : bool, optional Whether the adapter supports replay of past envelopes.
Returns¶
DigitalTwinSyncHardwareAdapter A new no-I/O hardware boundary bound to the contract.
Raises¶
ValueError
If device_ids is empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_hardware.py
handle_frame ¶
handle_frame(
frame: Mapping[str, object],
*,
headers: Mapping[str, str] | None = None,
) -> DigitalTwinSyncHardwareResponse
Validate one decoded hardware frame and queue accepted envelopes.
Parameters¶
frame : Mapping[str, object] The decoded hardware hardware frame. headers : Mapping[str, str] or None, optional Optional transport headers (e.g. auth tokens).
Returns¶
DigitalTwinSyncHardwareResponse
The hardware response; accepted envelopes are queued for :meth:drain.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_hardware.py
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | |
drain ¶
Return accepted hardware envelopes in arrival order and clear the queue.
Returns¶
tuple[DigitalTwinSyncEnvelope, ...] The queued sync envelopes in submission order; the internal queue is left empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_hardware.py
to_audit_record ¶
Return hardware adapter state without exposing payload contents.
Returns¶
dict[str, object] Deterministic, JSON-safe state of the DigitalTwinSyncHardwareAdapter (queue counters and status); no network surface or payload contents are exposed.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_hardware.py
DigitalTwinSyncHardwareResponse
dataclass
¶
DigitalTwinSyncHardwareResponse(
accepted: bool,
reason: str,
hardware_write_permitted: bool,
frame: dict[str, object],
)
No-I/O response for a hardware digital-twin sync boundary.
Methods:¶
to_audit_record ¶
Return a JSON-safe hardware adapter response.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncHardwareResponse fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_hardware.py
DigitalTwinSyncKafkaAdapter
dataclass
¶
DigitalTwinSyncKafkaAdapter(
contract: DigitalTwinBindingContract,
compatibility: DigitalTwinAdapterCompatibility,
topic: str,
_queue: list[DigitalTwinSyncEnvelope],
)
Dependency-free Kafka boundary for digital-twin sync payloads.
The adapter expects a broker consumer to pass a decoded message dictionary. It does not import Kafka clients, open sockets, or commit offsets. Accepted envelopes are queued for caller-controlled runtime handoff.
Methods:¶
for_contract
classmethod
¶
for_contract(
contract: DigitalTwinBindingContract,
*,
topic: str = "spo.digital_twin.sync",
name: str = "kafka-sync",
sync_capabilities: Sequence[
str
] = _DEFAULT_SYNC_CAPABILITIES,
requires_auth: bool = True,
supports_replay: bool = True,
) -> DigitalTwinSyncKafkaAdapter
Create a Kafka message-boundary adapter for a digital-twin contract.
Parameters¶
contract : DigitalTwinBindingContract The digital-twin binding contract the adapter serves. topic : str, optional Kafka topic the adapter binds to. name : str, optional Human-readable adapter name. sync_capabilities : Sequence[str], optional Sync capabilities the adapter advertises. requires_auth : bool, optional Whether the adapter boundary requires authentication. supports_replay : bool, optional Whether the adapter supports replay of past envelopes.
Returns¶
DigitalTwinSyncKafkaAdapter A new Kafka message-boundary adapter bound to the contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_kafka.py
handle_message ¶
handle_message(
message: Mapping[str, object],
*,
headers: Mapping[str, str] | None = None,
) -> DigitalTwinSyncKafkaResponse
Validate one decoded Kafka message and queue accepted envelopes.
Parameters¶
message : Mapping[str, object] The decoded Kafka message body. headers : Mapping[str, str] or None, optional Optional transport headers (e.g. auth tokens).
Returns¶
DigitalTwinSyncKafkaResponse
The Kafka response; accepted envelopes are queued for :meth:drain.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_kafka.py
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | |
drain ¶
Return accepted Kafka envelopes in arrival order and clear the queue.
Returns¶
tuple[DigitalTwinSyncEnvelope, ...] The queued sync envelopes in submission order; the internal queue is left empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_kafka.py
to_audit_record ¶
Return Kafka adapter state without exposing payload contents.
Returns¶
dict[str, object] Deterministic, JSON-safe state of the DigitalTwinSyncKafkaAdapter (queue counters and status); no network surface or payload contents are exposed.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_kafka.py
DigitalTwinSyncKafkaResponse
dataclass
¶
DigitalTwinSyncKafkaResponse(
accepted: bool,
reason: str,
retryable: bool,
message: dict[str, object],
)
Broker-style response for a Kafka digital-twin sync boundary.
Methods:¶
to_audit_record ¶
Return a JSON-safe Kafka adapter response.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncKafkaResponse fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_kafka.py
DigitalTwinSyncMemoryAdapter
dataclass
¶
DigitalTwinSyncMemoryAdapter(
contract: DigitalTwinBindingContract,
_queue: list[DigitalTwinSyncEnvelope],
)
In-memory reference adapter for validated digital-twin sync payloads.
Methods:¶
for_contract
classmethod
¶
Create an empty adapter for a digital-twin binding contract.
Parameters¶
contract : DigitalTwinBindingContract The digital-twin binding contract the adapter serves.
Returns¶
DigitalTwinSyncMemoryAdapter An empty in-memory adapter bound to the contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_memory.py
submit ¶
Validate and queue one envelope when accepted.
Parameters¶
envelope : DigitalTwinSyncEnvelope The sync envelope to validate and queue.
Returns¶
DigitalTwinTransportValidation The validation result; the envelope is queued only when accepted.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_memory.py
drain ¶
Return queued envelopes in submission order and clear the queue.
Returns¶
tuple[DigitalTwinSyncEnvelope, ...] The queued sync envelopes in submission order; the internal queue is left empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_memory.py
to_audit_record ¶
Return adapter state without exposing any network surface.
Returns¶
dict[str, object] Deterministic, JSON-safe state of the DigitalTwinSyncMemoryAdapter (queue counters and status); no network surface or payload contents are exposed.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_memory.py
DigitalTwinSyncRestAdapter
dataclass
¶
DigitalTwinSyncRestAdapter(
contract: DigitalTwinBindingContract,
compatibility: DigitalTwinAdapterCompatibility,
_queue: list[DigitalTwinSyncEnvelope],
)
Dependency-free REST boundary for digital-twin sync payloads.
The adapter deliberately does not open sockets. Web frameworks can call
:meth:handle_post from a route handler after parsing request JSON and
headers; the adapter then enforces manifest compatibility, authentication
posture, envelope shape, and contract validation before queuing payloads.
Methods:¶
for_contract
classmethod
¶
for_contract(
contract: DigitalTwinBindingContract,
*,
name: str = "rest-sync",
sync_capabilities: Sequence[
str
] = _DEFAULT_SYNC_CAPABILITIES,
requires_auth: bool = True,
supports_replay: bool = False,
) -> DigitalTwinSyncRestAdapter
Create a REST adapter boundary for a digital-twin contract.
Parameters¶
contract : DigitalTwinBindingContract The digital-twin binding contract the adapter serves. name : str, optional Human-readable adapter name. sync_capabilities : Sequence[str], optional Sync capabilities the adapter advertises. requires_auth : bool, optional Whether the adapter boundary requires authentication. supports_replay : bool, optional Whether the adapter supports replay of past envelopes.
Returns¶
DigitalTwinSyncRestAdapter A new REST adapter boundary bound to the contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_rest.py
handle_post ¶
handle_post(
body: Mapping[str, object],
*,
headers: Mapping[str, str] | None = None,
) -> DigitalTwinSyncRestResponse
Validate one HTTP POST body and queue accepted sync envelopes.
Parameters¶
body : Mapping[str, object] The decoded REST HTTP POST body. headers : Mapping[str, str] or None, optional Optional transport headers (e.g. auth tokens).
Returns¶
DigitalTwinSyncRestResponse
The REST response; accepted envelopes are queued for :meth:drain.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_rest.py
drain ¶
Return accepted REST envelopes in arrival order and clear the queue.
Returns¶
tuple[DigitalTwinSyncEnvelope, ...] The queued sync envelopes in submission order; the internal queue is left empty.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_rest.py
to_audit_record ¶
Return REST adapter state without exposing payload contents.
Returns¶
dict[str, object] Deterministic, JSON-safe state of the DigitalTwinSyncRestAdapter (queue counters and status); no network surface or payload contents are exposed.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_rest.py
DigitalTwinSyncRestResponse
dataclass
¶
DigitalTwinSyncRestResponse(
status_code: int,
accepted: bool,
reason: str,
body: dict[str, object],
)
HTTP-style response for a REST digital-twin sync boundary.
Methods:¶
to_audit_record ¶
Return a JSON-safe REST adapter response.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncRestResponse fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/adapter_rest.py
DigitalTwinAdapterCompatibility
dataclass
¶
DigitalTwinAdapterCompatibility(
compatible: bool,
reasons: tuple[str, ...],
manifest: DigitalTwinAdapterManifest,
contract_hash: str,
)
Compatibility result for an adapter manifest and binding contract.
Methods:¶
to_audit_record ¶
Return a JSON-safe adapter compatibility report.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinAdapterCompatibility fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
DigitalTwinAdapterManifest
dataclass
¶
DigitalTwinAdapterManifest(
name: str,
transport: str,
sync_capabilities: tuple[str, ...],
supports_replay: bool,
requires_auth: bool,
notes: str = "",
)
Reviewable manifest for a concrete digital-twin transport adapter.
Methods:¶
to_audit_record ¶
Return a JSON-safe adapter manifest.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinAdapterManifest fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
DigitalTwinBindingContract
dataclass
¶
DigitalTwinBindingContract(
contract_version: str,
binding_name: str,
binding_version: str,
safety_tier: str,
sample_period_s: float,
control_period_s: float,
layers: tuple[DigitalTwinLayerContract, ...],
actuators: tuple[dict[str, object], ...],
channel_algebra: ChannelAlgebraReport,
sync_capabilities: tuple[
DigitalTwinSyncCapability, ...
],
contract_hash: str,
)
Versioned bidirectional contract derived from a binding spec.
Methods:¶
to_audit_record ¶
Return a deterministic JSON-safe digital-twin contract.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinBindingContract fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
DigitalTwinLayerContract
dataclass
¶
DigitalTwinLayerContract(
name: str,
index: int,
oscillator_count: int,
oscillator_ids: tuple[str, ...],
family: str | None = None,
)
Reduced layer contract exposed to simulators and hardware twins.
Methods:¶
to_audit_record ¶
Return a JSON-safe layer contract.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinLayerContract fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
DigitalTwinSyncCapability
dataclass
¶
Named live-sync capability declared by the binding contract.
DigitalTwinSyncEnvelope
dataclass
¶
DigitalTwinSyncEnvelope(
contract_hash: str,
capability: str,
direction: str,
sequence: int,
payload: dict[str, object],
)
Transport-neutral live-sync payload envelope for digital twins.
Methods:¶
__post_init__ ¶
Validate envelope identity, sequence, and payload invariants.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
to_audit_record ¶
Return a JSON-safe sync envelope.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncEnvelope fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
DigitalTwinSyncJsonlReport
dataclass
¶
DigitalTwinSyncJsonlReport(
path: str,
written: int,
accepted: tuple[DigitalTwinTransportValidation, ...],
rejected: tuple[dict[str, object], ...],
)
JSONL file-adapter replay report for digital-twin sync envelopes.
Methods:¶
to_audit_record ¶
Return a JSON-safe file-adapter report.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinSyncJsonlReport fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
DigitalTwinTransportValidation
dataclass
¶
Validation result for one digital-twin sync envelope.
Methods:¶
to_audit_record ¶
Return a JSON-safe validation record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinTransportValidation fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
DigitalTwinOperatorEvidence
dataclass
¶
DigitalTwinOperatorEvidence(
contract_hash: str,
accepted_count: int,
rejected_count: int,
adapter_count: int,
unhealthy_adapter_count: int,
latest_sequence: int | None,
capability_counts: dict[str, int],
direction_counts: dict[str, int],
max_abs_twin_residual: float | None,
mismatch_reasons: tuple[str, ...],
status: str,
)
Transport-neutral operator summary for live or replayed twin sync.
Methods:¶
to_audit_record ¶
Return a JSON-safe operator evidence record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the DigitalTwinOperatorEvidence fields.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/evidence.py
Functions:¶
build_digital_twin_adapter_manifest ¶
build_digital_twin_adapter_manifest(
contract: DigitalTwinBindingContract,
*,
name: str,
transport: str,
sync_capabilities: Sequence[str],
supports_replay: bool,
requires_auth: bool,
notes: str = "",
) -> DigitalTwinAdapterCompatibility
Build and validate a transport-adapter manifest against a contract.
Parameters¶
contract : DigitalTwinBindingContract
The contract the adapter must satisfy.
name : str
Adapter name.
transport : str
Transport identifier (e.g. rest, grpc, kafka).
sync_capabilities : Sequence[str]
Capabilities the adapter implements.
supports_replay : bool
Whether the adapter supports replay.
requires_auth : bool
Whether the adapter requires authentication.
notes : str, optional
Free-form manifest notes.
Returns¶
DigitalTwinAdapterCompatibility The adapter compatibility report against the contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
build_digital_twin_binding_contract ¶
build_digital_twin_binding_contract(
spec: BindingSpec,
*,
contract_version: str = _DEFAULT_CONTRACT_VERSION,
sync_capabilities: Sequence[
str
] = _DEFAULT_SYNC_CAPABILITIES,
) -> DigitalTwinBindingContract
Build a versioned live-sync contract from a validated binding spec.
The contract is read-only and transport-neutral. It describes what a simulator, service twin, or hardware twin may exchange with SPO without opening network connections or applying actuation.
Parameters¶
spec : BindingSpec The validated binding specification. contract_version : str, optional Semantic version label for the emitted contract. sync_capabilities : Sequence[str], optional Capabilities the contract advertises.
Returns¶
DigitalTwinBindingContract A read-only, transport-neutral live-sync contract.
Raises¶
ValueError If the spec cannot form a valid live-sync contract.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/contract.py
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
build_digital_twin_sync_envelope ¶
build_digital_twin_sync_envelope(
contract: DigitalTwinBindingContract,
*,
capability: str,
direction: str,
sequence: int,
payload: dict[str, object],
) -> DigitalTwinSyncEnvelope
Build a transport-neutral sync payload envelope for a contract.
This helper does not send data. It creates the deterministic envelope that REST, gRPC, Kafka, file, or hardware adapters can validate before handing a payload to the runtime.
Parameters¶
contract : DigitalTwinBindingContract
The contract the envelope conforms to.
capability : str
The sync capability the envelope exercises.
direction : str
Sync direction (e.g. inbound/outbound).
sequence : int
Monotonic envelope sequence number.
payload : dict[str, object]
The deterministic payload to wrap.
Returns¶
DigitalTwinSyncEnvelope A validated, transport-neutral sync envelope.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
read_digital_twin_sync_jsonl ¶
read_digital_twin_sync_jsonl(
contract: DigitalTwinBindingContract, path: str | Path
) -> DigitalTwinSyncJsonlReport
Read JSONL sync envelopes and validate them against a contract.
Parameters¶
contract : DigitalTwinBindingContract The contract to validate envelopes against. path : str or pathlib.Path JSONL file to read.
Returns¶
DigitalTwinSyncJsonlReport A report of read, accepted, and rejected envelopes.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
validate_digital_twin_sync_envelope ¶
validate_digital_twin_sync_envelope(
contract: DigitalTwinBindingContract,
envelope: DigitalTwinSyncEnvelope,
) -> DigitalTwinTransportValidation
Validate a digital-twin sync envelope against a binding contract.
Parameters¶
contract : DigitalTwinBindingContract The binding contract to validate against. envelope : DigitalTwinSyncEnvelope The sync envelope to validate.
Returns¶
DigitalTwinTransportValidation The validation result (accepted, or rejected with reasons).
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
write_digital_twin_sync_jsonl ¶
write_digital_twin_sync_jsonl(
path: str | Path,
envelopes: Sequence[DigitalTwinSyncEnvelope],
) -> DigitalTwinSyncJsonlReport
Write sync envelopes to deterministic JSONL for offline replay.
Parameters¶
path : str or pathlib.Path Destination JSONL file path. envelopes : Sequence[DigitalTwinSyncEnvelope] The envelopes to serialise, in order.
Returns¶
DigitalTwinSyncJsonlReport A report of the written file and envelope count.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/envelope.py
build_digital_twin_operator_evidence ¶
build_digital_twin_operator_evidence(
contract: DigitalTwinBindingContract,
validations: Sequence[DigitalTwinTransportValidation],
*,
rejected: Sequence[Mapping[str, object]] = (),
adapter_records: Sequence[Mapping[str, object]] = (),
residual_warning_threshold: float = 0.05,
residual_critical_threshold: float = 0.2,
) -> DigitalTwinOperatorEvidence
Summarise live or replayed digital-twin sync evidence for operators.
Accepted validations may come from REST, gRPC, Kafka, hardware, memory, or JSONL replay paths. Rejected JSONL lines and adapter audit records are folded into the same deterministic summary so dashboards can display live and replayed health with the same fields.
Parameters¶
contract : DigitalTwinBindingContract The binding contract under observation. validations : Sequence[DigitalTwinTransportValidation] Accepted transport validations from any sync path. rejected : Sequence[Mapping[str, object]], optional Rejected JSONL lines folded into the summary. adapter_records : Sequence[Mapping[str, object]], optional Adapter audit records to include. residual_warning_threshold : float, optional Residual fraction above which a warning status is raised. residual_critical_threshold : float, optional Residual fraction above which a critical status is raised.
Returns¶
DigitalTwinOperatorEvidence A deterministic operator-facing health summary.
Raises¶
ValueError If the residual warning/critical thresholds are inconsistent.
Source code in src/scpn_phase_orchestrator/binding/digital_twin/evidence.py
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
Types¶
Core type definitions shared across the binding subsystem.
BindingSpec (dataclass)¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
str |
yes | Domainpack name |
version |
str |
yes | Spec version |
safety_tier |
str |
yes | Safety classification |
sample_period_s |
float |
yes | Input sampling interval |
control_period_s |
float |
yes | Control loop interval |
layers |
list[HierarchyLayer] |
yes | Oscillator layers |
oscillator_families |
dict[str, OscillatorFamily] |
yes | P/I/S families |
coupling |
CouplingSpec |
yes | K_nm parameters |
drivers |
DriverSpec |
yes | External drive config |
objectives |
ObjectivePartition |
yes | Optimisation targets |
boundaries |
list[BoundaryDef] |
yes | Safety boundaries |
actuators |
list[ActuatorMapping] |
yes | Output actuators |
imprint_model |
ImprintSpec \| None |
no | Memory dynamics |
geometry_prior |
GeometrySpec \| None |
no | Spatial constraints |
protocol_net |
ProtocolNetSpec \| None |
no | Petri net FSM |
amplitude |
AmplitudeSpec \| None |
no | Stuart-Landau params |
Other types¶
ActuatorMapping— maps a control knob to a named actuator with scope and limitsHierarchyLayer— declares a layer with channel, extractor, and frequency range. Whenfamilyis set, it must reference a key underoscillator_families; omittingfamilyuses the physical-channel default, but misspelled family names fail validation and direct runtime construction.VALID_KNOBS— recognised control knobs:K,alpha,zeta,Psi
types ¶
Typed dataclass model for SPO domain binding specifications.
These dataclasses are the in-memory contract produced by the YAML loader and
consumed by validators, CLIs, engines, supervisors, audit summaries, and
digital-twin exporters. Constructors keep lightweight invariant checks where
local consistency is unambiguous; cross-field and deployment-policy checks live
in binding.validator so error reporting can stay complete and actionable.
Classes¶
HierarchyLayer
dataclass
¶
HierarchyLayer(
name: str,
index: int,
oscillator_ids: list[str],
omegas: list[float] | None = None,
family: str | None = None,
)
Single layer in the SCPN oscillator hierarchy.
OscillatorFamily
dataclass
¶
Phase extraction configuration for one oscillator group.
CouplingSpec
dataclass
¶
Parameters for K_nm coupling matrix construction.
DriverSpec
dataclass
¶
DriverSpec(
physical: dict[str, Any],
informational: dict[str, Any],
symbolic: dict[str, Any],
extra: dict[str, dict[str, Any]] | None = None,
)
Configuration for standard and named external driver channels.
Methods:¶
channel_config ¶
Return driver config for a standard or named channel.
Parameters¶
channel : str
A standard channel (P/physical, I/informational,
S/symbolic) or a named extension channel id.
Returns¶
dict[str, Any] The driver configuration mapping for channel, or an empty mapping when the channel has no configured driver.
Source code in src/scpn_phase_orchestrator/binding/types.py
all_channel_configs ¶
Return standard driver configs plus named extension channels.
Returns¶
dict[str, dict[str, Any]]
Mapping of channel id (P/I/S plus any named extension
channels) to its driver configuration mapping.
Source code in src/scpn_phase_orchestrator/binding/types.py
ChannelSpec
dataclass
¶
ChannelSpec(
role: str,
required: bool = True,
units: str | None = None,
metric_semantics: str | None = None,
coupling_participation: bool = True,
audit_serialisation: bool = True,
replay_semantics: str = "phase",
supervisor_visibility: bool = True,
derived_from: list[str] = list(),
derive_rule: str | None = None,
)
Typed binding channel metadata for N-channel domainpacks.
ChannelGroupSpec
dataclass
¶
Named set of channels used for validation and supervisor summaries.
CrossChannelCouplingSpec
dataclass
¶
CrossChannelCouplingSpec(
source: str,
target: str,
strength: float,
mode: str = "bidirectional",
template: str | None = None,
)
Declared coupling relation between two binding channels.
ObjectivePartition
dataclass
¶
ObjectivePartition(
good_layers: list[int],
bad_layers: list[int],
good_weight: float = 1.0,
bad_weight: float = 1.0,
)
Partition of layers into good (synchronise) and bad (desynchronise) subsets.
BoundaryDef
dataclass
¶
Defines a soft or hard boundary on a monitored variable.
ActuatorMapping
dataclass
¶
ActuatorMapping(
name: str,
knob: str,
scope: str,
limits: tuple[float, float],
rate_limit_per_step: float | None = None,
)
Maps a control knob to a named actuator with scope and limits.
ImprintSpec
dataclass
¶
Parameters for the L9 memory imprint model.
GeometrySpec
dataclass
¶
Geometry constraint type and parameters for K_nm projection.
ProtocolTransitionSpec
dataclass
¶
ProtocolTransitionSpec(
name: str,
inputs: list[dict[str, Any]],
outputs: list[dict[str, Any]],
guard: str | None = None,
)
One transition in the Petri net protocol specification.
ProtocolNetSpec
dataclass
¶
ProtocolNetSpec(
places: list[str],
initial: dict[str, int],
place_regime: dict[str, str],
transitions: list[ProtocolTransitionSpec],
)
Full Petri net specification: places, initial marking, and transitions.
AmplitudeSpec
dataclass
¶
AmplitudeSpec(
mu: float,
epsilon: float,
amp_coupling_strength: float = 0.0,
amp_coupling_decay: float = 0.3,
)
Amplitude dynamics parameters (Stuart-Landau bifurcation).
BindingSpec
dataclass
¶
BindingSpec(
name: str,
version: str,
safety_tier: str,
sample_period_s: float,
control_period_s: float,
layers: list[HierarchyLayer],
oscillator_families: dict[str, OscillatorFamily],
coupling: CouplingSpec,
drivers: DriverSpec,
objectives: ObjectivePartition,
boundaries: list[BoundaryDef],
actuators: list[ActuatorMapping],
validation_tier: str = DEFAULT_VALIDATION_TIER,
imprint_model: ImprintSpec | None = None,
geometry_prior: GeometrySpec | None = None,
protocol_net: ProtocolNetSpec | None = None,
amplitude: AmplitudeSpec | None = None,
channels: dict[str, ChannelSpec] = dict(),
channel_groups: dict[str, ChannelGroupSpec] = dict(),
cross_channel_couplings: list[
CrossChannelCouplingSpec
] = list(),
value_alignment: dict[str, Any] = dict(),
)
Complete domainpack binding: layers, coupling, drivers, and actuators.
Methods:¶
get_omegas ¶
Collect natural frequencies from all layers.
Falls back to 1.0 rad/s per oscillator when a layer defines no omegas.
Returns¶
list[float] Natural frequencies in rad/s, concatenated in layer order, one per oscillator.
Raises¶
ValueError
If a layer defines an omegas list whose length differs from its
oscillator count.
Source code in src/scpn_phase_orchestrator/binding/types.py
used_channels ¶
Return channels referenced by families, drivers, and algebra.
Returns¶
set[str] The set of channel identifiers referenced by oscillator families, configured drivers, and cross-channel coupling declarations.
Source code in src/scpn_phase_orchestrator/binding/types.py
Functions:¶
is_valid_channel_id ¶
Return True when channel is a valid binding channel identifier.
Parameters¶
channel : str Candidate channel identifier to validate.
Returns¶
bool
True if channel matches the binding channel-id grammar.
Source code in src/scpn_phase_orchestrator/binding/types.py
resolve_extractor_type ¶
Map alias to algorithm name; pass algorithm names through unchanged.
Parameters¶
raw : str An extractor alias or canonical algorithm name.
Returns¶
str The canonical extractor algorithm name; unknown values pass through unchanged.
Source code in src/scpn_phase_orchestrator/binding/types.py
Loader¶
Loads binding specifications from YAML files. Supports:
- Single-file specs (most domainpacks)
- Multi-file specs with
$reftemplate references - Environment variable interpolation for credentials and endpoints
- Default value injection for optional fields
The loader does not validate — that is the validator's job. This separation allows testing with deliberately invalid specs.
loader ¶
Fail-closed YAML/JSON loader for domain binding specifications.
The loader converts untrusted mapping/list/scalar input into the typed
BindingSpec dataclass graph. Every required field, optional field type,
number pair, channel identifier, and nested section is checked during parsing
so later runtime code receives structured values rather than raw YAML objects.
Classes¶
BindingLoadError ¶
Bases: BindingError
Raised when a binding spec cannot be parsed.
Functions:¶
load_binding_spec ¶
Load a BindingSpec from a YAML or JSON file.
Parameters¶
path : str or pathlib.Path
Filesystem path to the binding-spec .yaml/.yml/.json file.
Returns¶
BindingSpec The parsed, structurally typed binding specification.
Raises¶
BindingLoadError If the file cannot be read, is not valid finite YAML/JSON, contains duplicate mapping keys, or does not satisfy the binding-spec schema.
Source code in src/scpn_phase_orchestrator/binding/loader.py
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | |
Validator¶
Schema validation for binding specifications. Checks:
- Field types and required fields (against JSON schema)
- Cross-references: actuator scopes must match declared layers, and explicit
layer families must match
oscillator_families - Frequency ranges:
f_min < f_max, both positive - Channel constraints: at least one layer, no duplicate names
- Template resolution: referenced templates must exist
Validation errors are collected (not raised on first failure) so that users see all problems at once.
validator ¶
Cross-field validation for loaded binding specifications.
validate_binding_spec returns every actionable configuration error it can
find instead of failing at the first issue. It checks version shape, safety
tier, timing, layer/objective references, N-channel declarations, extractor
aliases, boundary and actuator scopes, imprint, amplitude, geometry, and
protocol-net consistency before a binding is used by runtime code.
Classes¶
Functions:¶
validate_binding_spec ¶
Validate a BindingSpec and return a list of error strings.
Parameters¶
spec : BindingSpec The binding specification to validate.
Returns¶
list[str] Human-readable validation error messages; an empty list means the spec is structurally and cross-field valid.
Source code in src/scpn_phase_orchestrator/binding/validator.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | |
validate_binding_spec_security ¶
Return security-review findings for a loaded binding spec.
Normal binding validation checks structure and cross-field consistency.
This stricter pass is intended for spo validate --security and rejects
executable-looking payloads in free-form configuration fields. Binding specs
remain declarative data; they must not carry Python code, loader tags,
import expressions, subprocess references, or deserialisation gadgets.
Parameters¶
spec : BindingSpec The loaded binding specification to security-review.
Returns¶
list[str] Security-review findings; an empty list means no executable-looking payloads were detected in free-form configuration fields.
Source code in src/scpn_phase_orchestrator/binding/validator.py
Security¶
The binding loader enforces security constraints:
- Path traversal rejection —
../sequences in file paths are rejected to prevent reading outside the domainpack directory - Schema validation — all fields are checked against the JSON schema before any data is used
- Environment variable interpolation — only whitelisted env vars are substituted; arbitrary code execution is not possible
- Size limits — binding specs exceeding 1 MB are rejected
These protections are tested in tests/test_binding_loader_security.py
with adversarial inputs including malicious YAML, oversized files,
and path traversal attempts.
Hard scan (spo validate --security --hard)¶
spo validate --security rejects executable-looking payloads in the binding
spec itself. The harder --security --hard pass additionally scans the files
that ship beside the binding — the domainpack's Python scenarios and YAML
configuration — for the patterns that let an untrusted domainpack run arbitrary
code when it is loaded or executed: dynamic evaluation (eval / exec),
insecure deserialisation (pickle.load), unsafe YAML deep loads (yaml.load
without a safe loader, or !!python/ construction tags), and shell command
execution. The scan is review-only — it reports each match with its file, line
and category and never edits, executes, or imports the scanned files, so it is
safe to run on a domainpack of unknown provenance before deciding to trust it.
security_scan ¶
Scan a domainpack's user-facing files for dangerous code and config patterns.
spo validate --security rejects executable-looking payloads in the binding
spec itself. The harder --security --hard pass goes one level further and
statically scans the files that ship beside the binding — the domainpack's
Python scenarios and YAML configuration — for the patterns that let an untrusted
domainpack run arbitrary code when it is loaded or executed: dynamic evaluation
(eval / exec), insecure deserialisation (pickle.load), unsafe YAML
deep loads (yaml.load without a safe loader, or !!python/ construction
tags), and shell command execution.
The scan is review-only: it reports every match with its file, line and category; it never edits, executes, or imports the scanned files, so it is safe to run on a domainpack of unknown provenance before deciding whether to trust it.
Classes¶
UnsafePatternFinding
dataclass
¶
One dangerous pattern located during a hard security scan.
Parameters¶
path : str
The scanned file, relative to the scan root.
line : int
The one-based line number of the match.
category : str
The danger class, for example "dynamic-eval" or "unsafe-yaml".
snippet : str
The stripped source line containing the match.
Functions:¶
scan_unsafe_patterns ¶
Scan a directory tree for dangerous code and configuration patterns.
Parameters¶
root : pathlib.Path The directory (a domainpack) or single file to scan.
Returns¶
tuple[UnsafePatternFinding, ...] Every located pattern, ordered by path then line.
Raises¶
ValueError
If root does not exist.
Source code in src/scpn_phase_orchestrator/binding/security_scan.py
Domainpacks¶
A domainpack is a directory containing a binding spec plus optional data files (coupling templates, calibration data, policy rules). SPO ships with built-in domainpacks for common domains:
| Domainpack | Layers | Channels | Description |
|---|---|---|---|
power_grid |
generators, loads | P, I | AC power system sync |
neural_eeg |
cortical regions | P | EEG phase dynamics |
microservices |
API endpoints | I | IT infrastructure sync |
tokamak |
plasma + magnetics | P | Fusion plasma control |
smart_factory |
machines, queues | P, I, S | Manufacturing sync |
Each domainpack is validated at load time against the schema. Invalid domainpacks produce detailed error messages listing all violations.
Performance: load_binding_spec() < 10 ms.
Symbolic Binding Compiler¶
The SemanticDomainCompiler is the first review-gated symbolic-to-binding
path. It translates a domain intent string into a BindingSpec and can also
emit a complete artefact bundle:
binding_spec.yamlfor the domain interfacepolicy.yamlwith a conservative low-coherence recovery rulereview_notebook.ipynbwith validation and policy-review cellsaudit.jsonwith confidence factors, matched keywords, local retrieval evidence, validation status, dry-run coherence, and Petri-net review reachability metadataREADME.mdfor the generated domainpack directory
The compiler remains deterministic and local. It extracts layer counts,
domain-family keywords, oscillator counts, channel declarations, safe default
actuator mappings, and a review transition in protocol_net. The generated
binding is passed through validate_binding_spec() and a short
UPDEEngine dry run before artefacts are returned.
Local retrieval scans existing domainpacks/*/binding_spec.yaml, domainpack
README content, and long-form public docs under docs/. Each evidence record
is tagged with source: domainpack or source: docs, records matched terms,
and contributes the top score to generated confidence factors. Retrieval
records now also carry a deterministic rank plus ranking_features such as
matched-term count, prompt-term count, source priority, name/phrase match
evidence, and term density. Domainpack retrieval can be disabled with
retrieval_root=None; docs retrieval can be disabled with docs_root=None.
The generated review notebook also carries compiler-side execution evidence.
Before returning artefacts, the compiler writes the generated binding and
policy to a temporary review directory and runs the same binding-schema and
policy-loader checks that the notebook asks the reviewer to execute. The
result is recorded in audit.json and notebook metadata under
notebook_execution.
CLI usage:
spo generate "A 3-layer cardiac rhythm suppression system" \
--name cardiac_review \
--output-dir domainpacks/cardiac_review
spo validate domainpacks/cardiac_review/binding_spec.yaml
semantic ¶
Review-only symbolic compiler from natural-language intent to bindings.
The semantic compiler produces a candidate BindingSpec, policy YAML, review
notebook, retrieval evidence, and audit record from local heuristics and
domainpack/docs evidence. The implementation is split into responsibility
modules (input coercion, retrieval evidence, review notebook, YAML serialisation,
and the orchestrating compiler) behind a stable re-export surface. Generated
artefacts are intentionally reviewable and fail validation before use; this
package does not auto-accept live deployment bindings or actuate a system.
Classes¶
GeneratedBindingArtifacts
dataclass
¶
GeneratedBindingArtifacts(
binding_spec: BindingSpec,
binding_yaml: str,
policy_yaml: str,
notebook_json: str,
audit_record: dict[str, Any],
retrieval_evidence: list[RetrievalEvidence],
validation_errors: list[str],
dry_run_order_parameter: float,
)
Reviewable outputs from symbolic domain intent compilation.
Attributes¶
schema_valid
property
¶
Return True when the generated binding passed validator checks.
Returns¶
bool
True when the generated binding passed every validator check.
Methods:¶
write_domainpack ¶
Write generated artefacts as a reviewable domainpack directory.
Parameters¶
output_dir : str or pathlib.Path Destination directory; the binding spec, policy, review notebook, audit record, and README are written beneath it.
Source code in src/scpn_phase_orchestrator/binding/semantic/compiler.py
SemanticDomainCompiler ¶
Semantic Compiler Bridge for natural language domain modeling.
Translates plain-English system descriptions into formal BindingSpec configurations. It extracts hierarchical structures, typical frequencies, and coupling constraints from text.
Methods:¶
compile ¶
compile(
prompt: str,
*,
name: str = "semantically_generated_domain",
oscillators_per_layer: int = 8,
) -> BindingSpec
Translate a symbolic domain prompt into a BindingSpec.
Parameters¶
prompt : str Natural-language description of the target domain. name : str, optional Name for the generated binding spec. oscillators_per_layer : int, optional Number of oscillators to allocate per generated layer.
Returns¶
BindingSpec The compiled, structurally typed binding specification.
Source code in src/scpn_phase_orchestrator/binding/semantic/compiler.py
compile_artifacts ¶
compile_artifacts(
prompt: str,
*,
name: str = "semantically_generated_domain",
oscillators_per_layer: int = 8,
dry_run_steps: int = 8,
retrieval_root: str | Path | None = "domainpacks",
docs_root: str | Path | None = "docs",
) -> GeneratedBindingArtifacts
Compile domain intent into binding, policy, audit, and dry-run artefacts.
Parameters¶
prompt : str Natural-language description of the target domain. name : str, optional Name for the generated binding spec. oscillators_per_layer : int, optional Number of oscillators to allocate per generated layer. dry_run_steps : int, optional Number of integration steps for the embedded dry-run check. retrieval_root : str or pathlib.Path or None, optional Root directory searched for retrieval grounding evidence. docs_root : str or pathlib.Path or None, optional Root directory searched for documentation grounding evidence.
Returns¶
GeneratedBindingArtifacts The binding, policy, audit record, retrieval evidence, and dry-run result bundle.
Raises¶
ValueError If the generated binding fails validation or the embedded dry run.
Source code in src/scpn_phase_orchestrator/binding/semantic/compiler.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | |
RetrievalEvidence
dataclass
¶
RetrievalEvidence(
domainpack: str,
path: str,
score: float,
matched_terms: list[str],
summary: str,
source: str = "domainpack",
rank: int = 0,
ranking_features: dict[str, float] = dict(),
)
Local domainpack evidence used during symbolic binding generation.
Methods:¶
to_audit_record ¶
Return a JSON-safe retrieval evidence record.
Returns¶
dict[str, Any] Deterministic, JSON-safe audit mapping of the RetrievalEvidence fields.
Source code in src/scpn_phase_orchestrator/binding/semantic/retrieval.py
Functions:¶
compile_symbolic_binding ¶
compile_symbolic_binding(
prompt: str,
*,
name: str = "semantically_generated_domain",
oscillators_per_layer: int = 8,
dry_run_steps: int = 8,
retrieval_root: str | Path | None = "domainpacks",
docs_root: str | Path | None = "docs",
) -> GeneratedBindingArtifacts
Compile domain intent into a reviewable generated domainpack.
Parameters¶
prompt : str Natural-language description of the target domain. name : str, optional Name for the generated binding spec. oscillators_per_layer : int, optional Number of oscillators to allocate per generated layer. dry_run_steps : int, optional Number of integration steps for the embedded dry-run check. retrieval_root : str or pathlib.Path or None, optional Root directory searched for retrieval grounding evidence. docs_root : str or pathlib.Path or None, optional Root directory searched for documentation grounding evidence.
Returns¶
GeneratedBindingArtifacts The generated domainpack artefact bundle.
Raises¶
ValueError If the compilation inputs are invalid or the generated binding fails validation or its dry run.
Source code in src/scpn_phase_orchestrator/binding/semantic/compiler.py
Topos Binding Examples¶
Domain-level topos obligation fixtures and semantic validation examples used by the public roadmap and direct test-linkage gates.
topos_examples ¶
Deterministic topos obligation examples for binding review surfaces.
Classes¶
ToposProofObligation
dataclass
¶
Single proof obligation attached to one domain example.
Methods:¶
to_audit_record ¶
Return a JSON-safe obligation audit record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ToposProofObligation fields.
Source code in src/scpn_phase_orchestrator/binding/topos_examples.py
ToposDomainObligation
dataclass
¶
ToposDomainObligation(
domain: str,
symbolic_prompt: str,
binding_spec: BindingSpec,
policy_rules: tuple[PolicyRule, ...],
obligations: tuple[ToposProofObligation, ...],
binding_object_count: int,
policy_object_count: int,
non_actuating: bool,
proof_boundary: str,
passed: bool,
)
Concrete domain obligation example record.
The object keeps live repository objects for compilation correctness and
converts them into deterministic audit material through to_audit_record.
Methods:¶
to_audit_record ¶
Convert this example into a deterministic JSON-safe audit record.
Returns¶
dict[str, object] Deterministic, JSON-safe audit mapping of the ToposDomainObligation fields.
Source code in src/scpn_phase_orchestrator/binding/topos_examples.py
Functions:¶
build_topos_domain_obligation_examples ¶
Build deterministic topos obligation examples for benchmark consumption.
Returns¶
tuple[dict[str, object], ...] Deterministic, JSON-safe obligation example records.
Raises¶
ValueError If an internally constructed obligation example fails its own consistency checks.
Source code in src/scpn_phase_orchestrator/binding/topos_examples.py
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | |
Topos Semantic Binding¶
Topos-oriented semantic binding helpers for categorical validation surfaces.
topos_semantic ¶
Deterministic audit/proof-obligation validation for symbolic bindings.
Classes¶
SymbolicBindingObligation
dataclass
¶
Single proof obligation outcome for the symbolic-binding functor.
SymbolicBindingObject
dataclass
¶
Category object used in the symbolic-binding proof sketch.
SymbolicBindingMorphism
dataclass
¶
Deterministic relation between symbolic-binding validation objects.
Methods:¶
to_audit_record ¶
Return a deterministic JSON-safe audit record.
Returns¶
dict[str, Any] Deterministic, JSON-safe audit mapping of the SymbolicBindingMorphism fields.
Source code in src/scpn_phase_orchestrator/binding/topos_semantic.py
SymbolicBindingValidationReport
dataclass
¶
SymbolicBindingValidationReport(
schema_name: str,
schema_version: str,
object_count: int,
morphism_count: int,
obligation_records: tuple[
SymbolicBindingObligation, ...
],
objects: tuple[SymbolicBindingObject, ...],
morphisms: tuple[SymbolicBindingMorphism, ...],
passed: bool,
report_hash: str,
proof_boundary: str,
non_actuating: bool = True,
)
JSON-safe deterministic report for symbolic-binding validation.
Methods:¶
to_audit_record ¶
Return a deterministic JSON-safe audit record.
Returns¶
dict[str, Any] Deterministic, JSON-safe audit mapping of the SymbolicBindingValidationReport fields.
Source code in src/scpn_phase_orchestrator/binding/topos_semantic.py
Functions:¶
validate_symbolic_binding_functor ¶
validate_symbolic_binding_functor(
artifacts: GeneratedBindingArtifacts,
) -> SymbolicBindingValidationReport
Validate symbolic compiler output as a source-to-binding functor.
Parameters¶
artifacts : GeneratedBindingArtifacts The generated binding artefacts to check for functorial consistency.
Returns¶
SymbolicBindingValidationReport The validation report: objects, morphisms, and any obligation failures.
Source code in src/scpn_phase_orchestrator/binding/topos_semantic.py
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 | |
Domainpack Validation-Tier Gallery¶
Every binding spec carries a validation_tier (scaffold, partial, or
externally_validated; see VALID_VALIDATION_TIERS in
binding.types) recording how much
external evidence the scaffold carries. A binding is a reusable scaffold, not a
validated detector, so scaffold is the honest default; a pack is promoted only
with a citable evidence trail. These helpers let a Studio Hub select a single tier
or group every pack by tier for a tiered gallery, keeping a broad gallery from
reading as a broad set of validated solutions. See the
Domainpack validation tiers guide.
gallery ¶
Filter and group binding specs by their validation posture for a Hub gallery.
A Studio Hub that lists SPO's domainpacks needs to keep a broad gallery from
reading as a broad set of validated solutions. Every :class:BindingSpec carries
a validation_tier — one of
:data:~scpn_phase_orchestrator.binding.types.VALID_VALIDATION_TIERS. These
helpers let a gallery select a single tier (for example show only
externally-validated packs) or group every pack by tier for a tiered display. The
grouping always covers every tier — including empty ones — so the gallery shape is
stable as packs are promoted.
Classes¶
Functions:¶
select_specs_by_validation_tier ¶
select_specs_by_validation_tier(
specs: Iterable[BindingSpec], tier: str
) -> tuple[BindingSpec, ...]
Return the specs at one validation tier, preserving input order.
Parameters¶
specs:
The binding specs to filter.
tier:
The validation tier to keep, one of
:data:~scpn_phase_orchestrator.binding.types.VALID_VALIDATION_TIERS.
Returns¶
tuple[BindingSpec, ...]
The specs whose validation_tier equals tier (possibly empty).
Raises¶
ValueError
If tier is not a known validation tier.
Source code in src/scpn_phase_orchestrator/binding/gallery.py
group_specs_by_validation_tier ¶
group_specs_by_validation_tier(
specs: Iterable[BindingSpec],
) -> dict[str, tuple[BindingSpec, ...]]
Group specs by validation tier, covering every tier for a stable shape.
Parameters¶
specs: The binding specs to group.
Returns¶
dict[str, tuple[BindingSpec, ...]]
A mapping from every tier in
:data:~scpn_phase_orchestrator.binding.types.VALID_VALIDATION_TIERS
(in sorted order) to the specs at that tier, preserving input order
within a tier. Tiers with no specs map to an empty tuple. A spec whose
validation_tier is not a known tier is ignored, since the validator
is the gate that rejects such specs.