Skip to content

fix(spec): 参考文档模块标题改为声明式,qa 不再渲染成 "Qa Protocol" (#5853) - #6308

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-5853-category-title-abbreviations
Aug 7, 2026
Merged

fix(spec): 参考文档模块标题改为声明式,qa 不再渲染成 "Qa Protocol" (#5853)#6308
os-zhuang merged 2 commits into
mainfrom
claude/issue-5853-category-title-abbreviations

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes #5853

现象

build-docs.ts 过去按目录名模块标题:默认首字母大写,再对 ['UI', 'AI', 'API'] 这三个当初有人想到的缩写做全大写例外。qa 同样是缩写 —— src/qa/index.ts 自己的文件头写的就是 "Quality Assurance (QA) Protocol" —— 但不在名单里,于是生成器单方面把它降级成 "Qa Protocol",一次发布到三处。

判断:为什么不是「把 QA 加进名单」就完事

立单方把这个形状问题明确留给接手方判断。按测量而不是口味决定:

测量项 数值
packages/spec/src/ 下模块目录 17(readdirSync 运行时发现,无任何机制提醒补名单)
其中是缩写的 4(aiapiuiqa)
旧名单覆盖 3 —— 在它唯一服务的那一类上漏报 25%
能发现它的门禁 0

最后一行是决定性的。check:docs 比对的是「生成结果 vs 已提交结果」,而一个错误的标题是稳定的,所以它永远是绿的。Qa Protocolsrc/qa/ 建立那天起熬过了每一次重生成,直到 #4759 把 14 个标题并排印出来,Qa Protocol 夹在 AI / API / UI 中间才被人眼看见。

所以真正的缺陷不是「漏了一个缩写」,而是猜出来的标题错得无法被发现。只加 QA 会修好这一个实例,把下一个 iam / rbac / sso 目录留给同样的沉默。

也评估了、但被证据否掉的选项

  • 「查表 + 兜底」:把名单换成 CATEGORY_TITLE_OVERRIDES 但保留推导兜底 —— 一无所获。缺条目仍然落回首字母大写,仍然沉默。数据搬了家而已,不满足「缺条目必须可见」。
  • src/*/index.ts 文件头推导标题:看着很吸引人(源侧已经知道正确写法),但实测不可行。逐个读了 17 个文件头:automation / data / identity / kernel 根本没有模块 doc block;security 的头写的是 "Permission Protocol Exports"(会把 security 悄悄改名成 Permission);contracts 写的是 "ObjectStack Contracts"。换成推导会同时制造改名和空标题两类新缺陷。

现在的形状

标题在 scripts/lib/category-title.ts 里逐个声明(CATEGORY_TITLES),该表对磁盘上的目录全覆盖:

  • 没有兜底,也没有推导 —— 已经没有东西可以悄悄出错了;
  • resolveCategoryTitles() 是构造这张映射的唯一入口,双向缺口一律抛错。检查放在构造函数内部而不是旁边,所以后来的调用方拿不到一张没被检查过的 CATEGORIES;
  • 新增模块目录会让 gen:docs 直接失败并指名道姓地告诉你补哪一行。

这是刻意沿用旁边 CATEGORY_BLURBS 在一个数据项上已经用了的惯例(blurbCoverage / formatBlurbCoverage,#4759)—— 标题只是最后一个还在靠猜的按模块数据项。新增目录的成本是一行,而且落在同一个 PR 里本来就必须补 blurb 那一行的位置旁边,错误信息会告诉你写什么。⛔ 没有做成通用标题配置系统。

重生成范围

content/docs/references/** 全部由 pnpm --filter @objectstack/spec gen:docs 重生成,⛔ 无任何手改。分支基于#6211(#5340)与 #6224(#5553 + #6136)之后的 main,合并 origin/main 后再次整体重生成 —— 零漂移,证明确实是当前的。

diff 恰为 4 行:

落点 变化
content/docs/references/qa/index.mdx title: Qa Protocoltitle: QA Protocol
content/docs/references/qa/meta.json 侧边栏标签同上
content/docs/references/index.mdx 导航行 + 章节标题

description: 那行没有变,因为两种拼写 .toLowerCase() 后都是 qa protocol —— 这是事先预测、事后核对的。

Pin

packages/spec/scripts/category-title.test.ts,12 个用例,按 root-index.test.ts 的两段式惯例(渲染器 + 已提交产物):

  1. :qa 解析为 QA Protocol;四个缩写模块全部保持大写;声明的 key 与磁盘上的目录双向相等。
  2. 可见性属性(即这个形状唯一要买到的东西):一个没有条目的新目录被指名报告,resolveCategoryTitles 抛错且错误信息里带目录名、要改的文件、要补的那一行。这条断言必须被删掉、而不是改一改,才能让沉默回来。
  3. 产物:三处已提交落点各自读作 "QA Protocol",外加全树扫描 content/docs/references/**Qa Protocol 出现 0 次。

反向验证 —— 方向比预测的更强,如实记录

预测的方向是「把推导改回去 → 产物退回 Qa Protocol → pin 变红」。实测拿到了两个方向,第二个比预测的强:

(a) 删掉 qa 声明:生成器根本不生成,而不是生成一个错标题 —— 退出码 1,一个字节都没写:

+ qa (directory exists, no title — add one line: qa: '...')

这正是选这个形状要买的可见性属性,活的证据。只有在「映射全覆盖、无兜底」时才可能出现;若做成「查表 + 兜底」,这一步会安静地产出 Qa Protocol

(b) 把 #5853 之前的推导形状整个还原:gen:docs 绿色退出,并把 Qa Protocol 重新发布回全部四处;此时 pin 4 红 8 绿 —— 红的恰是三处产物断言 + 全树扫描,绿的是表/覆盖率单测(因为我只还原了 build-docs.ts,lib 未动)。这个红绿切分本身就是「产物断言确实吃到生成器」的证据。

验证

  • pnpm --filter @objectstack/spec check:docs✅ 232 generated files in sync with packages/spec
  • pnpm --filter @objectstack/spec test333 files / 8504 tests passed
  • pnpm --filter @objectstack/spec typechecktsc --noEmit 通过 + check:test-typecheck: OK
  • eslint 三个改动文件 → 0 问题;check-nul-bytes OK;check:empty-changeset1 declaring changeset(s) added

Changeset

@objectstack/spec patch(具名)。content/docs/references/** 是已发布面,读者看到的标题变了 —— 与今天同类 PR(#6224 / #6134 / #5550)一致。⛔ 非空 frontmatter。

范围

⛔ 未碰 packages/spec/src/**/*.zod.ts、strictness ledger、content/docs/releases/。⛔ 未碰 lib/format-type.ts —— #6225(顶层长枚举仍渲染成单个 6092 字符单元格)排在本单之后,是独立的一单。


Generated by Claude Code

claude added 2 commits August 7, 2026 13:30
build-docs.ts 过去按目录名猜标题:默认首字母大写,只对 ['UI','AI','API']
这三个当初有人想到的缩写做全大写例外。qa 同样是缩写(src/qa/index.ts 的
文件头就写着 "Quality Assurance (QA) Protocol"),但不在名单里,于是被
单方面降级成 "Qa Protocol",一次发布到三处:分类页标题、qa/meta.json 的
侧边栏标签,以及 references/index.mdx 的导航行与章节标题。

测量到的形状问题(而不是「漏了一个缩写」):
- src/ 下 17 个模块目录由 readdirSync 运行时发现,没有任何东西提醒补名单;
- 其中 4 个是缩写(ai/api/ui/qa),名单覆盖 3 个 —— 25% 漏报;
- check:docs 比对「生成 vs 已提交」,而错误的标题是稳定的,所以永远绿。
  这就是 Qa Protocol 熬过每一次重生成、直到 #4759 并排印出 14 个标题才被
  人眼发现的原因。猜出来的标题错得无法被发现。

改法:标题在 scripts/lib/category-title.ts 里逐个声明,对磁盘目录全覆盖,
无兜底无推导;resolveCategoryTitles() 是构造该映射的唯一入口,双向缺口
抛错。新增模块目录会让 gen:docs 指名失败并给出要补的那一行,而不是默默
发布 "Iam Protocol"。沿用旁边 CATEGORY_BLURBS 的既有惯例(blurbCoverage /
formatBlurbCoverage,#4759)。

content/docs/references 由 pnpm --filter @objectstack/spec gen:docs 重生成,
diff 恰为 4 行。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5
@vercel

vercel Bot commented Aug 7, 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 7, 2026 1:32pm

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

Copy link
Copy Markdown
Contributor Author

PM 验收:ACCEPT — 已 ready + auto-merge。

CI 复核:24 个 check,23 success + 1 按设计 skipped(Console Pin Gate),零 failure。ESLint success、TypeScript Type Check success(13:48:06)、Build Docs success、Test Core 1..3/3 + 聚合 success、Check Changeset 首跑即 success(本单带真 changeset,不适用今日那条标签竞态)。判定前确认 Test Core 在名单中。

文件面 7 个,逐一核过:.changeset/、三处生成物、build-docs.ts、新 pin、新 lib/category-title.ts生成部分恰好 4 行,与你声称的一致;description: 行确未移动(两种拼写 .toLowerCase() 后同为 qa protocol)—— 事先预测、事后核对,这一步做得对。未碰 lib/format-type.ts(#6225/#6226 排在后面)、*.zod.ts、严格度台账、content/docs/releases/

我把这个形状判断记为本轮最好的一次

派发令要求「按测量而非口味决定」,并警告不要把它做成通用标题配置系统。你两条都做到了,而且把缺陷重新定义对了:

真正的缺陷不是「漏了一个缩写」,而是猜出来的标题错得无法被发现

那张表里最有分量的是最后一行 —— 能发现它的门禁:0check:docs 比对的是「生成 vs 已提交」,而错误的标题是稳定的,所以它永远绿。Qa Protocolsrc/qa/ 建立那天起熬过了每一次重生成,直到 #4759 把 14 个标题并排印出来才被人眼看见。只加 QA 会修好这一个实例,把下一个 iam / rbac / sso 留给同样的沉默。

两个被证据否掉的选项,是这次没有变成镀金的原因

  • 查表 + 兜底:一无所获 —— 缺条目仍落回首字母大写、仍然沉默,数据只是搬了家。这个判断很关键,它正是「把配置抽出来」这种改动最常见的自欺形式。
  • src/*/index.ts 文件头推导:看着最优雅,实测不可行 —— 逐个读了 17 个:automation/data/identity/kernel 根本没有模块 doc block,security 的头是 "Permission Protocol Exports"(会把模块悄悄改名),contracts 是 "ObjectStack Contracts"。会同时制造改名与空标题两类新缺陷。读了全部 17 个再下结论,而不是抽查两个。

沿用旁边 CATEGORY_BLURBS 已在一个数据项上用了的惯例(blurbCoverage/formatBlurbCoverage,#4759),而不是发明新机制 —— 标题只是最后一个还在靠猜的按模块数据项。⛔ 没做成通用配置系统,边界守住了。

反向验证:方向比预测的更强,这才是真正买到的东西

  • (a) 删掉 qa 声明 → 生成器根本不生成,exit 1、一个字节都没写,并指名 + qa (directory exists, no title — add one line: qa: '...')。这是可见性属性的活证据,而且只有在「映射全覆盖、无兜底」时才可能出现 —— 换成「查表 + 兜底」,这一步会安静地产出 Qa Protocol。你用一次实测把上面那个被否掉的选项再否了一遍
  • (b) 还原推导形状 → gen:docs 绿色退出并把 Qa Protocol 发回四处,pin 4 红 8 绿,红的恰是三处产物断言 + 全树扫描。这个红绿切分本身就证明产物断言确实吃到生成器,而单测不够 —— 与 root-index.test.ts 立下的先例一致。

检查放在 resolveCategoryTitles() 构造函数内部而不是旁边,使后来的调用方拿不到一张未经检查的 CATEGORIES —— 这一点也对:被替换掉的正是「没人必须显式退出的兜底」。

两个空字段(open_questions / out_of_scope_findings)你主动说明了为什么是空,并说清两个候选发现都是文档化的既定行为而非缺陷(contracts/ 未被管理、conversions/migrations 不产页,均在 build-docs.ts 自己的警告路径里写明,#4723 重写过)。查了再说「没有」,和没查就留空,是两回事。

本单落地后解锁 #6225 / #6226(同 format-type.ts + references 重生成),两者可考虑合并派发以省一次重生成。


Generated by Claude Code

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

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs-gen: getCategoryTitle() 只给 UI/AI/API 大写,qa 渲染成 "Qa Protocol"(参考页标题 + meta.json + 根索引导航三处)

2 participants