Skip to main content

Module runtime_session_resumer

Module runtime_session_resumer 

Source
Expand description

Production SessionResumer that resumes a paused flow by feeding a synthesized IngressEnvelope back through the runtime ingress entry (StateMachineRuntime::handle).

§How a resume is keyed (verified against engine/runtime.rs)

When a sorla.call await node pauses, PackFlowAdapter::call persists the wait via FlowResumeStore::save(envelope, wait). The wait is keyed by build_store_ctx, which derives:

  • a store hint = session_hint (else canonical_session_hint), and when pack_id is present, suffixed with ::pack=<pack_id>;
  • a user id = sha256(store_hint) (see derive_user_id);
  • a reply scope = the envelope’s ReplyScope (whose scope_hash covers conversation/thread/reply_to).

To resume, FlowResumeStore::fetch(envelope) re-derives the same triplet, so the synthesized envelope MUST reproduce the exact store hint and reply scope used at save time. The dispatch correlation id echoed in the response is ctx.session_id — the canonical session hint (optionally carrying the ::pack=<id> suffix). This resumer splits that suffix off, sets the BARE hint as session_hint (so build_store_ctx re-appends the pack suffix exactly once), carries the recovered pack_id, and rebuilds the reply scope by parsing the conversation out of the canonical hint (tenant:provider:channel:conversation:user).

§Keying + routing caveat (IMPORTANT — see PR notes)

Resuming through handle requires the synthesized envelope to (a) ROUTE via StateMachine::step, which needs a registered (pack_id, flow_id), and (b) KEY the saved wait via FlowResumeStore::fetch, which needs the store hint (<bare hint>::pack=<pack_id>) and the reply scope (scope_hash over conversation/thread/reply_to).

The dispatch wire contract (greentic_types::RuntimeDispatchResponse plus the Greentic-* headers) carries only (tenant, env, correlation_id). The correlation id is the canonical session hint, which embeds the conversation (4th :-segment) but NOT the pack_id or flow_id needed to route.

This resumer recovers pack_id from a ::pack=<id> suffix (the convention pinned by tests/sorla_node.rs, where ctx.session_id carries it) and flow_id from an additional ::flow=<id> marker. For production resume to work, the dispatch side must therefore emit a correlation id of the form <bare hint>::pack=<pack_id>::flow=<flow_id> (or the wire contract must be extended to carry pack/flow, or a server-side correlation_id → (pack, flow, scope) map must exist). A bare canonical hint alone is NOT resumable.

Waits whose original inbound used a non-empty thread/reply_to ARE resumable: execute_sorla_call appends ::thread=<t>/::reply=<r> markers (each omitted when empty), and this resumer strips them and feeds them back into the synthesized ReplyScope so fetch recomputes the same scope_hash save used. The no-thread case is unchanged (no markers emitted → thread/reply_to stay None).

Structs§

RuntimeSessionResumer
Resumes paused flow sessions by driving the runtime ingress entry.