Skip to content

docs(generator): fix reference $ref links and opaque Object types#3126

Merged
os-zhuang merged 1 commit into
mainfrom
docs/generator-fixes
Jul 17, 2026
Merged

docs(generator): fix reference $ref links and opaque Object types#3126
os-zhuang merged 1 commit into
mainfrom
docs/generator-fixes

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

背景

文档审计发现 243 个自动生成的 reference 页有系统性缺陷:92 处指向不存在页面的 [__schema0](./__schema0)、6 处 (./#) 自链、大量 Object | Object。根因全在 packages/spec/scripts/build-docs.ts

根因与修复

  1. 所有 $ref 链接其实都是坏的(不只匿名的显眼):formatType$ref 转成 ./<schemaName>,但页面是按 zod 文件命名的(data/object.mdx),ref 指向的是 schema 名(Field)——两套命名空间从未打通。现在具名 ref 走 scanCategories() 早就建好、却从未被读取的 schemaCategoryMap/schemaZodFileMap 解析成站内路由;查不到页面则降级为纯文本而不是吐 404。
  2. __schemaN 是 Zod 把复用的内联 schema 提升进 $defs 时合成的名字,根本没有对应页面 → 就地展开结构,并加环路保护(这些 schema 是递归的——节点含节点——朴素内联会爆栈,第一版就爆了)。
  3. $ref: "#" 自引用 → 链到本节锚点。
  4. Object | Object:内联对象展开一层形状({ label: string; value: string; color?: string; … });const 变体渲染字面量,判别式联合读作 'a' | 'b'
  5. JSDoc {@link ../automation/sync.zod.ts} 链到仓库路径(站上 404)→ 重写为站内路由;裸 @see 渲染成 "See also:"。

重新生成后:__schemaN 链接 92 → 0,(./#) 6 → 0,zod.ts 坏链 → 0

附带:修好 lychee.toml(但不恢复触发)

查"为什么坏链能长期躺在 main 上"时发现:check-links.yml 的触发被注释掉了,而原因很可能是配置本身坏了 —— follow_redirects 与 boolean 形式的 include_fragments 在 lychee ≥0.24 都不是合法键,accept 要字符串数组。job 一启动就死。

本 PR 修好配置使其可加载,但不恢复触发:试跑后发现还需要 root_dir/fallback_extensions 才能解析根相对链接,且站内确有几处真 404 要先清。完整恢复路径与已发现的真坏链清单记录在 #3136。先修闸门再上锁,顺序反了就是每个 PR 都红——那正是它当初被关掉的原因。

验证

pnpm --filter @objectstack/spec gen:docs ✅ · pnpm --filter @objectstack/docs build ✅ (exit 0)。diff 含 186 个重新生成的 mdx(生成产物)。

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jul 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 17, 2026 1:08pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd tooling labels Jul 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

102 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 packages/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 packages/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/troubleshooting.mdx (via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx (via @objectstack/spec)
  • content/docs/getting-started/cli.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/validating-metadata.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/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 packages/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/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/i18n-standard.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/kernel/runtime-capabilities.mdx (via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx (via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx (via packages/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/v9.mdx (via @objectstack/spec)
  • content/docs/ui/actions.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/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.

Comment thread packages/spec/scripts/build-docs.ts Fixed
@xuyushun441-sys
xuyushun441-sys force-pushed the docs/generator-fixes branch 3 times, most recently from 7987387 to 45d0653 Compare July 17, 2026 12:30
@os-zhuang os-zhuang changed the title docs(generator): fix reference $ref links and opaque Object types; re-arm link CI docs(generator): fix reference $ref links and opaque Object types Jul 17, 2026
The 243 generated reference pages carried ~92 links to a page that never
existed (`[__schema0](./__schema0)`), 6 self-links to `(./#)`, and every
inline object rendered as an opaque `Object`. Root causes, all in
build-docs.ts:

- `formatType` turned `$ref` into `./<schemaName>`, but pages are named
  after the *zod file* — so no `$ref` link could ever resolve. Named refs
  now resolve through the schemaCategoryMap/schemaZodFileMap that
  scanCategories() already built (dead code until now) to
  `/docs/references/<category>/<file>#<schema>`, and fall back to plain
  text rather than a 404 when no page exists.
- `__schemaN` refs are Zod-hoisted inline schemas with no page at all;
  they are now expanded structurally, with a cycle guard (these schemas
  are recursive — a node contains nodes — and naive inlining blows the
  stack).
- `$ref: "#"` (self-reference) now links to the section's own anchor.
- Inline objects render their shape one level deep
  (`{ label: string; value: string; color?: string; … }`) instead of
  `Object`; const variants render their literal, so discriminated unions
  read as `'a' | 'b'` rather than `Object | Object`.
- JSDoc `{@link ../automation/sync.zod.ts}` linked to a repo path that
  404s on the site; source paths now rewrite to their docs route, and a
  bare `@see` renders as "See also:" prose instead of a stray tag.
- Property type cells escape backslashes before pipes, matching the
  neighbouring `desc` escaping (and its comment) — CodeQL's
  js/incomplete-sanitization on the old order.

Counts after regenerating: __schemaN links 92 → 0, (./#) 6 → 0,
zod.ts links → 0. Passes the new `--check` gate from #3134.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@os-zhuang
os-zhuang merged commit a605872 into main Jul 17, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the docs/generator-fixes branch July 17, 2026 13:17
os-zhuang added a commit that referenced this pull request Jul 17, 2026
#3138 extracted the emit()/manageDir()/flush() sink to lib/generated-output.ts and moved
build-skill-references + build-react-blocks-contract onto it, but left build-docs.ts
carrying the inline original — #3126 was rewriting the same file and the migration would
have conflicted. #3126 has landed, so collect the debt.

Two copies of a check/write sink is the one duplication this design cannot afford: its
whole claim is that --check and write are the same code, and that claim is per copy. A
fix to one silently leaves the other behind, and the failure mode is a gate that passes
on output a real run would not produce.

Adds wasEmitted() to the shared sink. build-docs is the first caller whose later output
depends on its earlier output — each category index links only the pages that got
generated — and that question belongs to the sink, which already owns the emitted map.
New export; the other two callers are unaffected. The empty-input guard moves to
flush()'s guard hook, same meaning.

Pure refactor, verified: byte-identical output across all 258 files; all five drift
classes still fail (stale content, missing page, stale leftover, no-schema guard,
in-sync green); both existing sink callers regress clean, including #3138's reverse test
that a hand-written .md in skills/*/references/ keeps the gate green and survives a write.

Net -58 lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd documentation Improvements or additions to documentation size/xl tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants