Skip to content

[decision] stale.yml 从未运行成功过一次(236/236 红,八个月)——修好它、退役它,还是修好并把 PM 协议的标签加进豁免集? #8548

Description

@os-zhuang

决策卡,由分诊席(claude-opus-5)从 objectui#8126pm:retriage 岔路产出。⛔ 分诊席不裁决本卡(CONTRACT_REVIEW_TIER 要求 fable 层);下方四棱分析、推荐与置信缺口是输入,⛔ 不是裁定。

⚠️ 触发进决策箱的判据:选项 B 删除一个已发布能力


一、已测量的事实(⛔ 无一条来自推断)

缺陷本身已查明并已修好。 .github/workflows/stale.yml 自 2026-01-16 的第 1 次运行起 236 次全部失败,每次都死在 Set up jobactions/stale 从未启动。根因是 runner 自己打印的:

##[error]Unable to resolve action `actions/stale@e00e804f6792d3fedb5bd3a27df2761c5f86c981`,
         unable to find version `e00e804f6792d3fedb5bd3a27df2761c5f86c981`

⇒ 那个 SHA 不是 actions/stale 里的任何一个提交。旁边的 # v9.0.0 注释一直是对的 —— 版本存在,只有 SHA 是编的。PR #8463 用一行修好它(draft,被执行席按住)。

修好之后会发生什么,已经实跑测过,⛔ 不是估的:

读数
修正后的文件首次绿灯(该工作流生命中第一次成功) run 34173608021
真实策略扫过整个开放板 Processed 466(457 issues, 9 PRs)
会被标记为 stale 的条目 0 —— 无 stale 计数、无 label 计数、无 comment 计数
阳性对照:同一文件、阈值降为 0 New stale 125 / Added labels 125 / Added comments 125
为何是 0 板子年轻:457 张开放 issue 中最久未动的是 18 天,阈值是 60 天
距离第一个候选出现 42 天;再 7 天才会关闭

⭐ 那个 0 是可用仪器上的读数,⛔ 不是一个沉默的仪器 —— 阈值对照证明了它会数。

写入对照(执行席独立取的)GET /repos/objectstack-ai/objectui/labels/stale404actions/stale 在打标签时会创建该标签,⇒ 该标签不存在 = 没有发生任何写入⚠️ 「数一下有多少 issue 带这个标签」才是这条检查的空洞版本(答案必然是 0,因为标签不存在);标签的缺席本身才是检查。


二、⚠️ 决定性的那条冲突:豁免集不含任何 PM 协议标签

stale.yml 声明: 60 天不动 ⇒ stale ⇒ 再 7 天关闭(PR 是 45/14)
  exempt-issue-labels: pinned, security, critical, bug, enhancement
  exempt-pr-labels:    pinned, security, in-progress, blocked

两个豁免集里没有任何 pm:*,也没有 needs-user-decision

而本仓的 PM 协议声明:pm:queuepm:on-holdneeds-user-decision 的卡是刻意停放、等人的。

⇒ ⭐ 决策箱里第一段 60 天的安静期,就是这个 job 开始关闭维护者自己收件箱的时候。 执行席实测:最久未动的 5 张开放 issue 里有 3 张只带 pm:queue + domain:ui


三、三个选项

形状 今天的代价 已知风险
A 落地 PR #8463(仅修 SHA),豁免集另议 实测影响 0 ⚠️ 安全状态依赖「一个裁定在 42 天内到达」
B 退役:删工作流 + content/docs/guide/ci-cd-pipeline.md 的小节 Workflow Inventory 行 + scripts/__tests__/workflow-cache-save-bound.test.ts 的 accept-360 条目 3 处编辑 ⚠️ AGENTS.md 记载:从默认分支删除工作流后 Actions registry 条目的下场本仓从未发生过、未经测试
C 落地 #8463 在同一改动里把 pm:queue / pm:on-hold / needs-user-decision 加进豁免集 一行 + 策略面 在能力本身未被确认需要之前先投入策略设计

四、四棱卡面

① 项目长远合理性

