fix(spec): check:docs 不再以 gen:schema 开头,生成交给调用方 (#4723) - #6000
Merged
Conversation
`check:docs` 曾是 `pnpm gen:schema && tsx scripts/build-docs.ts --check`。 前半截是生成器:manifest / authorable-surface 陈旧时它会写掉这两个 tracked 文件。于是跑一次「检查」就改了工作区,而陈旧本身从未被报告 —— 这是 #4711 从 `--check` 里摘掉的同一个缺陷,只是换了个入口。 在 check:generated 里最难解释:check:authorable-surface 排在前面且失败不中止 后续,所以一次聚合运行的结果是一份红色报告配一个已被悄悄修好的文件。 - check:docs 变为纯 `tsx scripts/build-docs.ts --check` - 生成由调用方承担(CI 的 check:authorable-surface 步骤 / check:generated 的 门禁顺序 / pnpm build / apps/docs build);它们跑的 `--check` 只写 gitignored 的 json-schema/,拒绝碰 tracked 文件 - 原第一步顺带保证的「新鲜度」改为显式断言:build-docs.ts 在所有模式下先检查 json-schema/ 存在且不旧于 src,否则红着退出并给出命令 —— 否则只是把「改工作区」 换成更糟的假绿 - 新鲜度规则 schemaTreeIsStale() 与 distIsStale() 同住 check-regen-pending.mjs - check:generated 的 GATED 表声明 readsSchemaTree,reconciliation 强制生产者 必须排在消费者之前 实测:check:docs 8.97s → 2.05s(少跑一次 ~1600 schema 的生成)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01559M8FVm6W6vDLABL3jvdW
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 111 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This was referenced Aug 6, 2026
baozhoutao
marked this pull request as ready for review
August 6, 2026 14:40
This was referenced Aug 6, 2026
This was referenced Aug 6, 2026
qq9340100
pushed a commit
that referenced
this pull request
Aug 6, 2026
含 #6000(#4723:check:docs 不再以 gen:schema 开头,并在 check-generated 的 GATED 表 里声明 `readsSchemaTree`),S2 的门禁构成改动叠在它之上而不是并排。 冲突一处,packages/spec/scripts/check-generated.ts 的 GATED 表:两侧都改了 `check:docs` 与 `check:api-surface` 两行。取并集 —— 保留 #6000 的 `readsSchemaTree: 'check:authorable-surface'`(它声明的是 check:docs 依赖 check:authorable-surface 先生成 json-schema/ 树,与分片无关),同时保留本分支把 artifact 标签从 `api-surface.json` 改成 `api-surface/`。 生成物按 os-regen 纪律处理:merge 提交先落地(MERGE 态跑 gen:schema 会被 #5851 守卫 拒绝),随后整体重生成并补跑 gen:openapi(#5371)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY
qq9340100
pushed a commit
that referenced
this pull request
Aug 6, 2026
merge 带进来的 #4723/#6000 新增了几处描述「check:docs 曾重写两个 tracked 投影」的散文, 它们指的是当前机制而不是历史叙述,所以路径随分片一起更新:build-docs.ts、AGENTS.md、 check-regen-pending.mjs、check-generated-ledger.test.ts、schema-tree-freshness.test.ts。 另外 build-schemas.ts 里把 api-surface 说成「另一个见证者」的两处、以及 migrations/spec-changes.ts 的 Release 工作流描述,同属活文档。 ⛔ 有意不动的:所有 `src/**` 与测试里追述「当年这个 key 怎么出账」的历史叙述 (http-server.zod.ts / theme.zod.ts / data-engine.zod.ts / retry-policy.* / …), 以及 ADR 正文 —— 后者按 AGENTS.md #13 用顶部 Amended 行声明路径迁移,不改写决策记录。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4723
前提复核(在当前 origin/main 上实测)
单子正文引用的那行仍在,今天四次合并(#5807/#5851/#5902/#5971)都没动它。前提成立,现象原样复现:
路线选择:实测否掉了 A,走精化的 B
派单允许「若实测 A(
--no-snapshots模式)代价更小则可选 A」。实测结论是 A 不更便宜,而是更贵,所以走 B:json-schema/check:docs(修复前)check:authorable-surface(--check)tsx scripts/build-docs.ts --check单跑关键测量是中间那行:
build-schemas.ts --check本身就已经是「只写 gitignored 产物」的那个模式 —— 它完整重建json-schema/,并且拒绝碰任何 tracked 文件。所以路线 B 需要的「显式先跑一步」已经存在、已经在跑,就在两个真实调用点上(lint.yml 的步骤顺序、check:generated的 GATED 顺序)。route A 要新加第四个模式位到一个 1639 行、带沙箱测试的脚本里,还要定义它与
--check/--update-base的三对互斥,并且仍然保留 check:generated 里那次重复生成。B 反而把重复生成也一起省了。check:generated自己显式跑gen:schema。那会在check:authorable-surface之前把 tracked 投影修好,把那道门禁变成永远绿的 —— 缺陷穿上修复的外衣。合格的「先跑一步」必须是不写 tracked 文件的那种生成,这个约束把方案空间收敛到了--check。改了什么
check:docs=tsx scripts/build-docs.ts --check,不再生成任何东西。json-schema/描述的是当前源码;直接删掉它,只是把「改工作区」换成更糟的假绿 —— 对着编辑前生成的树报告「文档已同步」,而这正是这道门禁存在的理由(加了个.describe()、改了个 key)。所以build-docs.ts在所有模式下先断言该树存在且不旧于src/,否则红着退出并给出命令。写模式尤其要拒绝:陈旧树上的gen:docs不会失败,它会写出陈旧页面 —— 就是readsDist那个坑挪一个产物。schemaTreeIsStale()与distIsStale()同住scripts/check-regen-pending.mjs(同一个问题、三个消费方:生成器 / pre-commit 钩子 / merge driver 的提示)。与distIsStale唯一的有意差别:排除.test.ts—— 测试文件不是build-schemas.ts的输入,算进去会让每个纯测试 PR 都被要求跑一次没有意义的gen:schema,而一道乱叫的门禁就是下一个人会删掉的门禁。check:generated的 GATED 表声明这条依赖(readsSchemaTree: 'check:authorable-surface'),reconciliation 在生产者缺失或排在消费者之后时失败 —— 数组字面量的顺序是一条真实依赖,不该靠巧合表达。lint.yml(纯注释 + 步骤顺序的regen-artifacts.mjs/git-merge-regen.mjs/ pre-commit(readsSchemaTree走readsDist同款拒绝路径)、AGENTS.md(「check:docs不再自足」)。apps/docsbuild 与 retirement skill 的门禁循环都以gen:schema/pnpm build开头,天然新鲜,无需改动。验收(单子的原文标准)
清洁树上、并且先手工把 tracked 投影改旧:
整条
check:generated(同样从改旧的 manifest 出发):报告,而不是修复。 修复前同一条命令跑完,manifest 已被写回、
git status干干净净 —— 一份红色报告配一个已经被悄悄修好的文件,正是单子说的那个状态。(
check:api-surface在这个全新 worktree 里是红的,原因是它自己报的readsDist:Is the package built?—— 与本 PR 无关。)护栏的四个方向都实测过:树缺失 → 红并给出命令;
src比树新 → 红;树比src新 → 绿;只 touch 一个.test.ts→ 仍然绿(那条有意的排除)。反向验证(方向是先预测再跑的)
预测:把删掉的
gen:schema那截装回去,新增的组合 pin 应当变红(标准方向 —— 这不是??链,不涉及反转)。关于「自证清洁测试」的形状,说明一句
派单要求按 #5358 先例 pin 成测试。#5358 是端到端跑脚本再断言
git status --porcelain为空,因为那里的写操作埋在一个 1600 行脚本内部,只有跑一遍才看得见。这里不是:写操作是 package.json 里的一行组合,所以 pin 在源码层更强而不是更弱 ——turbo run test恰好就让这个包处于该状态,root-index.test.ts里写着这件事)。所以 pin 写成了类而不是那一个实例:任何
check:脚本都不得组合gen:脚本(check-generated-ledger.test.ts),外加check:docs具名的那条。端到端证据在上面的「验收」小节,是手工实测的真实输出。这是刻意的取舍,写在这里而不是伪装成模板要求的形状。验证
pnpm --filter @objectstack/spec test→ 324 files / 8284 tests passed(含build-schemas-check-mode.test.ts单独复跑 36 passed —— 该脚本的门禁语义一行未动)pnpm --filter @objectstack/spec typecheck→ 通过(tsc --noEmit+check:test-typecheck,79 files / 691 errors 的 shrink-only 账本无变化)pnpm check:merge-driver→ 通过(含新增的json-schema/缺失即 STALE 自测)pnpm check:generated --reconcile-only→ 通过,并新增一行叙述:↳ check:docs renders from json-schema/, generated by check:authorable-surface above it.pnpm check:nul-bytes→ OK(5752 个文件);改动文件另跑了越过门禁盲区的自扫描,无控制字节eslint改动文件 → 0变更集
patchon@objectstack/spec——check:docs的行为对开发者可见(不再自足、不再改工作区),不是纯 CI 编排。Generated by Claude Code