Skip to content

automation: a subflow or map in a region body whose child suspends arms, fails every run at the region boundary, and leaves the child run suspended #28897

Closed

Description

@objectstack-fleet

domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH

Blocked-by: #28846 (its PR changes subflowTargets, which this reads)

Filing gate: ① the #28846 dev measured this before editing, in all six region cases (subflow and map, each in a loop body, a parallel branch and a try_catch slot). It was split off by seat ruling 6568462471. Filed by domain:server seat 3. ⛔ Not a claim.

Reach: a record-triggered (or any) flow whose region-nested subflow / map names a child that suspends (approval, wait, screen) has this behaviour:

The module's own header says the pause "is knowable only at RUN time, and only the run can refuse it", because the child record is not in hand at parse. Since #28840, the arming gate does have the child in hand (declineOntoDisabledSubflows, declineOntoSuspendingSubflowNotice, re-judged on every child registration).

Wanted

  1. Measure the orphan. After the region refusal, is the child run left suspended in storage, and what does a later decision on it do? If it is a leak, the region refusal also settles or cancels the child it started. ⛔ Do not change the refusal itself (service-automation: a durable suspension inside a structured region (loop / parallel branch / try_catch) must fail the run with a named error, not leave progress state and report success — runtime half of #15646 ruling D #18881, ruling D).
  2. A caller whose region-nested subflow / map names a child that can suspend is registered but not armed. Use the existing arming gate with its own FLOW_UNBOUND_CAUSES value naming the region node, the call node and the child's suspending node, re-judged on child registration as automation: a save_notice after a subflow or map whose child suspends passes publish and strands every decision of the parent run #28840 does. ⛔ No new gate. ⛔ No change to FLOW_PAUSE_CAPABLE_NODE_TYPES (ruling D). Update the region-suspension-refusal.ts header so it names the arming gate as the first door.

Shipped flows: HotCRM campaign_enrollment has a region-nested call (a loop body, two member-enroll children). The dev measured that those children do not suspend, so it must keep arming. Pin that.

This narrows arming (a flow that arms today will not), and adds a published cause value. So it is Clause-②: yes (narrowing), with a CONTRACT_REVIEW_TIER review owed.

Dedupe

Read open issues for durable pause structured region, subflow region suspend orphan and region boundary pause subflow: only #28846 (the guards' target list). New.

Reader who acts: domain:server (packages/services/service-automation).

Links back: #28846, #28840, PR #28875, #18881, #15646

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH

    Path: 能用的自动化 | none | P③

    Triage: p3 · domain:server · area:automation · 2026-11-02T03:39Z

    ⛔ Not a claim.

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH

    Claim: PM loop round 1 · card thread · 2026-11-02T05:52Z
    Session: session_01FEkQ5kE5BrPUPNMMyv6oCH (the seat); the card thread is session_01FEkQ5omF1nCbQTGgW1nbRA
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-9kerqb (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#3
    Ruling-ref: the maintainer, 2026-11-01T03:46Z: 「server 车道现在就是你负责,任务有一大堆啊,都可以派,包括 p3」, with 2026-10-26T10:29Z 「p1 p2 处理完了,就可以处理 p3」, and 2026-11-01T06:39Z 「server 队列还是很多任务,再开一个席位吧」. Seat 3 graded p3 under 「定级你可以自己决定」 (2026-11-01T12:11Z).
    File surface: packages/services/service-automation/src/ (engine.ts arming path, region-suspension-refusal.ts, subflow-guards.ts header, subflow-guard-region-calls.test.ts, new tests), the FLOW_UNBOUND_CAUSES declaration wherever it lives, changesets
    Container & model: card thread cmsg_01TenzsRopZj4jMbvjX8uz1X8pL9LbgDKbpvwydZJP7bTD (save_notice, same thread as #28846), mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
    Clause-②: yes (narrowing) — a flow that arms today will not, and a published unbound-cause value is added; CONTRACT_REVIEW_TIER review owed before landing
    Metadata-protocol: none (expected; the dev measures and declares)
    Responsibility: domain:server seat 3 owns the PR to merge
    Thread-read: 6568479800
    Premise: measured by the #28846 dev in all six region cases (os-dev-report 6569441106); the orphaned child run is re-measured first
    Serial constraints cleared: PR #28959 (same files) merged; #28939's thread edits only the held-connector branch of plugin.ts
    Resume-from: none — the branch restarts from origin/main at 4748bac8 or later (its PR #28959 is merged)

    State: → pm:dispatched, assigned to os-project-manager, recorded by this claim. Order: pm-orders/server/order-28897.md (project folder).

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-project-manager · session_01FEkQ5omF1nCbQTGgW1nbRA
    os-dev-report
    {
    "issue": 28897,
    "status": "done, handed back on the wrap-up order; dogfood test verdict not measured at hand-off",
    "branch": "claude/project-thread-9kerqb",
    "pr": "#29096",
    "head": "65a9454675b4b557c5ca827a63b9748c1ba1ac26",
    "session": "session_01FEkQ5omF1nCbQTGgW1nbRA",
    "premise_still_valid": "yes (measured: a leak)",
    "summary": "Arming gate region half: activateFlowTrigger declines (registers, does not arm) a flow whose region-nested subflow/map calls a child that can suspend, after the disabled-subflow and save-notice halves, with new FLOW_UNBOUND_CAUSES value suspending_subflow_in_region; reason names the innermost container, the call node and the child's suspending node; re-judged via rejudgeSubflowCallers on every registration reaching it. Calls are read through one reading, subflowCalls (subflow-region-guard.ts, collectFlowGraphs), which subflowTargets now maps. Orphan: runRegion cancels the child run the subflow/map parked (nestedChildRunId + resolveSuspensionChain + cancelRun, deepest first) before throwing the unchanged refusal; a failed cancel logs at error. Headers: region-suspension-refusal.ts names the arming gate as the first door; subflow-guards.ts no longer claims every body moved unedited. Ride-along enable-door pin added.",
    "measurement": {
    "orphan_before": "6/6 slot x call-type: execute() failed with the region refusal; child in listSuspendedRuns and listSuspendedRunsDurable, hasSuspendedRun true, record paused; resume(child) answered success, ran the rest of the child (record completed), then the up-bubble warned 'resuming parent ... failed'. A leak."
    },
    "tests": {
    "red_first": "subflow-region-suspension.test.ts: 20 cases; base 17 failed / 3 passed (3 controls); head 20/20",
    "ablations": [
    "A1 gate half off: 11 red",
    "A2 re-judge ignores region half: 2 red",
    "A3 no cancel: 7 red",
    "A4 cancel child only, not chain: 1 red",
    "A5 subflowTargets top-level only: 13 red incl. the enable-door pin",
    "A6 outermost container named: 1 red",
    "all via ablation-replace.mjs, restored blob == HEAD, tree clean"
    ],
    "changed_pin": "#28846 notice pin 1 (save_notice after a loop calling a suspending child) now asserts the region decline, reason not naming the save_notice",
    "suites": {
    "@objectstack/service-automation": "exit 0 (257 files, 3319 tests)",
    "@objectstack/plugin-approvals": "exit 0 (107 files, 1376 tests)",
    "@objectstack/trigger-record-change": "exit 0 (12 files, 121 tests)",
    "@objectstack/example-showcase": "exit 0 (42 files, 511 tests)",
    "@objectstack/spec src/automation + src/contracts": "exit 0 (95 files, 2214 tests)"
    },
    "typecheck": "workspace pnpm typecheck (6 GB): spec test-layer tsc killed exit null on the shared box, the rest cancelled; alone: @objectstack/spec (8 GB) exit 0, @objectstack/service-automation exit 0; other packages NOT MEASURED one by one"
    },
    "gates": {
    "derived": 83,
    "run": 83,
    "not_measured": 0,
    "unrun": 0,
    "reconcile": "dispatch-gates --ran exit 0, all 83 exit 0",
    "check_changeset_no_major_with_pr_body": "exit 0 (narrowing, none, patch)",
    "eslint": "--no-inline-config over packages/services/service-automation packages/spec/src/automation: exit 0"
    },
    "dogfood_battery": "under os-verify-lock: closure build VERDICT command-exit 0; dogfood test still running at hand-off: NOT MEASURED",
    "shipped_flows": "examples/** + packages/qa/**: every subflow/map top-level; hotcrm origin/main d4ffe99: campaign_enrollment (type screen, no trigger) calls two non-suspending children from loop bodies; a pin of that shape arms and completes",
    "line_budget": "no budget in the order; diff 12 files changed, 650 insertions(+), 35 deletions(-)",
    "declarations": "Clause-②: yes (narrowing); Metadata-protocol: none; changeset patch on service-automation and spec with BREAKING banner and ADR-0087 no-migration-prescription marker. CONTRACT_REVIEW_TIER review owed (seat).",
    "deviations": [
    "describeSuspendingNode factored out of describeSubflowNoticeTrap (wording unchanged) so both halves name a pause one way."
    ],
    "files_changed": [
    ".changeset/28897-region-call-suspending-subflow.md",
    "packages/services/service-automation/src/dag-traversal.ts",
    "packages/services/service-automation/src/engine.ts",
    "packages/services/service-automation/src/flow-definitions.ts",
    "packages/services/service-automation/src/region-suspension-refusal.ts",
    "packages/services/service-automation/src/subflow-guard-region-calls.test.ts",
    "packages/services/service-automation/src/subflow-guards.ts",
    "packages/services/service-automation/src/subflow-notice-guard.ts",
    "packages/services/service-automation/src/subflow-region-guard.ts",
    "packages/services/service-automation/src/subflow-region-suspension.test.ts",
    "packages/spec/src/contracts/automation-service.test.ts",
    "packages/spec/src/contracts/automation-service.ts"
    ],
    "mcp_calls": "1: mcp__github__issue_read (get_comments #28897); no write tool",
    "api_writes": "3: git push (new branch), fleet-write pr_create (run 41405185491, draft PR #29096, no labels, no assignees, read-back identical 12019 bytes), this report (post-stamped). No GitHub MCP writes.",
    "open_questions": [
    "Reading 1: a caller whose TOP-LEVEL call reaches a child with its own region call to a suspending grandchild is not declined (the child fails its own run; the order names the region-nested caller). Seat to say if it should count."
    ],
    "out_of_scope_findings": []
    }

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-project-manager · session_01FEkQ5kE5BrPUPNMMyv6oCH

    Release: claim 6570160746 (session_01FEkQ5kE5BrPUPNMMyv6oCH, card thread session_01FEkQ5omF1nCbQTGgW1nbRA, branch claude/project-thread-9kerqb) · 2026-11-02T07:38Z · seat 3 shift close (maintainer 2026-11-02T07:10Z 「尽快提交代码,然后收工」, 2026-11-02T07:33Z 「pm-dispatch 中车道下班的流程,都要走完」); handed back, no stay-behind
    Produce: draft PR #29096 (os-dev-report 6571401166)
    Resume-from: claude/project-thread-9kerqb@65a94546

    • Next: a CONTRACT_REVIEW_TIER review (Clause-②: yes (narrowing), new unbound cause suspending_subflow_in_region), then ACCEPT and land. Dogfood finished green after the report (383 files, VERDICT 0); the PR body still says NOT MEASURED. Dev reading for the reviewer: a top-level call to a child whose own region call reaches a suspending grandchild is not declined.
    • State: pm:dispatched → pm:queue, assignee cleared.
  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Claim: PM loop round 1 · takeover of a released claim · 2026-11-02T08:13Z
    Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat; no new dev: the seat lands the existing draft)
    Account: os-steve (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-9kerqb
    Worktree: none (review only)
    Domain: domain:server
    Seat: domain:server#3
    Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」 The predecessor's Release: 6571724612 names the next steps.
    File surface: unchanged from claim 6570160746 (PR #29096's files); no new code unless a review round asks for it
    Container & model: seat-held takeover, mode:thread for any REWORK round, model: fable (reason: the narrowing face owes one CONTRACT_REVIEW_TIER review before the queue, judged from the card content per dispatch-gates --tier; the review runs as an isolated at-tier subagent), effort: xhigh
    Clause-②: yes (narrowing)
    Metadata-protocol: none
    Responsibility: domain:server seat 3 owns the PR to merge
    Thread-read: 6571724612
    Premise: holds (draft PR #29096 at 65a94546, CI 55 success / 9 skipped on that head)
    Serial constraints cleared: none (no open lane PR or claim names packages/services/service-automation/src/engine.ts or subflow-guards.ts besides this one)
    Resume-from: claude/project-thread-9kerqb@65a94546

    State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim.

  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    ACCEPT → PR #29096 comment 6572502759 (contract review PASS 6572481670, head 65a94546). Landing: ready + auto-merge now.

  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Follow-up: the two non-blocking should-fix items of the contract review on PR #29096 (6572481670) are carried by #29166 (finding, ungraded).

  8. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Landing record · #28897 · PR #29096

    domain:server seat 3 · session_01ADHkmQJdgarUjPLNgFBY67 · 2026-11-02T09:47Z (taken over from session_01FEkQ5kE5BrPUPNMMyv6oCH, sign-off brief on #26761)

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29096-*' 0 refs (released)
    Ancestry git merge-base --is-ancestor 1ac1c24a74 origin/main yes
    Content git grep -n "export function regionSuspendingCall" origin/main -- packages/services/service-automation/src/subflow-region-guard.ts line 102
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions