The briefing now maps each update at the narrowest safely aligned granularity, widening deterministically on mapping failure: a change confined to the pair's byte-identical code fences is computed outright (--apply splices it into the counterpart and validates the result against the pairing gate's structural signature before writing); otherwise changed Markdown units — headings, paragraphs, table rows, list items, fences, block quotes, HTML blocks, thematic breaks, link definitions, matched by container-scoped kind sequences — each carry their last-confirmed source, current source, and current counterpart text; units that do not align fall back to depth-matched heading sections (depth only, so translated heading text still maps); and when sections do not align either, or both sides drifted, the briefing says so and withholds the mapping. Terminology rows now match the changed spans only, English terms on word boundaries with plural inflections, and Chinese-target briefings track each relevant term's document-wide first occurrence — a moved occurrence pulls the vacated and receiving spans into the briefing with an explanatory note. The unit mapping, mechanical code splice, and first-occurrence tracking adopt the planner design from the incremental prompt-pipeline PR (#684), whose provider-backed bake-off independently validated the same scope ladder; this PR carries those mechanics into the agent-facing briefing path so both consumers of the consistency records behave alike. The prior line-hunk section mapping and its heading-text alignment (which could not map cross-language sections) are replaced wholesale. Docs: SKILL.md update path, i18n README pair, development.md pair, and the briefed-updates Agent Note pair brought along; the development.md fence edit was applied with --apply itself, and the prose updates were made through the new unit/section briefings.
8.2 KiB
双语文档
English | 中文
本仓库的文档会被公司内外的人和 agent(智能体)阅读,因此范围内的每篇文档都以英文和简体中文维护。本页定义配对契约、强制门禁、范围与排除规则;translation-rules.md 定义如何翻译;terminology.md 是术语真源。仓库内置的 agent 工作流见 .agents/skills/dsh-translate-docs。
配对契约
-
两种语言同权。 一篇文档可以先用任一语言撰写和评审(先写中文的 Agent Note 与先写英文的一样正当),另一侧由它翻译而来。两个文件谁也不高于谁;约束它们的是二者必须说同样的话。
-
一对文档是三个同目录文件。 英文
foo.md、中文foo.zh.md,加一份一致性记录foo.i18n.yaml,都在同一目录。不用语言目录,不用独立翻译仓库,不用中英混排的单文件。配对必须整体合并:PR(Pull Request)永远不会只带一种语言而缺其余两个文件。 -
一致性记录。
foo.i18n.yaml保存两侧文件在上一次被确认「说同样的话」时各自的完整 git blob hash:foo.md: 3f786850e387550fdab836ed7e6dc881de23001b foo.zh.md: 89e6c98d92887913cadf06b2adb97f26cde4849b用 blob hash 而不是 commit hash,这样同一个 PR 里改动的文件也能算出记录(
git hash-object foo.md),一致性是纯内容比较。记录的 hash 还能还原任一侧上次确认时的确切文本,所以失去同步的配对是「按被改一侧的 diff 最小化地修补另一侧」,从不整篇重译。pnpm run gen-translation-brief <pair>会以能安全对齐的最窄粒度——先是有改动的 Markdown 单元,再是标题小节,最后是整篇文档——机械地汇集这次更新的工作集:被改一侧自上次确认以来的 diff、每个改动块的三方文本、改动触及的术语表行,以及有约束力的更新规则;仅落在配对中逐字节一致的围栏代码块内的改动可以直接算出,--apply则经结构签名校验后把它拼接进对侧文件(briefed-updates Agent Note)。两侧对齐后,pnpm run verify-translation-pairing --write <pair>重新记录两个 hash;那份 yaml diff 就是「确认一致」这个动作本身,可以被评审,也正因如此,--write要求点名你确认过的配对(--write --all是显式的全语料形式)。 -
语言切换行。 两个文件在各自 H1 标题之后立即互链:英文文件带
English | [中文](foo.zh.md),中文文件带[English](foo.md) | 中文。 -
结构与另一侧一一对应。 标题深度与顺序、列表类型、有序列表起始编号、列表项数量、表格行列数、链接目标与逐字节一致的代码块在配对两侧一一对应;完整保持规则见 translation-rules.md。既有 Markdown 门禁对
.zh.md文件原样生效(verify-md-wrap、verify-md-links)。
门禁:verify-translation-pairing
pnpm run verify-translation-pairing(doc-sync(文档同步门禁)的一环,贡献者会针对文档变更在本地运行,CI 则会完整运行)机械地强制执行这份契约:
- 范围内的每篇文档都有完整配对。发现 README 时,basename 不区分大小写,因此
missions/readme.md与其他文档根一样属于范围。 - 任何已存在的配对产物都完整且一致:三个文件齐全、每一侧的当前 blob hash 等于记录值(改了任一侧而没重新确认配对就变红)、双方都带语言切换行、结构签名按序一致:标题深度、逐字节一致的代码块(信息字符串与内容)、表格行列数、列表类型、有序列表起始编号、列表项数量,以及除切换行之外的每个链接目标。
- 列为
excluded的文件完全没有.zh.md,也没有.i18n.yaml。
面向源码的代码门禁会把精确的 .zh.md 围栏序列视为其无后缀兄弟文件的派生内容,而不会再次编译相同代码或在 manifest 中重复登记。该序列必须在长度、顺序、围栏类型和按字节精确的正文上一致;否则两份副本仍会独立受检,配对门禁也会报告结构不匹配。
pnpm run verify-translation-pairing --list 打印范围内每篇文档的当前配对状态(missing、out-of-sync 或 ok)。它从不失败;其中 missing 与 out-of-sync 行指出普通检查会拒绝的违规。
pnpm run verify-translation-pairing <pair...> 只检查被点名的配对——配对的三个文件中的任意一个(或其裸词干)都能点名它——因此更新循环几秒内就能验证自己的配对,而不必重新扫描全语料。doc-sync 与 CI 运行的是无参数的全语料形式;限定范围的绿灯在 PR 层面永远不能替代它。
这个门禁带来的实际规则是:当一个 PR 修改了已配对文档的任一侧时,同一个 PR 更新另一侧并重新记录配对(运行 dsh-translate-docs skill(技能),再 --write <pair>),与本仓库既有的代码与 README 的 doc-sync 规则完全一致。留下失去同步的配对的 PR 会在 CI 变红。
把门禁的边界说白:门禁通过意味着这组文档在当前内容上的一致性得到了确认,不代表确认本身正确可靠。 它检查记录的 hash 与结构签名;它无法判断两侧是否真的在说同样的话,也无法判断措辞是否准确、术语是否得当、行文是否自然;这部分契约由评审者把关,见 translation-rules.md。重新记录了 hash 但另一侧翻得潦草的配对能通过门禁;它不得通过评审。
范围与排除
范围:除 vendor 源码外的全部 README,以及 .agents/notes/**、docs/** 与 python/** 下的全部文档。匹配 README 时只看文件名且不区分大小写,因此今后新增的目录无需再修改 manifest。依赖目录和被忽略的构建产物目录只在发现阶段排除,并非源文档。
排除(永不配对,门禁拒绝为它们建 .zh.md 或 .i18n.yaml):
docs/cordis-catalog/、docs/tool-catalog/、docs/config-catalog.md、docs/persistence-catalog.md、docs/module-graph.md、docs/agent-lifecycle.md、docs/capability-seams.md、docs/event-producer-consumer.md、docs/graph-atlas.md与docs/tool-execution-pipeline.md:生成文件;生成器目前只输出英文,手写译文在每次重新生成时必然陈旧。计划中的后续工作是让生成器同时输出中文,届时这些文件移出排除清单。docs/AGENTS.md、.agents/notes/**/AGENTS.md以及指向它们的CLAUDE.md指令符号链接:agent 指令,与根AGENTS.md一样只以英文维护。docs/i18n/terminology.md与 style-samples.md:二者本身即为中英对照文档。- translation-prompt.md:自动翻译流水线的提示词模板;正文逐字进入模型请求,配对翻译会改变流水线行为。
统一要求:当前及今后纳入范围的每篇文档,合并时都必须构成完整的双语配对。scripts/translation-pairing.manifest.json 只包含显式排除项;不存在逐文件推进清单、日期分界或 README 专用政策类别。
分工
这里的对侧文件由运行 dsh-translate-docs 的 agent 生成,再由人评审:在这里推理(inference)很便宜,评审注意力才是稀缺资源。门禁负责检查配对是否完整、记录的 hash、语言切换行以及本文列出的结构签名;翻译质量、术语和签名未涵盖的结构要求仍由评审把关。提示词契约也有可执行实现:scripts/translation-prompt.ts 会把仓库内置的模板(注入术语表;模板自带经人工校准的规则)渲染为英译中或中译英两个方向的提示词,并解析三段式响应;doc-sync 中的 verify-translation-prompt 会检查两个渲染方向与仓库内示例。