Repository navigation
[Decision] Closing a paused flow screen dialog: should abandoning the run be possible, and who may do it #26149
Description
Ruled: 6423004356 · letter B (staged) · 2026-10-26T17:34Z
Filing class: ② a decision only the maintainer can make. This card carries the second half of #25801 (item 2, "closing a paused run's screen dialog cancels the run, or offers to"); the first half (a type: 'file' screen field) is in flight on PR #26134 under #25801 and is not decided here.
os-decision-facets
动手的读者:维护者裁决方向;domain:spec 席位(#18917)按「裁后执行」收口 #25801 并立实施卡。业务理由:hotclm 的请求人放弃录入向导后,运行一直暂停,平台没有让本人收尾的出口。
维护者速读
一句话问题:用户在流程向导里中途关掉对话框,这次运行就一直停在「暂停」,向导之前写下的记录也留着;要不要让用户自己放弃这次运行,如果要,关对话框时是静默放弃还是先问一句。
推荐:B(关对话框时询问「放弃这次运行?」,由发起人本人放弃),但分期:本轮不做,先落 #26134(向导可以把所有写入挪到最后一屏之后,hotclm 的残留草稿因此消失),等出现「必须中途写入」的真实流程再立实施卡。
背景
- 来源:hotclm 录入向导(Seven smaller things a real user hits (from the 17.7.0 browser pass): legal tabs shown to requesters, a template toggle with no template, renewal with no link, orphan drafts, a false demo note, an empty landing page for lawyers hotclm#99 item 4,维护者 2026-10-25 批 5 字母 B 立卡)。症状是请求人在上传版本那一屏关掉对话框,留下删不掉的无版本草稿(NDA-2026-0021)。
- 该症状的根因是「文件只能在建记录之后收」,feat(spec,automation,app-shell)!: a flow screen field typed
filecollects an upload, and the run resumes with the uploaded file's id #26134 已解决:type: 'file'屏字段在第一屏就能收文件,写入挪到最后一屏之后,关对话框不再留下半截记录。 - 剩下的只是「中途必须写入的流程」被放弃时的残留,以及一条一直暂停的运行本身。
Governing text
packages/runtime/src/domains/automation.ts(service-automation: the two operator run-lifecycle verbs (cancelRun, restoreConsumedSuspension) have no door — no REST route, no CLI command, and not on IAutomationService #13953):取消运行是平台运维动词,「a run belongs to the environment rather than to a user」;非运维者调用POST /automation/:name/runs/:runId/cancel得 403PERMISSION_DENIED。- 同文件 security: POST /automation/:name/runs/:runId/resume never checks WHO is resuming — an authenticated stranger with a run id continues another user's paused screen run, which then runs under the starter's stored context #19987:恢复(resume)门对发起人开放(
isRunStarterOrRunStateReader)。 - 选项 A、B 都要新增一个「发起人放弃自己暂停中的屏幕运行」的动词,即改写 service-automation: the two operator run-lifecycle verbs (cancelRun, restoreConsumedSuspension) have no door — no REST route, no CLI command, and not on IAutomationService #13953 对屏幕暂停这一类运行的立场;这一点只有维护者能定。
协议声明
- A/B:新增 REST 动词与控制台行为,不改 spec 元数据(Metadata-protocol: none),REST 面加宽(Clause-②: yes (widening))。C:无改动。D:可能新增流程级配置键(added)。
前提(带复核命令)
- 取消门仍是运维专属:
git grep -n "RUN_LIFECYCLE_DENY_VERB" origin/main -- packages/runtime/src/domains/automation.ts,命中 1 处即成立。 - 关对话框不发请求:
git grep -n "onOpenChange" origin/main -- ui/packages/app-shell/src/views/FlowRunner.tsx,读该行只调onClose。 - 取消不回滚屏前写入:取消只结束运行,不撤销已提交的写(dev 在 feat(spec,automation,app-shell)!: a flow screen field typed
filecollects an upload, and the run resumes with the uploaded file's id #26134 正文 Acceptance notes 实测陈述)。
选项
| 选项 | 做什么 | 客户看到的后果 | 工作量 |
|---|---|---|---|
| A 静默放弃 | 关对话框即调用新的发起人放弃动词 | 误关一次就丢掉整个向导进度,无法回来继续 | spec 车道 1 个 PR(运行时动词 + 控制台),无先例 |
| B 询问后放弃 | 关对话框弹出「放弃这次运行?」,确认才调用新动词;取消则保持暂停 | 用户明确知道自己在放弃;屏前写入仍不撤销 | 同 A,外加一个确认框,1 个 PR,无先例 |
| C 不改 | 关对话框保持暂停(现状) | 运行一直暂停;有 #26134 后向导不再留下半截记录 | 0 |
| D 到期清理 | 暂停超过期限的屏幕运行自动结束 | 用户回来时运行可能已过期;对谁都不需要新权限 | 1–2 个 PR,需定期限配置,无先例 |
业务含义直译:A 像网购时关掉结账页就清空购物车;B 像关页面时问「确定放弃订单?」;C 像购物车一直留着;D 像购物车 30 天后自动清空。
四轴
- ① 项目长远合理性:两年后的平台样子是「暂停中的运行归发起人管理,发起人可继续也可主动放弃,管理员可清理全部」,这是 Salesforce「Paused Flow Interviews」的模型(用户可删除自己的暂停会话)。B 最接近:放弃是明确动作,不靠关窗副作用;A 把放弃藏进关窗,误触不可恢复;D 是补充清理手段,不替代发起人的选择;C 不前进。
- ② 实际业务拉动:今天唯一的拉动方 hotclm 的残留问题由 feat(spec,automation,app-shell)!: a flow screen field typed
filecollects an upload, and the run resumes with the uploaded file's id #26134 解决;仓内与 hotclm 未见「必须中途写入」的屏幕流程。零剩余拉动 ⇒ 时序上延后。 - ③ 防 AI 犯错:B 出错时用户看到一个确认框,结果可见;A 出错时用户静默丢进度且没有提示;D 出错时用户回来才发现运行过期。响亮优于静默 ⇒ B。
- ④ 创业阶段不扩散:任何放弃动词都是新的永久 REST 面与权限面;没有拉动就不加。⇒ 现在不做。
只看①选 B;②③④ 是否翻转:否(②④只把 B 延后,不改字母)。
Prior rulings read: "cancel" "paused run" "starter" in objectstack issues → 0 hits; "paused" run abandon/expiry/TTL screen flow → 79 hits, none asks for abandonment or expiry of a screen-paused run; ADR-0044 (cancel is an operator verb), #13953, #19987; thread: objectstack-ai/hotclm#99 item 4.
推荐与置信缺口
- 推荐 B,分期:本轮不实施,Flow screens: a flat
screenhas nofilefield type, so a multi-step wizard must create the record before its last step to collect a file — and closing the screen dialog leaves the run paused and the half-written record behind #25801 只以前一半关闭;B 的实施卡在出现第一个必须中途写入的真实屏幕流程时再立。 - 不取 A:误关即丢进度,且无提示。不取 C 作终态:运行永久暂停,平台没有让发起人收尾的出口。不取 D 作主方案:它是清理而不是用户的选择,可另行评估。
- 盲区:未测线上暂停运行的累积量;若累积成为运维负担,D 的优先级会上升。
裁后执行
- 选 B 或 C:spec 席位在 feat(spec,automation,app-shell)!: a flow screen field typed
filecollects an upload, and the run resumes with the uploaded file's id #26134 落地后以Part of收口 Flow screens: a flatscreenhas nofilefield type, so a multi-step wizard must create the record before its last step to collect a file — and closing the screen dialog leaves the run paused and the half-written record behind #25801,在卡上记明后半由本卡承载;选 B 时同笔立实施卡(发起人放弃动词 + 确认框),按本卡裁决入队。 - 选 A:同上立实施卡,去掉确认框。选 D:立到期清理卡,期限值由维护者给出。
相关
#25801(母卡)、PR #26134(前一半)、#13953、#19987、#25692、objectstack-ai/hotclm#99。
Activity
objectstack-fleet commentedon Oct 26, 2026
Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #400 · 2026-10-26T14:07Z
Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #400 as its one item (the card entered the box at 13:50Z, after batch #399 was presented). Seat increment (re-verified on
origin/maincdd4eea9; the card's analysis is not restated):RUN_LIFECYCLE_DENY_VERBappears inpackages/runtime/src/domains/automation.ts(cancel is the operator verb of service-automation: the two operator run-lifecycle verbs (cancelRun, restoreConsumedSuspension) have no door — no REST route, no CLI command, and not on IAutomationService #13953; ADR-0044:164–166 recordscancelRunas the engine's first run-cancel primitive, consuming the continuation and logging terminalcancelled); the resume door's admission isisRunStarterOrRunStateReader(:259–284, security: POST /automation/:name/runs/:runId/resume never checks WHO is resuming — an authenticated stranger with a run id continues another user's paused screen run, which then runs under the starter's stored context #19987);FlowRunner.tsx:624closes the dialog withonClose()only, no request. PR feat(spec,automation,app-shell)!: a flow screen field typedfilecollects an upload, and the run resumes with the uploaded file's id #26134 (the first half of Flow screens: a flatscreenhas nofilefield type, so a multi-step wizard must create the record before its last step to collect a file — and closing the screen dialog leaves the run paused and the half-written record behind #25801,type: 'file'screen field) is open, draft, +959/−48; Flow screens: a flatscreenhas nofilefield type, so a multi-step wizard must create the record before its last step to collect a file — and closing the screen dialog leaves the run paused and the half-written record behind #25801 ispm:dispatched, spec p1.git grep -iE 'abandon|discard run'on the runner andpackages/spec/src/automation→ 0: no abandon verb or UI exists today, so any of A/B/D is a new REST verb or a new config key (the card's protocol line is right).pm:on-holdcard — the ruling records the direction and this card closesnot_plannedwith the ruling as its record, reopened free when such a flow appears; Flow screens: a flatscreenhas nofilefield type, so a multi-step wizard must create the record before its last step to collect a file — and closing the screen dialog leaves the run paused and the half-written record behind #25801 closes on feat(spec,automation,app-shell)!: a flow screen field typedfilecollects an upload, and the run resumes with the uploaded file's id #26134 with a pointer here. The seat states this so the letter decides the direction and the close at once.filecollects an upload, and the run resumes with the uploaded file's id #26134 lands). Not A (silent loss on a mis-click), not C as an end state (no exit for the starter), D as a separate operations question if paused runs accumulate. Workload now: 0; when picked up, spec lane · 1 PR (runtime verb + console confirm), no precedent.Prior rulings read:
RUN_LIFECYCLE_DENY_VERB·#13953·#19987·ADR-0044 cancelRun→ the operator-only cancel stance and the starter-open resume door; thread: none (new card).objectstack-fleet commentedon Oct 26, 2026
Ruling: batch #401 item 1 (batch #400's open item) · letter B, staged · maintainer 「同意」 2026-10-26T17:34Z
Recorded by the director seat (summon #51 continuation,
session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708, brief 6418049443). Letter B, staged. Direction: the starter of a paused screen run may abandon it — closing the dialog asks "abandon this run?", and only a confirmed answer calls a new starter-scoped abandon verb (the run's pre-dialog writes are not rolled back; cancel stays the operator verb of #13953 / ADR-0044). Not A (silent loss on a mis-click), not C as an end state, D as a separate operations question if paused runs accumulate. Timing: not built now — the only measured pull (hotclm#99 item 4) was removed by PR #26134 (merged: atype: 'file'screen field lets a wizard move every write past its last screen), and no screen flow that must write mid-run exists in this repository or in hotclm; a new verb is a permanent REST and permission surface, added when such a flow exists.Closed
not_plannedwith this ruling as the record: a staged letter has no machine-readable restart condition, so it is not apm:on-holdcard; reopening is free the day a real mid-run-writing screen flow appears, and the implementation card then cites this comment (Ruling-ref:). #25801 closes on #26134 with a pointer here (the spec seat's act).Workload of the chosen letter: 0 now; spec lane · 1 PR (runtime verb + console confirm) when reopened, no precedent.