symfonic.services.switching.binding_stage¶
binding_stage ¶
DMC-2 — the compiled binding stage, executed once per invocation.
The plan is compiled once and never changes. The binding is not part of it:
if it were, a long-lived Agent would keep serving the generation that was
current when it was constructed, and a revert would require every adopter to
rebuild their agents. So the plan carries the stage — a declaration of which
bundle to bind and under whose scope — and executing that stage at the start
of each invocation is what captures one atomic vector for that invocation
alone.
BindingStage
dataclass
¶
BindingStage(bundle_id: str, tenant_scope_hash: str = '', inherited_pin: InvocationPin | None = None)
A bind-phase stage: what to bind, never what was bound.
Deliberately holds no vector, epoch, or binding source. Two invocations of one compiled plan must be able to observe two different generations, and a stage that cached a resolved vector could not express that.
child ¶
Derive the stage a sub-agent runs under (EFX-L-2: never widening).
A child inherits the parent's pin rather than resolving its own. A child that re-resolved could land on a newer generation mid-way through its parent's invocation, which is the exact mixed-generation run that CUT-SS-4 forbids.
Source code in src/symfonic/services/switching/binding_stage.py
execute
async
¶
Capture exactly one generation vector for one invocation.