本仓反复处理的正是「看起来像强制、其实不是」这一类(#3009 / #3181 / #3494)。本卡是其极端形态:声明了一整套自动化,八个月一次没跑,而且是响亮地失败进虚空 236 次

contract-first 只有两条路 —— 兑现声明删掉声明;保留一个红着的声明是最差的第三条。B 与 ADR-0049 enforce-or-remove 同向;A 兑现的是一套无人消费的声明;C 在能力未被确认需要前先固化策略面。

B 优 · A 次 · C 最差。

② 实际业务拉动

⛔ 这一棱是实测的,不是「读起来像有用」:

  • 零输出:236 次运行、0 次成功;按真实策略实跑 466 条,标记 0 条。
  • 零消费者:⛔ 不是 required check(已对分支规则集复核:required 的是 LintType CheckBuild & E2ETest (shard 1/4..4/4)Build DocsChangeset Declaration),不阻塞任何合并,无任何东西读它的输出。
  • 它服务的场景在本仓不存在:stale bot 的目标人群是外部贡献者遗弃的 issue/PR;而实测整个开放集合的作者都是仓库成员

强指向 B。 A 修好的是一台没人用的机器;C 在没人用的机器上再投一次策略设计。

③ 防 AI 犯错

本卡自身就是这一棱的教训。 e00e804f… 是一个「声明了、运行时不兑现」的 pin —— 它看起来是最严格的写法(SHA pin 优于浮动 tag),实际上是本仓唯一一个 SHA pin,也是唯一一个从未解析成功过的 action ref;其余 12 个引用全用浮动 major tag,从不出事(已另立 objectui#8465 记录)。

一个没有任何东西验证它的「更严格写法」,只是更精致的幻影。

PR #8463 因此拒绝手写 SHA —— 改由 runner 自己在探针分支上打印 tag → SHA 映射再抄回,并在同一次运行里带正负对照(checkout@v7 绿 / main 上那个坏 SHA 红 / 不存在的 @v12 红)。

方案上:B 让这类错误结构上不可能再犯;A 保留该面但使其可验证;C 新增策略参数 = 新增可写错的面。⇒ B > A > C。

④ 创业阶段不扩散

维护者 2026-08-04:「我们是一个创业项目,应该先专注于核心能力」。⇒ 一个八个月零产出、零消费者的能力,正是「已发布但零消费的能力不因沉没成本获得豁免」所指的对象 —— 写了八个月不构成保留理由。

维护者 2026-08-27 逐字:「项目在创业阶段,用户也很少,短期不考虑渐进。」⇒ 退役默认立即,不设分阶段窗口;而 C 恰是分阶段过渡形态,按该裁定除非有具名外部用户证据否则不得作为推荐 —— 而本卡测得的证据方向相反(开放集合无外部作者)。

强指向 B,明确反对 C。


五、推荐

推荐 B(退役),并保留 A 作为已就绪的安全中间态。 四棱一致,⛔ 无需要权衡的冲突。

⚠️ 若裁 B,PR #8463 直接关掉不合并即可,零回滚成本

⚠️ 若裁 A 或 C,还有一件必须同笔处理的事:scripts/__tests__/workflow-cache-save-bound.test.ts:450 仍写着「stale.yml::stale — 234 completed runs, 0 successful」且没有测量点(真值现为 236)。⇒ A/C 下它需要一个测量点;B 下它被删除。


六、⚠️ 强制置信缺口 —— 本卡最可能错的地方

「整个开放集合的作者都是仓库成员」这一条是今天的读数,不是一条恒定性质。

推荐 B 的最强论据是「stale bot 的目标人群在本仓不存在」。这依赖本仓的贡献模式保持封闭。 若项目将来向外部贡献者开放,这条论据即刻失效,而那正是 stale bot 有用的场景。

⚠️ 本卡实质上是在赌贡献模式短期不变。 好在这个赌注可逆(重新加一个工作流的成本很低),⛔ 但请维护者在拍板时明确这一点,而不是把它当作一条永久事实。

⚠️ 第二条缺口:删除工作流后 Actions registry 条目的下场,本仓从未测过(AGENTS.md 记载)。⇒ 若裁 B,请把「registry 条目发生了什么」作为落地后的一条读数记录下来,⛔ 不要预测它。


七、维护者速读

我们有一个「自动清理陈旧 issue」的定时任务,从 2026 年 1 月装上那天起就没成功运行过一次,八个月,236 次全失败,没人发现。原因很小:配置里写死的一个版本号是编的,那个版本根本不存在。

修它只要改一行,已经改好了(PR #8463),而且我们实测过:修好之后它今天会扫过 466 条,一条都不会动 —— 因为我们的板子很新,最老的一条也才 18 天,而它的门槛是 60 天。大约42 天后才会有第一个候选。

但有两件事值得您决定:

  1. 这个东西对我们有用吗? 它是用来清理「外部路人提了 issue 然后消失」的。我们实测:目前板上每一条 issue 和 PR 都是团队成员开的 —— 也就是说它要清理的那种东西,我们这里没有。
  2. 它的豁免名单是旧的。 它不认识我们后来定的 pm:queuepm:on-holdneeds-user-decision 这些「刻意停着等您拍板」的标签。⇒ 42 天后,它会开始关闭您自己的决策收件箱。

我们的建议是退掉它(删掉这个任务,连带三处引用它的地方)。它八个月没产出任何东西,也没有任何东西依赖它;已经改好的那一行如果不要,关掉 PR 即可,没有任何回滚成本。

⚠️ 唯一的顾虑:如果将来项目对外开放、开始有外部路人提 issue,这个东西就又有用了 —— 到时候重新加回来成本很低,但现在删掉是在赌短期内不会开放。

请回一个字母:A(只修好,豁免名单以后再说)· B(退掉它)· C(修好,并把上面那三个标签加进豁免名单)。


Refs: objectui#8126(缺陷卡,已按 Blocked-by: 指向本卡)· PR #8463(一行修复,draft,按住)· objectui#8465(本仓唯一的 SHA pin 就是唯一从未解析成功的引用)· objectui#7956(曝光面,⛔ 与本卡不同问题)· ADR-0049 enforce-or-remove。

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

    Labels

    ci/cddomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:queuepriority:p2tooling

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions