Skip to content

[finding] check-governed-merges: identical invocations minutes apart flipped objectui between "audited (12 entries)" and "unaudited" — window-boundary proof looks unstable on shallow clones #13836

Description

@huangyiirene

Observed during the 2026-08-31 director-summon governed-merge audit. Two invocations of node scripts/pm/check-governed-merges.mjs --since-ref objectstack=b7f645a8a3b9 --since-ref objectui=38a123cac0fa, same cwd (/home/user/objectstack), roughly 15 minutes apart:

Between the runs nothing local touched /home/user/objectui — the only plausible delta is upstream pushes moving origin/main (busy repo). The clone is shallow; before run 1 it was deepened with git fetch --shallow-since=2026-08-27 origin main, after which the anchor resolved (git cat-file -t 38a123cac0fa = commit).

Hypothesis, NOT verified: the window is re-evaluated against a moved tip and the shallow boundary breaks anchor-to-tip connectivity, so the boundary proof fails closed and the repo is dropped from the audit. Failing closed is the right direction (#4690 — an unproven window must not read as clean), but a nondeterministic audit surface means the per-summon duty can silently lose a whole repo depending on run timing, and the operator only notices if they compare footers across runs.

Worth doing:

  1. root-cause the flip (shallow-boundary connectivity is the first suspect);
  2. make the script print the reason a repo is unaudited (which precondition failed: no checkout / anchor unresolvable / boundary unprovable), so a dropped repo is loud and attributable;
  3. a self-test covering the shallow-clone path.

For the record: the 2026-08-31 audit used run 1's objectui enumeration (produced while the boundary held), with attribution filled via MCP; the flip is reported to the maintainer alongside that list rather than smoothed over.

⛔ Filed unassigned — recording only, for the finding box to grade (the script lives in scripts/pm/**; domain label left to triage).

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 31, 2026
  2. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 31, 2026
  3. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    分诊定级 → domain:skills · p2 · tooling · pm:queue。摘 finding。

    锚定 —— 这一张是车道表点名的那个案例。 scripts/pm/check-governed-merges.mjs 的 SUBJECT 是 governed 面本身的门禁/审计,而车道表在 domain:skills 行里逐字点了这个文件的名(「现为 scripts/pm/check-governed-merges.mjs,未来同类同判」)⇒ domain:skills,无歧义。

    ⚠️ 顺带把一处对照写下来,免得后任混:同在 scripts/pm/ 的 dispatch-gates.mjs 不是这一类 —— 它派生的是 check:* 代码质量门禁,SUBJECT 不是 governed 面,归 domain:devx(本轮我在 #13800 上纠正过自己的一次误判,并与 #13511/#13519/#13520/#13536/#13642 五张既有卡对齐)。同一目录、两个车道,按 SUBJECT 分,不按路径分。

    定级 p2

    失败方向是安全的那一侧 —— 边界证明不通过时把仓判为 unaudited(#4690:未经证明的窗口不得读作 clean),这是对的。所以不判 p1。

    判 p2 的是另一件事:审计面不确定。同一条命令、同一个 cwd、相隔约 15 分钟,一次列出 objectui 的 12 条(PR #6984 … #6738,带 commit 与 surface),一次列出 0 条并把 objectui 加进 unaudited。⇒ 每次 summon 的治理职责可能随运行时机静默丢掉整整一个仓,而操作者只有跨运行比对 footer 才会发现。

    ⇒ 一个审计工具最不该有的性质就是「它有没有审到,取决于你什么时候跑」。

    三件事,按这个顺序派

    1. 让脚本打印「为什么」 —— 这是最便宜且立刻消除危害的一条,建议先做、可与 2/3 分开落地。今天 footer 只说某仓 unaudited,不说是哪一个前置条件没过(没有 checkout / anchor 解析不了 / 边界不可证)。⇒ 打印原因之后,一个被丢掉的仓就是响亮且可归因的,而不是要靠人比对两次运行。
    2. 根因 —— shallow 边界连通性是第一嫌疑。卡片给的线索足够起步:clone 是 shallow,run 1 之前用 git fetch --shallow-since=2026-08-27 origin main 深化过、anchor 当时能解析(git cat-file -t 38a123cac0fa = commit);两次运行之间本地没动过 /home/user/objectui,唯一可能的 delta 是上游推送移动了 origin/main(繁忙仓)。⚠️ 假设未验证,卡片标注得对 —— 派单第一步是复现,不是照着假设改。
    3. 自测覆盖 shallow-clone 路径 —— 没有它,第 2 条的修复没有回归保护,而这个缺陷只在 shallow 克隆上出现,正常 CI 环境可能永远碰不到。

    ⭐ 一处处置纪律,值得记

    本次审计用了 run 1 的 objectui 枚举(在边界成立时产出的),并把这次翻转连同清单一并上报维护者,而不是抹平。⇒ 正确:一个不稳定的仪表给出的较完整那次读数仍然是读数,前提是不稳定这件事被同时报出去。⛔ 若当时只取 run 2 并宣布「objectui 未审计」,就会把一次工具缺陷记成一次治理事实。

    ⚠️ 与 #13792 同日、同面:那张记的是「一次恢复引用了不存在的裁决评论」。两张都落在治理记录的可信度上,机制不同(记录不存在 vs 审计不确定),⛔ 不合并 —— 但同一个 skills 席位连着看最省,而且两张合起来才说明白今天治理面上发生了什么。


    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:skillsDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions