feat(showcase): parallel approval example + docs (ADR-0037 Track A)#1708
Merged
Conversation
"Finance AND legal sign off concurrently" is one `approval` node with two approver groups and behavior: 'unanimous' — not two parallel pauses. ADR-0037's Track A: the aggregating-node pattern (Camunda multi-instance / Step Functions Map) covers parallel/batch approvals with the engine's existing single program counter, no token tree. - showcase_invoice_signoff: on invoice send, one approval node opens a single request listing both finance + legal in pending_approvers (notified in parallel); unanimous holds until both approve, then resumes down `approve` (→ notify); any rejection resumes down `reject` (→ flag held). - flow guide: new "Parallel approvals — one aggregating node" section with the config and a pointer to ADR-0037 Track B for the larger pause-inside-region capability. No engine/service change — the unanimous-over-N-groups aggregation already exists and is unit-tested (approval-service.test.ts). Browser-verified live: one request with [role:finance, role:legal] pending; approving finance keeps it paused with legal still pending; approving legal resumes to completed; the reject path flags and completes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
os-zhuang
added a commit
that referenced
this pull request
Jun 11, 2026
Building A2 surfaced a real error in the ADR: it claimed Track A's `map` / multi-instance node needs "no change to the engine's execution model." Examined against the resume/bubble code, that is false for any map that serves batch approval (each item can pause): - concurrent map needs durable N:1 aggregation + per-parent serialization + completion-ordering handling (part of Track B's hard concurrency, confined to one node); - sequential map needs resume-INTO-the-node (next item) instead of the engine's resume-past-the-node default (the DAG has no back-edge to loop the node); - only a synchronous, non-pausing map is engine-free, and that does not serve batch approval. Splits Track A into A1 (aggregating approval — truly free, shipped #1708) and A2 (map node — a bounded, separately-justified engine task, design-first). A1 covers parallel approvals at zero engine cost; A2 is not a free rider on it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
First step of ADR-0037 Track A: prove and showcase that parallel approvals ("finance AND legal sign off concurrently") work today as a single aggregating
approvalnode — no engine-core change, no token tree.behavior: 'unanimous'over two approver groups opens onesys_approval_requestwhosepending_approverslists both groups (notified in parallel) and stays suspended until both approve. This is the Camunda multi-instance / Step FunctionsMappattern: one program counter, one pause/resume.Changes
showcase_invoice_signoff— on invoice send, oneapprovalnode aggregates finance + legal (unanimous); approve → notify, reject → flag held.No engine/service code: the unanimous-over-N-groups aggregation already exists and is unit-tested (
approval-service.test.ts).Test plan
[role:finance, role:legal]pending → approving finance keeps itpausedwith legal still pending → approving legal resumes tocompleted(start → dual_signoff → notify_cleared).reject→flag_heldsets the invoice back to draft → completed.pnpm --filter @objectstack/docs buildgreen; flow registers + validates at backend boot (the two pre-existingpages/*.page.tstsc errors are unrelated to this change).🤖 Generated with Claude Code