在实现 #4711 (build-schemas.ts --check 不再写 json-schema.manifest.json)时撞到的,与该单是同一缺陷类别但不同入口 ,按 Prime Directive #10 单独记录。
现象
packages/spec/package.json:
"check:docs" : " pnpm gen:schema && tsx scripts/build-docs.ts --check" ,
gen:schema 是生成器 ,不是检查:它在 json-schema.manifest.json / authorable-surface.json 陈旧时会把这两个 tracked 文件写掉。于是 check:docs(以及包含它的 check:generated)仍然是一条「跑一次门禁,工作区被改」的路径 —— 正是 #4711 的现象,只是换了个入口。
实测(在 #4711 的修复分支上,即 --check 自身已经不写了)
manifest staled by hand: 94234b0acb9f79122580537e997dd84b
$ git status --porcelain packages/spec/json-schema.manifest.json
M packages/spec/json-schema.manifest.json
$ pnpm --filter @objectstack/spec check:docs
check:docs exit=0
manifest after check:docs: 94ddfeb6032474c1e62661a0fd6dca03
$ git status --porcelain packages/spec/json-schema.manifest.json
← 空:本地改动被这条「检查」吃掉了
为什么修完 #4711 之后这条反而更值得看一眼
check:generated 的执行顺序里 check:authorable-surface 在前、check:docs 在后(scripts/check-generated.ts 的 GATED 表),而且它不会因为前面失败就停 。所以在 manifest 陈旧的情况下,跑一次 check:generated 的结果是:
check:authorable-surface 红,报「manifest is out of date,去跑 gen:schema」(check:authorable-surface 在 --check 模式下仍会写 json-schema.manifest.json —— 一个「检查」在改工作区 #4711 修好的部分);
随后 check:docs 里的 gen:schema 把它写好了 ;
开发者回头一看工作区 —— 干净的,或者多了一个自己没写的 diff。
一份红色报告配一个已经被悄悄修好的文件,比修之前更难解释。
关于 CI
线上不会漏(干净 checkout + 顺序执行),这条主要是本地/agent 并行开发的困惑成本,以及「一个名字叫 check 的脚本会写 tracked 文件」这个语义漏洞本身。
可能的方向(需要维护者定,不要照抄)
build-docs.ts 需要磁盘上的 packages/spec/json-schema/(gitignored 产物),这才是 check:docs 前面挂 gen:schema 的原因。所以至少三条路:
A. 给 build-schemas.ts 一个「只写 gitignored 产物」的模式 (例如 --no-snapshots),check:docs 用它。改动最小,但多一个模式位,得想清楚它和 --check 的关系。
B. 让 check:docs 依赖 build 的产物 而不是每次现场生成。语义最干净(检查就是检查),代价是它不再自足,顺序依赖要写进 CI 与文档。
C. build-docs.ts 改成直接从 Zod 源产出内存里的 schema ,不再经过磁盘。最彻底,改动也最大。
倾向 B 或 A;但这会动到 check:generated / 合并驱动(scripts/regen-artifacts.mjs)对「check 证明 currency」的假设,值得先拍板再动手。
关联:#4711 (同类缺陷,manifest ratchet 自身,已修)、#4675 / PR #4702 (生成物合并驱动 —— 「a plausible generated file is an invisible error」)、#4203 / #4232 (check:generated 分类不一致的历史)。
在实现 #4711(
build-schemas.ts --check不再写json-schema.manifest.json)时撞到的,与该单是同一缺陷类别但不同入口,按 Prime Directive #10 单独记录。现象
packages/spec/package.json:gen:schema是生成器,不是检查:它在json-schema.manifest.json/authorable-surface.json陈旧时会把这两个 tracked 文件写掉。于是check:docs(以及包含它的check:generated)仍然是一条「跑一次门禁,工作区被改」的路径 —— 正是 #4711 的现象,只是换了个入口。实测(在 #4711 的修复分支上,即
--check自身已经不写了)为什么修完 #4711 之后这条反而更值得看一眼
check:generated的执行顺序里check:authorable-surface在前、check:docs在后(scripts/check-generated.ts的GATED表),而且它不会因为前面失败就停。所以在 manifest 陈旧的情况下,跑一次check:generated的结果是:check:authorable-surface红,报「manifest is out of date,去跑 gen:schema」(check:authorable-surface在 --check 模式下仍会写json-schema.manifest.json—— 一个「检查」在改工作区 #4711 修好的部分);check:docs里的gen:schema把它写好了;一份红色报告配一个已经被悄悄修好的文件,比修之前更难解释。
关于 CI
线上不会漏(干净 checkout + 顺序执行),这条主要是本地/agent 并行开发的困惑成本,以及「一个名字叫 check 的脚本会写 tracked 文件」这个语义漏洞本身。
可能的方向(需要维护者定,不要照抄)
build-docs.ts需要磁盘上的packages/spec/json-schema/(gitignored 产物),这才是check:docs前面挂gen:schema的原因。所以至少三条路:build-schemas.ts一个「只写 gitignored 产物」的模式(例如--no-snapshots),check:docs用它。改动最小,但多一个模式位,得想清楚它和--check的关系。check:docs依赖build的产物而不是每次现场生成。语义最干净(检查就是检查),代价是它不再自足,顺序依赖要写进 CI 与文档。build-docs.ts改成直接从 Zod 源产出内存里的 schema,不再经过磁盘。最彻底,改动也最大。倾向 B 或 A;但这会动到
check:generated/ 合并驱动(scripts/regen-artifacts.mjs)对「check 证明 currency」的假设,值得先拍板再动手。关联:#4711(同类缺陷,manifest ratchet 自身,已修)、#4675 / PR #4702(生成物合并驱动 —— 「a plausible generated file is an invisible error」)、#4203 / #4232(
check:generated分类不一致的历史)。