Skip to content

fix(spec): check:docs 不再以 gen:schema 开头,生成交给调用方 (#4723) - #6000

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-4723-check-docs-no-gen
Aug 6, 2026
Merged

fix(spec): check:docs 不再以 gen:schema 开头,生成交给调用方 (#4723)#6000
baozhoutao merged 1 commit into
mainfrom
claude/issue-4723-check-docs-no-gen

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #4723

前提复核(在当前 origin/main 上实测)

单子正文引用的那行仍在,今天四次合并(#5807/#5851/#5902/#5971)都没动它。前提成立,现象原样复现:

$ git status --porcelain packages/spec/json-schema.manifest.json
 M packages/spec/json-schema.manifest.json      ← 手工改旧(删掉 ui/WidgetSource)
   md5 = f9237c0caeb9d007fb5d03d6e6506ff0

$ pnpm --filter @objectstack/spec check:docs
check:docs exit=0                               ← 绿
real 0m8.966s
   md5 = 66f382332217c4af0eb857b405944bc8      ← 被写回去了

$ git status --porcelain packages/spec/json-schema.manifest.json
                                                ← 空:本地改动被这条「检查」吃掉了

路线选择:实测否掉了 A,走精化的 B

派单允许「若实测 A(--no-snapshots 模式)代价更小则可选 A」。实测结论是 A 不更便宜,而是更贵,所以走 B:

命令 耗时 写 gitignored json-schema/ 写 tracked 投影
check:docs(修复前) 8.97s 是 ← 缺陷
check:authorable-surface(--check) 4.90s 是(1609 个文件) 否(#4711)
tsx scripts/build-docs.ts --check 单跑 1.84s

关键测量是中间那行: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

改了什么

  1. check:docs = tsx scripts/build-docs.ts --check,不再生成任何东西。
  2. 新鲜度从「隐式保证」改为「显式断言」。 原来的第一步顺手保证了 json-schema/ 描述的是当前源码;直接删掉它,只是把「改工作区」换成更糟的假绿 —— 对着编辑前生成的树报告「文档已同步」,而这正是这道门禁存在的理由(加了个 .describe()、改了个 key)。所以 build-docs.ts所有模式下先断言该树存在且不旧于 src/,否则红着退出并给出命令。写模式尤其要拒绝:陈旧树上的 gen:docs 不会失败,它会写出陈旧页面 —— 就是 readsDist 那个坑挪一个产物。
  3. 规则 schemaTreeIsStale()distIsStale() 同住 scripts/check-regen-pending.mjs(同一个问题、三个消费方:生成器 / pre-commit 钩子 / merge driver 的提示)。与 distIsStale 唯一的有意差别:排除 .test.ts —— 测试文件不是 build-schemas.ts 的输入,算进去会让每个纯测试 PR 都被要求跑一次没有意义的 gen:schema,而一道乱叫的门禁就是下一个人会删掉的门禁。
  4. check:generated 的 GATED 表声明这条依赖(readsSchemaTree: 'check:authorable-surface'),reconciliation 在生产者缺失或排在消费者之后时失败 —— 数组字面量的顺序是一条真实依赖,不该靠巧合表达。
  5. 调用点全量清点后同步:lint.yml(纯注释 + 步骤顺序的 ⚠️ 说明,未新增步骤、未调整顺序,与 parked PR ci(dx): DEBT/TEST_DEBT 台账数字改为每次重测的真棘轮 —— 实测 > 记录即红 (#5278) #5827 无冲突)、regen-artifacts.mjs / git-merge-regen.mjs / pre-commit(readsSchemaTreereadsDist 同款拒绝路径)、AGENTS.md(「check:docs 不再自足」)。apps/docs build 与 retirement skill 的门禁循环都以 gen:schema / pnpm build 开头,天然新鲜,无需改动。

验收(单子的原文标准)

清洁树上、并且先手工把 tracked 投影改旧:

$ md5sum packages/spec/json-schema.manifest.json
f9237c0caeb9d007fb5d03d6e6506ff0      ← 已改旧

$ pnpm --filter @objectstack/spec check:docs
check:docs exit=0
real 0m2.052s                          ← 8.97s → 2.05s

$ md5sum packages/spec/json-schema.manifest.json
f9237c0caeb9d007fb5d03d6e6506ff0      ← 原样,没被修
$ git status --porcelain packages/spec/json-schema.manifest.json
 M packages/spec/json-schema.manifest.json      ← 本地改动还在

整条 check:generated(同样从改旧的 manifest 出发):

  ✗ check:authorable-surface   authorable-surface.json (+ its .base.json anchor) + JSON schemas
  ✓ check:docs                 content/docs/references/**
✗ 2 of 10 artifact(s) stale
=== 之后 md5 仍是 f9237c0...,git status 里那条 M 仍在 ===

报告,而不是修复。 修复前同一条命令跑完,manifest 已被写回、git status 干干净净 —— 一份红色报告配一个已经被悄悄修好的文件,正是单子说的那个状态。

(check:api-surface 在这个全新 worktree 里是红的,原因是它自己报的 readsDist:Is the package built? —— 与本 PR 无关。)

护栏的四个方向都实测过:树缺失 → 红并给出命令;src 比树新 → 红;树比 src 新 → 绿;只 touch 一个 .test.ts → 仍然绿(那条有意的排除)。

反向验证(方向是先预测再跑的)

预测:把删掉的 gen:schema 那截装回去,新增的组合 pin 应当变红(标准方向 —— 这不是 ?? 链,不涉及反转)。

$ # 把 check:docs 改回 "pnpm gen:schema && tsx scripts/build-docs.ts --check"
       × is true of every check: script in this package
       × leaves check:docs as the read-only half it is named for
AssertionError: `check:docs` runs the generator(s) `gen:schema`:
 Tests  2 failed | 6 passed (8)

关于「自证清洁测试」的形状,说明一句

派单要求按 #5358 先例 pin 成测试。#5358 是端到端跑脚本再断言 git status --porcelain 为空,因为那里的写操作埋在一个 1600 行脚本内部,只有跑一遍才看得见。这里不是:写操作是 package.json 里的一行组合,所以 pin 在源码层更强而不是更弱 ——

  • 它不需要执行任何东西就能看见回归;
  • 它不会像 spawn 出来的运行那样在 gitignored 输入缺失时静默退化(turbo run test 恰好就让这个包处于该状态,root-index.test.ts 里写着这件事)。

所以 pin 写成了而不是那一个实例:任何 check: 脚本都不得组合 gen: 脚本(check-generated-ledger.test.ts),外加 check:docs 具名的那条。端到端证据在上面的「验收」小节,是手工实测的真实输出。这是刻意的取舍,写在这里而不是伪装成模板要求的形状。

验证

  • pnpm --filter @objectstack/spec test324 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
  • 新增 14 个测试(6 个新鲜度规则 + 8 个账本/组合)

变更集

patch on @objectstack/spec —— check:docs 的行为对开发者可见(不再自足、不再改工作区),不是纯 CI 编排。


Generated by Claude Code

`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
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 6, 2026 2:15pm

Request Review

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec.

111 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx (via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx (via @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx (via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx (via @objectstack/spec)
  • content/docs/api/index.mdx (via @objectstack/spec)
  • content/docs/automation/approvals.mdx (via @objectstack/spec)
  • content/docs/automation/connectors.mdx (via @objectstack/spec)
  • content/docs/automation/flows.mdx (via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx (via packages/spec)
  • content/docs/automation/hooks.mdx (via @objectstack/spec)
  • content/docs/automation/index.mdx (via @objectstack/spec)
  • content/docs/automation/webhooks.mdx (via @objectstack/spec)
  • content/docs/automation/workflows.mdx (via @objectstack/spec)
  • content/docs/concepts/architecture.mdx (via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx (via packages/spec)
  • content/docs/concepts/index.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx (via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx (via packages/spec)
  • content/docs/concepts/north-star.mdx (via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx (via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx (via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx (via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx (via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx (via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx (via @objectstack/spec)
  • content/docs/data-modeling/index.mdx (via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx (via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx (via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx (via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx (via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx (via @objectstack/spec)
  • content/docs/deployment/cli.mdx (via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx (via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx (via @objectstack/spec)
  • content/docs/getting-started/examples.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx (via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx (via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx (via @objectstack/spec)
  • content/docs/kernel/cluster.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx (via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx (via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx (via packages/spec)
  • content/docs/kernel/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx (via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx (via packages/spec)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/spec)
  • content/docs/kernel/services.mdx (via @objectstack/spec)
  • content/docs/permissions/authorization.mdx (via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx (via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx (via @objectstack/spec)
  • content/docs/permissions/positions.mdx (via @objectstack/spec)
  • content/docs/permissions/rls.mdx (via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx (via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx (via @objectstack/spec)
  • content/docs/plugins/development.mdx (via @objectstack/spec)
  • content/docs/plugins/index.mdx (via @objectstack/spec)
  • content/docs/plugins/packages.mdx (via @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx (via @objectstack/spec)
  • content/docs/protocol/diagram.mdx (via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx (via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx (via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx (via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx (via @objectstack/spec)
  • content/docs/releases/index.mdx (via @objectstack/spec)
  • content/docs/releases/v12.mdx (via @objectstack/spec)
  • content/docs/releases/v13.mdx (via @objectstack/spec)
  • content/docs/releases/v16.mdx (via @objectstack/spec)
  • content/docs/releases/v17.mdx (via @objectstack/spec)
  • content/docs/releases/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.mdx (via @objectstack/spec)
  • content/docs/ui/apps.mdx (via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx (via @objectstack/spec)
  • content/docs/ui/dashboards.mdx (via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx (via @objectstack/spec)
  • content/docs/ui/forms.mdx (via @objectstack/spec)
  • content/docs/ui/index.mdx (via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx (via @objectstack/spec)
  • content/docs/ui/setup-app.mdx (via @objectstack/spec)
  • content/docs/ui/translations.mdx (via @objectstack/spec)
  • content/docs/ui/views.mdx (via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation ci/cd dependencies Pull requests that update a dependency file tests tooling labels Aug 6, 2026
@baozhoutao
baozhoutao marked this pull request as ready for review August 6, 2026 14:40
@baozhoutao
baozhoutao added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit b5bdf48 Aug 6, 2026
26 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-4723-check-docs-no-gen branch August 6, 2026 14:56
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation size/l tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check:docs 的第一步是 gen:schema —— 修好 #4711 之后,「检查改工作区」仍从这里漏进来

2 participants