Skip to content

check:authorable-surface 在 --check 模式下仍会写 json-schema.manifest.json —— 一个「检查」在改工作区 #4711

Description

@os-zhuang

#4703(C12,PR #4710)做承接表 sabotage 验证时撞到的,与该单无关,按 Prime Directive #10 单独记录。

现象

pnpm --filter @objectstack/spec check:authorable-surfacebuild-schemas.ts --check,名字和 check:generated 里的定位都是「只检查、不改」。但它会写 packages/spec/json-schema.manifest.json

实测:我把 authorable-surface.json / json-schema.manifest.json 暂存(git stash push)到改名前的状态,只跑了 --check,随后 git stash pop 直接失败:

error: Your local changes to the following files would be overwritten by merge:
	packages/spec/json-schema.manifest.json
Please commit your changes or stash them before you merge.

原因

packages/spec/scripts/build-schemas.ts 的 manifest ratchet 段落没有 CHECK 判别:

const added = [...generatedKeys].filter((key) => !(manifest?.schemas ?? []).includes(key));
const renamedAway = (manifest?.schemas ?? []).filter((key) => key in RENAMED_DEFS);
if (!manifest || added.length > 0 || renamedAway.length > 0) {
  const updated: SchemaManifest = { /* … */ schemas: [...generatedKeys].sort() };
  fs.writeFileSync(MANIFEST_PATH, JSON.stringify(updated, null, 2) + '\n');   // ← 无条件写
  console.log(`\n📒 json-schema.manifest.json …  — commit it.`);
}

对比紧随其后的 authorable-surface 段落,那里是分开处理的,正是本 issue 期望的形状:

if (surfaceChanged && CHECK)  { /* 报错 + process.exit(1) */ }
if (surfaceChanged && !CHECK) { /* 写文件 */ }

即:missing(已发布 schema 消失)那条会 process.exit(1),是真检查;但新增/改名导致的 manifest 变更在 check 模式下被静默写掉,而不是报「stale,请跑 gen:schema」。

为什么值得修,而不只是洁癖

  1. 「检查」不该有副作用。 check:generated 会顺序跑这一条,开发者跑一次门禁就得到一个未预期的 tracked 文件改动;在脏工作区里 git stash / git worktree 一类操作会莫名其妙地失败(上面那段就是)。
  2. 它让 manifest 的 additions 分支永远无法在 CI 里红。 其它 7 个生成物都是「stale 就红,让人跑 gen」;这一个是「stale 就自己写」。两种语义混在同一个 check:generated 汇总里。
  3. 和刚落地的 spec 生成物没有 merge driver:两个 PR 各改几行,语义上是集合运算,却每次都打成文本冲突 #4675 合并驱动叠加更糟。 合并冲突期间跑任何 check,都可能拿半合并的树算出一个 manifest 并写进去 —— 而 build: merge driver for generator-owned spec artifacts (#4675) #4702 的 commit message 恰好花了一整段解释为什么合并驱动故意不在那个时刻重新生成:「a plausible generated file is an invisible error」。这里是同一个坑的另一个入口。

建议

把 manifest 段落改成和 authorable-surface 同构:

  • CHECK 时:若 added.length > 0 || renamedAway.length > 0,打印差异 + 提示 pnpm --filter @objectstack/spec gen:schema,process.exit(1);
  • CHECK 时:照旧写。

missing 那条(已发布 schema 消失)的行为不变,它已经是对的。

影响面

低——CI 是干净 checkout,check:docs 本身又会先跑一遍 gen:schema,所以线上不会漏。主要是本地开发/agent 并行工作时的困惑成本,以及上面第 2、3 条的语义漏洞。

关联:#4684 / PR #4695(RENAMED_DEFSrenamedAway 分支的来源)、#4675 / PR #4702(生成物合并驱动)、#4703 / PR #4710(撞到本问题的上下文)、#4203 / #4232(check:generated 分类不一致的历史)。

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions