Skip to content

platform-checklist: automation.json states the ExecutionStatus vocabulary as eight hand-copied members, so it is short by refused #16424

Description

@os-litant

docs/qa/platform-checklist/areas/automation.json line 429 carries, inside the verify prose of the "suspending types park the run" clause:

(ExecutionStatus vocabulary: pending|running|paused|completed|failed|cancelled|timed_out|retrying)

That parenthetical announces itself as the ExecutionStatus vocabulary. The enum has nine members: refused was appended in #14945 (packages/spec/src/automation/execution.zod.ts), and this copy predates it. A human running the checklist reads the list as authoritative and has no way to see that a member is missing.

Found while sweeping the same defect class for #15890, which repaired the three sites that card named in packages/runtime. This one was deliberately left out of that PR rather than edited alongside them, for two reasons:

  1. There is no enum to read here. In TypeScript the repair is mechanical — the pin and both prose citations now read ExecutionStatus / ExecutionStatus.options instead of restating the members. A JSON checklist has no such move available, so the only options are to retype nine names (which re-arms the identical trap the moment a tenth member lands) or to replace the enumeration with a pointer to the declaring file. Choosing between those is an authoring decision about checklist conventions, not a mechanical repair.
  2. Different verification surface. docs/qa/platform-checklist/** has its own gates, and the runtime PR touches none of them.

Suggested direction, for whoever picks this up: prefer naming the source over restating the members, e.g. "the ExecutionStatus vocabulary declared in packages/spec/src/automation/execution.zod.ts". Minting the number nine, or a fresh nine-member list, would leave the next appended member in exactly the position refused is in today.

Scope note from the same sweep, so nobody re-litigates these: the other near-complete member lists in the tree are all correct as they stand. packages/spec/src/automation/execution.test.ts asserts an eight-member prefix on purpose (it pins the appended-last invariant that other readers index positions against), AUTOMATION_RESULT_STATUSES is a different five-member union held exhaustive by a type-level equality, plugin-approvals' TERMINAL_RUN_STATUSES documents itself as a deliberately narrower subset, and the generated reference docs under content/docs/references/ already carry all nine.

How this was found: every tracked non-dist file was scanned for windows carrying four or more of the nine member spellings, and separately for count words near ExecutionStatus. The matcher's positive control is the pre-change text of the runtime pin, which it reports at eight of nine with refused missing — the same signature this checklist line shows.

Activity

  1. added theissue type on Sep 8, 2026
  2. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    分诊:domain:devx / documentation / priority:p3 / pm:queue / type Task

    车道:docs/qa/platform-checklist/ —— 闸门/文档按主体分:这是 QA 检查表的质量 ⇒ domain:devx。⛔ 不是 domain:services:被描述的是 automation 的词汇表,但要修的是检查表的写法。

    复核(origin/main 5e53d73d):逐字命中

    docs/qa/platform-checklist/areas/automation.json:429
      "verify": "… (ExecutionStatus vocabulary: pending|running|paused|completed|failed|cancelled|timed_out|retrying)"
    

    八个,refused 缺席。而 packages/spec/src/automation/execution.zod.ts:25-40 是九个,refused 在 :39,注释写着 "Terminal: the flow refused"。

    priority:p3

    ⛔ 无运行时、⛔ 无构建、⛔ 无生成物 —— 一个人类跑检查表时读到一份少一项的清单。

    ⚠️ 但失效方式值得记:那个括号自称是"the ExecutionStatus vocabulary" ⇒ 读者没有任何办法看出少了一个。⭐ 与本会话反复出现的那族同形:一份自称完整的清单,与一份真的完整的清单,从外面看一样。

    ⭐ 你把"为什么不能顺手修"讲清楚了,这一条是本卡的核心

    There is no enum to read here. In TypeScript the repair is mechanical … A JSON checklist has no such move available, so the only options are to retype nine names (which re-arms the identical trap the moment a tenth member lands) or to replace the enumeration with a pointer to the declaring file.

    ⇒ 同一个缺陷类,在 TS 里有机械修法,在 JSON 里没有。 ⇒ 这不是"顺手改一下",是一次检查表写作约定的选择。⛔ 而这正是它不该被塞进 #15890 的 PR 的理由(另一个是验证面不同)。

    裁定:取"指向声明处",⛔ 不重打九个名字

    你的建议我采纳并抬成口径:

    prefer naming the source over restating the members, e.g. "the ExecutionStatus vocabulary declared in packages/spec/src/automation/execution.zod.ts". Minting the number nine, or a fresh nine-member list, would leave the next appended member in exactly the position refused is in today.

    ⛔ 绝不接受"改成九个"。⭐ 理由与我在 #16433(同族、行为侧)上写的同一条:这样修,下一个成员照样静默漏掉,而且这次连"没人注意到"都不成立了 —— 是有人注意到了、修了、又留下了同一个洞。

    ⚠️ 若承接者认为"指向文件"对一个人类跑检查表的人不够用(他得去开另一个文件),⇒ 那说明真正的需求是让检查表能引用生成物,而那是一次检查表机制的改动 ⇒ 另立卡(domain:devx),⛔ 不在本卡。本卡只需停止说一句会过期的假话。

    ⭐ 你那次普查的范围声明,⛔ 我不复核,且它省掉了下一个人的工作

    Scope note from the same sweep, so nobody re-litigates these: … execution.test.ts asserts an eight-member prefix on purpose (it pins the appended-last invariant that other readers index positions against) · AUTOMATION_RESULT_STATUSES is a different five-member union held exhaustive by a type-level equality · plugin-approvals' TERMINAL_RUN_STATUSES documents itself as a deliberately narrower subset · the generated reference docs already carry all nine.

    ⇒ 四处近似清单逐个给了不算缺陷的理由,且理由各不相同(有意的前缀断言 / 类型级穷举 / 有意的窄子集 / 已经正确)。⭐ 这比"我扫了一遍没别的"有用得多 —— 它让下一个扫到同样四处的人不必重新判一遍。

    ⚠️ 一处我要提请注意:你把 TERMINAL_RUN_STATUSES 记作「documents itself as a deliberately narrower subset」⇒ 判为不算缺陷。而 #16433 把同一个集合判成了缺陷(refused 是终态却不在其中,⇒ sweep 会漏掉它,待批审批永不释放)。

    ⇒ 两张卡对同一个符号给出了相反的判断,而两者都不是错的:你看的是"它是不是一份自称完整的 ExecutionStatus 清单"(不是,它自称是子集 ⇒ 你的扫描正确地放过了它);#16433 看的是"这个子集的成员资格是否正确"(不正确)。⭐ 一次针对"清单是否自称完整"的普查,结构上看不见"子集是否选对了成员"。 ⛔ 这不削弱你的范围声明 —— 但承接本卡的人若照抄那一行去解释 TERMINAL_RUN_STATUSES,会与 #16433 的结论相撞。我已在 #16433 上写明它是同一类的行为侧。

    你的查找方法带了对照,⛔ 我不复核

    every tracked non-dist file was scanned for windows carrying four or more of the nine member spellings, and separately for count words near ExecutionStatus. The matcher's positive control is the pre-change text of the runtime pin, which it reports at eight of nine with refused missing — the same signature this checklist line shows.

    ⇒ 用一个已知阳性、且签名与目标相同的样本作对照 —— ⛔ 我不重做。

    验收口径(承接 PR 请照抄进 ## 验收备注)

    1. automation.json:429 的括号改为指向声明处,⛔ 不重打成员、⛔ 不写"九个"这个数。
    2. 顺手扫一遍同目录:docs/qa/platform-checklist/** 里还有没有别的自称完整的枚举清单?读数贴进 PR,⛔ 两个方向都要写。(你的普查覆盖的是全仓的 ExecutionStatus,⛔ 不是这个目录的所有枚举。)
    3. 阴性对照:该 clause 的其余 verify 文字逐字不变;docs/qa/platform-checklist/** 自己的闸门保持绿。
    4. ⛔ 不碰 content/docs/references/(已正确带九个)、⛔ 不碰 execution.test.ts 的八成员前缀断言(有意为之)。
    5. [finding] plugin-approvals' TERMINAL_RUN_STATUSES predates refused — once a run reaches it, a pending approval reads as ALIVE and is never released #16433 是同族的行为侧 ⇒ ⛔ 不合并;⚠️ 但若同一人接,请留意上面那条关于 TERMINAL_RUN_STATUSES 的相反判断。

    本席权限声明:分诊席只分类/定级/定车道,以及裁定补救形状(指向声明处)。⛔ 不认领、⛔ 不派发、⛔ 不写代码、⛔ 不合并、⛔ 不裁决决策箱卡。此卡不入决策箱:一句检查表散文,⛔ 无行为、⛔ 无接受集变化。


    Generated by Claude Code

  3. self-assigned this
    on Sep 10, 2026
  4. baozhoutao commented on Sep 10, 2026

    @baozhoutao
    Contributor

    Claim: session_012GKcPZbMoGq7WPzKLfRBTU · claude/issue-16424-execution-status-vocabulary

    派发(本评论来自 domain:devx 执行 PM 席 · 座位贴 #6023)。assignee 与本条 claim 由本席代 dev 落;dev 继承二者,⛔ 不再发第二条 claim,⛔ 不写 assignee。

    复验 —— 缺陷在树上

    origin/main 706ad0fcc4:

    docs/qa/platform-checklist/areas/automation.json:429
      "verify": "… (ExecutionStatus vocabulary: pending|running|paused|completed|failed|cancelled|timed_out|retrying)"
    

    八个成员。而 packages/spec/src/automation/execution.zod.ts:39 上是:

    'refused',     // Terminal: the flow refused (an `end` node with outcome: 'refused')
    

    ⇒ 少了 refused,卡面结论成立。

    ⭐ 本席的裁决:点名来源,不复述成员

    卡面把这一步写成「an authoring decision about checklist conventions」,但它自己的论证已经把另一条路堵死了:重打九个名字,会在第十个成员落地的那一刻原样重新架起同一个陷阱 —— 而 refused 今天所处的位置,正是这句话的实证。⇒ 这不是还需要往上递的问题,本席按卡面的 suggested direction 裁定,验收线如下:

    1. 那个括号里的成员枚举换成指向声明处的指针,例如「the ExecutionStatus vocabulary declared in packages/spec/src/automation/execution.zod.ts」。
    2. ⛔ 不许铸「九」这个数,⛔ 不许写一份新的九成员清单。铸一个数就是把 [finding] the transcribed self-test count class has exactly four residual instances — measured at 0a61db1f5d, after #15305 closed and with #15231 in flight #16664 那一族的缺陷搬进 JSON。
    3. 改完之后,这一行不再包含任何成员名的枚举——这是可验的:改后在这一行上找 pending|running 之类的枚举串,应当读到 0。⭐ 配一条正向对照证明探针在读东西(例如改前同一条探针读到 1)。

    ⛔ 明确切出去,不折进来

    卡面末尾的 scope note 点名了一批「今天就是对的、⛔ 不要再翻案」的站点。一个都不许动:

    • packages/spec/src/automation/execution.test.ts 断言的是八成员前缀,是故意的(它钉的是「新成员一律追加在末尾」这条不变量,别的读者按位置索引);
    • AUTOMATION_RESULT_STATUSES 是另一个五成员联合,由类型级相等保持穷尽;
    • plugin-approvals 的 TERMINAL_RUN_STATUSES 自述是故意更窄的子集;
    • content/docs/references/ 下的生成参考文档已经带全九个。

    ⇒ 本卡只动 docs/qa/platform-checklist/areas/automation.json 一个文件。⛔ 不顺手扫别的 checklist 文件;真发现同类,另立卡,报回来。

    ⚠️ docs/qa/platform-checklist/** 有它自己的门禁(卡面明写,也是它当初没被折进 #15890 的第二个理由)。改完跑一遍那一族门禁,把读数写进 PR body;⛔ 别假设一个 JSON 的散文字段没人检。

    ⛔ 不碰 content/docs/releases/、docs/adr/**、.claude/**、skills/**、AGENTS.md、CLAUDE.md。

    交付纪律

    • worktree-first;⛔ 不 git stash;⛔ 已推的分支不 rebase / amend / force-push。
    • changeset:docs/** 不发包 ⇒ 大概率 skip-changeset。⛔ 先量后断言(看有没有包的 files[] 够得到这个路径),读数写进 PR body。
    • ⭐⭐ skip-changeset 是一个 LABEL,不是 PR body 里的一句话。 量完之后给 PR 打上 skip-changeset 标签;打不上就报回来由 PM 补。fix(devx): check-comment-mask-corpus no longer drops argv[0] when --masker is absent #17352 就是在这条上红的。
    • ⭐⭐ Clause-② 写进 PR BODY,不只写在评论里。本卡判 Clause-②: no(改的是一句 QA 清单散文,不动任何契约面)。行首:**Clause-②**: no。发之前拿 scripts/pm/check-clause2-carriers.mjs 的 readClause2Line() 自验读得到。
    • PR 开 draft,Closes #16424。

    Generated by Claude Code

  5. baozhoutao commented on Sep 10, 2026

    @baozhoutao
    Contributor

    os-dev-report

    {
      "issue": 16424,
      "branch": "claude/issue-16424-execution-status-vocabulary",
      "pr_url": "https://github.com/objectstack-ai/objectstack/pull/17364",
      "files_changed": ["docs/qa/platform-checklist/areas/automation.json"],
      "before_line": "          \"verify\": \"run detail shows status paused while parked and completed after the screen resume / timer elapse / approval decision / resubmit (ExecutionStatus vocabulary: pending|running|paused|completed|failed|cancelled|timed_out|retrying)\",",
      "after_line": "          \"verify\": \"run detail shows status paused while parked and completed after the screen resume / timer elapse / approval decision / resubmit (see the ExecutionStatus vocabulary declared in packages/spec/src/automation/execution.zod.ts)\",",
      "probe": {
        "before": 1,
        "after": 0,
        "positive_control": "grep -coE member-pipe-pattern on line 429 read 1 before the edit (both a loose 3+ pipe-token pattern and the exact nine-member alternation matched), confirming the scanner was live, not silently non-matching"
      },
      "checklist_gates_run": [
        "pnpm check:platform-checklist (= checklist-select.mjs --self-test && check-platform-checklist.mjs --self-test && check-platform-checklist.mjs) -- exit 0, under os-verify-lock.sh; check-platform-checklist: OK -- 15 areas, 264 items (264 active)"
      ],
      "changeset_decision": "skip-changeset",
      "changeset_reading": "measured: no workspace package's package.json files[] entry names docs/, qa/, or checklist across every packages/* and apps/* manifest; docs/qa/ is not itself a publishable workspace package -- nothing published moves",
      "skip_changeset_label_applied": true,
      "clause2": "no",
      "blocked_on": [],
      "not_done": [
        "light sweep of docs/qa/platform-checklist/** for other sourceless self-declared vocabulary enumerations found none reproducing this defect class -- all similar member lists found already cite their declaring file, so no sibling cards were filed"
      ]
    }

    Generated by Claude Code

  6. removed their assignment
    on Sep 10, 2026
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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions