Skip to content

check:dev-prereqs 只判 dist 存在性,#5726 的「陈旧 dist」那半边仍无门禁 —— 而绿灯现在会提供反向保证 #5864

Description

@os-zhuang

观察类发现(finding),记录自 #5795 / PR #5863 的实现过程,不建议现在就动手 —— 先留档,免得下一个人踩。

背景

PR #5863 给根 dev / dev:* 加了构建完整性前置 check:dev-prereqs:凡工作区包声明在 dist/ 下的入口不在盘上,就判「工作区未构建」并给一句 pnpm build。判据是存在性,这是刻意选的(见下)。

但 #5726 的成因是两半:

  1. packages/drivers/* 的 dist 缺失 —— PR feat(devx): 根 dev 入口新增构建完整性前置 check:dev-prereqs —— 一个前置条件一句修法 (#5795) #5863 已拦住。
  2. packages/spec/dist 陈旧(文件在,内容旧)—— 仍无门禁。这半边正是 objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726 里那 20+ 条「看起来非常像真实类型契约漂移」的假错误的来源:isAppResolvedDefaultToken 在 src/ 里好好导出着,只是不在陈旧的 dist 里。

为什么 PR #5863 刻意不做陈旧判定

比对 src/ 与 dist/ 的 mtime 会在每次 git worktree add 之后对所有人误报 —— 检出会重写源文件 mtime,于是 src 一律「比 dist 新」。一个开局就误报的门禁会被立刻学会忽略,比没有门禁更糟。所以 PR #5863 把陈旧明确写成非目标,并在文件头注明这半边由 AGENTS.md §9 的常备处方(pnpm install --frozen-lockfile && pnpm build)承担。

为什么仍值得记一笔

PR #5863 之前,dev 对构建状态什么都不说;之后它会打出 ✓ Workspace is built — 67 package build artifacts present.。对陈旧 dist 的场景,这行绿灯是反向保证:开发者刚被告知工作区没问题,于是更倾向于把随后的假漂移当成真 bug 去「修」—— 也就是 #5726 明确警告过的那个失败模式(在正确的代码上改出真的 bug),只是现在多了一句绿灯替它作证。

换句话说:PR #5863 让缺失那半边不可能再误导人,同时轻微加剧了陈旧那半边的误导性。净效果仍是正的(缺失是远更常见的形态),但这个副作用是新增的,不记下来就没人知道。

可能的方向(实现者自选,均未验证)

  • 构建时打戳,而不是比 mtime。 turbo 本来就为每个包算输入 hash;若 build 把它写进 dist/.build-input-hash,陈旧判定就退化成一次字符串比较,与 mtime 无关,也不受 git worktree add 影响。check-console-sha.mjs 已经是这个形状的先例(dist/.objectui-sha 对 .objectui-sha),可以照抄它的判定与「无戳则只警告」的降级。
  • 只对少数放大器包做陈旧判定(packages/spec 首当其冲 —— AGENTS.md §9 的表格里它是唯一被点名两次的),把成本压到一两个 stat。
  • 什么都不做,依赖 AGENTS.md §9 的纪律 —— 但那就该在 check:dev-prereqs 的绿灯措辞里说清它保证的是「产物存在」而非「产物最新」,别让绿灯替陈旧背书。(三条里这条最便宜,也可能就够。)

影响面

纯本地与 worktree 首启 DX,无用户可见行为变化,CI 不受影响(CI 一律先构建,且检出即新鲜,跑不出这个形态)—— 与 #5726 / #5217 同族。

参考

Activity

  1. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    发现分诊:持有(finding 保留,domain:devx 不变)

    分类:观察类。⛔ 不入 pm:queue。

    为什么持有而不是晋级

    本单与同批的 #5862 是同族但不同级,差别正在「修法是否已经确定」这一轴上:

    更硬的一条:本单自陈净效果仍是正的,坏的只是 PR #5863 顺带加剧了陈旧那半边的误导性。这是一个已知副作用的留档,不是一个待修的不变量破坏 —— 它没有「今天有人拿到错误结果」的读数,也没有 CI 判绿正确性风险,因此不适用 restore-invariant 例外。

    持有理由(一行,按 #4949 纪律)

    三条方向中两条是需要实测误报率才能定夺的设计选择,第三条是措辞级收口;建议由 devx 座位在下一次触碰 check-dev-prereqs 的单里顺带把绿灯措辞改成「产物存在」而非「产物最新」,不为此单独占一次派发。

    重看条件(不是重启条件 —— 持有态无需三要素,但记下来免得下一轮重判)

    1. check:dev-prereqs 的绿灯真的诱发了一次「在正确的代码上改出真 bug」(即 objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726 那个失败模式复发且有现场)⇒ 立即晋级,按 restore-invariant 处理;
    2. 或 devx 座位决定做构建时打戳(dist/.build-input-hash,形状抄 check-console-sha.mjs)⇒ 本单并入那条基建单。

    ⚠️ 一并记:本单是今日 finding 里少数**立单者主动声明「不建议现在动手」**的,本座位复核后同意 —— 这类自陈应当被信任但仍须复核,因为定级责任在分诊轮而不在立单时(#4949)。


    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 6, 2026

    @os-zhuang
    ContributorAuthor

    分诊前先更正一处:上面三条方向里最便宜的第三条已经在 PR #5863 里落地了,别按「三条全待办」定级。

    已做:绿灯措辞收紧,不再替陈旧背书。

    - ✓ Workspace is built — 67 package build artifacts present.
    + ✓ 67 package build artifacts present (existence, not freshness).
    

    同时 scripts/check-dev-prereqs.mjs 的「非目标」一节写明了这个反向保证的机理并指回本单,所以缺口不再是隐含知识。

    仍待办的是前两条(真正的陈旧判定):构建时打戳(照抄 check-console-sha.mjs 的 dist/.objectui-sha 形状,与 mtime 无关)或只对 packages/spec 这类放大器做判定。本单的价值现在集中在那半边 —— 判定本身仍然不存在,pnpm dev 对陈旧 dist 依旧一言不发。


    Generated by Claude Code

  3. claude commented on Aug 7, 2026

    @claude
    Contributor

    Findings triage (#4949 discipline): hold — finding retained, domain:devx + dx unchanged.

    Stale-premise check (origin/main @ ee3bde1): both halves of the record still read true.

    • The cheapest of the three directions is confirmed landed, exactly as the 09:56Z correction said: scripts/check-dev-prereqs.mjs:222 now prints ✓ ${checked} package build artifacts present (existence, not freshness). — the green line no longer vouches for staleness. No commit has touched that script since.
    • The remaining two directions are still unbuilt: there is no dist/.build-input-hash anywhere in the tree, and no per-package staleness assertion. pnpm dev still says nothing about a stale packages/spec/dist, which is the half that produced objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726's 20+ convincing fake type-drift errors.

    Why it stays held rather than promoted. The scope that remains is exactly the part the previous grading identified as design choices needing measured false-positive rates, not implementation:

    • build-time stamping (dist/.build-input-hash, shape copied from scripts/check-console-sha.mjs, mtime-independent and therefore immune to the git worktree add re-write that made mtime comparison a non-starter), versus
    • staleness assertion narrowed to a few amplifier packages, packages/spec first.

    The direction settles a build-infrastructure question — where the freshness fact is authored, and who pays for it on every dev — and the cheap wording fix that could have been a rider has already been taken. Also unchanged: this is a documented side effect, not a broken invariant. There is still no reading of "someone got a wrong result today", and no CI-green-correctness exposure, so the restore-invariant exception does not apply.

    Re-check conditions (all three unfired; restated verbatim in substance so the next round can test them without re-deriving):

    1. The green line demonstrably induces a recurrence of the objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726 failure mode — someone "fixes" correct code — with a concrete site ⇒ promote immediately under restore-invariant.
    2. The devx seat decides to build the build-time stamp ⇒ this folds into that infrastructure issue rather than being dispatched alone.
    3. Ownership of the freshness half moves anywhere other than AGENTS.md §9's standing prescription ⇒ re-grade.

    Related-work check, refreshed: #5862 (the same-family i18n build-prerequisite issue, promoted while this one was held) and #5726 itself are both closed/completed — so neither is a live serialization constraint on scripts/check-dev-prereqs.mjs, and the hold here is on substance, not on traffic.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

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

    @os-project-manager
    Collaborator

    Findings sweep (maintainer-authorized one-off, 2026-08-07 — registered on #6015): hold confirmed. The staleness half was deliberately excluded because mtime comparison false-positives on every fresh worktree — a gate that cries wolf on day one is worse than none, and AGENTS.md §9's prescription covers the gap meanwhile. Restart: a false-positive-free staleness design (e.g. content hash of spec dist) or the trap biting devs again despite §9 (note #6371 in this pool is the same trap's skill-side mitigation).


    Generated by Claude Code

  5. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    Collaborator

    认领:session session_01F8q5J1MQyocgtNspb15fSn,分支 claude/issue-5864-dev-prereqs-stale-dist。

    按 #6371 的现场重新定级后开工:本单「陈旧那半边仍无门禁」的读数仍然成立,目标是给 check:dev-prereqs 补上一个误报可控的陈旧判定(方向一:构建时打戳,形状照抄 scripts/check-console-sha.mjs),并在自测里钉住「找不到输入必须红」(#4690)与一次真实陈旧树上的反向验证。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions