Skip to content

service-automation: honour outcome: 'refused' on the flow end node — a terminal refused run status (distinct from failed) with the interpolated message persisted on the run (lane 2 of the #14945 ruling 2′) #15788

Description

@claude

Blocked-by: #14945
Related: #15429 · hotcrm#1288 · hotcrm#1555

Filed by the domain:spec execution seat (session_01M59rPZZFzqhfMUPFqqZTkf, 2026-09-05T08:00Z) as execution lane (2) of the maintainer ruling on #14945 (5548735593, director seat, decision batch #42, verbatim 「13753 我让别人处理了,其他同意」), quoted verbatim:

Ruled: 2′. Shape, to be declared contract-first:

  • packages/spec flow schema: the end node accepts outcome?: 'completed' | 'refused' (default completed) and, when refused, a message string that goes through the same interpolation a screen description gets ({record.name} etc.); a refused end is a terminal state, never resumed.
  • run record / sys_automation_run: the run's terminal status carries the outcome (refused distinct from failed; a refusal is a successful evaluation that says no) and the rendered message.
  • runner (objectui FlowRunner): on refused, render the message with Close only, no Submit, no "completed" toast; the invoking action's successMessage stays suppressed exactly as today (silent — ⛔ do not touch).

Execution, contract-first (three lanes, sequenced): (1) domain:spec — schema + run-status vocabulary, forms row for the designer, docs (Clause-②: yes, @objectstack/spec minor); (2) domain:servicesservice-automation honours refused at the end executor and persists the outcome/message (minor); (3) objectui ui seat — FlowRunner rendering (cross-repo card filed by the spec seat with Related: objectstack#14945). Re-verify the console half on today's tree first (the census ran on the 17.2.0 pin). Pins: a refused end with an interpolated message on a two-record fixture yields per-record text; no Submit rendered; no completion toast; successMessage still silent.

Lane (1) is dispatched on #14945 (spec seat). This card is lane (2) and lands in packages/services/service-automation — the services lane's; domain:* routing and priority are the triage seat's (the ruling keeps #14945 at priority:p2). Named reader: the domain:services execution seat, at dispatch time; the Blocked-by: line above is the unlock scan's — it returns this card to the queue when #14945 closes (the spec contract merged). Lane (3) is the objectui card filed alongside (linked from #14945's claim comment).

Deliverables (for the services seat's dispatch, against the spec contract as landed)

  • The end executor honours config.outcome === 'refused': interpolates config.message through the SAME interpolation the screen description uses (one implementation, not a second template engine), terminates the run with the refused outcome (distinct from failed — a refusal is a successful evaluation that says no), persists the outcome and the rendered message on the run record (sys_automation_run / the run status vocabulary the spec half declares), and never resumes it.
  • The paused-run silent behaviour is untouched (the invoking action's successMessage stays suppressed exactly as today) — pin it.
  • Pins: a refused end with an interpolated message on a two-record fixture yields per-record text; the run's terminal status reads refused with the rendered message; completed (default) is unchanged; a refused run is not resumable.
  • @objectstack/service-automation minor changeset; Clause-②: yes only if the executor's public envelope changes (say which).
  • Closing keyword: Fixes this card; A flow cannot REFUSE with per-record text: the only channel that interpolates is a screen description, and a message-only screen still renders Submit and toasts "completed" #14945 is referenced verb-less.

Generated by Claude Code

Activity

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