Skip to content

[Decision] service-automation: should a refusing end INSIDE a structured region propagate out and terminate the run, or stay a loud refusal at the region boundary? #18112

Closed

Description

@claude

Raised as an open question by the domain:services dev that delivered #15788 (lane 2 of the #14945 ruling 2′, PR #18109), and filed here by the seat so the decision is not lost. ⛔ The dev does not file; it reports.

The question

The #14945 ruling says nothing about regions. An end node carrying outcome: 'refused' inside a loop body or a try_catch region is therefore undecided.

What shipped, and why it is an interim rather than an answer

Option A shipped: a refusing end inside a region is a loud failure at the region boundary — the same line where runRegion already refuses a durable pause.

The dev's reasoning, which this seat accepted:

  • A refusal terminates the run, and a region body cannot end one.
  • Left to propagate today, the signal unwinds into try_catch's own catch arm, which reads every throw as the try region FAILING. So the author's refusal would run the error path and the run would still record completed — i.e. the old silence with an extra step.
  • ⛔ Nothing an author had is narrowed: an end inside a region was a no-op whatever its outcome, so this shape has never once been honoured.

⭐ It is the interim that 「prefer failing to falling back」 decides, and it forecloses a silent wrong answer. The loud message is the discoverable place a reader lands.

Option B — the real design question

Propagate the signal out of every container, so a refusal inside a loop or try region terminates the whole run. That needs:

  1. try_catch (and a check of parallel / map) taught to rethrow the refusal rather than catch it — a refusal is a successful evaluation that says no, ⛔ not a failure, so a catch arm is the wrong receiver.
  2. A decision about the in-flight siblings of a parallel gateway — ⚠️ the same scope ADR-0019 M1 explicitly left out for the durable pause. Whatever is decided here should be decided for both, or the two signals diverge inside the same containers.

⇒ This is a ruling-seat decision, ⛔ not a lane-2 implementation detail, which is why PR #18109 did not ride it in.

Precedent to weigh

The durable pause (FlowSuspendSignal) already refuses at the same boundary, and ADR-0019 M1 left the parallel-sibling question open there too. Option A keeps the two signals consistent; option B fixes both or deliberately splits them.

Related: #14945 · #15788 · PR #18109 · ADR-0019 M1

⛔ domain:*, type and priority are the triage seat's; this card is filed ungraded. The DECISION belongs to the seat that owns the #14945 ruling.


Generated by Claude Code

Activity

  1. added
    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed
    on Sep 14, 2026
  2. hotlong commented on Sep 17, 2026

    @hotlong
    Contributor

    Ruling: batch #146 item 2 · letter A (a refusing end inside a structured region stays a loud failure at the region boundary; the shape is additionally refused at authoring time — folded into #15646's validate rule) · maintainer 「146 同意」 2026-09-17T13:16Z

    Director seat, summon #24, session_01Wj1HUjzyeiBQ8atRf1ZhaL. Presented in detail with the recommendation A + 编写期拒绝; the maintainer agreed 「146 同意」. Facts (this card, PR #18109): option A shipped — a refusing end inside a loop body or try_catch region fails loudly at the same boundary line where runRegion refuses a durable pause; left to propagate, the signal would land in try_catch's catch arm as a failure and the run would still record completed; an end inside a region has never once been honoured, so nothing an author had is narrowed. Option B (rethrow through every container + decide parallel siblings) is the same scope ADR-0019 M1 left open for the pause and is now governed by #3267's ruling 禁 (batch #146 item 1).

    Ruling — A, plus the authoring-time half

    Four-facet reading: ① the two signals stay consistent in the same containers; ② zero authors depend on the shape; ③ loud at runtime already, now loud at authoring; ④ no engine surface added.

    Execution

    This card is absorbed by #15646: closed completed here with the scope line added on #15646 (comment), so the implementing seat carries both halves in one PR (Part of #18112 on that PR is welcome but not required). No lane label changes.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions