ProtocolScope
The builder scope of a MidnightSdk.runProtocol saga — an ordered list of idempotent, ledger-anchored steps (#253 + #254).
The engineering pattern: the blockchain is the durable execution journal. Each step declares a doneWhen predicate that reads the CHAIN; before running a step the engine asks the chain, and if the effect is already there it SKIPS. So:
re-running a saga (after process death, or on app resume) skips every already-landed step → resume-for-free, no fragile local workflow store, and
no double-submit — re-running is always safe.
The whole saga runs as ONE foreground operation (the Layer-1 framework keeps the process alive + shows one notification + fires one finalization push); the inner contract.calls coalesce under it via the registry's nesting guard.
Because this is a plain suspend block, real control flow between steps — if, while, inline waits — is native Kotlin (a fluent .then() chain can't express it).
Functions
Boundary for an UNBOUNDED wait on a counterparty (e.g. the opponent's move). No foreground service may span it, so if doneWhen isn't yet true the engine ENDS this segment — releasing the foreground service — and the saga resumes (re-run via MidnightSdk.runProtocol with the same id) when the counterparty acts. Ledger- anchored doneWhens carry the resumed run forward past the already-done steps.