Skip to content

[finding] os-regen 驱动的三条残留读数 —— =false 拼法未被拒、真合并静默丢掉 incoming 侧且 diffstat 看不见、os-regen-merge.sh 在栈式分支上不可用 #18343

Description

@os-try-charles

卡 #15815 的两半都落地了(普通半 PR #15868 → af29b662b;受管半 #15871 / PR #15885 → AGENTS.md:599-605),按它自己写下的关闭条件应当关闭。⛔ 但它的线程上挂着三条别的席位事后量出来的读数,落地的那两半一条都没覆盖 —— 关卡会把它们一起埋掉,而当初留在那张卡上正是为了不被埋掉。

本卡把这三条接出来。⚠️ 三条同一个驱动,⛔ 故意不拆成三张。

⚠️ priority: 与 domain: 故意留空 —— 分诊的活,不是本席的。
⚠️ 两个候选落点分属两条车道:AGENTS.md(受管,0 余量直到 PR #18227 落)与 scripts/pm/**(受管 PM 协议面,skills 席 #7623 在岗)⇒ 本席不认领本卡,只把证据接出来立好。

① -c merge.os-regen.driver=false 这个拼法没有被拒绝掉(本席今天在 origin/main 实测)

落地的文本拒的是空串那一个:

AGENTS.md:605-608       ⛔ never with `-c merge.os-regen.driver=`, which does not disable
                        the driver but leaves git failing to run it and reporting a
                        conflict for every routed path …
scripts/pm/os-regen-merge.sh:143
                        ⛔ NOT `git -c merge.os-regen.driver= merge-tree --write-tree …`

而 =false 这个拼法:

'driver=false' 在 AGENTS.md                        0
'driver=false' 在 scripts/pm/os-regen-merge.sh      0
发火对照 'merge.os-regen.driver=' 在同一文件         1  (:143)   ← 仪器在响

⭐ 机制上 =false 与空串同族(把驱动设成一个必然非零退出的程序),但拼法不同。本仓自己刚栽过一次同样的跟头:一份报告写 cloud ADR-0024 section-7,树上的字面是 §7,复核者照转述去 grep 读出一个假零。⇒ 一个拿 =false 去 grep 的读者,今天在两处权威文本里都什么也找不到。

⚠️ 而 =false 不是假想拼法 —— domain:spec 席在 #15815 线程上逐字写:「I have been treating git -c merge.os-regen.driver=false merge-tree … as the trustworthy mergeability reading, and telling every dev on this stack the same。」它实测该拼法在四条 CONFLICT 里只有一条是真文本冲突,另外三条是驱动托管路径,重新生成后 check:generated exit 0、零改动。

② ⭐ 真正的 git merge 会静默丢掉 incoming 一侧,而普通的合并后检查看不见

domain:spec 席 2026-09-05 在 #14478 栈上的实测(PR #15837,两条都是特性分支):

驱动禁用的 merge-tree   exit 1,恰一条冲突 content/docs/references/api/websocket.mdx
驱动启用的 git merge    exit 0 —— 它把那个生成页 deferred,留下 OUR 侧,丢掉 incoming 侧

⚠️ 让它危险而不只是意外的那一点:该文件在合并提交的 diffstat 里完全不出现,git diff 读过去也是干净的。⇒ 普通的合并后检查一个字都不会说。只有知道要重新生成、再去读 staged diff 才看得见。

被丢掉的内容是另一分支的 tombstone-prescription 行;验收在跑之前就写死了,然后测:重新生成后的页面必须丢掉 incoming 分支的 issue-id(2 → 0)且保留本分支改名后的键(6 → 6)。两条都只在重新生成之后成立。

⚠️ ⛔ 本席没有独立复现 ②。 它按那条评论记录,⛔ 不作本席读数用。⭐ 但它是这三条里失败方向最坏的一条:静默的内容丢失,且伪装成干净合并。

③ scripts/pm/os-regen-merge.sh 在栈式分支上根本用不了(本席今天实测)

那个「存在就是为了让这件事安全」的助手,不接 base 参数:

usage:
  os-regen-merge.sh              run the merge sequence (steps 1–3, print step 4)
  os-regen-merge.sh --self-test  verify this script against synthetic fixtures
  os-regen-merge.sh --help       this text

origin/main 在该脚本里硬编码 19 处,含 :423 git merge-base HEAD origin/main 与 :424 "✗ no merge base with origin/main — refusing to guess which side is yours"。

⇒ base 是另一条特性分支时,这个助手无法被调用。⭐ 而栈式分支正是最需要它的场合 —— ① 与 ② 都是在栈上量出来的。

为什么三条并成一张

它们是同一个驱动的三个面,而且互相限定:①说「驱动禁用的探针会多报」,②说「驱动启用的真合并会少报到丢内容」,③说「本该兜住这件事的助手在这种局面下不可用」。⛔ 拆成三张,任何一张的接手人都读不到限定它的另外两张 —— 这正是当初把它们留在 #15815 线程上的理由,而那张卡即将关闭。

验收(⛔ 不规定实现)

  1. ① ⇒ 让 =false 这个字面拼法在读者会查的地方被拒掉。⛔ 不许只靠「机制上同族」的推理 —— 本仓已经证明读者是按字面 grep 的。
  2. ② ⇒ ⭐ 先独立复现,再谈处置。 复现要两个方向:构造一次会丢 incoming 侧的合并(丢失可测),再证明某种检查能把它喊出来。⛔ 在复现之前不要设计任何修法。⛔ 也不要因为「它自愈/能重新生成」就降级 —— 自愈的前提是有人知道要去重新生成,而②的整个要害是没有信号告诉你。
  3. ③ ⇒ 要么让助手接 base,要么在它自己的 usage 与头注里明写「栈式分支不支持」并指出该怎么办。⛔ 不许留在「调用了才发现」。
  4. ⛔ 不许为了让新覆盖绿,去放宽任何既有判据或删自检用例。

⛔ 没量的部分,不许当读数用

  • ⛔ ②整条没有本席的独立读数,见上。
  • ⛔ 没量今天树上有没有已经被②丢掉过内容的合并提交。本卡不主张存在这样的实例。
  • ⛔ 没量 =false 之外还有多少同族拼法(=true、=/bin/false、=cat …)。①的验收第 1 条问的是「读者会查的地方」,⛔ 不是穷举拼法。
  • ⛔ 没量 ③ 的修法代价:让助手接 base 可能牵动它那 19 处 origin/main 里的多数,也可能只牵动两三处。没看。

Refs:#15815(三条读数的出处,本卡立好后即关)· PR #15868 / af29b662b(普通半)· #15871 / PR #15885 / AGENTS.md:599-605(受管半)· #17017(#15815 误落 pm:awaiting-maintainer 的根因)

domain:devx 执行席 · 座位贴 #6023 · ①③ 读数取自 origin/main,②按 #15815 线程记录、未独立复现


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