symfonic.kernel.finalize¶
finalize ¶
The finalize seam: capability stages that close a turn that finished.
Not :mod:symfonic.kernel.finalizers, and the names are close enough that the
distinction has already cost a reader once. That module is the run's finalizer
stack -- callables popped during teardown, which the kernel owns. This one
dispatches the FINALIZE phase of the stage ladder, which capabilities
contribute to. Phase.TEARDOWN is kernel-owned and stays closed; FINALIZE
is the last rung a capability may reach.
Only a turn that finished. The caller runs this after the loop completes and before the outcome is assembled, so a paused run and a failed run never reach it. That is deliberate rather than incidental: the phase's first real consumer is memory's flush, and publishing what a turn staged is exactly the thing that must not happen when the turn did not produce it. A pause is resumable and its memories belong to the resumed turn; a failure produced no answer to remember.
It applies nothing. apply=None, the same documented case
post-model states: no contract exists for what a finalize contribution
mutates, and inventing one here would be the fabrication those modules refused.
A finalize stage is here for its effect, and its receipt rides in the trace.
It grants explicitly. grants=None skips the effect check rather than
failing it, so a rung that forgets the argument reopens STG-8 in silence -- the
PR #92 class. Every other rung passes it by hand for that reason and this one
does too.
FinalizeContext
dataclass
¶
FinalizeContext(plan: Any, request: Any, stage: Any, resolved: Any, turn: Any, transcript: Any = None)
What a finalize stage is handed.
run_finalize
async
¶
run_finalize(plan: Any, request: Any, turn: Any, *, resolved: Any = None, transcript: Any = None, handlers: Mapping[str, StageHandler] | None = None) -> tuple[StageTrace, ...]
Dispatch the finalize stages for one turn that ran to completion.