docs(i18n): re-translate RFC batch with the prompt-v4 pipeline
146 篇 RFC 译文按 v4 基线(#348)重出:v4 模板+术语表、金标 few-shot、三段协议、切换行后处理;全量机械核对零异常(一处 task id 术语违规已修)。三篇超长 RFC(code-mode 已入,web-seam/ agent-scope/sandbox/cds-core 仍在长文档通道产出)随后补。
This commit is contained in:
@@ -1,41 +1,41 @@
|
||||
# RFC:Cordis 接口的 JSDoc 完整性门禁
|
||||
|
||||
Status: implemented
|
||||
# RFC:针对 Cordis 对外服务接口的 JSDoc 完整性门禁
|
||||
|
||||
[English](2026-07-04-cordis-jsdoc-completeness-gate.md) | 中文
|
||||
|
||||
Status: implemented
|
||||
|
||||
## 问题
|
||||
|
||||
生成的 Cordis 目录已强制检查事件的 dispatch 模式,但未检查服务与事件契约的完整性。方法可以缺少描述,参数或返回值可以在跨插件 API 接口上不写文档——而这恰恰是 IDE 引导最重要的地方。
|
||||
生成的 Cordis 目录此前强制了事件分发模式,但未强制要求完整的服务与事件契约。方法可以缺少描述,参数或返回值可以在跨插件 API 接口上不写文档——而这恰恰是 IDE 引导最重要的地方。
|
||||
|
||||
AGENTS.md 规则("每个导出都有解释语义的 JSDoc")只能靠评审以行文方式检查;本仓库的既定偏好是将不变式编码为机械门禁。"Cordis 服务函数与事件"这一范围有一个精确的机器定义,只有目录生成器知道:事件是 `declare module 'cordis'` 内 `interface Events` 的成员,服务接口是每个 `interface Context` 键所指向的类的公开方法。ESLint 规则看不到这层映射;生成器在每次运行时都会计算它。
|
||||
AGENTS.md 中的规则(「每个导出都有解释语义的 JSDoc」)只能靠评审以行文形式检查;本仓库的既定偏好是将不变式编码为机械门禁。「Cordis 服务函数与事件」这一范围有精确的机器定义,只有目录生成器知道:事件是 `declare module 'cordis'` 内 `interface Events` 的成员,服务接口是每个 `interface Context` 键所指向的类的公开方法。ESLint 规则看不到这层映射;生成器在每次运行时计算它。
|
||||
|
||||
## 决策
|
||||
|
||||
扩展 `scripts/gen-cordis-catalog.ts`——同一次遍历、同一个 `@mode` 先例——对其目录化的所有内容强制 JSDoc 完整性。`verify-cordis-catalog` 运行在 `doc-sync` 内部,CI 和 lefthook pre-push 钩子都已执行 `doc-sync`,因此门禁无需新增任何接线(质量门禁原则:单一真源)。
|
||||
扩展 `scripts/gen-cordis-catalog.ts`(同一次遍历、同一个 `@mode` 先例),对其编目的所有内容强制 JSDoc 完整性。`verify-cordis-catalog` 在 `doc-sync`(文档同步门禁)内运行,CI 和 lefthook pre-push 钩子都已执行 `doc-sync`,因此门禁无需新增任何接线(质量门禁原则:单一真源)。
|
||||
|
||||
契约如下:
|
||||
|
||||
- **事件**需要描述文字,并为每个**载荷参数**提供非空 `@param`。载荷参数是签名中承载事件数据的参数;`this` 接收者注解和尾部的 waterfall `next` 免检——`next` 是 dispatch 机制,其语义已由 `@mode waterfall` 标签(及其结构交叉检查)拥有,逐事件重述只是样板。对免检参数写文档是允许的;门禁只检查缺失。
|
||||
- **服务类**需要类级 JSDoc,每个公开方法需要描述文字、每个参数一个非空 `@param`,以及一个非空 `@returns`(除非标注的返回类型是 `void`/`Promise<void>`,此时 `@returns` 可选——解析时机可能值得记录——但从不强制要求)。
|
||||
- **事件**需要描述性文字,以及为每个**载荷参数**提供非空的 `@param`。载荷参数是携带事件数据的签名参数;`this` 接收者注解和尾部的 waterfall(瀑布式事件) `next` 免检——`next` 是分发机制,其语义已由 `@mode waterfall` 标签(及其结构交叉检查)拥有,逐事件重述只是样板代码。为免检参数写文档是允许的;只有缺失才被检查。
|
||||
- **服务类**需要类级 JSDoc,每个公开方法需要描述性文字、为每个参数提供非空的 `@param`,以及非空的 `@returns`——除非标注的返回类型是 `void`/`Promise<void>`(此时 `@returns` 可选——resolve 时机有时值得记录——但从不强制要求)。
|
||||
- **陈旧标签报错**:`@param` 命名了一个不存在的参数即为违规,与 `@mode` 与签名矛盾的检查对称。标签描述必须非空;超出此范围的语义质量由评审负责。
|
||||
- **遍历可检查的显式性**:门禁是纯 AST 遍历(不使用类型检查器),因此服务方法必须显式标注返回类型(推断的返回类型无法分类),接口参数必须是简单标识符(解构模式没有名字供 `@param` 匹配)。
|
||||
- **违规聚合**为一条错误信息,列出所有违规项——修复时一次看到全部。此前快速失败的 `@mode` 检查也移入同一份聚合报告,消息文本不变。
|
||||
- **遍历可检查的显式性**:门禁是纯 AST 遍历(不使用类型检查器),因此服务方法必须显式标注返回类型(推断的返回类型无法分类),接口参数必须是简单标识符(解构模式没有名称供 `@param` 匹配)。
|
||||
- **违规聚合**为一条错误信息,列出所有违规项——修复时一次看到完整清单。此前快速失败的 `@mode` 检查也移入同一份聚合报告,消息文本不变。
|
||||
|
||||
这些标签**仅用于门禁强制**:`parseJsDoc` 现在在遇到第一个块标签时截止描述文字(标准 JSDoc 语义,同时也防止多行标签描述泄漏到目录中成为正文),因此 `@param`/`@returns` 永远不会改变渲染出的目录。
|
||||
这些标签**仅用于强制检查**:`parseJsDoc` 现在在遇到第一个块标签时截止描述性文字(标准 JSDoc 语义,同时也防止多行标签描述泄漏到目录中充当正文),因此 `@param`/`@returns` 不会改变渲染出的目录。
|
||||
|
||||
`packages/core/agent/tests/gen-cordis-catalog.spec.ts` 中的负向路径测试用合成 fixture(测试前置数据)驱动 `collectEvents`/`collectServices`,证明每个守卫都能触发且免检规则成立。撰写规则写在根 [AGENTS.md](../../../../AGENTS.md) 约定条目中,与 `@mode` 规则并列。
|
||||
`packages/core/agent/tests/gen-cordis-catalog.spec.ts` 中的负路径测试对合成 fixture(测试前置数据)运行 `collectEvents`/`collectServices`,验证每条守卫都会触发且免检规则成立。撰写规则写在根 [AGENTS.md](../../../../AGENTS.md) 的约定条目中,与 `@mode` 规则并列。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
- **ESLint 规则**:看不到范围的机器定义(哪些 `interface Events` 成员、哪些 `ctx.<key>` 类构成 Cordis 接口);目录生成器在每次运行时恰好计算这层映射,因此门禁放在那里。
|
||||
- **将标签渲染到目录中**:曾考虑将服务部分重构为逐方法条目,但有意推迟:方法文档的消费场景是源码 JSDoc 加 IDE 悬浮提示,目录保持索引定位。
|
||||
- **逃生标签**:不设。接口面小且经过策划(采纳时 12 个服务、57 个方法、27 个事件),重点在于检查不可豁免。
|
||||
- **ESLint 规则**:无法看到该范围的机器定义(哪些 `interface Events` 成员、哪些 `ctx.<key>` 类构成 Cordis 对外服务接口);目录生成器在每次运行时恰好计算这层映射,因此门禁放在那里。
|
||||
- **将标签渲染到目录中**:曾考虑将服务部分重构为逐方法条目,但有意推迟:方法文档的消费场景是源码 JSDoc 加 IDE 悬停,目录保持索引定位。
|
||||
- **逃逸标签**:不设。该接口面小且经过策展(采纳时 12 个服务、57 个方法、27 个事件),要点在于检查不可豁免。
|
||||
|
||||
## 后果
|
||||
|
||||
- 新增事件或服务方法如果参数或返回值未写文档,就无法合入:生成器拒绝重新生成,`verify-cordis-catalog` 在 pre-push 和 CI 中失败。采纳时发现的约 139 处缺口在同一个变更中补齐,门禁以绿色状态落地。
|
||||
- 服务接口必须显式标注返回类型并使用标识符参数。两项约束在采纳时均未构成负担(所有方法已有标注;不存在解构的 seam 参数);二者现在都是承重要求,违反时会被机械发现。
|
||||
- AGENTS.md 的通用 JSDoc 规则("一行能说清就写一行")在此接口上获得一条更严格的特例:只有当方法无参数且返回 void 时,一行摘要才仍然足够。
|
||||
- 对 `next` 或 `this` 写 `@param` 合法但不检查——这是有意的不对称:门禁强制载荷契约,拒绝索要样板。
|
||||
- 标签不改变渲染出的目录(正文在第一个块标签处截止)。如果日后需要方法级渲染,那是目录设计的独立决策,不是本门禁的缺口。
|
||||
- 新增事件或服务方法时,若参数或返回值未写文档则无法落地:生成器拒绝重新生成,`verify-cordis-catalog` 在 pre-push 和 CI 中失败。采纳时发现的约 139 处缺口在同一个变更中补齐,门禁以绿色状态落地。
|
||||
- 服务接口必须显式标注返回类型并使用标识符参数。两项约束在采纳时均未构成限制(所有方法已有标注;不存在解构的 seam 参数);但二者现在是承重要求,违反时会被机械检测到。
|
||||
- AGENTS.md 中通用的 JSDoc 规则(「一行能说清就用一行」)在此接口上获得了更严格的特例:仅当方法无参数且返回 void 时,一行摘要才足够。
|
||||
- 为 `next` 或 `this` 写 `@param` 合法但不检查——这是有意的不对称:门禁强制载荷契约,拒绝要求样板代码。
|
||||
- 渲染出的目录不受这些标签影响(正文在第一个块标签处截止)。如果后续需要方法级渲染,那是一个独立的目录设计决策,而非本门禁的缺口。
|
||||
|
||||
Reference in New Issue
Block a user