docs(flows): split the subflow-strand paragraph into its three cases - #20377
Merged
objectstack-fleet[bot] merged 2 commits intoSep 28, 2026
Merged
Conversation
The paragraph conflated three outcomes of a paused subflow chain into one
prose block, and its closing sentence ("an ancestor is never stranded,
because resuming it is not what moves it") was written for the child-strand
case only. #15556 (PR #17908, merged c8a006f) shipped a third case the
paragraph never described: the child completes, bubbleToParent resumes the
parent, and the parent's own downstream node throws — the parent itself
lands on the engine's 'stranded' exit and is reported on resumeFailure.
Measured against origin/main a88a1bb:
- packages/services/service-automation/src/engine.ts:1737 (SubflowParentStrand),
:7434 (the 'stranded' exit bubbleToParent records it on)
- packages/plugins/plugin-approvals/src/approval-service.ts:3476 (the
resumeFailure shape: RESUME_FAILED / stranded / repairable)
…n call PM review on PR #20377: remove the two sentences that talk about the page's own prose ("that sentence is scoped to..." / "the claim above does not hold for it") and state the scoping as behaviour instead. Name the third case's repair verb the same way the other two cases do -- the `restore-suspension` REST verb (routed to `restoreConsumedSuspension` at packages/runtime/src/domains/automation.ts:2752), issued on the parent's run id, the one `resumeFailure` names -- rather than only the engine method name.
objectstack-fleet
Bot
deleted the
claude/issue-17940-flows-subflow-strand
branch
September 28, 2026 05:29
This was referenced Sep 28, 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.
Fixes #17940
Clause-②: no
What was wrong
content/docs/automation/flows.mdx's subflow-chain repair paragraphconflated three distinct outcomes into one block of prose, and its closing
sentence — "an ancestor is never stranded, because resuming it is not
what moves it" — was written for exactly one of them. #15556 (PR #17908,
merged
c8a006fc41) shipped a case the paragraph never described, wherethat sentence is false: the child completes,
bubbleToParentresumes theparent, and the parent's own downstream node throws. There the bubble is
exactly what moves the parent, and the parent itself lands on the engine's
'stranded'exit.Before
After (revised per PM review — no self-reference, repair verb named)
Code measured on
origin/maina88a1bb39(not copied from the card)packages/services/service-automation/src/engine.ts:1737— theSubflowParentStrandinterface (runId,repairable: true,error),recorded only on the arm
AutomationResult.statuscalls'stranded'.packages/services/service-automation/src/engine.ts:7434—bubbleToParent:if (parentRes.status === 'stranded')records theSubflowParentStrandunder the child's own run id.
packages/services/service-automation/src/engine.ts:7511—takeSubflowParentStrand(childRunId), the delete-on-read hand-off.packages/plugins/plugin-approvals/src/approval-service.ts:3476— theapprovals decision door's
resumeFailureon abubbleStrand:{ code: 'RESUME_FAILED', runId: bubbleStrand.runId, status: 'stranded', repairable: bubbleStrand.repairable }— matches the card's claimed shape.packages/services/service-automation/src/engine.ts:7994—restoreConsumedSuspension, the repair verb for the parent strand.packages/runtime/src/domains/automation.ts:2752— the REST door,POST /:name/runs/:runId/restore-suspension, routesparts[2](the:runIdpath segment) straight intoautomationService.restoreConsumedSuspension(parts[2], …)— so the samerestore-suspensionverb an operator calls in case (a)/(b) is what athird-case operator calls too, on the parent's run id (the
runIdresumeFailurenames).Binding honoured (thread comment
5697194225): #17541 owns the naming of anynew
AutomationResult.statusmember. This PR coins none —'stranded'isthe status the engine and the approvals door already use today.
PM review addendum
PM review verified all code anchors and asked for two prose fixes, applied
in commit
28c110796:("that sentence is scoped to…" / "the claim above does not hold for
it") and restated the scoping as behaviour.
— the
restore-suspensionREST verb (restoreConsumedSuspensionunderneath), issued on the parent's run id — instead of only the engine
method name.
Gates run (docs-only change, no changeset —
content/docs/**is not apublished package surface)
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands content/docs/automation/flows.mdxderived 40 command(s), same 40before and after the revision. All 40 ran green both times (reconciled with
--ran:40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN). One-timeprerequisite builds these gates needed (
@objectstack/formula+@objectstack/lint, and@objectstack/client+@objectstack/client-react)— neither package's source was touched by this diff. Full command list and
outputs are in the report comment on #17940.
Serial neighbour: draft PR #20344 edits the same file at
:1357and below;this diff's hunk sits at
:1104–:1129, 245+ lines above it — no overlap.Generated by Claude Code