Files
deepseek-harness/docs/rfc/implemented/process/2026-07-06-generated-config-catalog.zh.md
Ziya 2565133af3 docs(i18n): RFC tree batch — 146 bilingual pairs via the committed pipeline
implemented(除 4 篇超长文档随后补)、proposed、rejected 全树配对;
同一流水线 + 二遍校验(paraphrase-back + 仓库上下文一致性)产出。
docs/rfc/implemented/AGENTS.md 与其 CLAUDE.md 符号链接列入排除
(agent 指令文件,与根 AGENTS.md 同策略)。
2026-07-15 23:25:06 -07:00

41 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RFC:生成式插件配置目录
Status: implemented
[English](2026-07-06-generated-config-catalog.md) | 中文
## 问题
仓库此前没有以源码为后盾的插件配置参考。各 package 的 README 对字段的记录方式不一致,没有列举哪些包可被加载,也没有校验运行时 schema 是否与声明的配置类型一致。
## 决策
`scripts/gen-config-catalog.ts` 从每个插件声明的配置类型与 JSDoc 生成 [docs/config-catalog.md](../../../config-catalog.md),包含注入要求、引用类型链接和源码指针。package 内部类型被传递性地包含;workspace 和外部类型以链接或名称引用。确定性的 `--write` 和 `--check` 模式使提交到仓库的页面成为一个生成产物(artifact)。
此处采用纯 AST 生成是正确的,原因与事件/服务目录相同,也与工具目录不同:配置类型是静态声明,仓库中每个 schemastery schema 都是静态的 `z.object`/`z.intersect` 字面量,因此源码就是全部真相——配置表面没有任何部分是运行时组合的。
具体选择:
- **配置类型取自第二参数类型。** 目录记录的是 `apply(ctx, config)` / 服务构造函数 `(ctx, config)` 的声明参数类型——即 Cordis 实际传入的值——而非按命名约定定位的 `Config` 导出。这使得遍历是全量的:无论接口名为 `AcpConfig` 还是 `BasicCompactConfig`,无论类型声明在兄弟文件中,还是插件根本没有校验 schema,都能正常工作。
- **分类是全量的。** 每个 `packages/<group>/<pkg>` 条目都会被解析(镜像 Loader 的 `unwrapExports`(`exports.default ?? exports`)),归入以下之一:可配置插件、无配置插件、抽象 seam 类或库——各自渲染在独立章节中——无法归类的条目会硬错误。新 package 不可能被静默地遗漏。
- **逐字段 JSDoc 强制要求。** 粘贴的声明中每个属性(包括嵌套的类型字面量)都需要非空的 JSDoc 描述,否则生成失败。粘贴本身就是文档,因此这与事件目录通过 `@mode` 施加的强制函数相同:源码文档不足时门禁失败,而非产出一份单薄的目录。
- **Schema 键与声明类型交叉检查。** 生成器通过本地和 workspace 类型解析嵌套的对象与数组路径。确定缺失的路径会失败;无法枚举的外部或动态形状则跳过。检查有意设计为单向的,因为声明类型可能包含从 loader 配置中排除的运行时专用字段。
- **专用围栏。** 粘贴的声明使用 ` ```ts config-catalog ` 信息字符串,`doc-typecheck` 会跳过它(引用了导入类型的孤立声明无法独立编译),并将其排除在 opt-out 比例之外——与 `cordis-catalog` 和 `persistence-catalog` 围栏的处理方式相同。
- **单文件 `docs/config-catalog.md`**,而非一个单文件目录:该页面服务于单一受众(`cordis.yml` 的编写者),只有一个维度,不同于 `cordis-catalog/`(它包含两个并列页面)。
各 package README 的 `## Config` 章节保留。这种重叠是有意接受的:README 是精心策划的逐 package 契约(部署上下文中的配置语义,连同限制与扩展点),目录则是穷举式的生成枚举。因为目录是生成的,二者之间的分歧说明 README 有误,修复方式是编辑 README——目录不会漂移。
## 曾考虑的替代方案
- **合成式逐字段渲染**:为每个字段生成一个项目符号列表、表格或带注释的 YAML 片段,由解析后的 JSDoc 加 schema 元数据组装。否决,改用逐字粘贴:带 JSDoc 的接口本身就是以其原始形式撰写的契约,合成渲染器会重新格式化它不拥有的行文,增加一层可能歪曲原意的渲染。
- **运行时启动 + schema 内省(如工具目录的做法)**:否决。此处没有任何内容是运行时组合的,而且 schema 本身对配置表面的文档化不足(行文记录的默认值、运行时专用字段、完全没有 schema 的插件)。启动只会增加脆弱性而不增加真相。
- **双向 schema/接口相等性检查**:否决,改用子集检查。声明类型合理地包含 schema 拒绝从配置接受的成员(运行时专用的 seam)。
- **在同一变更中废弃 README 的 `## Config` 章节**:否决。接受的重叠使逐 package 契约在原地可读,而一次清扫需要先把每个 README 的额外事实折入字段 JSDoc——这是可分离的工作,目录不依赖它。
## 后果
- 目录不会漂移:源码变化而提交的文件未反映时,`verify-config-catalog` 在 pre-push 和 CI 中失败。未记录的配置字段、无法解析的引用类型名称、或 schema 键在配置类型中缺失,都会导致生成器直接报错。
- 配置行文现在在声明处有了强制函数:编写新的配置字段意味着编写其 JSDoc,而 JSDoc 会逐字成为目录条目。
- 生成器对无法静态遍历的形状硬错误——别名化的 package 内部配置导入、非 `object`/`intersect` 组合构建的 schema、未列入的全局类型名。引入这样的形状就必须同时教会生成器(否则该形状不能进入仓库),这正是设计意图:目录始终是全部真相。
- `gen-cordis-catalog.ts` 导出其 JSDoc/指针辅助函数与 `LINK_MAP` 供复用,因此两个目录以相同方式交叉链接类型,新增一条 link-map 条目同时服务于两者。