feat(automation): map node — sequential batch approval (ADR-0037 A2)#1709
Merged
Conversation
"Sign off every item in a list, one at a time" as a single `map` node. Unlike `loop` (synchronous body, cannot pause), each item is a full child run, so the per-item subflow may durably pause on its own approval; the map waits for that item, then moves to the next — the run holds ONE program counter throughout (no token tree). Bounded engine change in the resume path only (no scheduler, no traverseNext rewrite): - resumeInternal: a run paused at a `map` node (correlation `map:<childRunId>`) RE-ENTERS the node on resume (re-runs executeNode) instead of continuing past it — so the executor records the just-completed item and starts the next. The default path is unchanged. - bubbleToParent: a map child (`$parentMapNode` in its context) hands its output to the map node and flags completion, vs the subflow 1:1 mapping. - new `map` builtin executor: collection → per-item subflow, item-as-$record when the item is a record, results collected in order, fail-fast in v1. Reuses ADR-0019 linked-runs (#1693); correlation `map:` carries re-entry (no new persisted field). Tests: +5 engine tests (synchronous map, empty, sequential per-item pause with re-entry, fail-fast, cold-boot restart mid-map); full suite 177 green. Showcase: showcase_release_signoff maps over a release's tasks → per-task approval subflow. Browser-verified live: trigger with 2 tasks → task 1 approval opens, paused → approve → ONLY task 2's approval opens (sequential) → approve → run completes. Docs: "Batch approval — a map node" section. Concurrent fan-out stays Track B. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jun 11, 2026
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
ADR-0037 Track A2: a
mapnode for sequential batch approval — "sign off every item in a list, one at a time." Unlikeloop(synchronous body, cannot pause), each item is a full child run, so the per-item subflow may durably pause on its ownapproval; the map waits for that item, then moves to the next. The run holds one program counter throughout — no token tree.As flagged in the revised ADR, A2 is not engine-free (unlike A1). It needs a bounded change in the resume path only — no scheduler, no
traverseNextrewrite:resumeInternal: a run paused at amapnode (correlationmap:<childRunId>) re-enters the node on resume (re-runsexecuteNode) instead of continuing past it, so the executor records the just-completed item and starts the next. Default path unchanged.bubbleToParent: a map child ($parentMapNodein context) hands its output to the map node + flags completion, vs the subflow 1:1 mapping. Reuses the ADR-0019 linked-runs (feat(automation): nested durable pause — subflow chains (linked runs) #1693); themap:correlation prefix carries re-entry, so no new persisted field.mapbuiltin executor: collection → per-item subflow, item-as-$recordwhen the item is a record, results collected in order, fail-fast in v1. Concurrent fan-out stays Track B.Test plan
showcase_release_signofftriggered with 2 tasks → task 1's approval opens, run paused → approve task 1 → only task 2's approval opens (sequential, one at a time) → approve task 2 → runcompleted(start → signoffs×3 → notify_done). Distinct record per item, no dedup collision.showcase_release_signoff→showcase_one_task_signoff. Docs: "Batch approval — a map node" section.🤖 Generated with Claude Code