Skip to content

feat(approvals): add the approval orchestration node producer - #538

Merged
arantespp merged 4 commits into
mainfrom
claude/approvals-prd-update-8zmzra
Jul 14, 2026
Merged

feat(approvals): add the approval orchestration node producer#538
arantespp merged 4 commits into
mainfrom
claude/approvals-prd-update-8zmzra

Conversation

@arantespp

Copy link
Copy Markdown
Member

Summary

Implements producer #1 of the Approvals PRD (docs/prd-approvals.md): an approval orchestration node that converts a risky tool call into a human decision through the approvals queue landed previously (#537). A run parks on the node, the platform files an ApprovalItem, and resolving it (approve / reject / expire) resumes the run and routes it down the matching decision edge.

What's included

  • New approval node type — resolves tool_id / arguments / reasoning / evidence / predicted_impact / expires_in against run state and parks the run as awaiting_input, like a human node. Extracted into orchestrationApprovalNode.ts.
  • Emit at settle — when a run settles into awaiting_input on an approval node, the engine emits an ApprovalItem (origin: node, linked to the run + node) and stamps approval_id / expires_at onto the persisted required_action.
  • Resume via a producer-registered callback — the approvals module invokes a registered handler on resolution; the engine registers one that resumes the parked run. The dependency points one way (engine → approvals), so the approvals module never imports the engine (no cycle).
  • Decision routing — the decision (approved | rejected | expired) becomes the node's branch label. Labeled edges route by decision (the counterpart of a condition node); an unlabeled edge follows only on approval. Server-side expiry routes the run down its expired edge.
  • Validation, OpenAPI, docsapproval requires tool_id; node schema documented in orchestrations.yaml; orchestrations.md gains a Node Types row + an "Approval Nodes" section; approvals.md clarified.
  • Tests — end-to-end integration test (approvalNode.test.ts): park → approve/reject/expire → resume + route, plus double-resolve 409.

Verification

tsc typecheck ✓, ESLint ✓, docs-lint ✓, SDK/CLI regenerated ✓. Server integration tests can't run in this environment (no Docker runtime), so they run in CI build-and-test.

Notes

  • The result field of an approved decision stays null in v1 — the node produces the decision and a downstream tool node executes the approved action, rather than the platform auto-executing at resolution.
  • Smoke-test steps for this flow are deferred (the flow is covered by the integration test).
  • Remaining PRD phases (tool-call interception, exceptions, activity feed) are follow-ups.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 3 commits July 14, 2026 17:41
Wires producer #1 from the Approvals PRD: an `approval` orchestration
node that parks a run for a human decision through the approvals queue.

- New `approval` node type (orchestrations): resolves tool_id/arguments/
  reasoning/evidence/predicted_impact/expires_in against run state and
  parks the run as awaiting_input, like a human node.
- The engine emits an ApprovalItem (origin=node, linked to run+node) when
  the run settles into awaiting_input, stamping approval_id/expires_at onto
  the persisted required_action.
- Resolution resumes the parked run via a producer-registered callback, so
  approvals never imports the engine (dependency points engine -> approvals).
  The decision (approved|rejected|expired) becomes the node's branch label:
  labeled edges route by decision; an unlabeled edge follows only on
  approval. Server-side expiry routes the run down its expired edge.
- OpenAPI node schema, validation (approval requires tool_id), module docs,
  and an end-to-end integration test (park -> approve/reject/expire ->
  resume + route).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDwNa8xgN4HGPbnchuuG82
The expiry sweeper resumes the run detached, so the run transitions
through a transient 'running' state. Poll until a terminal status rather
than just leaving 'awaiting_input', which raced the resume.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDwNa8xgN4HGPbnchuuG82
Adds a direct unit test for executeApprovalNode covering the full/absent
mapping cases, default vs explicit expiry, null/non-object coercion, and
the missing-toolId guard — clearing the per-file branch threshold and the
global 100% function-coverage threshold. All 2996 tests already pass; the
job was failing on coverage only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDwNa8xgN4HGPbnchuuG82
@github-actions

Copy link
Copy Markdown

Deploy Outputs

Package Stack Output Key Output Value
@soat/website SoatWebsite-claude-approvals-prd-update-8zmzra BucketWebsiteURL http://soatwebsite-claude-approvals-prd-upda-staticbucket-rq33s0otg4dv.s3-website-us-east-1.amazonaws.com

@arantespp
arantespp merged commit 90fd793 into main Jul 14, 2026
5 checks passed
@arantespp
arantespp deleted the claude/approvals-prd-update-8zmzra branch July 14, 2026 18:45
arantespp added a commit that referenced this pull request Jul 14, 2026
* docs(approvals): mark Phase 1 complete in the PRD checklist

Phase 1 (approvals queue core + approval orchestration node) shipped in
PRs #537 and #538. Update the implementation-status checklist and phase
headings to reflect what is done vs deferred (dedup/re-classification →
Phase 2/guardrails; exceptions → Phase 3; activity feed → Phase 4).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDwNa8xgN4HGPbnchuuG82

* docs(approvals): add the approval-gate tutorial

Adds an end-to-end tutorial for the approval orchestration node: create a
gated orchestration, start a run that pauses awaiting approval, then
approve one run and reject another and watch each resume down the matching
decision edge. Registers it in the sidebar and links it from the Approvals
module's Related Tutorials. Runs deterministically (no AI provider), so
the tutorials-test job exercises the park -> resolve -> resume flow via the
CLI end to end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MDwNa8xgN4HGPbnchuuG82

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants