OptionalreconcileAuthenticates the request and binds the tenant scope: the approval service, the runId mint, and the ownership predicate all come from the resolved TenantContext. undefined yields 401.
Host topology: in-process runtime, or a DO stub fetch.
OptionalsystemCreator identity for bridge-queued approval records. Only the id is configurable — the role is 'operator' (create-capable) and the tenant is ALWAYS the request's resolved tenant, so the record lands in the same tenant as the run it gates. Must differ from human actor ids or the separation-of-duties check can never fire. Default: 'flowsafe-system'.
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).
Self-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(systemActorId) here, optionally wrapped for waitUntil-detachment.