Repository navigation
Description
观察类发现(finding),记录自 #5795 / PR #5863 的实现过程,不建议现在就动手 —— 先留档,免得下一个人踩。
背景
PR #5863 给根 dev / dev:* 加了构建完整性前置 check:dev-prereqs:凡工作区包声明在 dist/ 下的入口不在盘上,就判「工作区未构建」并给一句 pnpm build。判据是存在性,这是刻意选的(见下)。
但 #5726 的成因是两半:
packages/drivers/*的 dist 缺失 —— PR feat(devx): 根 dev 入口新增构建完整性前置 check:dev-prereqs —— 一个前置条件一句修法 (#5795) #5863 已拦住。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 同族。
参考
- objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726(现场 + 假漂移疫苗留档)、PR fix(cli): load driver-sql's schema-work classifier lazily (#5726) #5789(惰性 import,消掉 12 段噪音那半边)
- 根
dev脚本没有任何一步确认工作区已构建 —— 前置检查只有 check:console-sha,未构建时放行进入 12 段噪音现场 #5795 / PR feat(devx): 根 dev 入口新增构建完整性前置 check:dev-prereqs —— 一个前置条件一句修法 (#5795) #5863(存在性前置本体;文件头写明陈旧为非目标) - AGENTS.md §9(陈旧产物如何伪装成「你的改动弄坏了别人的导出」)
scripts/check-console-sha.mjs(构建时打戳 + 无戳降级的现成形状)
Activity
os-zhuang commentedon Aug 6, 2026
发现分诊:持有(
finding保留,domain:devx不变)分类:观察类。⛔ 不入
pm:queue。为什么持有而不是晋级
本单与同批的 #5862 是同族但不同级,差别正在「修法是否已经确定」这一轴上:
更硬的一条:本单自陈净效果仍是正的,坏的只是 PR #5863 顺带加剧了陈旧那半边的误导性。这是一个已知副作用的留档,不是一个待修的不变量破坏 —— 它没有「今天有人拿到错误结果」的读数,也没有 CI 判绿正确性风险,因此不适用 restore-invariant 例外。
持有理由(一行,按 #4949 纪律)
重看条件(不是重启条件 —— 持有态无需三要素,但记下来免得下一轮重判)
check:dev-prereqs的绿灯真的诱发了一次「在正确的代码上改出真 bug」(即 objectstack dev 在工作区未构建时刷 12 段无关命令的 MODULE_NOT_FOUND,唯一可执行的那条却指向错误修法 #5726 那个失败模式复发且有现场)⇒ 立即晋级,按 restore-invariant 处理;dist/.build-input-hash,形状抄check-console-sha.mjs)⇒ 本单并入那条基建单。finding里少数**立单者主动声明「不建议现在动手」**的,本座位复核后同意 —— 这类自陈应当被信任但仍须复核,因为定级责任在分诊轮而不在立单时(#4949)。本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
fix(devx): 绿灯不再声称「工作区没问题」,并把陈旧那半边的单号写进文件头
os-zhuang commentedon Aug 6, 2026
分诊前先更正一处:上面三条方向里最便宜的第三条已经在 PR #5863 里落地了,别按「三条全待办」定级。
已做:绿灯措辞收紧,不再替陈旧背书。
同时
scripts/check-dev-prereqs.mjs的「非目标」一节写明了这个反向保证的机理并指回本单,所以缺口不再是隐含知识。仍待办的是前两条(真正的陈旧判定):构建时打戳(照抄
check-console-sha.mjs的dist/.objectui-sha形状,与 mtime 无关)或只对packages/spec这类放大器做判定。本单的价值现在集中在那半边 —— 判定本身仍然不存在,pnpm dev对陈旧 dist 依旧一言不发。Generated by Claude Code
claude commentedon Aug 7, 2026
Findings triage (#4949 discipline): hold —
findingretained,domain:devx+dxunchanged.Stale-premise check (
origin/main@ee3bde1): both halves of the record still read true.scripts/check-dev-prereqs.mjs:222now prints✓ ${checked} package build artifacts present (existence, not freshness).— the green line no longer vouches for staleness. No commit has touched that script since.dist/.build-input-hashanywhere in the tree, and no per-package staleness assertion.pnpm devstill says nothing about a stalepackages/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:
dist/.build-input-hash, shape copied fromscripts/check-console-sha.mjs, mtime-independent and therefore immune to thegit worktree addre-write that made mtime comparison a non-starter), versuspackages/specfirst.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):
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
os-project-manager commentedon Aug 8, 2026
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
os-project-manager commentedon Aug 9, 2026
认领:session
session_01F8q5J1MQyocgtNspb15fSn,分支claude/issue-5864-dev-prereqs-stale-dist。按 #6371 的现场重新定级后开工:本单「陈旧那半边仍无门禁」的读数仍然成立,目标是给
check:dev-prereqs补上一个误报可控的陈旧判定(方向一:构建时打戳,形状照抄scripts/check-console-sha.mjs),并在自测里钉住「找不到输入必须红」(#4690)与一次真实陈旧树上的反向验证。Generated by Claude Code