OptionalbeforeOptionalbeforeHost policy that must pass immediately before a validated run start.
OptionalreconcileSelf-healing hook invoked after a status() read reports the run suspended, so every status poll of a stuck run doubles as a check for a gate whose approval never made it into the queue (see reconcileApprovalsForSummary in approval-bridge.ts). Awaited rather than fire-and-forget by default: this host-agnostic layer has no ctx.waitUntil of its own to keep a detached promise alive past the response, so a plain awaited call is what it can offer on its own. Reconciliation pages the run's full approval history and may supersede stale open records before filing a fresh one, so the two ctx-capable hosts (deploy/worker.ts and the showcase worker) hand this hook a wrapper that detaches the real work via ctx.waitUntil and resolves immediately — this option's contract (an awaited function of this exact shape) is unchanged either way, only what a given host's function actually blocks on. A throw is caught and logged here, never surfaced to the caller: a broken reconcile must not turn a working status read into a 500; the next poll simply retries. Absent => today's behavior (no reconciliation). Hosts wire reconcileApprovalsOnStatus(systemPrincipalId) here, optionally wrapped for waitUntil-detachment.
Authenticates the request and resolves the actor-scoped approval service and server-owned id minters. undefined yields 401.
Host topology: in-process runtime, or a DO stub fetch.
How this host honours idempotencyKey on POST /runs — the reservation
store plus the liveness probe that resolves a claimed-but-unpersisted run.
REQUIRED, and with no undefined in the type, for the reason
ExecutionFenceWiring spells out: an option a host may omit is one a host
will omit, and the failure mode of omitting THIS one is silent. A router
that ignored an unwired key would answer an exactly-once request with
at-least-once behaviour, and the caller would have no way to find out. The
typed opt-out ('none') is honest — it makes every keyed start refuse with
IDEMPOTENT_START_UNSUPPORTED — and unkeyed starts are unaffected either way.
The probe travels WITH the store rather than beside it because a store without one cannot answer the only question the reservation cannot settle on its own, and a host that wired the first and forgot the second would fall back to guessing.
OptionalsystemSystem-principal id used to authorize bridge bookkeeping. Approval requester provenance comes from the run summary, so this id need not be globally disjoint from human ids. Default: 'flowsafe-system'.
OptionalterminateOptional for compatibility; when supplied, mounts POST .../terminate.
The catalog: GET /workflows lists these; POST /runs resolves against them
and enforces each one's allowedRoles.
Metadata, not WorkflowModules: the router registers nothing, so depending
on the registration machinery would force every host to build a
WorkflowModuleContext (and its AuditLogger) just to expose a route. Hosts
pass modules.map((m) => m.meta); that the ids match what was actually
committed is asserted at registration (see buildShowcaseRuntime).
Host policy that must pass immediately before a validated raw resume.