在实施 #6484(同目录裸路径)时顺带量出,非本单范围,按 Prime Directive #10 独立记录。⛔ 未自我认领、未打 pm:queue —— 观察类,今天没有用户会撞上。
观察
packages/spec/scripts/build-docs.ts 是一 import 就执行的顶层脚本(读 SCHEMA_DIR、写 content/docs/references/**、process.exit)。因此它自己的函数无法被单测 import,packages/spec/scripts/*.test.ts 里没有一个文件测它。
这在 #6484 里被实测出来了,不是推断。该单给 sourcePathToDocsRoute() 补上了它文档里一直声明、实现却没做的一半 —— 「分类为真 ≠ 页面存在」。反向验证时把那一行判据删掉:
pnpm --filter @objectstack/spec test → Tests 57 passed (57) ← 全绿
pnpm --filter @objectstack/spec gen:docs → 产物里多出 4 条死链
identity/identity.mdx -> /docs/references/identity/auth
system/security-context.mdx -> /docs/references/system/audit
system/security-context.mdx -> /docs/references/system/compliance
system/security-context.mdx -> /docs/references/system/masking
即:删掉一条真判据,整个 pnpm test 一条都不红。#6484 的单测里有对应的 stand-in 用例,但那是在 lib/file-description.ts 那道缝上钉的,它自带一个模拟页面清单 —— 钉住的是「解析器返回 null 时回退成代码段」这条规则,不是build-docs.ts 里那份实现。
真正把关的是 CI 的 Check Documentation Links(lychee,--offline --root-dir content --fallback-extensions mdx,md,覆盖整个 content/**)。它确实会红,而且覆盖面比任何单测都宽 —— 所以这不是「没人管」,是「管的人离得远」:一条死链要等到全仓 MDX 链接检查那一步才报,而不是在改动那个函数的单测里。
为什么记为观察类而不是缺陷
若要处理,方向是现成的
仓库对这个问题已经有一条走过三次的路:把纯逻辑从生成器里抽成可 import 的一面,再对它写单测 ——
同样的手法适用于 sourcePathToDocsRoute / groupSchemasByPage / sourcePathFor 这组路由与归页逻辑:它们都是纯函数,依赖只有 CATEGORIES、schemaIndex 和页面清单三样,注入即可。
⚠️不建议的做法:在 file-description.test.ts 里加一条「扫 content/docs/references/** 断言无死链」。那既与 lychee 重复,又会把单测绑到生成产物上;而如果 stand-in 的页面集合本身就取自那棵产物树,断言还会变成循环的。
未做的事
未自我认领,未打 pm:queue,不阻塞任何在飞项。是否值得排期留给分诊裁定 —— 按「创业期核心能力优先」的取向,这更像是等到下一次真的要动 build-docs.ts 的路由逻辑时顺手做的事,而不是独立立项的理由。
Generated by Claude Code
在实施 #6484(同目录裸路径)时顺带量出,非本单范围,按 Prime Directive #10 独立记录。⛔ 未自我认领、未打
pm:queue—— 观察类,今天没有用户会撞上。观察
packages/spec/scripts/build-docs.ts是一 import 就执行的顶层脚本(读SCHEMA_DIR、写content/docs/references/**、process.exit)。因此它自己的函数无法被单测 import,packages/spec/scripts/*.test.ts里没有一个文件测它。这在 #6484 里被实测出来了,不是推断。该单给
sourcePathToDocsRoute()补上了它文档里一直声明、实现却没做的一半 —— 「分类为真 ≠ 页面存在」。反向验证时把那一行判据删掉:即:删掉一条真判据,整个
pnpm test一条都不红。#6484 的单测里有对应的 stand-in 用例,但那是在lib/file-description.ts那道缝上钉的,它自带一个模拟页面清单 —— 钉住的是「解析器返回 null 时回退成代码段」这条规则,不是build-docs.ts里那份实现。真正把关的是 CI 的
Check Documentation Links(lychee,--offline --root-dir content --fallback-extensions mdx,md,覆盖整个content/**)。它确实会红,而且覆盖面比任何单测都宽 —— 所以这不是「没人管」,是「管的人离得远」:一条死链要等到全仓 MDX 链接检查那一步才报,而不是在改动那个函数的单测里。为什么记为观察类而不是缺陷
Check Links工作流的 push / pull_request 触发器被注释掉 —— lychee 断链门只剩 workflow_dispatch,文档断链在 CI 里无人把守 #6028 维护者裁定过它的范围);lib/file-description.ts的模块注释本身就写着这件事:「the generator is a top-level script with side effects, so the only way to assert on its block SELECTION used to be to run the whole thing and read the emitted.mdx」。若要处理,方向是现成的
仓库对这个问题已经有一条走过三次的路:把纯逻辑从生成器里抽成可 import 的一面,再对它写单测 ——
lib/format-type.ts(gen:docs 把数组内的 passthrough 对象渲染成Record<string, any>[],抹掉已声明键 —— #4001 战役每个 open 分类站点都会复发 #4912)lib/escape-mdx.ts(docs-gen:.describe()里的{{var}}在生成的参考文档里被转义成 `{{var}+ 游离的}`(main 上现存 3 处) #5452)lib/file-description.ts(两张公开参考页的正文被 #4001 的内部注释顶替(#3746 陷阱 1 已实际发生两次) #5059)同样的手法适用于
sourcePathToDocsRoute/groupSchemasByPage/sourcePathFor这组路由与归页逻辑:它们都是纯函数,依赖只有CATEGORIES、schemaIndex和页面清单三样,注入即可。file-description.test.ts里加一条「扫content/docs/references/**断言无死链」。那既与 lychee 重复,又会把单测绑到生成产物上;而如果 stand-in 的页面集合本身就取自那棵产物树,断言还会变成循环的。未做的事
未自我认领,未打
pm:queue,不阻塞任何在飞项。是否值得排期留给分诊裁定 —— 按「创业期核心能力优先」的取向,这更像是等到下一次真的要动build-docs.ts的路由逻辑时顺手做的事,而不是独立立项的理由。Generated by Claude Code