symfonic.agent.cutover.criteria¶
criteria ¶
Cutover criteria: the evidence a switch needs before it may be flipped.
Every capability here is non-shadowable in the T2.3.7 sense — the legacy
engine's paths reach adopter tools, adopter plugins, and contributed prompt
sections, none of which can be replayed under effect suppression. So the
evidence road is the non-shadow one, and its three criteria are the ones
symfonic.services.shadow.cutover already enforces: a parity suite, a
characterization record, and a live cutover.
The ledgers below are not claims; they are citations. Each entry points at a
file in the build's own evidence tree, and a capability whose live cutover has
not happened yet carries None there rather than an optimistic string —
which is exactly why invocation.stream stayed on legacy for as long as it
did. It no longer does: TA8.2 filed the parity report and the call site, so
invocation.stream joined invocation.run on the kernel. TA8.30 filed the
third, invocation.stream_typed, citing ST2's parity rather than re-deriving
it -- so all three switches in :data:DEFAULT_CRITERIA are complete and all
three route to the kernel.
Say precisely what that means, because the word "flipped" collects meanings it
has not earned. It means the route is derived from filed evidence and comes
out KERNEL. It does not mean the legacy body is unreachable — dispatch
still falls back out of the migrated envelope, and on a release line that
predates the text-delta chunk contract stream() takes legacy on purpose
(see invocation.stream's entry below). Unreachability is a separate
measurement and RET-6's, not this ledger's.
There are two ledgers, and the split is the same one routes.py makes:
- :data:
DEFAULT_CRITERIAis what gates a flip, so it holds exactly the names dispatch reads. A record here is an argument the switchboard accepts. - :data:
COVERAGE_EVIDENCEis what was built and verified for the nine capabilities dispatch does not route through. Same citations, no flip to gate, and a separate type so the distinction cannot be lost by assignment.
One ledger held all eleven, and the switchboard's constructor refuses a
register by name -- so CutoverSwitchboard(criteria=DEFAULT_CRITERIA), the
most obvious thing a caller can write, raised on models. The exported
default has to be constructible with, or it is not a default.
CoverageEvidence
dataclass
¶
CoverageEvidence(kind: CoverageKind, parity_suite: str | None = None, characterization: str | None = None, live_cutover: str | None = None, dispatch_proof: str | None = None, opaque_dependencies: tuple[str, ...] = ())
What was built and verified for a capability nothing routes through.
Deliberately without complete. On a switch, complete is the
predicate that flips it; a register has no flip, so the same word here
would answer a question nobody can act on -- and that reading is how "nine
of eleven complete" came to be heard as "nine of eleven serving turns".
What it answers instead is :attr:verified: the evidence this kind of
register owes has been filed. A true claim, and a different one.
CoverageKind ¶
Bases: StrEnum
How a migrated capability reaches real turns — and so what proves it.
One requirement list for all nine registers was wrong in a way that matters
to the instrument: it demanded a live_cutover citation from every one,
and only three can have one. memory and prompting are composed and
dispatched on every hydrating turn since #14 and #21 — through the
envelope, on the evidence a bundle carries — and reported verified =
False because no switch flipped to make that happen. The ledger built to
stop understating progress was understating exactly the two capabilities
that had travelled furthest.
So the requirement is a function of the kind:
- :attr:
CALL_SITE— the migrated implementation is the only one left on the engine's call path. Proof is that call site, insrc/. - :attr:
ENVELOPE— composed and dispatched through admission, on bundle evidence rather than a route. Proof is the integration test that shows the segment reaching the model; there is no call site to name because the legacy body is still reachable when the envelope refuses. - :attr:
BUILT— implemented and verified, and nothing dispatches it. Parity and characterization are the whole claim, and asking for more would file an optimistic citation to satisfy a field.
SwitchCriteria
dataclass
¶
SwitchCriteria(parity_suite: str | None = None, characterization: str | None = None, live_cutover: str | None = None, opaque_dependencies: tuple[str, ...] = (), preconditions: tuple[str, ...] = ())
default_criteria ¶
A mutable copy of the flip ledger, one per switchboard instance.