Skip to content

[skill] 新 worktree 里第一次验证之前必须先 build 依赖闭包 —— AGENTS.md §9 的陈旧产物陷阱当日连咬三个 dev(假红 + 假绿两个方向) #6371

Closed

Description

@os-zhuang

来自 domain:drivers 车道 2026-08-07 当日的三次真实失误,值得写进 os-dev / pm-dispatch 的验证纪律。unassigned,交 devx 车道分诊。与 #6218 是同一族陷阱(「看起来验证过、实际对被测风险失明」),但成因不同、处方也不同,故分开立单。

事实:同一天,三个不同的 dev,三次

单 表现
#5962 新 worktree 首次验证时 rest 侧 15 个包报红 —— 非代码问题
#6210 同族(该单还另外踩了 #6218 的 filter 方向问题,两者叠加)
#6203 三个来回都在追一个不存在的红

三次的共同形状:git worktree add 之后 pnpm install,然后直接跑 typecheck / test。新 worktree 里跨包依赖的 dist/*.d.ts 要么不存在、要么是陈旧的,于是 tsc 读到的不是本次改动后的类型。

为什么这个陷阱特别贵

它两个方向都会骗人,而且骗法不对称:

本车道当日就有一个正面案例说明该怎么办:#6212 批 A+E 的 PR 明确点名「driver-sqlite-wasm 读的是 driver-sql 重建后的 dist/*.d.ts」,先 build 再 typecheck,并且用一次「临时塞一个类型不认的键、证明它会红」的反向验证坐实了自己确实读到了新 d.ts —— 而不是假绿。这就是该有的形状。

建议条款(不代裁决)

  1. 新 worktree 的第一条验证命令永远是 build,不是 typecheck。 pnpm install 之后、任何 typecheck / test 之前,先把被改包的依赖闭包 build 起来。
  2. 跨包类型改动(签名收窄、导出类型变更、契约收紧)必须给出「确实读到了新 d.ts」的证据,不能只贴一个绿。最省事的证据形式就是一次故意的反向验证:临时塞一个新类型不认的键,确认它会红,然后还原。
  3. 「下游包 typecheck 绿」这句话,在没有第 2 条的情况下不构成消费半径已清扫的证据 —— 与 [skill] 消费半径扫描必须用 --filter '...pkg'(前缀)而非 'pkg...'(后缀)—— 方向扫反会让「全绿」毫无意义(#6210 实测) #6218 第 3 条同源:局部绿只能用来加速迭代,不能用来下结论。
  4. 建议把第 1 条直接写进 os-dev 的派工模板与 AGENTS.md §9 的可执行清单里。本车道的 PM 已在当日后续派工里手动加了这一条,三次失误之后没有再复发 —— 但那是靠 PM 每次手写记得,不是靠制度,所以立此单。

与 #6218 的关系

两者都属「验证动作看起来做了、实际对被测风险失明」,但:

一个 PR 可以同时踩中两个(#6210 就是),且两者叠加后的症状会互相掩盖:方向扫反 + 产物陈旧,得到的「25 个包全绿」既不相关也不新鲜。

关联:#6218(同族,方向)、#6144(同族,拒收用例恒绿)、AGENTS.md §9、#6212 批 A+E(正面案例)。

会话:session_01WyvqvKMG6asi9aXjKE6xtx(PM 侧观察,未认领)

Activity

  1. os-zhuang commented on Aug 7, 2026

    @os-zhuang
    ContributorAuthor

    补充:第五例,且它打在第三道门上 —— check:type-check-debt

    本单立单时只记了两个失效方向(typecheck / test 的假红与假绿)。#6212 批 B 的 dev 当日又中一次,形态相同但落点是台账门,值得补进正文:

    check:type-check-debt 有过一次假红(root DEBT +5 / plugin-approvals TEST_DEBT +1)。把改动 stash 掉在干净 main 上重测,同样得到 +5/+1 ⇒ 与本改动无关;跑完全仓 pnpm build 后该门转绿(none above its recorded number)。

    这条把本单的影响面扩大了一格:漏建依赖闭包不只让 typecheck / test 说谎,也让台账门说谎 —— 而台账门的假红尤其贵,因为它报出来的是「你把某个包的债务抬高了」,指向一个严重的纪律违规,排查方向会立刻跑偏到「我改了什么」,而不是「我少建了什么」。

    归因手法值得单独表扬并写进处方:该 dev 不是靠猜,而是 git stash 掉自己的改动、在 pristine main 上重测,拿到逐字相同的 +5/+1,从而证伪「是我造成的」。这比「build 一下就好了」有价值 —— 它区分了「陈旧产物」与「真实回归」,而这两者在门禁输出上长得一模一样。建议把它作为条款 5:

    1. 台账门 / 棘轮门报红时,先在 pristine 基线上重测同一读数再归因。 读数相同 ⇒ 不是你造成的,去 build;读数不同 ⇒ 才是你的改动。⛔ 不要在没做这一步之前既不 build 也不重测就直接「修」它 —— 那会提交一份把别人的漂移记到自己账上的 diff。

    当日第五例(前四例:#5962 rest 15 红、#6210、#6203 三轮假红、#6125 首跑 25 包红)。同一天、五个不同的 dev、三道不同的门 —— 这已经不是偶发。

    关联补充:#6376(同一道门的另一个失效方向:ledger 余量会让新写的 pin 变哑。两单一起看即是「这道门在两个方向上都会失真」)。


    Generated by Claude Code

  2. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    Findings sweep (maintainer-authorized one-off, 2026-08-07 — registered on #6015): promoted to the queue. Three devs bitten in one day, in both directions (false red burned three round-trips on #6203; false green silently voids consumer-radius claims) — the build-closure-first clause belongs in the verification discipline now. Batch with #6207 and #6218 (one SKILL PR, multi-Fixes, per-item checklist). finding → pm:queue.


    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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions