symfonic.capabilities.human.resume¶
resume ¶
The resume command contract โ one path for ask_user and generic interrupts.
The shipped engine had two resume methods with the same six steps in the same order and three differences between them, two of which were accidental. Here there is one, and the differences are read off the registration.
Consume comes last on purpose. Every step before it can be retried by an honest caller who mistyped an answer; the claim is the one step that cannot. Putting it earlier would mean a malformed payload burns a token the user then cannot re-answer โ which turns a validation error into "ask the question again".
HK2 (TA8.35) added a seventh step in the same position for the same reason: the paused turn's state is rebuilt from the checkpointer before the claim, so a resume that fails part way through consumes nothing and the token still redeems.
ResumeService ¶
ResumeService(*, tokens: PauseTokenService, registry: InteractionRegistry, payloads: PausePayloadStore, clock: Callable[[], float] = time.time, audit: Callable[[CrossScopeRedemption], None] | None = None, turns: TurnCheckpointStore | None = None)
Turns one redemption attempt into either an outcome or a named refusal.
Source code in src/symfonic/capabilities/human/resume.py
resume
async
¶
Redeem one token. require_turn is the caller's demand, not the
request's.
A route that will continue the run needs the recorded turn state and must be refused, by name, when there is none. A route that only needs the answer validated -- the legacy body, which continues through its own saver -- must not be, or every token minted before this build stops resolving the moment the deployment upgrades. Same six checks, same order, one decision about what counts as missing.