symfonic.services.shadow.ports¶
ports ¶
The declared port of the shadow / cutover service (LAY-ADR §2, port).
Same cell, same rule as :mod:symfonic.services.models.ports:
facade-compiler → runtime-service is port, so the per-capability
cutover switchboard in :mod:symfonic.agent.cutover may consult this service
only through a declared narrow interface. Before TA2.1 it imported
:mod:~symfonic.services.shadow.cutover, :mod:~symfonic.services.shadow.errors
and :mod:~symfonic.services.shadow.trust directly — three internal modules of
a twenty-two-module service package.
The names below are exactly what the switchboard needs to answer "may this capability leave shadow mode, and on which path" — the criteria table, the evidence recorder, the trust registry, and the one error the refusal raises. Nothing here is defined locally; every name is re-exported from its owning module.
PRIVACY_DELETION_PARTICIPANTS is here for a different importer.
:mod:symfonic.agent.fastapi is ruled platform, whose runtime-service
cell is yes — unrestricted — so tenant_privacy_router could reach
:mod:symfonic.services.shadow.privacy directly and no rule would fire. It
goes through this port anyway: the matrix leaving an edge unchecked is not the
same as the edge being sound, and the rest of symfonic.agent was reworked
onto declared ports. test_the_facade_reaches_runtime_services_only_through_a_port
holds the whole symfonic.agent tree — fastapi included — to that rule.
CutoverCriteriaRecorder ¶
Files cutover evidence and enforces which path a capability may use.
Source code in src/symfonic/services/shadow/cutover.py
CutoverEvidence
dataclass
¶
CutoverEvidence(capability: str, path: CutoverPath, recorded_at: datetime, criteria: dict[str, Any] = dict(), opaque_dependencies: tuple[str, ...] = (), comparison: ComparisonReport | None = None)
One capability's cutover evidence, filed under exactly one path.
CutoverPathError ¶
Bases: ConfigurationError
Cutover evidence was filed under a path the capability may not use.
ExtensionTrustRegistry ¶
Assigns and enforces trust classes. Default-deny by construction.
Source code in src/symfonic/services/shadow/trust.py
classify_port_mediated ¶
classify_port_mediated(extension_id: str, kind: ExtensionKind, *, proof: ConstructionProof, approval: ReviewerApproval, origin: ExtensionOrigin = ExtensionOrigin.FRAMEWORK) -> ExtensionRecord
Promote to port-mediated. Refuses everything short of the bar.
Source code in src/symfonic/services/shadow/trust.py
demote ¶
Force an extension to opaque and bar re-promotion under this id.
Source code in src/symfonic/services/shadow/trust.py
record_of ¶
The record, or a synthesized opaque one. Never raises for unknown.
Source code in src/symfonic/services/shadow/trust.py
register ¶
register(extension_id: str, kind: ExtensionKind, *, origin: ExtensionOrigin = ExtensionOrigin.ADOPTER, reason: str = 'registered without a construction proof') -> ExtensionRecord
Register an extension as opaque. This is the only bulk entry point.