Status: Developer preview — contract-stable per @nexislabs/ai-platform v1; not yet serving public traffic.A run parks pending a human or peer decision whenever the policy engine (design spec §3.3) classifies a proposed action above
auto:
auto | peer_review | human_approval | deny, each with a TTL and approver
requirements attached. deny never reaches an approval — the action is
rejected outright. The other two levels emit
approval.required.
Approval semantics are the same for mode:"turn" and mode:"task": the
stream/run pauses, the caller renders the canonical payload, and the caller
posts the decision back.
The approval.required event
Repeated here for convenience — see Events
for the full envelope.
action_digest
The design spec describes resume_task_after_approval as digest-bound:
the digest binds a decision to the exact canonical payload that was
proposed, so a decision cannot be replayed against a different action. This
mirrors the render == record == gate-match invariant the existing
first-party approval domains already hold (design spec §3.3).
Neither source in scope for this reference states the digest’s algorithm or
where it is carried on the wire response — this reference assumes it
travels alongside (or is derivable from) the approval.required event, and
flags the gap below rather than inventing a transport.
Endpoint: approve or reject
Request body
Behavior
A valid call invokesresume_task_after_approval, which unparks the run.
The caller should continue consuming the run’s event stream (or webhook
deliveries) rather than expecting the full result synchronously from this
call — the design spec does not describe this endpoint’s success response
body beyond “resumes the run.”
The design spec separately notes that today’s wakeTaskWorkflow swallows
errors when the underlying sendEvent doesn’t land, and states the fabric’s
approve wrapper must fail loudly instead — i.e., a 2xx from this endpoint
is meant to guarantee the resume was actually delivered to the run, not just
accepted for delivery.
Errors
approval_timed_out— the approval’sexpiresAtpassed before a decision was posted.- Posting against a run with no pending approval, an already-resolved
approval, or a mismatched
action_digestis expected to be rejected — most plausibly asconflict, but neither source ties a specific code to this case; treat as inferred, not confirmed.
Inline approvals (mode: turn)
The publishedAiPlatformChatRequestV1 schema carries a second,
differently-shaped approval mechanism: an approvals array on the request
itself.
Ambiguity. The design spec states approval semantics are “identical in both modes,” and describes that contract asaction_digest+decision. The published chat schema instead threadsapprovalId+receipt(resubmitted as part of a fresh request, presumably to continue amode:"turn"stream past anapproval.requiredpause). Whetherreceiptis an encodedaction_digest/decisionpair, or a distinct mechanism that predates the fabric’s/v1/runs/:id/approveendpoint, is not stated by either source. Both shapes are documented here rather than merged into one, silently-assumed contract.