From f5774a2a269322a73fad447f19b361227c28e322 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sat, 4 Jul 2026 05:41:18 -0700 Subject: [PATCH 01/17] =?UTF-8?q?feat(i18n):=20new=20documents=20merge=20b?= =?UTF-8?q?ilingual=20=E2=80=94=20the=20requiredSince=20date=20frontier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New docs must not enlarge the translation backlog: any date-named document (yyyy-mm-dd-*.md, i.e. an RFC) dated on/after the manifest's requiredSince cutoff must merge with its complete pair, independent of the required back-catalog list. Cutoff ships at 2026-07-05, so the existing 2026-07-04 RFC wave is grandfathered into the batch backlog and everything after is bilingual from birth. The date comes from the filename, deliberately: it is deterministic from tree content alone — no git history (shallow CI checkouts hold), no PR base ref — matching the gate's pure-content design. A proposal dated before the cutoff that merges later escapes the rule; that is the graceful grandfathering of in-flight work, not a hole. --list marks such files (required by date); contract and RFC updated in both languages and the pairs re-recorded. --- docs/i18n/README.i18n.yaml | 4 +-- docs/i18n/README.md | 2 +- docs/i18n/README.zh.md | 2 +- ...-bilingual-docs-and-pairing-gate.i18n.yaml | 4 +-- ...6-07-02-bilingual-docs-and-pairing-gate.md | 2 +- ...7-02-bilingual-docs-and-pairing-gate.zh.md | 2 +- scripts/translation-pairing.manifest.json | 1 + scripts/verify-translation-pairing.ts | 28 +++++++++++++++++-- 8 files changed, 34 insertions(+), 11 deletions(-) diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 7a2407ed36..8fc169bdaa 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: 6e2bbd27c3288037bafeb6cc71b801d56b956ab4 -README.zh.md: 04c99ae336cf1e96cbc185f0ccbd063ef8977944 +README.md: ba3431c72d9f2a86220df4ed682620514401291f +README.zh.md: 02957c97937525a1da27242620a8327b863de040 diff --git a/docs/i18n/README.md b/docs/i18n/README.md index 6e2bbd27c3..ba3431c72d 100644 --- a/docs/i18n/README.md +++ b/docs/i18n/README.md @@ -43,7 +43,7 @@ The gate's limit, stated plainly: **a green gate means the pair was confirmed co - `docs/AGENTS.md` — agent instructions, maintained in English only like the root `AGENTS.md`. - `docs/i18n/terminology.md` — the terminology table is itself bilingual by construction. -**Rollout**: the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. +**Rollout**: new documents don't wait for a batch — a date-named document (`yyyy-mm-dd-*.md`, i.e. an RFC) dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. ## Division of labor diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md index 04c99ae336..02957c9793 100644 --- a/docs/i18n/README.zh.md +++ b/docs/i18n/README.zh.md @@ -43,7 +43,7 @@ - `docs/AGENTS.md`——agent 指令,与根 `AGENTS.md` 一样只以英文维护。 - `docs/i18n/terminology.md`——术语表本身即是双语构造。 -**推进**:manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 +**推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 ## 分工 diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml index bc9a1cd466..1ef023ec50 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -2026-07-02-bilingual-docs-and-pairing-gate.md: 517a6371eca5d747313c7efdb2756a50257701e4 -2026-07-02-bilingual-docs-and-pairing-gate.zh.md: f8f68bf5d4d7e6795318d9dd435a525f20a4f407 +2026-07-02-bilingual-docs-and-pairing-gate.md: 764ad5a9345c2a138b56e9cedb54848a5f7d6054 +2026-07-02-bilingual-docs-and-pairing-gate.zh.md: f039fbe3fa44cb379905bbea9a4692af19d71230 diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md index 517a6371ec..764ad5a934 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md @@ -32,5 +32,5 @@ Paired sibling files with locale suffixes are the dominant Chinese big-tech conv - Every pair adds a third file to the tree. The record is machine-written (`--write`), so the cost is directory noise, not maintenance effort; in exchange, "who confirmed these consistent, and when" is answerable from git blame on the yaml. - When the two sides disagree, no mechanical rule picks a winner — the PR review does. That is the price of equal authority, accepted deliberately: the alternative (a canonical language) forbids Chinese-first authoring. - Generated docs (`cordis-catalog/`, `tool-catalog/`, `module-graph.md`) are excluded for now; the planned follow-up is to teach their generators to emit Chinese alongside English, at which point they leave the exclusion list. -- Rollout is incremental by design: documents outside `required` are visible backlog (`--list`), not red CI, so pairs land in reviewable batches without a big-bang PR. +- Rollout is incremental by design: documents outside `required` are visible backlog (`--list`), not red CI, so pairs land in reviewable batches without a big-bang PR. New documents are the exception — a date-named document dated on/after the manifest's `requiredSince` cutoff merges bilingual or not at all, so the backlog only ever shrinks. - The recorded hashes double as the update tool (`git cat-file -p ` recovers either side's last-confirmed text for a minimal diff-based update), so re-translation of whole files is never forced by the mechanism. diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md index f8f68bf5d4..f039fbe3fa 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md @@ -32,5 +32,5 @@ - 每个配对给目录树多添一个文件。记录由机器写入(`--write`),代价是目录噪音而非维护负担;换来的是「谁在何时确认过这对一致」可以从 yaml 的 git blame 直接回答。 - 两侧说法冲突时,没有机械规则裁决谁赢——由 PR 评审裁决。这是同权的代价,是有意接受的:另一个选项(正典语言)禁止中文先行撰写。 - 生成文档(`cordis-catalog/`、`tool-catalog/`、`module-graph.md`)暂被排除;计划中的后续工作是让它们的生成器在输出英文的同时输出中文,届时移出排除清单。 -- 推进天然是渐进的:`required` 之外的文档是可见的 backlog(`--list`),不是红的 CI,因此配对按可评审的批次落地,无需一个巨型 PR。 +- 推进天然是渐进的:`required` 之外的文档是可见的 backlog(`--list`),不是红的 CI,因此配对按可评审的批次落地,无需一个巨型 PR。新文档是例外——文件名日期在 manifest `requiredSince` 当天或之后的文档,要么连同配对一起合入,要么不合入,因此 backlog 只会缩小。 - 记录的 hash 兼作更新工具(`git cat-file -p ` 能还原任一侧上次确认的文本,用于基于 diff 的最小更新),所以这套机制从不强迫整篇重译。 diff --git a/scripts/translation-pairing.manifest.json b/scripts/translation-pairing.manifest.json index 8c2708d48d..92e6eef950 100644 --- a/scripts/translation-pairing.manifest.json +++ b/scripts/translation-pairing.manifest.json @@ -1,4 +1,5 @@ { + "requiredSince": "2026-07-05", "required": [ "README.md", "docs/development.md", diff --git a/scripts/verify-translation-pairing.ts b/scripts/verify-translation-pairing.ts index eea30e4b22..3e9043b39d 100644 --- a/scripts/verify-translation-pairing.ts +++ b/scripts/verify-translation-pairing.ts @@ -21,7 +21,10 @@ * depths in order, fenced code blocks VERBATIM (info string + content), * table column counts, list kinds, and every link target except the * switcher itself. - * 3. `excluded` files (generated docs, agent instructions, the bilingual + * 3. Date-named documents (`yyyy-mm-dd-*.md`, i.e. RFCs) dated on/after the + * manifest's `requiredSince` merge bilingual — the frontier for NEW + * documents, independent of the `required` back-catalog list. + * 4. `excluded` files (generated docs, agent instructions, the bilingual * terminology table) have no `.zh.md` and no `.i18n.yaml` at all. * * What it deliberately does NOT check is translation quality or which side @@ -63,6 +66,8 @@ const SCOPE_PATTERNS = ['README.md', 'README.zh.md', 'README.i18n.yaml', 'docs/* interface Manifest { required: string[] excluded: string[] + /** Date-named documents (yyyy-mm-dd-*.md, i.e. RFCs) dated on/after this day must merge bilingual. */ + requiredSince: string } const manifest = JSON.parse(readFileSync(join(root, 'scripts/translation-pairing.manifest.json'), 'utf8')) as Manifest @@ -250,7 +255,22 @@ for (const req of manifest.required) { } } -// 2. Every pair that exists at all is complete and consistent. Anchor on the +// 2. Date-named documents (RFCs) dated on/after the requiredSince cutoff merge +// bilingual: a new RFC lands with its pair or not at all. Deterministic from +// the filename alone — no git history, so it holds on shallow CI checkouts. +const DATED = /(\d{4}-\d{2}-\d{2})-[^/]*\.md$/ +for (const source of sources) { + if (isExcluded(source)) continue + const dated = DATED.exec(source) + if (!dated?.[1] || dated[1] < manifest.requiredSince) continue + const { zh } = pairPaths(source) + if (!existsSync(join(root, zh))) { + errors.push(`${source}: dated ${dated[1]} — documents dated on/after ${manifest.requiredSince} merge bilingual (docs/i18n/README.md); add the counterpart and record the pair`) + state.set(source, 'missing') + } +} + +// 3. Every pair that exists at all is complete and consistent. Anchor on the // union of .zh.md files and .i18n.yaml records so a half-deleted pair is // caught from either remnant. const pairAnchors = new Set() @@ -317,7 +337,9 @@ if (listMode) { const rows = [...state.entries()].sort((a, b) => order[a[1]] - order[b[1]] || a[0].localeCompare(b[0])) for (const [file, status] of rows) { const required = manifest.required.includes(file) - console.log(`${status.padEnd(11)} ${file}${status === 'missing' ? (required ? ' (required)' : ' (backlog)') : ''}`) + const date = DATED.exec(file)?.[1] + const tag = required ? ' (required)' : date && date >= manifest.requiredSince ? ' (required by date)' : ' (backlog)' + console.log(`${status.padEnd(11)} ${file}${status === 'missing' ? tag : ''}`) } const counts = { 'ok': 0, 'out-of-sync': 0, 'missing': 0 } for (const status of state.values()) counts[status]++ From 0bccb483a5b85ff668f5536fdbc9505b8a0b5bff Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sat, 4 Jul 2026 05:54:22 -0700 Subject: [PATCH 02/17] docs(i18n): state the requiredSince grandfather semantics explicitly Files dated before the cutoff are the grandfathered backlog by definition (including cutoff-eve creations); backdating is a review-visible RFC-convention violation, not a loophole. --- docs/i18n/README.i18n.yaml | 4 ++-- docs/i18n/README.md | 2 +- docs/i18n/README.zh.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 8fc169bdaa..cb4e049728 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: ba3431c72d9f2a86220df4ed682620514401291f -README.zh.md: 02957c97937525a1da27242620a8327b863de040 +README.md: bbf292893fc1ca634f3437a8ea0bae855c5712cb +README.zh.md: 29f7408d1e0511ebf5a708507e0ea93aeb7e9ff3 diff --git a/docs/i18n/README.md b/docs/i18n/README.md index ba3431c72d..bbf292893f 100644 --- a/docs/i18n/README.md +++ b/docs/i18n/README.md @@ -43,7 +43,7 @@ The gate's limit, stated plainly: **a green gate means the pair was confirmed co - `docs/AGENTS.md` — agent instructions, maintained in English only like the root `AGENTS.md`. - `docs/i18n/terminology.md` — the terminology table is itself bilingual by construction. -**Rollout**: new documents don't wait for a batch — a date-named document (`yyyy-mm-dd-*.md`, i.e. an RFC) dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. +**Rollout**: new documents don't wait for a batch — a date-named document (`yyyy-mm-dd-*.md`, i.e. an RFC) dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. Files dated before the cutoff are the grandfathered backlog by definition — including files created on the cutoff's eve — and a document's filename date is its first-proposed date per the RFC convention, so backdating past the cutoff is a review-visible violation, not a loophole. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. ## Division of labor diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md index 02957c9793..29f7408d1e 100644 --- a/docs/i18n/README.zh.md +++ b/docs/i18n/README.zh.md @@ -43,7 +43,7 @@ - `docs/AGENTS.md`——agent 指令,与根 `AGENTS.md` 一样只以英文维护。 - `docs/i18n/terminology.md`——术语表本身即是双语构造。 -**推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 +**推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。日期早于 cutoff 的文件按定义属于被豁免的存量——包括 cutoff 前夜创建的文件——而文件名日期按 RFC 惯例即首次提出日期,倒填日期绕过 cutoff 是评审可见的违规,不是漏洞。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 ## 分工 From abb145d99f74ac3635f1c00c89b02eb57149d42b Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:03:14 -0700 Subject: [PATCH 03/17] =?UTF-8?q?docs(i18n):=20translation=20capability=20?= =?UTF-8?q?=E2=80=94=20style=20samples,=20voice=20rules,=20two-pass=20skil?= =?UTF-8?q?l?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Human-annotated gold pairs land as docs/i18n/style-samples.md (bilingual by construction, excluded from pairing) and outrank prose tone rules. translation-rules gains a Voice section; shape stays gate-owned so the writer optimizes for natural Chinese. The skill's translate step becomes two passes: native-author writing, then clause-level fidelity check. Terminology rulings: hash -> 哈希 (blob 哈希/提交哈希), HMR and fiber confirmed as tabled. --- .agents/skills/dsh-translate-docs/SKILL.md | 4 +- docs/i18n/README.i18n.yaml | 4 +- docs/i18n/README.md | 2 +- docs/i18n/README.zh.md | 2 +- docs/i18n/style-samples.md | 61 ++++++++++++++++++++++ docs/i18n/terminology.md | 4 +- docs/i18n/translation-rules.i18n.yaml | 4 +- docs/i18n/translation-rules.md | 11 +++- docs/i18n/translation-rules.zh.md | 11 +++- scripts/translation-pairing.manifest.json | 3 +- 10 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 docs/i18n/style-samples.md diff --git a/.agents/skills/dsh-translate-docs/SKILL.md b/.agents/skills/dsh-translate-docs/SKILL.md index cde9f00b0e..8a2b231e8f 100644 --- a/.agents/skills/dsh-translate-docs/SKILL.md +++ b/.agents/skills/dsh-translate-docs/SKILL.md @@ -37,7 +37,9 @@ Do not process every file the same way: ## Translate -- Work through the document applying [translation-rules.md](../../../docs/i18n/translation-rules.md). Internally: first render faithfully, then re-read the counterpart alone for awkward or ambiguous phrasing, then polish — but write ONLY the final text to the file, never drafts or notes. +- **Pass 1 — write, don't transpose.** You are a native technical author of the target language. Read a semantic unit of the source (a paragraph or a tight group), close it, and state its content the way [docs/i18n/style-samples.md](../../../docs/i18n/style-samples.md) does — match the nearest genre sample's register. Shape is the gate's job, not yours: never trade natural phrasing for sentence-by-sentence correspondence. +- **Pass 2 — verify against the source, clause by clause.** Fidelity is checked here, not written in: confirm nothing was added or dropped, every term follows the table, and each code span survived verbatim. Fix by rewriting the sentence natively, not by patching words into it. +- Write ONLY the final text to the file, never drafts or notes. - Every term in [terminology.md](../../../docs/i18n/terminology.md) renders exactly as specified, in both directions, including first-occurrence annotations. A term the table misses: translate only with a citable precedent from a major Chinese OSS/vendor doc; otherwise keep the English and add it to the PR's 「待定术语」 list with your suggested rendering. Never invent a rendering inline — that decision belongs to a human and then to the table. - Code blocks are byte-identical across the pair, comments included. Relative links keep their `.md` targets; only the switcher line links `.zh.md`. diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index cb4e049728..84cc3e7977 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: bbf292893fc1ca634f3437a8ea0bae855c5712cb -README.zh.md: 29f7408d1e0511ebf5a708507e0ea93aeb7e9ff3 +README.md: f28676b7d555aca30d8b5b21eba9fb4222949763 +README.zh.md: 5353a8ba04288cf72defa30b5896731b3d419b69 diff --git a/docs/i18n/README.md b/docs/i18n/README.md index bbf292893f..f28676b7d5 100644 --- a/docs/i18n/README.md +++ b/docs/i18n/README.md @@ -41,7 +41,7 @@ The gate's limit, stated plainly: **a green gate means the pair was confirmed co - `docs/cordis-catalog/`, `docs/tool-catalog/`, `docs/module-graph.md` — generated files; their generators emit English only today, so a hand-written translation would go stale on every regeneration. The planned follow-up is to teach the generators to emit Chinese alongside English, at which point these leave the exclusion list. - `docs/AGENTS.md` — agent instructions, maintained in English only like the root `AGENTS.md`. -- `docs/i18n/terminology.md` — the terminology table is itself bilingual by construction. +- `docs/i18n/terminology.md` and [style-samples.md](style-samples.md) — both are bilingual by construction. **Rollout**: new documents don't wait for a batch — a date-named document (`yyyy-mm-dd-*.md`, i.e. an RFC) dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. Files dated before the cutoff are the grandfathered backlog by definition — including files created on the cutoff's eve — and a document's filename date is its first-proposed date per the RFC convention, so backdating past the cutoff is a review-visible violation, not a loophole. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md index 29f7408d1e..5353a8ba04 100644 --- a/docs/i18n/README.zh.md +++ b/docs/i18n/README.zh.md @@ -41,7 +41,7 @@ - `docs/cordis-catalog/`、`docs/tool-catalog/`、`docs/module-graph.md`——生成文件;生成器目前只输出英文,手写译文在每次重新生成时必然陈旧。计划中的后续工作是让生成器同时输出中文,届时这些文件移出排除清单。 - `docs/AGENTS.md`——agent 指令,与根 `AGENTS.md` 一样只以英文维护。 -- `docs/i18n/terminology.md`——术语表本身即是双语构造。 +- `docs/i18n/terminology.md` 与 [style-samples.md](style-samples.md)——二者本身即为中英对照文档。 **推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。日期早于 cutoff 的文件按定义属于被豁免的存量——包括 cutoff 前夜创建的文件——而文件名日期按 RFC 惯例即首次提出日期,倒填日期绕过 cutoff 是评审可见的违规,不是漏洞。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md new file mode 100644 index 0000000000..d5d920c0d8 --- /dev/null +++ b/docs/i18n/style-samples.md @@ -0,0 +1,61 @@ +# 翻译语体样例(style samples) + +本文件是翻译语体的校准锚点:每组样例是一段英文原文与一段人工定稿的中文译文,覆盖本仓库文档的主要文体。**译文的语体以这些样例为准**——它们的效力高于任何对语气的文字描述。翻译或评审时对照最接近的文体样例;样例与规则冲突时,样例胜出。本文件中英对照、自成双语,不参与配对(见 [README.md](README.md) 排除清单)。 + +维护方式:人工评审校准出新的金标段落后追加到对应文体;样例只增不改,改动需评审人签字(PR 评审即签字)。 + +## ① 架构叙述 + +> This document describes the architecture of the DeepSeek Harness — the foundation of **DeepSeek Code**. The governing principle, from the microkernel design discussion: **everything is a plugin**. The core is deliberately tiny — a handful of abstract services plus one concrete loop plugin (`dsh-agent-loop`) — and every product feature is a plugin against the extension surface described here, without modifying the loop. + +本文介绍 DeepSeek Harness 整体架构,它是 **DeepSeek Code** 的底层基座。微内核设计讨论中确立了核心设计准则:**一切皆插件**。内核刻意做得极精简,仅包含少量抽象服务,外加一个实体循环插件 `dsh-agent-loop`。所有产品功能均基于本文定义的扩展接口开发为独立插件,无需改动主循环逻辑。 + +> Dependency rule: extension plugins depend on interfaces, never on `dsh-agent-loop` (the loop is swappable); the sanctioned exception is the composition bundle `dsh-agent-core`, whose job is assembling the concrete spine. + +依赖约束规范:各类扩展插件仅依赖抽象接口,严禁直接依赖 `dsh-agent-loop`(该主循环支持替换实现);唯一允许的特例是组合包 `dsh-agent-core`,它的职责是组装整套实体主干。 + +## ② 防御模式规则 + +> Hard-won bug-class rules: each pattern below is a class of defect that actually shipped or nearly shipped here, stated as the rule that prevents its recurrence. Read this before writing lifecycle, concurrency, subprocess, or teardown code. + +这些都是踩坑总结得出的缺陷分类规范:下文每种范式都对应一类曾上线、或险些流入线上的问题,每条规范旨在杜绝同类问题复现。编写生命周期、并发、子进程、资源销毁相关代码前,请务必阅读本文档。 + +## ③ 测试政策清单 + +> **Coverage gate** (`pnpm run test:coverage`): the gating run, per-file 100% on `packages/*/*/src`. An uncovered line is often dead code the gate is correctly flagging for deletion, not a missing test to bolt on. Line coverage is necessary, never sufficient — it proves lines ran, not that the feature works as shipped. + +覆盖率门禁(`pnpm run test:coverage`):作为合入门禁校验,要求 `packages/*/*/src` 目录下每个文件行覆盖率达到 100%。未覆盖代码行大多是无用死代码,门禁标记这类代码是提示删除,而非单纯补充测试。行覆盖率是必要条件,但远不充分:它仅能证明代码被执行过,无法保证功能符合线上预期。 + +## ④ 机制描述 + +> Blob hashes, not commit hashes, so the record is computable for files edited in the same PR (`git hash-object foo.md`) and consistency is a pure content comparison. The recorded hash also recovers the exact last-confirmed text of either side (`git cat-file -p `), so an out-of-sync pair is updated by diffing the edited side against its last-confirmed state and patching the counterpart minimally — never by re-translating whole files. + +系统采用文件 blob 哈希而非提交哈希记录状态。同一 PR 内修改文件时,可通过 `git hash-object foo.md` 直接算出对应哈希,仅对比文件内容即可判断双语文档是否同步。通过记录的哈希值,可使用 `git cat-file -p ` 还原上次确认对齐时两侧的原文。当双语文档不一致时,只需对比修改版本与上次确认版本的差异,最小幅度同步修改另一侧译文,无需全文重新翻译。 + +## ⑤ 政策声明 + +> The gate's limit, stated plainly: a green gate means the pair was confirmed consistent at these exact contents, not that the confirmation was sound. It checks hashes and shape; it cannot judge whether the two sides actually say the same thing — that is the reviewer's half of the contract. A re-recorded pair with a sloppy counterpart passes the gate; it must not pass review. + +明确门禁校验边界:门禁校验通过,仅代表两份文档哈希与结构完全匹配,不代表译文内容准确无误。门禁仅校验哈希与结构,无法判断双语表意是否统一——译文质量把关是评审人的责任。即便译文粗糙、表意偏差,只要哈希匹配,门禁就会放行,但这类 PR 绝不能通过人工评审。 + +## ⑥ RFC 论证 + +> Comparing git timestamps of the pair (no record) — rejected: formatting-only edits would false-positive, and a counterpart committed after an unrelated edit would false-negative; content identity is the only signal that means what the gate claims. + +对比双语文件的 git 时间戳(无哈希记录方案)——不予采纳:仅调整格式的改动会触发误报,无关修改后再提交译文又会造成漏检。只有文件内容完全一致,才能作为门禁可信的校验依据。 + +## ⑦ 推进策略(长段拆分示范) + +> **Rollout**: new documents don't wait for a batch — a date-named document dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. […] Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. + +**推进**:新增文档不再走批量分批翻译流程。以日期命名的文档,若其标注日期等于或晚于 manifest 里 `requiredSince` 分界时间,提交合入时必须配套对应的双语译文文件——所有新文档从创建起就要求中英双语齐备。针对存量旧文档:manifest 内的强制翻译列表只是当下执行红线,并非最终目标。(……)文档完成双语配对等同于一份长期约束承诺:后续只要修改任一版本,就必须同步更新对应另一语种文件。因此强制翻译范围的推进节奏,要匹配翻译评审实际可投入人力,切勿超前铺开。 + +## 从样例提炼的要点 + +- 语体是规范制度文:完整主谓、确定语气;不口语化,也不学术腔。 +- 给句子补显式执行主体:英文的被动句和抽象主语,中文写成「系统/门禁/工具/评审人」做主语。 +- 用中文工程惯用语替换直译:false positive/negative→误报/漏检、enforcement frontier→执行红线、ratchet→只向前收紧不倒退放宽、reviewable act→评审凭证。 +- 隐喻本地化而非移植:bilingual from birth→从创建起就要求双语齐备;grandfathered→历史存量遗留。 +- 类别名词说中文并在首现括注英文:实操手册(cookbook)、事故复盘(postmortem);指目录或路径时保留代码体英文。 +- 长段按语义单元拆段,一段一件事;名词短语展开为动词句。 +- 母语重写不等于删减:原文每个语义成分都要落地。 diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index f95a8e3a8f..94b182ae4f 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -25,7 +25,9 @@ | agent | agent | 首次出现可写:agent(智能体) | | agent loop | agent loop | | | backlog | backlog | 双语翻译语境指待翻清单 | -| blob hash | blob hash | git 对象哈希;`git hash-object` 的结果 | +| blob hash | blob 哈希 | git 对象哈希;`git hash-object` 的结果 | +| commit hash | 提交哈希 | | +| hash | 哈希 | 代码与命令中保留英文(如 `git hash-object`、`` 占位符) | | doc-sync | doc-sync | 仓库门禁名,保留英文 | | e2e | e2e | | | fiber | fiber | 首次出现可写:fiber(插件运行时) | diff --git a/docs/i18n/translation-rules.i18n.yaml b/docs/i18n/translation-rules.i18n.yaml index 579bd51511..f1aa737d08 100644 --- a/docs/i18n/translation-rules.i18n.yaml +++ b/docs/i18n/translation-rules.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -translation-rules.md: 4e190f58469f7d402dfa5600f17cf1621484f138 -translation-rules.zh.md: 89a1cddd23126f24354ce1f8d9af4e7bd403454d +translation-rules.md: 3e99aa5432ccd904f702238e9b802a9ed9bf6832 +translation-rules.zh.md: 78778907f959d62dad2c9b4c02baf1f664791a43 diff --git a/docs/i18n/translation-rules.md b/docs/i18n/translation-rules.md index 4e190f5846..3e99aa5432 100644 --- a/docs/i18n/translation-rules.md +++ b/docs/i18n/translation-rules.md @@ -10,9 +10,18 @@ How to translate between the two sides of a documentation pair in this repo. Bot - The counterpart SHOULD read as natural technical writing in its own language, not word-by-word gloss. Translate meaning, restructure sentences where the target grammar wants it, and keep the author's register — terse stays terse. - Do not translate the untranslatable: if a sentence resists natural rendering because it leans on an idiom of the source language, translate the idea, not the idiom. +## Voice + +- The register is calibrated by [style-samples.md](style-samples.md) — human-approved gold pairs, one per document genre. The counterpart MUST match the register of the nearest sample; where a sample and a prose rule here disagree, the sample wins. The target is institutional technical Chinese: complete sentences, declarative, neither chatty nor academic. +- Write as a native technical author restating the content, not as a translator transposing sentences. Then verify against the source clause by clause: nothing added, nothing dropped — fluency never justifies losing a clause. +- Give sentences an explicit agent: where the English uses a passive or an abstract subject, name the actor (系统、门禁、评审人). +- Prefer established Chinese engineering idiom over calques (误报/漏检 for false positive/negative, 执行红线 for enforcement frontier); localize metaphors instead of transplanting them, and unpack English noun chains into verb clauses. +- Split long paragraphs by semantic unit — one idea per paragraph. Paragraph boundaries MAY differ from the source; the structural signature does not count paragraphs. +- Category nouns render in Chinese with a first-mention English annotation (实操手册(cookbook)); literal directory or file references stay code-formatted English. + ## Structure preservation -The paired files MUST match one to one in: +Shape is enforced by the pairing gate, so the writer never trades fluency against it — write naturally inside the frame. The paired files MUST match one to one in: - heading hierarchy (same levels, same order — heading TEXT is translated), - list shape and numbering, diff --git a/docs/i18n/translation-rules.zh.md b/docs/i18n/translation-rules.zh.md index 89a1cddd23..78778907f9 100644 --- a/docs/i18n/translation-rules.zh.md +++ b/docs/i18n/translation-rules.zh.md @@ -10,9 +10,18 @@ - 另一侧应当读起来是其语言自然的技术文字,而不是逐词对照。翻译语义,在目标语言语法需要处重组句子,并保持原作者的语域——简练的保持简练。 - 不要翻译不可译的东西:一句话如果依赖源语言的习语而无法自然转换,就翻译它的意思,而不是习语本身。 +## 行文 + +- 语体以 [style-samples.md](style-samples.md) 为校准锚点——人工定稿的金标样例按文体各一组,译文必须对齐最接近的样例语体;样例与本文条款冲突时,以样例为准。目标语体是规范的技术制度文:完整主谓、确定语气,不口语化也不学术腔。 +- 以母语技术作者的身份重述内容,而不是逐句转写的译者。写完后逐句对照原文核验:不添加、不遗漏——流畅永远不是丢掉语义成分的理由。 +- 给句子补显式执行主体:英文的被动句和抽象主语,中文写成「系统、门禁、评审人」等实际执行者做主语。 +- 优先使用中文工程惯用语而非直译(false positive/negative→误报/漏检、enforcement frontier→执行红线);隐喻做本地化替换而不是移植,英文名词链展开为动词句。 +- 长段按语义单元拆分,一段一件事。段落边界可以与原文不同;结构签名不比对段落数。 +- 类别名词说中文并在首现括注英文(实操手册(cookbook));指目录或文件本身时保留代码体英文。 + ## 结构保持 -配对的两个文件必须在以下方面一一对应: +形状由配对门禁强制,译者不需要用流畅度去换结构——在框架内自然行文即可。配对的两个文件必须在以下方面一一对应: - 标题层级(相同级别、相同顺序——标题的**文字**要翻译), - 列表形态与编号, diff --git a/scripts/translation-pairing.manifest.json b/scripts/translation-pairing.manifest.json index 92e6eef950..6f05431ced 100644 --- a/scripts/translation-pairing.manifest.json +++ b/scripts/translation-pairing.manifest.json @@ -12,6 +12,7 @@ "docs/module-graph.md", "docs/cordis-catalog/", "docs/tool-catalog/", - "docs/i18n/terminology.md" + "docs/i18n/terminology.md", + "docs/i18n/style-samples.md" ] } From 4f852742371fda1eb93abd4477cbd2affda3e2fc Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:17:14 -0700 Subject: [PATCH 04/17] docs(i18n): absorb the with-key-testing gold sample; table rules mock and real-API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gold sample recorded terminology-corrected per the table-wins rule (agent stays English, cancellation renders 取消), and that rule itself lands in the samples' notes. New table rows: mock -> 模拟; API row notes real-API as 真实接口 when attributive. --- docs/i18n/style-samples.md | 9 +++++++++ docs/i18n/terminology.md | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index d5d920c0d8..4e20e960b6 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -26,6 +26,14 @@ 覆盖率门禁(`pnpm run test:coverage`):作为合入门禁校验,要求 `packages/*/*/src` 目录下每个文件行覆盖率达到 100%。未覆盖代码行大多是无用死代码,门禁标记这类代码是提示删除,而非单纯补充测试。行覆盖率是必要条件,但远不充分:它仅能证明代码被执行过,无法保证功能符合线上预期。 +> We are DeepSeek — do not ration real-API tests. A no-key test proves the plumbing; only a with-key run proves the agent works against a real model. Write many: real prompts that write files, multi-turn conversations, tool use, cancellation mid-stream. Cheapest and highest-value are **smoke tests** that boot the real example, send one real prompt, and check the world — they catch the "green unit tests, broken product" class that mocks structurally cannot. The self-skip exists only so secretless CI and keyless contributors aren't blocked; it is not a cost signal. + +我们是 DeepSeek:真实接口相关测试不得刻意缩减用例数量。无密钥测试仅能验证底层通路;只有携带有效密钥执行的用例,才能确认 agent 可正常对接真实模型。请大量编写此类测试:包含文件写入类真实提示词、多轮对话、工具调用、流式中途取消等场景。 + +成本最低、收益最高的是**冒烟测试**:拉起完整真实示例,发送一条真实提示并校验整体运行状态。这类用例能捕获一类问题——单元测试全部绿灯,但产品实际运行故障,单靠模拟接口完全无法发现这类缺陷。 + +自带自动跳过逻辑,仅用于保障无密钥 CI 环境、无权限贡献者不会被流程拦截,不代表可以以此为由削减真实接口测试投入。 + ## ④ 机制描述 > Blob hashes, not commit hashes, so the record is computable for files edited in the same PR (`git hash-object foo.md`) and consistency is a pure content comparison. The recorded hash also recovers the exact last-confirmed text of either side (`git cat-file -p `), so an out-of-sync pair is updated by diffing the edited side against its last-confirmed state and patching the counterpart minimally — never by re-translating whole files. @@ -59,3 +67,4 @@ - 类别名词说中文并在首现括注英文:实操手册(cookbook)、事故复盘(postmortem);指目录或路径时保留代码体英文。 - 长段按语义单元拆段,一段一件事;名词短语展开为动词句。 - 母语重写不等于删减:原文每个语义成分都要落地。 +- 样例与 [terminology.md](terminology.md) 冲突时,以术语表为准:收录样例前按表修正术语(例如 agent 保留英文、cancellation 译「取消」)。 diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 94b182ae4f..5ce1efe7b2 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -6,7 +6,7 @@ |---|---|---| | ACP | ACP | 首次出现可写:ACP(Agent Client Protocol) | | AI | AI | 首次出现可写:人工智能(AI) | -| API | API | | +| API | API | real-API 作定语时可译「真实接口」(如 real-API tests → 真实接口测试) | | CI | CI | | | CLI | CLI | 首次出现可写:命令行界面(CLI) | | Cordis | Cordis | 保留英文 | @@ -92,6 +92,7 @@ | language switcher | 语言切换行 | i18n 机制词:双语配对文件顶部的互链行 | | memory | memory / 记忆 / 内存 | 按上下文区分:agent memory 译为“记忆”;resource/memory usage 译为“内存” | | message | 消息 | | +| mock | 模拟 | 如「模拟接口」「模拟模型」;指测试替身 | | mod | 模组 | 区别于 module(模块);plugin 译作「插件」 | | model provider | 模型提供方 | | | module | 模块 | | From 74699d25ba2079abb497ae104622952f9489f026 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:18:08 -0700 Subject: [PATCH 05/17] docs(i18n): mock stays English per ruling; sample corrected to match --- docs/i18n/style-samples.md | 4 ++-- docs/i18n/terminology.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index 4e20e960b6..cb043a19d9 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -30,7 +30,7 @@ 我们是 DeepSeek:真实接口相关测试不得刻意缩减用例数量。无密钥测试仅能验证底层通路;只有携带有效密钥执行的用例,才能确认 agent 可正常对接真实模型。请大量编写此类测试:包含文件写入类真实提示词、多轮对话、工具调用、流式中途取消等场景。 -成本最低、收益最高的是**冒烟测试**:拉起完整真实示例,发送一条真实提示并校验整体运行状态。这类用例能捕获一类问题——单元测试全部绿灯,但产品实际运行故障,单靠模拟接口完全无法发现这类缺陷。 +成本最低、收益最高的是**冒烟测试**:拉起完整真实示例,发送一条真实提示并校验整体运行状态。这类用例能捕获一类问题——单元测试全部绿灯,但产品实际运行故障,单靠 mock 完全无法发现这类缺陷。 自带自动跳过逻辑,仅用于保障无密钥 CI 环境、无权限贡献者不会被流程拦截,不代表可以以此为由削减真实接口测试投入。 @@ -67,4 +67,4 @@ - 类别名词说中文并在首现括注英文:实操手册(cookbook)、事故复盘(postmortem);指目录或路径时保留代码体英文。 - 长段按语义单元拆段,一段一件事;名词短语展开为动词句。 - 母语重写不等于删减:原文每个语义成分都要落地。 -- 样例与 [terminology.md](terminology.md) 冲突时,以术语表为准:收录样例前按表修正术语(例如 agent 保留英文、cancellation 译「取消」)。 +- 样例与 [terminology.md](terminology.md) 冲突时,以术语表为准:收录样例前按表修正术语(例如 agent、mock 保留英文,cancellation 译「取消」)。 diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 5ce1efe7b2..36b0244343 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -92,7 +92,7 @@ | language switcher | 语言切换行 | i18n 机制词:双语配对文件顶部的互链行 | | memory | memory / 记忆 / 内存 | 按上下文区分:agent memory 译为“记忆”;resource/memory usage 译为“内存” | | message | 消息 | | -| mock | 模拟 | 如「模拟接口」「模拟模型」;指测试替身 | +| mock | mock | 保留英文;指测试替身 | | mod | 模组 | 区别于 module(模块);plugin 译作「插件」 | | model provider | 模型提供方 | | | module | 模块 | | From daaddcaaf3c5ec355b94725d701ae00dceecfc8c Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:24:56 -0700 Subject: [PATCH 06/17] docs(i18n): absorb round-4 gold samples, terminology-corrected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architecture pointer paragraph, two defensive patterns, and the prefer-real-over-mock rule join the samples. Recorded per the table-wins rule: agent/mock/LLM stay English, registry renders 注册表, and code-spanned identifiers (event names, status values, package names) survive verbatim — that boundary is now a stated sample note. orphan row notes the process-context rendering 孤儿进程. --- docs/i18n/style-samples.md | 19 ++++++++++++++++++- docs/i18n/terminology.md | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index cb043a19d9..d75fa6e54b 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -14,12 +14,24 @@ 依赖约束规范:各类扩展插件仅依赖抽象接口,严禁直接依赖 `dsh-agent-loop`(该主循环支持替换实现);唯一允许的特例是组合包 `dsh-agent-core`,它的职责是组装整套实体主干。 +> This document covers **behavior**; type shapes live in [core-data-structures/](core-data-structures/core.md), the per-event/service reference in the [generated catalog](cordis-catalog/events-and-services.md), per-package contracts in the package READMEs ([map](../packages/README.md)). + +本文档描述整体行为逻辑;类型定义存放于 [core-data-structures/](core-data-structures/core.md);各类事件、服务的详细参考见[生成目录](cordis-catalog/events-and-services.md);各 package 对外约束协议写在对应包的 README([索引](../packages/README.md))。 + ## ② 防御模式规则 > Hard-won bug-class rules: each pattern below is a class of defect that actually shipped or nearly shipped here, stated as the rule that prevents its recurrence. Read this before writing lifecycle, concurrency, subprocess, or teardown code. 这些都是踩坑总结得出的缺陷分类规范:下文每种范式都对应一类曾上线、或险些流入线上的问题,每条规范旨在杜绝同类问题复现。编写生命周期、并发、子进程、资源销毁相关代码前,请务必阅读本文档。 +> **Dispose must reach quiescence, not just request it** — A teardown that issues kills/aborts but returns before the work stops leaves orphans. Make cleanup async and await the children's exit (kill → await `done`), and close listener/notification registries BEFORE killing so late completions stay silent. Tests prove disposal waited (pid gone right after `await fiber.dispose()`), not merely that the process eventually dies. + +**销毁操作必须等待所有任务完全停稳,不能仅下发终止指令就返回**——若销毁逻辑仅发送终止、中断信号,但不等任务停止就直接退出,会产生孤儿进程。清理逻辑需设为异步,等待所有子任务彻底退出(先下发终止信号,再等待执行完成);在执行终止操作前先关闭监听器与通知注册表,让延迟到达的完成事件不再触发任何通知。测试要验证销毁流程确实完成等待:执行完 `await fiber.dispose()` 后进程 PID 立即消失,不能仅校验进程最终会自行消亡。 + +> **Async state is not synchronous state** — `agent.send()` does not flip status before returning; a background task's completion races turn boundaries; `reader.close()` fires for both EOF and disposal. Never gate control flow on a status you only just requested — drive lifecycle off the events/promises that actually fire (`agent/status`, `task.done`), and observe the transition (saw `running` THEN `idle`) rather than counting actions you assume map 1:1 to turns. + +**异步状态不等同于同步瞬时状态**——调用 `agent.send()` 不会在返回前同步更新状态;后台任务完成时机与轮次边界存在竞态;调用 `reader.close()` 既可能是读到文件末尾,也可能是资源销毁触发。切勿仅凭刚查询到的状态来阻断流程;生命周期逻辑应基于真实触发的事件与 promise 驱动(`agent/status`、`task.done`),观测完整状态切换(先 `running`、再 `idle`),而非主观认定操作和执行轮次一一对应(主循环会批量处理排队消息)。 + ## ③ 测试政策清单 > **Coverage gate** (`pnpm run test:coverage`): the gating run, per-file 100% on `packages/*/*/src`. An uncovered line is often dead code the gate is correctly flagging for deletion, not a missing test to bolt on. Line coverage is necessary, never sufficient — it proves lines ran, not that the feature works as shipped. @@ -34,6 +46,10 @@ 自带自动跳过逻辑,仅用于保障无密钥 CI 环境、无权限贡献者不会被流程拦截,不代表可以以此为由削减真实接口测试投入。 +> **Prefer the real implementation over a mock** — Mock only the genuinely expensive or non-deterministic boundary (the LLM adapter, the network, the clock); keep everything downstream real. A hand-rolled stand-in proves the bridge moves bytes, not that the shipping tool behaves as asserted — the two drift while the test stays green. + +**优先使用真实实现,而非 mock 替身**——仅对开销极大、结果不确定的边界模块做 mock(LLM 适配器、网络、时钟),其余下游组件全部使用真实实现。手写的 mock 替身只能验证数据通路能传输字节,无法保证线上工具符合预期逻辑;长期下来业务逻辑与 mock 实现会出现偏差,但测试仍会显示通过。 + ## ④ 机制描述 > Blob hashes, not commit hashes, so the record is computable for files edited in the same PR (`git hash-object foo.md`) and consistency is a pure content comparison. The recorded hash also recovers the exact last-confirmed text of either side (`git cat-file -p `), so an out-of-sync pair is updated by diffing the edited side against its last-confirmed state and patching the counterpart minimally — never by re-translating whole files. @@ -67,4 +83,5 @@ - 类别名词说中文并在首现括注英文:实操手册(cookbook)、事故复盘(postmortem);指目录或路径时保留代码体英文。 - 长段按语义单元拆段,一段一件事;名词短语展开为动词句。 - 母语重写不等于删减:原文每个语义成分都要落地。 -- 样例与 [terminology.md](terminology.md) 冲突时,以术语表为准:收录样例前按表修正术语(例如 agent、mock 保留英文,cancellation 译「取消」)。 +- 样例与 [terminology.md](terminology.md) 冲突时,以术语表为准:收录样例前按表修正术语(例如 agent、mock、LLM 保留英文,cancellation 译「取消」)。 +- 代码体标识符(事件名 `agent/status`、状态值 `running`、包名 `dsh-bash-local` 等)在译文中保留 code span 原文,不得口语化改写——这是行文规则的硬边界,Pass 2 逐句核验的重点。 diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 36b0244343..7d3360a689 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -96,7 +96,7 @@ | mod | 模组 | 区别于 module(模块);plugin 译作「插件」 | | model provider | 模型提供方 | | | module | 模块 | | -| orphan | 孤立 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;不要译作:孤儿 | +| orphan | 孤立 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;不要译作:孤儿。进程语境按 OS 惯用语译「孤儿进程」 | | pairing | 配对 | | | permission | 权限 | | | persistence | 持久化 | | From 60cfec6073954b7eeff6f10f03d89b980b84dafa Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:33:24 -0700 Subject: [PATCH 07/17] docs(i18n): retarget sample-excerpt links to resolve from docs/i18n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relative links copied into an excerpt resolve from the excerpt's home, not the source doc's — verify-md-links caught the moved-directory break. --- docs/i18n/style-samples.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index d75fa6e54b..b72d810afc 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -14,9 +14,9 @@ 依赖约束规范:各类扩展插件仅依赖抽象接口,严禁直接依赖 `dsh-agent-loop`(该主循环支持替换实现);唯一允许的特例是组合包 `dsh-agent-core`,它的职责是组装整套实体主干。 -> This document covers **behavior**; type shapes live in [core-data-structures/](core-data-structures/core.md), the per-event/service reference in the [generated catalog](cordis-catalog/events-and-services.md), per-package contracts in the package READMEs ([map](../packages/README.md)). +> This document covers **behavior**; type shapes live in [core-data-structures/](../core-data-structures/core.md), the per-event/service reference in the [generated catalog](../cordis-catalog/events-and-services.md), per-package contracts in the package READMEs ([map](../../packages/README.md)). -本文档描述整体行为逻辑;类型定义存放于 [core-data-structures/](core-data-structures/core.md);各类事件、服务的详细参考见[生成目录](cordis-catalog/events-and-services.md);各 package 对外约束协议写在对应包的 README([索引](../packages/README.md))。 +本文档描述整体行为逻辑;类型定义存放于 [core-data-structures/](../core-data-structures/core.md);各类事件、服务的详细参考见[生成目录](../cordis-catalog/events-and-services.md);各 package 对外约束协议写在对应包的 README([索引](../../packages/README.md))。 ## ② 防御模式规则 From b43a9e9ab1c4fae76a5a1ccde5b71607a1de4215 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 5 Jul 2026 06:41:04 -0700 Subject: [PATCH 08/17] docs(i18n): package stays English per ruling --- docs/i18n/terminology.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 7d3360a689..0166b87e4c 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -36,6 +36,7 @@ | harness | harness | 保留英文 | | manifest | manifest | 描述模块或工具元数据的文件 | | monorepo | monorepo | | +| package | package | 保留英文;指 npm 包(`@deepseek-ai/dsh-*`) | | schema DSL | schema DSL | | | schema | schema | 保留英文 | | seam | seam | 首次出现可写:seam(扩展点) | From 1a4ef8c8d957622f86c293309353ec8ba00f873c Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 20:34:05 -0700 Subject: [PATCH 09/17] =?UTF-8?q?docs(i18n):=20restructure=20terminology?= =?UTF-8?q?=20table=20=E2=80=94=20=E9=A6=96=E6=AC=A1=E5=87=BA=E7=8E=B0/?= =?UTF-8?q?=E4=B8=8D=E8=A6=81=E8=AF=91=E4=BD=9C=20as=20real=20columns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 自由文本备注里的「首次出现可写:」「不要译作:」提为独立列,机器可 直接按列执行;表头补各列语义。按评审意见收录 counterpart、sidecar record(禁「旁挂记录」)、source of truth 裁定行,agent 组合词与 seam 括注规则细化。 --- docs/i18n/terminology.md | 282 ++++++++++++++++++++------------------- 1 file changed, 145 insertions(+), 137 deletions(-) diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 0166b87e4c..408048a66f 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -1,140 +1,148 @@ # Terminology -本表约定本仓库的中英术语统一译法。 +本表约定本仓库的中英术语统一译法。各列语义: -| English | 中文 | 备注 | -|---|---|---| -| ACP | ACP | 首次出现可写:ACP(Agent Client Protocol) | -| AI | AI | 首次出现可写:人工智能(AI) | -| API | API | real-API 作定语时可译「真实接口」(如 real-API tests → 真实接口测试) | -| CI | CI | | -| CLI | CLI | 首次出现可写:命令行界面(CLI) | -| Cordis | Cordis | 保留英文 | -| Function Calling | Function Calling | 首次出现可写:Function Calling(函数调用) | -| HMR | HMR | 首次出现可写:热模块替换(HMR) | -| JSON Schema | JSON Schema | | -| JSONL | JSONL | | -| lint | lint | | -| loader | loader | | -| LLM | LLM | 首次出现可写:大语言模型(LLM) | -| MCP | MCP | | -| PR | PR | 首次出现可写:PR(pull request) | -| RAG | RAG | 首次出现可写:检索增强生成(RAG) | -| SDK | SDK | | -| SSE | SSE | 首次出现可写:SSE(Server-Sent Events) | -| agent | agent | 首次出现可写:agent(智能体) | -| agent loop | agent loop | | -| backlog | backlog | 双语翻译语境指待翻清单 | -| blob hash | blob 哈希 | git 对象哈希;`git hash-object` 的结果 | -| commit hash | 提交哈希 | | -| hash | 哈希 | 代码与命令中保留英文(如 `git hash-object`、`` 占位符) | -| doc-sync | doc-sync | 仓库门禁名,保留英文 | -| e2e | e2e | | -| fiber | fiber | 首次出现可写:fiber(插件运行时) | -| fixture | fixture | 指测试前置数据或环境 | -| fork | fork | 保留英文 | -| harness | harness | 保留英文 | -| manifest | manifest | 描述模块或工具元数据的文件 | -| monorepo | monorepo | | -| package | package | 保留英文;指 npm 包(`@deepseek-ai/dsh-*`) | -| schema DSL | schema DSL | | -| schema | schema | 保留英文 | -| seam | seam | 首次出现可写:seam(扩展点) | -| skill | skill | 首次出现可写:skill(技能) | -| spawn | spawn | 保留英文 | -| steering | steering | 首次出现可写:steering(中途引导) | -| subagent | subagent | 首次出现可写:subagent(子 agent) | -| transcript | transcript | 首次出现可写:transcript(文本记录);指会话渲染给用户或编辑器的完整文本,区别于事件日志(event log) | -| waterfall | waterfall | 首次出现可写:waterfall(瀑布式事件) | -| worktree | worktree | git 工作区概念,保留英文 | -| wire format | 协议格式 | 首次出现可写:协议格式(wire format) | -| adapter contract | 适配器契约 | 首次出现可写:适配器契约(adapter contract) | -| adapter | 适配器 | | -| append-only | 仅追加 | | -| artifact | 产物 | | -| block | 块 | | -| background task | 后台任务 | | -| backend | 后端 | | -| capability | 能力 | | -| cancel | 取消 | | -| checkpoint | 检查点 | | -| chunk | 分片 | | -| compaction | compaction | 首次出现可写:compaction(上下文压缩);正文优先保留英文 | -| consumer | 消费方 | | -| content block | 内容块 | | -| config | 配置 | | -| context | 上下文 | | -| context compaction | 上下文压缩 | 首次出现可写:上下文压缩(context compaction) | -| contract | 契约 | 如:配对契约(pairing contract);另见 adapter contract | -| coverage | 覆盖率 | | -| crash recovery | 崩溃恢复 | | -| dispose | dispose | 首次出现可写:dispose(释放资源);正文优先保留英文 | -| durability | 持久性 | | -| enforcement frontier | 强制边界 | i18n 机制词:manifest `required` 清单所划的门禁生效范围 | -| event log | 事件日志 | | -| event | 事件 | | -| event stream | 事件流 | | -| event-sourced | 事件溯源 | DDD 社区通行译法 | -| executor | 执行器 | | -| extension | 扩展 | | -| fail-fast | 快速失败 | | -| fenced code block | 围栏代码块 | MDN 中文同译 | -| finish reason | 结束原因 | | -| fingerprint | 指纹 | i18n 机制词:`.zh.md` 首行记录英文源 blob hash 的 `i18n-source` 注释 | -| foreground run | 前台运行 | | -| freshness | 新鲜度 | MDN HTTP 缓存中文同译(freshness lifetime → 新鲜度生命周期);指译文相对英文源的同步状态 | -| hook | 钩子 | | -| implementation | 实现 | | -| inference | 推理(inference) | 每次提及时保留英文括注,避免与 reasoning 混淆 | -| info string | 信息字符串 | CommonMark 中文同译;代码围栏 ``` 之后的语言标注 | -| injection | 注入 | | -| interface | 接口 | | -| integration | 集成 | | -| language switcher | 语言切换行 | i18n 机制词:双语配对文件顶部的互链行 | -| memory | memory / 记忆 / 内存 | 按上下文区分:agent memory 译为“记忆”;resource/memory usage 译为“内存” | -| message | 消息 | | -| mock | mock | 保留英文;指测试替身 | -| mod | 模组 | 区别于 module(模块);plugin 译作「插件」 | -| model provider | 模型提供方 | | -| module | 模块 | | -| orphan | 孤立 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;不要译作:孤儿。进程语境按 OS 惯用语译「孤儿进程」 | -| pairing | 配对 | | -| permission | 权限 | | -| persistence | 持久化 | | -| pipeline | 流水线 | | -| plugin | 插件 | mod 对应“模组” | -| prompt | 提示词 | | -| provider | 提供方 | | -| provider-neutral | 提供方无关 | | -| quality gate | 质量门禁 | | -| registry | 注册表 | | -| reasoning | 推理(reasoning) | 需要和 inference 区分时保留英文括注;`reasoning_content` 译为“思考内容” | -| replay | 回放 | | -| resume | 恢复 | | -| runtime | 运行时 | | -| sandbox | 沙箱 | | -| service | 服务 | | -| session | 会话 | | -| session event | 会话事件 | | -| smoke test | 冒烟测试 | | -| snapshot | 快照 | | -| spine | 主干 | | -| staged | 暂存 | git 官方中文同译 | -| stale | 陈旧 | MDN HTTP 缓存中文同译,与「新鲜(fresh)」成对;门禁输出保留英文 `stale`;expired 才译「过期」 | -| step | 步骤 | | -| stream | 流 | | -| streaming | 流式输出 | | -| structural signature | 结构签名 | i18n 机制词:配对门禁比对的有序结构序列 | -| system prompt | 系统提示词 | | -| taxonomy | 分类体系 | | -| token usage | token 用量 | | -| thinking | thinking | API 字段保留;模型模式译为“思考” | -| tool | 工具 | | -| tool call | 工具调用 | | -| tool result | 工具结果 | | -| tool schema | 工具 schema | | -| toolkit | 工具包 | | -| turn | 轮次 | | -| typecheck | 类型检查 | | -| vocabulary | 词汇 | | -| workflow | 工作流 | | +- **中文** — 正文中的固定译法;写「保留英文」表示不译。 +- **首次出现** — 术语在一篇文档中第一次出现时的完整写法(含括注);之后只写「中文」列的形式。组合词已括注过的成分,单独出现时不再括注。 +- **不要译作** — 禁用译法,逐项列出;出现任何一项即评审阻断。 +- **备注** — 语境区分、裁定出处等自由说明;不承载可执行规则。 + +| English | 中文 | 首次出现 | 不要译作 | 备注 | +|---|---|---|---|---| +| ACP | ACP | ACP(Agent Client Protocol) | | | +| AI | AI | 人工智能(AI) | | | +| API | API | | | real-API 作定语时可译「真实接口」(如 real-API tests → 真实接口测试) | +| CI | CI | | | | +| CLI | CLI | 命令行界面(CLI) | | | +| Cordis | Cordis | | | 保留英文 | +| Function Calling | Function Calling | Function Calling(函数调用) | | | +| HMR | HMR | 热模块替换(HMR) | | | +| JSON Schema | JSON Schema | | | | +| JSONL | JSONL | | | | +| lint | lint | | | | +| loader | loader | | | | +| LLM | LLM | 大语言模型(LLM) | | | +| MCP | MCP | | | | +| PR | PR | PR(pull request) | | | +| RAG | RAG | 检索增强生成(RAG) | | | +| SDK | SDK | | | | +| SSE | SSE | SSE(Server-Sent Events) | | | +| agent | agent | agent(智能体) | | 括注只落在 agent 单独首现处;组合词见下行 | +| agent harness, agent workflow, agent loop, agent skill | 保留英文 | | | agent 组合词整体保留英文、不括注;其中的 workflow/loop/skill 不单独拆译;未列出的 agent 组合词同此处理 | +| backlog | backlog | | | 双语翻译语境指待翻清单 | +| blob hash | blob 哈希 | | | git 对象哈希;`git hash-object` 的结果 | +| commit hash | 提交哈希 | | | | +| hash | 哈希 | | | 代码与命令中保留英文(如 `git hash-object`、`` 占位符) | +| doc-sync | doc-sync | | | 仓库门禁名,保留英文 | +| e2e | e2e | | | | +| fiber | fiber | fiber(插件运行时) | | | +| fixture | fixture | | | 指测试前置数据或环境 | +| fork | fork | | | 保留英文 | +| harness | harness | | | 保留英文 | +| manifest | manifest | | | 描述模块或工具元数据的文件 | +| monorepo | monorepo | | | | +| package | package | | | 保留英文;指 npm 包(`@deepseek-ai/dsh-*`) | +| schema DSL | schema DSL | | | | +| schema | schema | | | 保留英文 | +| seam | seam | seam(扩展点) | | 同句已出现「扩展点」(extension point)时不加括注,直接写 seam,避免一词两指 | +| skill | skill | skill(技能) | | | +| spawn | spawn | | | 保留英文 | +| steering | steering | steering(中途引导) | | | +| subagent | subagent | subagent(子 agent) | | | +| transcript | transcript | transcript(文本记录) | | 指会话渲染给用户或编辑器的完整文本,区别于事件日志(event log) | +| waterfall | waterfall | waterfall(瀑布式事件) | | | +| worktree | worktree | | | git 工作区概念,保留英文 | +| wire format | 协议格式 | 协议格式(wire format) | | | +| adapter contract | 适配器契约 | 适配器契约(adapter contract) | | | +| adapter | 适配器 | | | | +| append-only | 仅追加 | | | | +| artifact | 产物 | | | | +| block | 块 | | | | +| background task | 后台任务 | | | | +| backend | 后端 | | | | +| capability | 能力 | | | | +| cancel | 取消 | | | | +| checkpoint | 检查点 | | | | +| chunk | 分片 | | | | +| compaction | compaction | compaction(上下文压缩) | | 正文优先保留英文 | +| consumer | 消费方 | | | | +| counterpart | 对侧文件 | | 对应物、配对物 | 双语配对语境;泛指“另一侧”时可写「另一侧」 | +| content block | 内容块 | | | | +| config | 配置 | | | | +| context | 上下文 | | | | +| context compaction | 上下文压缩 | 上下文压缩(context compaction) | | | +| contract | 契约 | | | 如:配对契约(pairing contract);另见 adapter contract | +| coverage | 覆盖率 | | | | +| crash recovery | 崩溃恢复 | | | | +| dispose | dispose | dispose(释放资源) | | 正文优先保留英文 | +| durability | 持久性 | | | | +| enforcement frontier | 强制边界 | | | i18n 机制词:manifest `required` 清单所划的门禁生效范围 | +| event log | 事件日志 | | | | +| event | 事件 | | | | +| event stream | 事件流 | | | | +| event-sourced | 事件溯源 | | | DDD 社区通行译法 | +| executor | 执行器 | | | | +| extension | 扩展 | | | | +| fail-fast | 快速失败 | | | | +| fenced code block | 围栏代码块 | | | MDN 中文同译 | +| finish reason | 结束原因 | | | | +| fingerprint | 指纹 | | | i18n 机制词:`.zh.md` 首行记录英文源 blob hash 的 `i18n-source` 注释 | +| foreground run | 前台运行 | | | | +| freshness | 新鲜度 | | | MDN HTTP 缓存中文同译(freshness lifetime → 新鲜度生命周期);指译文相对英文源的同步状态 | +| hook | 钩子 | | | | +| implementation | 实现 | | | | +| inference | 推理(inference) | | | 每次提及时保留英文括注,避免与 reasoning 混淆 | +| info string | 信息字符串 | | | CommonMark 中文同译;代码围栏 ``` 之后的语言标注 | +| injection | 注入 | | | | +| interface | 接口 | | | | +| integration | 集成 | | | | +| language switcher | 语言切换行 | | | i18n 机制词:双语配对文件顶部的互链行 | +| memory | memory / 记忆 / 内存 | | | 按上下文区分:agent memory 译为“记忆”;resource/memory usage 译为“内存” | +| message | 消息 | | | | +| mock | mock | | | 保留英文;指测试替身 | +| mod | 模组 | | | 区别于 module(模块);plugin 译作「插件」 | +| model provider | 模型提供方 | | | | +| module | 模块 | | | | +| orphan | 孤立 | | 孤儿 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;进程语境按 OS 惯用语译「孤儿进程」 | +| pairing | 配对 | | | | +| permission | 权限 | | | | +| persistence | 持久化 | | | | +| pipeline | 流水线 | | | | +| plugin | 插件 | | | mod 对应“模组” | +| prompt | 提示词 | | | | +| provider | 提供方 | | | | +| provider-neutral | 提供方无关 | | | | +| quality gate | 质量门禁 | | | | +| registry | 注册表 | | | | +| reasoning | 推理(reasoning) | | | 需要和 inference 区分时保留英文括注;`reasoning_content` 译为“思考内容” | +| replay | 回放 | | | | +| resume | 恢复 | | | | +| runtime | 运行时 | | | | +| sandbox | 沙箱 | | | | +| service | 服务 | | | | +| session | 会话 | | | | +| session event | 会话事件 | | | | +| sidecar record | 伴随记录 | | 旁挂记录 | 指 `.i18n.yaml` 这类随主文件存放的记录文件 | +| smoke test | 冒烟测试 | | | | +| snapshot | 快照 | | | | +| source of truth | 真源 | 真源(source of truth) | | 评审裁定译法;如后续裁定调整,改此表即可 | +| spine | 主干 | | | | +| staged | 暂存 | | | git 官方中文同译 | +| stale | 陈旧 | | | MDN HTTP 缓存中文同译,与「新鲜(fresh)」成对;门禁输出保留英文 `stale`;expired 才译「过期」 | +| step | 步骤 | | | | +| stream | 流 | | | | +| streaming | 流式输出 | | | | +| structural signature | 结构签名 | | | i18n 机制词:配对门禁比对的有序结构序列 | +| system prompt | 系统提示词 | | | | +| taxonomy | 分类体系 | | | | +| token usage | token 用量 | | | | +| thinking | thinking | | | API 字段保留;模型模式译为“思考” | +| tool | 工具 | | | | +| tool call | 工具调用 | | | | +| tool result | 工具结果 | | | | +| tool schema | 工具 schema | | | | +| toolkit | 工具包 | | | | +| turn | 轮次 | | | | +| typecheck | 类型检查 | | | | +| vocabulary | 词汇 | | | | +| workflow | 工作流 | | | | From 8ad6dbc3596fcbeb46da1c6383e7a7663ea2895a Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 20:34:19 -0700 Subject: [PATCH 10/17] docs(i18n): commit the pipeline translation prompt as a repo asset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 自动翻译流水线的 prompt 模板进仓(docs/i18n/translation-prompt.md): 占位符契约(source_lang/target_lang/terminology 三个,旧 %% 分段协议 废弃)+ 逐字模板正文(三段 XML 输出、分类自审、8 组正误例)。列入 配对排除清单;skill 与流水线自此共用同一套规则文件。 --- .agents/skills/dsh-translate-docs/SKILL.md | 1 + docs/i18n/README.i18n.yaml | 4 +- docs/i18n/README.md | 1 + docs/i18n/README.zh.md | 1 + docs/i18n/translation-prompt.md | 178 +++++++++++++++++++++ scripts/translation-pairing.manifest.json | 3 +- 6 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 docs/i18n/translation-prompt.md diff --git a/.agents/skills/dsh-translate-docs/SKILL.md b/.agents/skills/dsh-translate-docs/SKILL.md index 8a2b231e8f..1a5cc03549 100644 --- a/.agents/skills/dsh-translate-docs/SKILL.md +++ b/.agents/skills/dsh-translate-docs/SKILL.md @@ -14,6 +14,7 @@ These are authoritative; read them at the source so this skill never drifts out - **[docs/i18n/README.md](../../../docs/i18n/README.md)** — the pairing contract: the three-file pair (`foo.md`, `foo.zh.md`, `foo.i18n.yaml`), the consistency record's both-side blob hashes, the language-switcher lines, scope/exclusions, and the rollout manifest. - **[docs/i18n/translation-rules.md](../../../docs/i18n/translation-rules.md)** — how to translate: faithfulness, structure preservation, terminology discipline, typography (MUST/SHOULD levels). - **[docs/i18n/terminology.md](../../../docs/i18n/terminology.md)** — the terminology table, binding in both directions. Load it BEFORE translating, not when a term feels uncertain; the terms you don't notice are the ones that drift. +- **[docs/i18n/translation-prompt.md](../../../docs/i18n/translation-prompt.md)** — the automated pipeline's prompt template (placeholder contract + the verbatim prompt body). Agents following THIS skill do not render that template; it exists so the pipeline and this skill share one set of rules — a rule change lands in both or it is a bug. ## Find the work diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 84cc3e7977..3c954439ce 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: f28676b7d555aca30d8b5b21eba9fb4222949763 -README.zh.md: 5353a8ba04288cf72defa30b5896731b3d419b69 +README.md: 94c8ad9e3a83b490a854dce69b27bd7e13d834b5 +README.zh.md: 4c66da76feff1b1a6c175da62cbd986838b3577e diff --git a/docs/i18n/README.md b/docs/i18n/README.md index f28676b7d5..94c8ad9e3a 100644 --- a/docs/i18n/README.md +++ b/docs/i18n/README.md @@ -42,6 +42,7 @@ The gate's limit, stated plainly: **a green gate means the pair was confirmed co - `docs/cordis-catalog/`, `docs/tool-catalog/`, `docs/module-graph.md` — generated files; their generators emit English only today, so a hand-written translation would go stale on every regeneration. The planned follow-up is to teach the generators to emit Chinese alongside English, at which point these leave the exclusion list. - `docs/AGENTS.md` — agent instructions, maintained in English only like the root `AGENTS.md`. - `docs/i18n/terminology.md` and [style-samples.md](style-samples.md) — both are bilingual by construction. +- [translation-prompt.md](translation-prompt.md) — the automated pipeline's prompt template; its body is machine-consumed verbatim, so a paired translation would change pipeline behavior. **Rollout**: new documents don't wait for a batch — a date-named document (`yyyy-mm-dd-*.md`, i.e. an RFC) dated on or after the manifest's `requiredSince` cutoff must merge with its pair, so everything new is bilingual from birth. Files dated before the cutoff are the grandfathered backlog by definition — including files created on the cutoff's eve — and a document's filename date is its first-proposed date per the RFC convention, so backdating past the cutoff is a review-visible violation, not a loophole. For the back-catalog, the `required` list in the manifest is the enforcement frontier, not the goal. The goal is full bilingual coverage of the scope. Pairs land in reviewable batches (core entry docs, cookbook, RFCs, postmortems, …); each merged batch adds its files to `required`, so the gate ratchets forward and never regresses. Documents not yet in `required` are backlog — visible in `--list` — but any pair that already exists is held to the full contract regardless of the list. Pairing a document is a commitment: every later edit to either side must carry the counterpart along, so grow the frontier at the pace translation review is actually resourced, not ahead of it. diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md index 5353a8ba04..4c66da76fe 100644 --- a/docs/i18n/README.zh.md +++ b/docs/i18n/README.zh.md @@ -42,6 +42,7 @@ - `docs/cordis-catalog/`、`docs/tool-catalog/`、`docs/module-graph.md`——生成文件;生成器目前只输出英文,手写译文在每次重新生成时必然陈旧。计划中的后续工作是让生成器同时输出中文,届时这些文件移出排除清单。 - `docs/AGENTS.md`——agent 指令,与根 `AGENTS.md` 一样只以英文维护。 - `docs/i18n/terminology.md` 与 [style-samples.md](style-samples.md)——二者本身即为中英对照文档。 +- [translation-prompt.md](translation-prompt.md)——自动翻译流水线的 prompt 模板;正文逐字进入模型请求,配对翻译会改变流水线行为。 **推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。日期早于 cutoff 的文件按定义属于被豁免的存量——包括 cutoff 前夜创建的文件——而文件名日期按 RFC 惯例即首次提出日期,倒填日期绕过 cutoff 是评审可见的违规,不是漏洞。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 diff --git a/docs/i18n/translation-prompt.md b/docs/i18n/translation-prompt.md new file mode 100644 index 0000000000..db9b78aaee --- /dev/null +++ b/docs/i18n/translation-prompt.md @@ -0,0 +1,178 @@ +# Translation prompt (pipeline asset) + +本文件是自动翻译流水线使用的 prompt 模板,正文(自 `# Translation Prompt` 起)逐字进入模型请求,不参与双语配对(见 [README.md](README.md) 排除清单)。模板与仓库规则的关系:[terminology.md](terminology.md) 在渲染时整表填入 `{{terminology}}`;文体金标见 [style-samples.md](style-samples.md),模板内嵌的 Examples 是其中问题类别的最小抽样,两者冲突时以 style-samples 为准。修改本文件即修改线上翻译行为,按正常 PR 评审。 + +## 占位符契约 + +流水线渲染模板时替换以下占位符,除此之外不做任何文本处理: + +| 占位符 | 填入内容 | 来源 | +|---|---|---| +| `{{source_lang}}` | 源语言名(`English` / `Chinese`) | 由改动侧文件推断:`.zh.md` 被改则为 `Chinese` | +| `{{target_lang}}` | 目标语言名(`Chinese` / `English`) | 与 `{{source_lang}}` 相对 | +| `{{terminology}}` | [terminology.md](terminology.md) 的完整表格(Markdown 原文) | 渲染时读取仓库当前版本,不缓存 | + +历史模板的 `{{to}}`、`{{title_prompt}}`、`{{summary_prompt}}`、`{{terms_prompt}}`、`{{imt_style_guide}}` 占位符与 `%%` 分段协议已废弃:本模板按整文档翻译(非分段),输出协议为下方三段 XML。 + +## 模板正文 + +````text +# Translation Prompt + +You are a senior technical translator specializing in LLM and agent development documentation. Your task is to translate the given source document from {{source_lang}} to {{target_lang}}, producing natural, professional technical prose. + +## Quality Requirements + +### Structure and Format Preservation +- Output a complete translated document that maintains exactly the same structure as the source: heading hierarchy, list shape, table columns, link targets, and code blocks. +- Fenced code blocks must be byte-identical to the source, including comments. Do not translate any content inside code fences. +- Inline code spans (commands, flags, paths, API names, version numbers) must be kept verbatim. Never translate or reformat them. +- Every relative link must point to the same target as in the source. Link text is translated; link targets are not. +- After a closing bold marker `**`, always insert a space before the next character. + +### Tone and Style +- The translation must read as if originally written in the target language by a native speaker. If an expression sounds like a word-for-word rendering from the source language, rephrase it. +- Write in a professional, formal tone appropriate for developer documentation. Never use colloquial or casual expressions. +- Use polite imperative forms where the text instructs the reader to do something. +- Keep the author's register: concise stays concise, detailed stays detailed. + +### Sentence Structure +- Break long sentences with commas or semicolons. Avoid run-on sentences. +- Prefer active voice. Convert passive constructions to active if it reads more naturally. +- Translate meaning, not words. Restructure sentences where the target language grammar requires it. +- Do not invent words or expressions that do not exist in natural technical writing of the target language. + +### Word Choice +- Prefer precise, formal vocabulary over casual or colloquial alternatives. +- When multiple synonyms exist, choose the one most commonly used in professional technical documentation of the target language. +- Avoid slang, internal jargon, or overly literal translations that would not be recognized by the general developer audience. +- Do not use the same word to translate two different source-language terms that carry distinct meanings. +- Avoid repeating the same verb in close proximity; vary word choice for readability. + +### Punctuation + +#### When translating into Chinese +- Use full-width Chinese punctuation in prose: `,。:;?!()「」`. +- Replace em-dashes (——) with colons, periods, commas, or parentheses as appropriate. Only keep em-dashes when they are truly the best choice. +- Use enumeration commas (、) between parallel items, not regular commas. +- List item endings: use semicolons or no punctuation. Do not end list items with commas. +- Put one half-width space between Chinese text and Latin words/numbers. +- For RFC 2119 keywords (MUST, MUST NOT, SHOULD, MAY), render the corresponding Chinese term in italics: *必须*、*禁止*、*应当*、*可以*. + +#### When translating into English +(To be added.) + +## Terminology + +A terminology table is provided below. Follow it strictly: +- Render every listed term exactly as specified. +- First occurrence: write as shown in the "首次出现" column (with parenthetical gloss). Subsequent occurrences: write only the part before the parentheses. +- If a term has already been glossed as part of a compound term, do not gloss it again when it appears alone later. +- NEVER use translations listed in the "不要译作" column. +- For technical terms not in the table: keep them in the source language. Do not invent a translation. This rule applies to terminology only; for general prose, freely restructure and paraphrase for natural expression. + +{{terminology}} + +## Output Format + +Produce your output in three XML sections: + +```xml + +(Complete translation of the source document) + + + +(Self-review notes, one correction per line with category tag, e.g.) +- [Tone] "旁挂记录" → "伴随记录"(生造词) +- [Sentence] 第 3 段补充逗号断句 +- [Punctuation] 两处破折号替换为冒号 +- 无修正 + + + +(Final translation after corrections) + +``` + +## Self-Review Instructions + +After writing ``, re-read it in the target language only, without looking at the source. Check by category: + +**Structure** +- Is the heading hierarchy, list shape, and code block content identical to the source? +- Are link targets preserved and bold markers followed by a space? + +**Tone & Style** +- Does every sentence read as if originally written by a native speaker? +- Is there any colloquial, casual, or overly informal phrasing? + +**Sentence Structure** +- Are there run-on sentences that need breaking? +- Are there stiff passive constructions that should be converted to active voice? + +**Word Choice** +- Are there overly literal translations that sound unnatural? +- Is the same target-language word used to translate two distinct source concepts? +- Is any slang or internal jargon present? + +**Terminology** +- Are first-occurrence glosses correctly applied (not missing, not repeated)? +- Are any "不要译作" forbidden translations present? +- Are unlisted terms correctly kept in the source language? + +**Punctuation** (when target is Chinese) +- Are there em-dashes that should be replaced with colons, periods, or commas? +- Are list items ending with commas instead of semicolons? +- Are RFC 2119 keywords rendered in italics? + +Record corrections in `` with category tags. Then output the corrected version in ``. If no corrections are needed, write "无修正" in `` and copy the translation unchanged into ``. + +## Examples + +Below are representative examples of common problems and their corrections. Follow the "Good" versions. + +### Colloquial verb → Professional verb +- Source: `The repo pins pnpm@11.7.0 in package.json` +- Bad: `仓库在 package.json 中钉住 pnpm@11.7.0` +- Good: `该仓库在 package.json 中固定使用 pnpm@11.7.0` + +### Run-on sentence → Natural phrasing with pause +- Source: `Read docs/architecture.md before changing anything under packages/.` +- Bad: `改动 packages/ 下的任何东西之前先读 docs/architecture.md。` +- Good: `在修改 packages/ 目录下的任何内容之前,请先阅读 docs/architecture.md。` + +### Stiff passive voice → Active and natural +- Source: `a green gate means the pair was confirmed consistent at these exact contents, not that the confirmation was sound.` +- Bad: `门禁绿意味着这对文档曾在当前内容上被确认一致,不意味着这次确认本身是对的。` +- Good: `门禁通过意味着这组文档在当前内容上的一致性得到了确认,不代表确认本身正确可靠。` + +### Invented word → Natural expression +- Source: `A sidecar record of both blob hashes makes consistency checkable` +- Bad: `旁挂记录两侧 blob hash,使一致性可检查` +- Good: `伴随记录保存两侧 blob hash,使一致性可检查` + +### Em-dash → Colon/period +- Source: `FIXME — an issue that should block a new release. A release should not ship with an open FIXME unless reviewers explicitly agree the change can be merged anyway.` +- Bad: `FIXME——应当阻塞新版本发布的问题。除非评审者明确同意可以照常合入,发布不应带着未解决的 FIXME 出门。` +- Good: `FIXME:应当阻塞新版本发布的问题。除非评审者明确同意该更改可以合并,否则发布版本不应包含未解决的 FIXME。` + +### Overly literal → Meaningful rendering +- Source: `awkward phrasing is easier to hear without the source anchoring you` +- Bad: `没有源文锚着,别扭的表述更容易被听出来` +- Good: `不对照原文时,更容易察觉别扭的表达` + +### Terminology — do not translate what should be kept in English +- Source: `typed service seams, and explicit extension points` +- Bad: `类型化的服务 seam(扩展点)与显式扩展点` +- Good: `类型化的服务 seam 与显式扩展点` + +### Slang/jargon → Professional phrasing +- Source: `The committed agent workflow lives in .agents/skills/dsh-translate-docs` +- Bad: `进仓的 agent 工作流见 .agents/skills/dsh-translate-docs` +- Good: `仓库内置的 agent 工作流见 .agents/skills/dsh-translate-docs` + +--- + +Now translate the following document: +```` diff --git a/scripts/translation-pairing.manifest.json b/scripts/translation-pairing.manifest.json index 6f05431ced..77d7936822 100644 --- a/scripts/translation-pairing.manifest.json +++ b/scripts/translation-pairing.manifest.json @@ -13,6 +13,7 @@ "docs/cordis-catalog/", "docs/tool-catalog/", "docs/i18n/terminology.md", - "docs/i18n/style-samples.md" + "docs/i18n/style-samples.md", + "docs/i18n/translation-prompt.md" ] } From c74cc5a6099c79d62a5c0ba7a19b3d136dc3cc15 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 20:41:10 -0700 Subject: [PATCH 11/17] docs(i18n): credit the prompt and few-shot examples to jingtingxiang --- docs/i18n/translation-prompt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/i18n/translation-prompt.md b/docs/i18n/translation-prompt.md index db9b78aaee..573f125878 100644 --- a/docs/i18n/translation-prompt.md +++ b/docs/i18n/translation-prompt.md @@ -1,6 +1,6 @@ # Translation prompt (pipeline asset) -本文件是自动翻译流水线使用的 prompt 模板,正文(自 `# Translation Prompt` 起)逐字进入模型请求,不参与双语配对(见 [README.md](README.md) 排除清单)。模板与仓库规则的关系:[terminology.md](terminology.md) 在渲染时整表填入 `{{terminology}}`;文体金标见 [style-samples.md](style-samples.md),模板内嵌的 Examples 是其中问题类别的最小抽样,两者冲突时以 style-samples 为准。修改本文件即修改线上翻译行为,按正常 PR 评审。 +本文件是自动翻译流水线使用的 prompt 模板,正文(自 `# Translation Prompt` 起)逐字进入模型请求,不参与双语配对(见 [README.md](README.md) 排除清单)。模板正文与其内嵌 few-shot 正误例由 jingtingxiang 基于对存量译文的质量评审撰写。模板与仓库规则的关系:[terminology.md](terminology.md) 在渲染时整表填入 `{{terminology}}`;文体金标见 [style-samples.md](style-samples.md),模板内嵌的 Examples 是其中问题类别的最小抽样,两者冲突时以 style-samples 为准。修改本文件即修改线上翻译行为,按正常 PR 评审。 ## 占位符契约 From ba4e39f10d52507c05c31e852bd9622bb905b784 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 21:07:45 -0700 Subject: [PATCH 12/17] docs(i18n): adopt jingtingxiang's calibrated terminology table and five gold pairs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 术语表整体采用 jingtingxiang 的重构版(PR #244):按缩写类/英文类/ 双语类分节、通用规则前置、首次出现与不要译作独立列;保留本 stack 的 mock/package/counterpart 与 agent 组合词裁定行。五组金标译文按 其定稿采用(development、i18n README、translation-rules、双语 RFC、 根 README),README.zh 吸收 PR #249 的两处措辞(「智能体辔架」括注 与其自身新表冲突,未采用)。translation-prompt.md 增补 Few-shot 金 标一节:声明这 5 组配对即流水线的整文档级 few-shot,注入方式为多轮 示例对话。style-samples 的 blob hash 译法按新表回改为保留英文。 Supersedes the .zh.md content of #244/#249/#264. --- README.i18n.yaml | 2 +- README.zh.md | 4 +- docs/development.i18n.yaml | 2 +- docs/development.zh.md | 58 ++-- docs/i18n/style-samples.md | 2 +- docs/i18n/terminology.md | 301 +++++++++--------- docs/i18n/translation-prompt.md | 12 + docs/i18n/translation-rules.i18n.yaml | 2 +- docs/i18n/translation-rules.zh.md | 62 ++-- ...-bilingual-docs-and-pairing-gate.i18n.yaml | 2 +- ...7-02-bilingual-docs-and-pairing-gate.zh.md | 42 +-- 11 files changed, 262 insertions(+), 227 deletions(-) diff --git a/README.i18n.yaml b/README.i18n.yaml index 0a981d4323..b765b44217 100644 --- a/README.i18n.yaml +++ b/README.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write README.md: 7ddf68bab06ecf891856e6d1393ccdefd9eeba38 -README.zh.md: 59a0419164f2dfee6f66903cc93d7b35da1d9063 +README.zh.md: ad568c808d4c8003a84734bc8035fac9a07d27b4 diff --git a/README.zh.md b/README.zh.md index 59a0419164..ad568c808d 100644 --- a/README.zh.md +++ b/README.zh.md @@ -6,7 +6,7 @@ ## 开发 -本 monorepo 基于 [Cordis](https://github.com/cordiverse/cordis) 框架构建(以源码形式收录在 `vendor/` 下),采用微内核风格:一切皆插件。 +本 monorepo 基于 [Cordis](https://github.com/cordiverse/cordis) 框架构建(以源码形式收录在 `vendor/` 下),采用微内核风格:所有功能都以插件形式提供。 ```sh pnpm install @@ -15,6 +15,6 @@ pnpm run demo:repl # REPL agent demo (needs DEEPSEEK_API_KEY) pnpm run demo:acp # ACP server agent demo (needs DEEPSEEK_API_KEY) ``` -面向人类读者:先读[开发指南](docs/development.md)了解本地环境搭建、钩子、环境变量与质量门禁,动手改 package 之前再读[架构设计](docs/architecture.md)。局部上下文见 [packages/](packages/) 与 [vendor/](vendor/)。 +面向开发者:先读[开发指南](docs/development.md),了解本地环境搭建、钩子、环境变量与质量门禁,动手改 package 之前再读[架构设计](docs/architecture.md)。局部上下文见 [packages/](packages/) 与 [vendor/](vendor/)。 面向 agent:遵循 [AGENTS.md](AGENTS.md)。 diff --git a/docs/development.i18n.yaml b/docs/development.i18n.yaml index d8f76162db..ac9ee414b1 100644 --- a/docs/development.i18n.yaml +++ b/docs/development.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write development.md: 28babca2b59c844690750d767c242c08c37bf702 -development.zh.md: b34c52cebd3f333b6554ca2b5ebd66463e436572 +development.zh.md: 91b63d7511f856f21162f8ab66eae6e25d925059 diff --git a/docs/development.zh.md b/docs/development.zh.md index b34c52cebd..91b63d7511 100644 --- a/docs/development.zh.md +++ b/docs/development.zh.md @@ -2,14 +2,14 @@ [English](development.md) | 中文 -本指南覆盖参与 DeepSeek Harness 开发所需的本地环境搭建,并帮助你理解本地钩子、日常检查与 CI 门禁。 +本指南覆盖参与 DeepSeek Harness 开发所需的本地环境搭建,并帮助你了解本地钩子、日常检查与 CI 门禁。 ## 前置条件 -- Node.js 24 或更新版本。仓库声明 `node >=24`;CI 在 Node 24 和 26 上跑矩阵。 -- 启用了 Corepack 的 pnpm。仓库在 `package.json` 中钉住 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,先运行 `corepack enable`。 +- Node.js 24 或更新版本。仓库声明 `node >=24`;CI 在 Node 24 和 26 上运行矩阵测试。 +- 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`。 - Git。 -- 可选:一个 DeepSeek API key,用于 REPL/ACP agent(智能体)演示和真实 API 的 e2e 测试。 +- 可选:一个 DeepSeek API key,用于 REPL/ACP agent 演示和真实 API 的 e2e 测试。 ## 首次搭建 @@ -19,23 +19,23 @@ pnpm install ``` -安装同时会运行根目录的 `postinstall` 脚本,它通过 `scripts/install-lefthook.mjs` 从仓库 dev 依赖安装 lefthook;该包装脚本使用 lefthook 经过评审的 `--force` 模式,使已存在 `core.hooksPath` 的关联 worktree 不会让正常的 `pnpm run …` 命令失败。 +安装过程同时会运行根目录的 `postinstall` 脚本,该脚本通过 `scripts/install-lefthook.mjs` 从仓库 dev 依赖安装 lefthook。包装脚本使用 lefthook 经过评审的 `--force` 模式,确保已存在 `core.hooksPath` 的关联 worktree 不会导致正常的 `pnpm run …` 命令失败。 -如果因为依赖是从缓存恢复或 `postinstall` 被跳过而缺少钩子,手动安装: +如果依赖是从缓存恢复或 `postinstall` 被跳过而导致缺少钩子,请手动安装: ```sh pnpm exec lefthook install --force ``` -新克隆后先跑一次类型检查: +新克隆后请先运行一次类型检查: ```sh pnpm run typecheck ``` -这次首跑会构建 package/vendor 构建图,并跑根目录 no-emit `tsconfig.json` 图(覆盖 examples、tests 和 scripts)。根图使用同一份源码 `paths` 映射,但依赖 project references,因此 vendor 代码在它自己的 tsconfig 设置下被检查。 +首次类型检查会执行 package/vendor 的构建图,以及根目录下用于示例、测试和脚本的 no-emit `tsconfig.json` 项目图。根图使用同一份源码 `paths` 映射,但依赖 project references,因此 vendor 代码在它自己的 tsconfig 设置下被检查。 -如果准备从新克隆或新 worktree 推送,还要构建一次: +如果准备从新克隆或新 worktree 推送,还需要构建一次: ```sh pnpm run build @@ -45,29 +45,29 @@ pnpm run build ## 环境变量 -真实的 DeepSeek 适配器和需要密钥的 agent 演示从环境变量或仓库根目录一个被 gitignore 的 `.env` 读取凭证: +真实的 DeepSeek 适配器和需要密钥的 agent 演示从环境变量或仓库根目录一个被 gitignore 的 `.env` 文件读取凭证: ```sh DEEPSEEK_API_KEY=sk-... DEEPSEEK_BASE_URL=https://... # optional ``` -`DEEPSEEK_BASE_URL` 可选,默认为公开 API。绝不要提交真实凭证。未设置 `DEEPSEEK_API_KEY` 时,真实 API 的 e2e 套件会自动跳过。 +`DEEPSEEK_BASE_URL` 可选,默认为公开 API。请勿提交真实凭证。未设置 `DEEPSEEK_API_KEY` 时,真实 API 的 e2e 套件会自动跳过。 ## Git 钩子 lefthook 在 `lefthook.yml` 中配置,作为评审前的本地早期检查点: -- `pre-commit` 运行对暂存文件的 ESLint 修复、`pnpm run typecheck` 和 vendor manifest 守卫。 +- `pre-commit` 运行对暂存文件的 ESLint 修复、`pnpm run typecheck` 和 vendor manifest 守卫; - `pre-push` 运行 `pnpm run test`、`pnpm run test:snapshot`、`pnpm run hygiene`、`pnpm run doc-sync` 和 `pnpm run verify-module-graph`。 -vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。编辑 vendor 代码前先看 `vendor/README.md`。 +vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md`。 -这些钩子并不与 CI 完全一致。特别是:`pre-push` 跑不带覆盖率的单元测试,而 CI 跑 `pnpm run test:coverage`;CI 还会跑 echo-agent 和 built-bin 冒烟测试,并在 Node 24 和 26 上跑矩阵。 +这些钩子并不与 CI 完全一致。特别是:`pre-push` 运行不带覆盖率的单元测试,而 CI 运行 `pnpm run test:coverage`;CI 还会运行 echo-agent 和 built-bin 冒烟测试,并在 Node 24 和 26 上运行矩阵。 ## CI 门禁 -GitHub 工作流在每个 pull request 上运行这些门禁: +GitHub 工作流在每个 Pull Request 上运行以下门禁: - `pnpm install --frozen-lockfile` - `pnpm run constraints` @@ -82,7 +82,7 @@ GitHub 工作流在每个 pull request 上运行这些门禁: - 一个 echo-agent 冒烟测试,检查演示的工具调用、工具结果和 JSONL 输出 - built-bin 冒烟测试,用纯 `node` 运行发布产物 `lib/bin.js` 入口 -`pnpm run hygiene` 是 `pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-node-next-types` 的本地简写;CI 还会把 `pnpm run constraints` 作为更早的快速失败步骤单独跑一次,然后在 `pnpm run build` 之后跑完整的 hygiene 脚本。 +`pnpm run hygiene` 是 `pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-node-next-types` 的本地简写;CI 还会将 `pnpm run constraints` 作为更早的快速失败步骤单独运行一次,然后在 `pnpm run build` 之后运行完整的 hygiene 脚本。 ## 日常命令 @@ -96,9 +96,13 @@ pnpm run typecheck # build package/vendor outputs, then typecheck examples, pnpm run lint # eslint . pnpm run lint:fix # eslint . --fix pnpm run doc-typecheck # compile checked TypeScript snippets in Markdown docs -pnpm run gen-cordis-catalog # regenerate docs/cordis-catalog/events-and-services.md from source -pnpm run verify-cordis-catalog # fail if the cordis events/services catalog is stale +pnpm run gen-cordis-catalog # regenerate docs/cordis-catalog/events.md + services.md from source +pnpm run verify-cordis-catalog # fail if either cordis catalog is stale +pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions +pnpm run verify-doc-graphs # fail if generated relationship docs are stale +pnpm run gen-rfc-index # regenerate the docs/rfc/README.md index tables from the RFC tree pnpm run verify-md-wrap # fail on hard-wrapped prose paragraphs in docs/README markdown +pnpm run verify-mermaid # fail if a ```mermaid diagram has invalid Mermaid syntax pnpm run verify-type-equiv # fail if a ```ts type-equiv doc block drifts from its source type pnpm run verify-doc-budgets # fail if a budgeted standing doc exceeds its word ceiling pnpm run doc-sync # all Markdown/doc gates; see the doc-sync script in package.json for the full list @@ -109,7 +113,7 @@ pnpm run verify-node-next-types # fail if built declarations are not NodeNext-c pnpm run hygiene # knip, publint, workspace constraints, and NodeNext declaration check ``` -改动 package 的公开行为时,在同一个变更里更新相关 README 或 JSDoc。`pnpm run doc-sync` 能抓住被检查的 TypeScript 片段、cordis 事件/服务目录漂移和硬折行的 markdown 段落,但更广泛的行文/API 同步仍需评审把关。 +修改 package 的公开行为时,请在同一个变更中更新相关 README 或 JSDoc。`pnpm run doc-sync` 能检测到被检查的 TypeScript 片段、生成文档的新鲜度、Markdown 换行/链接漂移、type-equiv、翻译配对、Mermaid 语法和文档预算,但更广泛的行文/API 同步仍需评审把关。 ## 演示 @@ -133,24 +137,24 @@ pnpm run demo:acp ## TODO 标记 -用三种注释标签之一标记代码中的已知问题,按紧急程度排序: +请使用以下三种注释标签之一标记代码中的已知问题,按紧急程度排序: -- `FIXME`——应当阻塞新版本发布的问题。除非评审者明确同意可以照常合入,发布不应带着未解决的 `FIXME` 出门。 -- `TODO`——应当尽快修复的问题,等资源到位就处理。 -- `XXX`——也许某天会修的问题;优先级最低,不作承诺。 +- `FIXME`:应当阻塞新版本发布的问题。除非评审者明确同意该更改可以合并,否则发布版本不应包含未解决的 `FIXME`; +- `TODO`:应当尽快修复的问题,等资源到位即可处理; +- `XXX`:也许某天会修复的问题,优先级最低,不作承诺。 -选择与紧急程度匹配的标签,让扫代码的人一眼分清「发布阻塞」和「有空再说」。 +请选择与紧急程度匹配的标签,让浏览代码的人一眼分清「发布阻塞」和「有空再说」。 ## 逐字记录类型(`ts type-equiv`) -[核心数据结构](core-data-structures/core.md)文档粘贴真实的类型定义,让读者看到确切的形状。为防止粘贴内容在源码变化时漂移,把它围栏成 ` ```ts type-equiv `(而不是 ` ```ts `),并在 `scripts/type-equiv.manifest.json` 中登记它镜像的源文件和符号: +[核心数据结构](core-data-structures/core.md)文档粘贴真实的类型定义,让读者看到确切的形状。为防止粘贴内容在源码变化时漂移,请将其围栏为 ` ```ts type-equiv `(而不是 ` ```ts `),并在 `scripts/type-equiv.manifest.json` 中登记它镜像的源文件和符号: ```json { "doc": "docs/core-data-structures/session.md", "symbol": "SessionEvent", "source": "packages/core/session/src/types.ts" } ``` -`pnpm run verify-type-equiv`(`doc-sync` 的一环)随后通过 TypeScript 解析器从源码提取该符号的声明,并断言文档块与之一致(对空白和注释不敏感,因此文档块可以展示干净的定义,语义由行文承载)。它还强制 1:1 对应:每个 `ts type-equiv` 块恰好有一条 manifest 条目,反之亦然,因此不会有块被静默漏检,也不会有陈旧条目滞留。`doc-typecheck` 跳过 `ts type-equiv` 块(它们不能独立编译),并将其排除在 opt-out 比例之外。当你改动一个被记录的类型,门禁会失败直到你更新粘贴内容;当你增删一个块,在同一个变更里更新 manifest。 +`pnpm run verify-type-equiv`(`doc-sync` 的一环)随后通过 TypeScript 解析器从源码提取该符号的声明,并断言文档块与之一致(对空白和注释不敏感,因此文档块可以展示干净的定义,语义由行文承载)。它还强制 1:1 对应:每个 `ts type-equiv` 块恰好有一条 manifest 条目,反之亦然;因此不会有块被静默漏检,也不会有陈旧条目滞留。`doc-typecheck` 跳过 `ts type-equiv` 块(它们不能独立编译),并将其排除在 opt-out 比例之外。当你改动一个被记录的类型时,门禁会失败直到你更新粘贴内容;当你增删一个块时,请在同一个变更里更新 manifest。 ## 架构上下文 -改动 `packages/` 下的任何东西之前先读 `docs/architecture.md`。这套代码围绕 Cordis 插件、事件溯源的会话、类型化的服务 seam(扩展点)与显式扩展点构建。 +在修改 `packages/` 目录下的任何内容之前,请先阅读 `docs/architecture.md`。这套代码围绕 Cordis 插件、事件溯源的会话、类型化的服务 seam 与显式扩展点构建。 diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index b72d810afc..6376b3964f 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -54,7 +54,7 @@ > Blob hashes, not commit hashes, so the record is computable for files edited in the same PR (`git hash-object foo.md`) and consistency is a pure content comparison. The recorded hash also recovers the exact last-confirmed text of either side (`git cat-file -p `), so an out-of-sync pair is updated by diffing the edited side against its last-confirmed state and patching the counterpart minimally — never by re-translating whole files. -系统采用文件 blob 哈希而非提交哈希记录状态。同一 PR 内修改文件时,可通过 `git hash-object foo.md` 直接算出对应哈希,仅对比文件内容即可判断双语文档是否同步。通过记录的哈希值,可使用 `git cat-file -p ` 还原上次确认对齐时两侧的原文。当双语文档不一致时,只需对比修改版本与上次确认版本的差异,最小幅度同步修改另一侧译文,无需全文重新翻译。 +系统采用文件 blob hash 而非 commit hash 记录状态。同一 PR 内修改文件时,可通过 `git hash-object foo.md` 直接算出对应 blob hash,仅对比文件内容即可判断双语文档是否同步。通过记录的 blob hash,可使用 `git cat-file -p ` 还原上次确认对齐时两侧的原文。当双语文档不一致时,只需对比修改版本与上次确认版本的差异,最小幅度同步修改另一侧译文,无需全文重新翻译。 ## ⑤ 政策声明 diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index 408048a66f..ae6f24acdb 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -1,148 +1,165 @@ # Terminology -本表约定本仓库的中英术语统一译法。各列语义: +本表约定本仓库的中英术语统一译法。 -- **中文** — 正文中的固定译法;写「保留英文」表示不译。 -- **首次出现** — 术语在一篇文档中第一次出现时的完整写法(含括注);之后只写「中文」列的形式。组合词已括注过的成分,单独出现时不再括注。 -- **不要译作** — 禁用译法,逐项列出;出现任何一项即评审阻断。 -- **备注** — 语境区分、裁定出处等自由说明;不承载可执行规则。 +**通用规则:** +- "中文"列为中文译文的正文默认用词。若该列为英文,则中文译文的正文中保留英文不翻译。 +- 首次出现按"首次出现"列书写(带括号注释);后续出现只写括号前的部分(可能为中文,也可能为英文),不出现括号内的注释。 +- "不要译作"列为严格禁止的译法。 +- 如果某术语已经作为另一个术语的组成部分被括注过(如 `agent loop(智能体循环)` 中已包含 `agent` 的括注),则该术语后续单独出现时无需再次括注。 + +## 缩写类(中英文文本中均使用缩写) | English | 中文 | 首次出现 | 不要译作 | 备注 | |---|---|---|---|---| -| ACP | ACP | ACP(Agent Client Protocol) | | | -| AI | AI | 人工智能(AI) | | | -| API | API | | | real-API 作定语时可译「真实接口」(如 real-API tests → 真实接口测试) | -| CI | CI | | | | -| CLI | CLI | 命令行界面(CLI) | | | -| Cordis | Cordis | | | 保留英文 | -| Function Calling | Function Calling | Function Calling(函数调用) | | | -| HMR | HMR | 热模块替换(HMR) | | | -| JSON Schema | JSON Schema | | | | -| JSONL | JSONL | | | | -| lint | lint | | | | -| loader | loader | | | | -| LLM | LLM | 大语言模型(LLM) | | | -| MCP | MCP | | | | -| PR | PR | PR(pull request) | | | -| RAG | RAG | 检索增强生成(RAG) | | | -| SDK | SDK | | | | -| SSE | SSE | SSE(Server-Sent Events) | | | -| agent | agent | agent(智能体) | | 括注只落在 agent 单独首现处;组合词见下行 | -| agent harness, agent workflow, agent loop, agent skill | 保留英文 | | | agent 组合词整体保留英文、不括注;其中的 workflow/loop/skill 不单独拆译;未列出的 agent 组合词同此处理 | -| backlog | backlog | | | 双语翻译语境指待翻清单 | -| blob hash | blob 哈希 | | | git 对象哈希;`git hash-object` 的结果 | -| commit hash | 提交哈希 | | | | -| hash | 哈希 | | | 代码与命令中保留英文(如 `git hash-object`、`` 占位符) | -| doc-sync | doc-sync | | | 仓库门禁名,保留英文 | -| e2e | e2e | | | | -| fiber | fiber | fiber(插件运行时) | | | -| fixture | fixture | | | 指测试前置数据或环境 | -| fork | fork | | | 保留英文 | -| harness | harness | | | 保留英文 | -| manifest | manifest | | | 描述模块或工具元数据的文件 | -| monorepo | monorepo | | | | -| package | package | | | 保留英文;指 npm 包(`@deepseek-ai/dsh-*`) | -| schema DSL | schema DSL | | | | -| schema | schema | | | 保留英文 | -| seam | seam | seam(扩展点) | | 同句已出现「扩展点」(extension point)时不加括注,直接写 seam,避免一词两指 | -| skill | skill | skill(技能) | | | -| spawn | spawn | | | 保留英文 | -| steering | steering | steering(中途引导) | | | -| subagent | subagent | subagent(子 agent) | | | -| transcript | transcript | transcript(文本记录) | | 指会话渲染给用户或编辑器的完整文本,区别于事件日志(event log) | -| waterfall | waterfall | waterfall(瀑布式事件) | | | -| worktree | worktree | | | git 工作区概念,保留英文 | -| wire format | 协议格式 | 协议格式(wire format) | | | -| adapter contract | 适配器契约 | 适配器契约(adapter contract) | | | -| adapter | 适配器 | | | | -| append-only | 仅追加 | | | | -| artifact | 产物 | | | | -| block | 块 | | | | -| background task | 后台任务 | | | | -| backend | 后端 | | | | -| capability | 能力 | | | | -| cancel | 取消 | | | | -| checkpoint | 检查点 | | | | -| chunk | 分片 | | | | -| compaction | compaction | compaction(上下文压缩) | | 正文优先保留英文 | -| consumer | 消费方 | | | | -| counterpart | 对侧文件 | | 对应物、配对物 | 双语配对语境;泛指“另一侧”时可写「另一侧」 | -| content block | 内容块 | | | | -| config | 配置 | | | | -| context | 上下文 | | | | -| context compaction | 上下文压缩 | 上下文压缩(context compaction) | | | -| contract | 契约 | | | 如:配对契约(pairing contract);另见 adapter contract | -| coverage | 覆盖率 | | | | -| crash recovery | 崩溃恢复 | | | | -| dispose | dispose | dispose(释放资源) | | 正文优先保留英文 | -| durability | 持久性 | | | | -| enforcement frontier | 强制边界 | | | i18n 机制词:manifest `required` 清单所划的门禁生效范围 | -| event log | 事件日志 | | | | -| event | 事件 | | | | -| event stream | 事件流 | | | | -| event-sourced | 事件溯源 | | | DDD 社区通行译法 | -| executor | 执行器 | | | | -| extension | 扩展 | | | | -| fail-fast | 快速失败 | | | | -| fenced code block | 围栏代码块 | | | MDN 中文同译 | -| finish reason | 结束原因 | | | | -| fingerprint | 指纹 | | | i18n 机制词:`.zh.md` 首行记录英文源 blob hash 的 `i18n-source` 注释 | -| foreground run | 前台运行 | | | | -| freshness | 新鲜度 | | | MDN HTTP 缓存中文同译(freshness lifetime → 新鲜度生命周期);指译文相对英文源的同步状态 | -| hook | 钩子 | | | | -| implementation | 实现 | | | | -| inference | 推理(inference) | | | 每次提及时保留英文括注,避免与 reasoning 混淆 | -| info string | 信息字符串 | | | CommonMark 中文同译;代码围栏 ``` 之后的语言标注 | -| injection | 注入 | | | | -| interface | 接口 | | | | -| integration | 集成 | | | | -| language switcher | 语言切换行 | | | i18n 机制词:双语配对文件顶部的互链行 | -| memory | memory / 记忆 / 内存 | | | 按上下文区分:agent memory 译为“记忆”;resource/memory usage 译为“内存” | -| message | 消息 | | | | -| mock | mock | | | 保留英文;指测试替身 | -| mod | 模组 | | | 区别于 module(模块);plugin 译作「插件」 | -| model provider | 模型提供方 | | | | -| module | 模块 | | | | -| orphan | 孤立 | | 孤儿 | git 官方中文同译(如「孤立分支」);指英文源已不存在的 `.zh.md`;进程语境按 OS 惯用语译「孤儿进程」 | -| pairing | 配对 | | | | -| permission | 权限 | | | | -| persistence | 持久化 | | | | -| pipeline | 流水线 | | | | -| plugin | 插件 | | | mod 对应“模组” | -| prompt | 提示词 | | | | -| provider | 提供方 | | | | -| provider-neutral | 提供方无关 | | | | -| quality gate | 质量门禁 | | | | -| registry | 注册表 | | | | -| reasoning | 推理(reasoning) | | | 需要和 inference 区分时保留英文括注;`reasoning_content` 译为“思考内容” | -| replay | 回放 | | | | -| resume | 恢复 | | | | -| runtime | 运行时 | | | | -| sandbox | 沙箱 | | | | -| service | 服务 | | | | -| session | 会话 | | | | -| session event | 会话事件 | | | | -| sidecar record | 伴随记录 | | 旁挂记录 | 指 `.i18n.yaml` 这类随主文件存放的记录文件 | -| smoke test | 冒烟测试 | | | | -| snapshot | 快照 | | | | -| source of truth | 真源 | 真源(source of truth) | | 评审裁定译法;如后续裁定调整,改此表即可 | -| spine | 主干 | | | | -| staged | 暂存 | | | git 官方中文同译 | -| stale | 陈旧 | | | MDN HTTP 缓存中文同译,与「新鲜(fresh)」成对;门禁输出保留英文 `stale`;expired 才译「过期」 | -| step | 步骤 | | | | -| stream | 流 | | | | -| streaming | 流式输出 | | | | -| structural signature | 结构签名 | | | i18n 机制词:配对门禁比对的有序结构序列 | -| system prompt | 系统提示词 | | | | -| taxonomy | 分类体系 | | | | -| token usage | token 用量 | | | | -| thinking | thinking | | | API 字段保留;模型模式译为“思考” | -| tool | 工具 | | | | -| tool call | 工具调用 | | | | -| tool result | 工具结果 | | | | -| tool schema | 工具 schema | | | | -| toolkit | 工具包 | | | | -| turn | 轮次 | | | | -| typecheck | 类型检查 | | | | -| vocabulary | 词汇 | | | | -| workflow | 工作流 | | | | +| ACP | ACP | ACP(Agent Client Protocol) | | | +| AI | AI | AI(人工智能) | | | +| API | API | | | | +| CI | CI | | | | +| CLI | CLI | CLI(命令行界面) | | | +| e2e | e2e | | | | +| HMR | HMR | HMR(热模块替换) | | | +| JSON Schema | JSON Schema | | | | +| JSONL | JSONL | | | | +| LLM | LLM | LLM(大语言模型) | | | +| MCP | MCP | | | | +| PR | PR | PR(Pull Request) | | | +| RAG | RAG | RAG(检索增强生成) | | | +| SDK | SDK | | | | +| SSE | SSE | SSE(Server-Sent Events) | | | + +## 英文类(中英文文本中均使用英文) + +| English | 中文 | 首次出现 | 不要译作 | 备注 | +|---|---|---|---|---| +| agent | agent | agent(智能体) | | | +| agent harness | agent harness | | | agent 组合词(agent harness/workflow/loop/skill 等)整体保留英文;未括注过 agent 时首现按 agent 行处理 | +| agent loop | agent loop | agent loop(智能体循环) | | | +| backlog | backlog | backlog(待翻清单) | | 仅在双语翻译语境里括注`待翻清单` | +| blob hash | blob hash | | | `git hash-object` 的结果 | +| Cordis | Cordis | | | | +| dispose | dispose | dispose(资源释放) | | | +| doc-sync | doc-sync | doc-sync(文档同步门禁) | | | +| fiber | fiber | fiber(插件运行时) | | | +| fixture | fixture | fixture(测试前置数据) | | | +| fork | fork | | | | +| Function Calling | Function Calling | Function Calling(函数调用) | | | +| harness | harness | | | | +| harness engineering | harness engineering | | | | +| lint | lint | | | | +| mock | mock | | | 保留英文;指测试替身 | +| loader | loader | | | | +| manifest | manifest | manifest(元数据清单) | | | +| monorepo | monorepo | | | | +| package | package | | | 保留英文;指 npm 包(`@deepseek-ai/dsh-*`) | +| schema | schema | | | | +| schema DSL | schema DSL | | | | +| seam | seam | | | 与 `extension point` 是不同概念;根据具体语境,可译为`服务边界`或`可替换点` | +| skill | skill | skill(技能) | | | +| spawn | spawn | | | | +| steering | steering | steering(中途引导) | | | +| subagent | subagent | | | | +| thinking | thinking | | | API 字段保留英文;描述模型模式时译为`思考` | +| transcript | transcript | transcript(文本记录) | | 指会话渲染给用户或编辑器的完整文本,区别于事件日志 | +| waterfall | waterfall | waterfall(瀑布式事件) | | | +| worktree | worktree | | | git 工作区概念 | + +## 双语类(中英文文本各自使用中英文) + +| English | 中文 | 首次出现 | 不要译作 | 备注 | +|---|---|---|---|---| +| adapter | 适配器 | | | | +| adapter contract | 适配器契约 | 适配器契约(adapter contract) | | | +| append-only | 仅追加 | | | | +| artifact | 产物 | | | | +| backend | 后端 | | | | +| background task | 后台任务 | | | | +| block | 块 | | | | +| cancel | 取消 | | | | +| capability | 能力 | | | | +| checkpoint | 检查点 | | | | +| chunk | 分片 | | | | +| compaction | 压缩 | 压缩(compaction) | | | +| config | 配置 | | | | +| consumer | 消费方 | | | | +| content block | 内容块 | | | | +| context | 上下文 | | | | +| counterpart | 对侧文件 | | 对应物、配对物 | 双语配对语境;泛指"另一侧"时可写「另一侧」 | +| context compaction | 上下文压缩 | 上下文压缩(context compaction) | | | +| contract | 契约 | | | 如:`pairing contract` →`配对契约` | +| coverage | 覆盖率 | | | | +| crash recovery | 崩溃恢复 | | | | +| durability | 持久性 | | | | +| enforcement frontier | 强制边界 | | | i18n 配对机制用语:manifest `required` 清单所划的门禁生效范围 | +| event | 事件 | | | | +| event log | 事件日志 | | | | +| event stream | 事件流 | | | | +| event-sourced | 事件溯源 | | | 沿用 DDD 社区通行译法 | +| executor | 执行器 | | | | +| extension | 扩展 | | | | +| extension point | 扩展点 | | | 注意与 `seam` 区分 | +| fail-fast | 快速失败 | | | | +| fenced code block | 围栏代码块 | | | 沿用 MDN 中文翻译 | +| fingerprint | 指纹 | | | i18n 配对机制用语:`.zh.md` 首行记录英文源 blob hash 的注释 | +| finish reason | 结束原因 | | | | +| foreground run | 前台运行 | | | | +| freshness | 新鲜度 | | | 沿用 MDN 中文翻译;在本项目中指译文相对源文的同步状态 | +| hook | 钩子 | | | | +| implementation | 实现 | | | | +| inference | 推理 | 推理(inference) | | 需要和 `reasoning` 区分时保留英文括注 | +| info string | 信息字符串 | | | 沿用 CommonMark 中文翻译;指代码围栏 ``` 之后的语言标注 | +| injection | 注入 | | | | +| integration | 集成 | | | | +| interface | 接口 | | | | +| language switcher | 语言切换行 | | | i18n 配对机制用语:双语配对文件顶部的互链行 | +| memory | 记忆 / 内存 | | | 与 `agent` 搭配时译为`记忆`(如 `agent memory` →`智能体记忆`);指系统资源时译为`内存` | +| merge | 合并 | | | | +| message | 消息 | | | | +| mod | 模组 | | | | +| model provider | 模型提供方 | | | | +| module | 模块 | | | | +| orphan | 孤立 | | 孤儿 | 指英文源已不存在的 `.zh.md` | +| orphan branch | 孤立分支 | | 孤儿分支 | 沿用 git 官方中文翻译 | +| pairing | 配对 | | | | +| permission | 权限 | | | | +| persistence | 持久化 | | | | +| pipeline | 流水线 | | | | +| plugin | 插件 | | | | +| prompt | 提示词 | | | | +| provider | 提供方 | | | | +| provider-neutral | 提供方无关 | | | | +| quality gate | 质量门禁 | | | | +| reasoning | 推理 | 推理(reasoning) | | 需要和 `inference` 区分时保留英文括注 | +| reasoning_content | 思考内容 | | | | +| registry | 注册表 | | | | +| replay | 回放 | | | | +| resume | 恢复 | | | | +| runtime | 运行时 | | | | +| sandbox | 沙箱 | | | | +| service | 服务 | | | | +| session | 会话 | | | | +| session event | 会话事件 | | | | +| sidecar record | 伴随记录 | | 旁挂记录 | 指与文档同目录的伴随记录文件 | +| smoke test | 冒烟测试 | | | | +| snapshot | 快照 | | | | +| source of truth | 真源 | | | | +| spine | 主干 | | | | +| staged | 暂存 | | | 沿用 git 官方中文翻译 | +| stale | 陈旧 | | 过期 | 与 `fresh`(`新鲜`)成对;门禁输出中保留英文 `stale` 不翻译;`expired` 才译为`过期` | +| step | 步骤 | | | | +| stream | 流 | | | | +| streaming | 流式输出 | | | | +| structural signature | 结构签名 | | | i18n 配对机制用语:门禁比对两侧文件时提取的有序结构序列(标题层级、代码块、列表等) | +| system prompt | 系统提示词 | | | | +| taxonomy | 分类体系 | | | | +| token usage | token 用量 | | | | +| tool | 工具 | | | | +| tool call | 工具调用 | | | | +| tool result | 工具结果 | | | | +| tool schema | 工具 schema | | | | +| toolkit | 工具包 | | | | +| turn | 轮次 | | | | +| typecheck | 类型检查 | | | | +| vocabulary | 词汇 | | | | +| wire format | 协议格式 | 协议格式(wire format) | | | +| workflow | 工作流 | | | | diff --git a/docs/i18n/translation-prompt.md b/docs/i18n/translation-prompt.md index 573f125878..db707730fa 100644 --- a/docs/i18n/translation-prompt.md +++ b/docs/i18n/translation-prompt.md @@ -14,6 +14,18 @@ 历史模板的 `{{to}}`、`{{title_prompt}}`、`{{summary_prompt}}`、`{{terms_prompt}}`、`{{imt_style_guide}}` 占位符与 `%%` 分段协议已废弃:本模板按整文档翻译(非分段),输出协议为下方三段 XML。 +## Few-shot 金标 + +流水线的 few-shot 是**整文档级**的中英对照,不是模板内嵌的句子级正误例(那是最小抽样)。few-shot 集取自以下 5 组人工定稿的配对文档,以仓库当前版本为准、随仓库更新: + +- `README.md` ↔ `README.zh.md` +- `docs/development.md` ↔ `docs/development.zh.md` +- `docs/i18n/README.md` ↔ `docs/i18n/README.zh.md` +- `docs/i18n/translation-rules.md` ↔ `docs/i18n/translation-rules.zh.md` +- `docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.md` ↔ 对应 `.zh.md` + +注入方式:在系统消息(本模板)之后、待译文档之前,每组作为一轮示例对话——user 消息为源文档全文,assistant 消息为定稿译文全文(不带三段 XML 包装;只有真实请求要求三段输出)。上下文紧张时按上列顺序从后往前裁剪组数。这 5 组也是评审校准锚点(见 [style-samples.md](style-samples.md)),改动任何一组即改变流水线行为。 + ## 模板正文 ````text diff --git a/docs/i18n/translation-rules.i18n.yaml b/docs/i18n/translation-rules.i18n.yaml index f1aa737d08..d340ff42b8 100644 --- a/docs/i18n/translation-rules.i18n.yaml +++ b/docs/i18n/translation-rules.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write translation-rules.md: 3e99aa5432ccd904f702238e9b802a9ed9bf6832 -translation-rules.zh.md: 78778907f959d62dad2c9b4c02baf1f664791a43 +translation-rules.zh.md: 0ff2ab43d59c6e0dd07e20e2f1a0a1c28c2f245c diff --git a/docs/i18n/translation-rules.zh.md b/docs/i18n/translation-rules.zh.md index 78778907f9..0ff2ab43d5 100644 --- a/docs/i18n/translation-rules.zh.md +++ b/docs/i18n/translation-rules.zh.md @@ -2,13 +2,13 @@ [English](translation-rules.md) | 中文 -本文规定如何在本仓库文档配对的两侧之间进行翻译。两种语言同权(见 [README.md](README.md)):一次变更用任一语言撰写,那一侧就是这次更新的源——本文的规则约束的是产出或更新另一侧。这些规则对人和 agent(智能体)同等生效;应用它们的进仓 agent 工作流是 [.agents/skills/dsh-translate-docs](../../.agents/skills/dsh-translate-docs/SKILL.md)。规则级别沿用 RFC 2119 的用法:**必须(MUST)**/**禁止(MUST NOT)**会卡门禁或评审;**应当(SHOULD)**偏离时要说明理由;**可以(MAY)**自行裁量。 +本文规定:如何在本仓库文档配对的中英文两种语言之间进行翻译。两种语言同权(见 [README.md](README.md)):每次变更可以用任一语言撰写,被编辑的一侧即为本次更新的源;本文的规则约束如何产出或更新对侧文件。这些规则对人类和 agent(智能体)同等生效;应用这些规则的仓库内置 agent 工作流是 [.agents/skills/dsh-translate-docs](../../.agents/skills/dsh-translate-docs/SKILL.md)。规则级别沿用 RFC 2119 的用法:**必须(MUST)** / **禁止(MUST NOT)** 会卡门禁或评审;**应当(SHOULD)** 偏离时要说明理由;**可以(MAY)** 自行裁量。 ## 忠实性 -- 另一侧必须说撰写侧所说的话——不添加行为、前置条件、警告、版本声明或示例,也不丢弃任何一项。如果两侧在实质内容上不一致,没有哪种语言默认获胜:改正错的那一侧,并在同一个变更里把另一侧带上。 -- 另一侧应当读起来是其语言自然的技术文字,而不是逐词对照。翻译语义,在目标语言语法需要处重组句子,并保持原作者的语域——简练的保持简练。 -- 不要翻译不可译的东西:一句话如果依赖源语言的习语而无法自然转换,就翻译它的意思,而不是习语本身。 +- 对侧文件*必须*传达与撰写侧相同的内容:不添加行为、前置条件、警告、版本声明或示例,也不漏掉任何一项。如果两侧在实质内容上不一致,没有哪种语言默认获胜;请修正错误的一侧,并在同一个变更里同步更新另一侧。 +- 对侧文件读起来*应当*是其语言自然的技术文字,而非逐词对照的译文。请根据语义翻译,在目标语言语法需要时重组句子,并保持原作者的语域(比如:简练的保持简练)。 +- 不要翻译不可译的内容:如果一句话依赖源语言的习语、无法自然转换,请翻译它的意思,而非习语本身。 ## 行文 @@ -23,47 +23,47 @@ 形状由配对门禁强制,译者不需要用流畅度去换结构——在框架内自然行文即可。配对的两个文件必须在以下方面一一对应: -- 标题层级(相同级别、相同顺序——标题的**文字**要翻译), -- 列表形态与编号, -- 表格(相同的列、相同的行序;表头单元格按术语表翻译), -- 围栏代码块——**逐字节一致,包括注释**;代码属于受验证的范围(` ```ts ` 块要通过 `doc-typecheck` 编译),而被改动的注释是代码块计数门禁看不见的漂移, -- 行内代码(命令、flag、配置键、文件路径、事件名、API 名、版本号)——原样保留,从不翻译或重排, -- 链接与锚点:每个相对链接在两个文件中必须指向相同的目标——按约定是 `.md` 路径而非 `.zh.md` 兄弟文件——这样某对文档先于相邻文件落地时,链接也永不悬空。唯一的 zh 特有链接是语言切换行。链接**文字**翻译;链接目标不翻。 +- 标题层级(相同级别、相同顺序;标题的**文字**要翻译); +- 列表形态与编号; +- 表格(相同的列、相同的行序;表头单元格按术语表翻译); +- 围栏代码块:**逐字节一致,包括注释**。代码属于受验证的范围(` ```ts ` 块要通过 `doc-typecheck` 编译),而被改动的注释是代码块计数门禁看不见的漂移; +- 行内代码(命令、flag、配置键、文件路径、事件名、API 名、版本号):原样保留,从不翻译或重排; +- 链接与锚点:每个相对链接在两个文件中必须指向相同的目标(按约定是 `.md` 路径而非 `.zh.md` 兄弟文件),这样即使某对文档先于相邻文件落地,链接也不会悬空。唯一的 zh 特有链接是语言切换行。链接**文字**翻译;链接目标不翻。 本仓库的 Markdown 约定对 `.zh.md` 文件原样生效:一个段落一个物理行(`verify-md-wrap`)、相对链接必须可解析(`verify-md-links`)、文件末尾恰好一个换行。 ## 术语 -- [terminology.md](terminology.md) 是双向的术语真源。翻译前先加载它;翻译中,表内的每个术语都必须严格按表规定的译法呈现,包括首次出现的括注(如首现写 `agent(智能体)`,之后写 `agent`)与「不要译作」的禁项。中文先行撰写时,英文另一侧同样按表中英文列使用术语。 -- 表中**没有**的技术术语,只有当某个主要中文 OSS 或厂商文档已有成型译法时(K8s/Vue/MDN 中文文档、微软简中风格指南、大厂项目文档)才可以翻译。在 PR 中注明先例出处。 -- **没有**成型先例的术语,译文中必须保留英文,并且必须在 PR 描述的「待定术语」下列出、附上建议译法交评审者定夺。禁止就地发明中文译法——无先例的翻译恰恰制造了术语表要防止的歧义。定下来的术语随后在同一个 PR 或后续 PR 进入 [terminology.md](terminology.md)。 +- [terminology.md](terminology.md) 是双向的术语真源。翻译前请先加载它;翻译过程中,表内的每个术语都*必须*严格按表中规定的译法呈现,包括首次出现的括注(如首现写 `agent(智能体)`,之后写 `agent`)与「不要译作」的禁项。中文先行撰写时,英文对侧同样按表中英文列使用术语。 +- 表中**没有**的技术术语,只有当某个主要中文 OSS 或厂商文档已有成型译法时(K8s/Vue/MDN 中文文档、微软简中风格指南、大厂项目文档)才*可以*翻译。请在 PR 中注明先例出处。 +- **没有**成型先例的术语,译文中*必须*保留英文,并且*必须*在 PR 描述的「待定术语」下列出,附上建议译法交评审者定夺。*禁止*就地发明中文译法,因为无先例的翻译恰恰会制造术语表要防止的歧义。确定下来的术语随后在同一个 PR 或后续 PR 中进入 [terminology.md](terminology.md)。 ## 排版 -本节规则约束中文一侧;英文一侧遵循仓库常规的 Markdown 约定(根 `AGENTS.md`)。下面的中西文混排规则遵循 [MDN 简体中文翻译指南](https://github.com/mdn/translated-content/blob/main/docs/zh-cn/translation-guide.md)、[Kubernetes 中文本地化指南](https://kubernetes.io/zh-cn/docs/contribute/localization_zh/)、[Vue.js 中文翻译须知](https://github.com/vuejs-translations/docs-zh-cn/wiki/%E7%BF%BB%E8%AF%91%E9%A1%BB%E7%9F%A5)与[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines)的跨项目共识,其根据是 [W3C clreq](https://www.w3.org/TR/clreq/) 与 GB/T 15834—2011: +本节规则约束中文一侧;英文一侧遵循仓库常规的 Markdown 约定(根 `AGENTS.md`)。以下中西文混排规则遵循 [MDN 简体中文翻译指南](https://github.com/mdn/translated-content/blob/main/docs/zh-cn/translation-guide.md)、[Kubernetes 中文本地化指南](https://kubernetes.io/zh-cn/docs/contribute/localization_zh/)、[Vue.js 中文翻译须知](https://github.com/vuejs-translations/docs-zh-cn/wiki/%E7%BF%BB%E8%AF%91%E9%A1%BB%E7%9F%A5) 与[中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines)的跨项目共识,其根据是 [W3C clreq](https://www.w3.org/TR/clreq/) 与 GB/T 15834—2011: -- 必须在中文与拉丁词之间、中文与数字之间各留一个半角空格:`每个 plugin 注册 3 个 tool`。全角标点与任何字符之间不加空格。 -- 中文行文必须使用全角(中文)标点:`,。:;?!()「」`。半角标点保留在代码内、按原样引用的完整英文句子内、以及数字内(`3.5`、`1,024`)。 -- 并列顿开:中文的并列项之间用顿号(、),不用逗号。 -- 禁止使用全角数字或全角拉丁字母——永远不写 `123`,永远写 `123`。 -- 专有名词保持规范大小写:GitHub、TypeScript、DeepSeek——除非引用代码,否则绝不写 `github`/`Github`。 +- *必须*在中文与拉丁词之间、中文与数字之间各留一个半角空格:`每个 plugin 注册 3 个 tool`。全角标点与任何字符之间不加空格。 +- 中文行文*必须*使用全角(中文)标点:`,。:;?!()「」`。半角标点保留在代码内、按原样引用的完整英文句子内、以及数字内(`3.5`、`1,024`)。 +- 顿号:中文的并列项之间使用顿号(、),而非逗号。 +- *禁止*使用全角数字或全角拉丁字母:永远不写 `123`,永远写 `123`。 +- 专有名词保持规范大小写:GitHub、TypeScript、DeepSeek。除非引用代码,否则绝不写 `github`/`Github`。 - 第二人称用「你」,不用「您」(与 Vue、Kubernetes 中文约定及本仓库的直接语气一致)。 -- 强调标记(`**加粗**`、`*斜体*`)落在与另一侧相同的文字段上;中文没有斜体,渲染效果可能看不出差别——不要用引号或其他装饰替代。 +- 强调标记(`**加粗**`、`*斜体*`)落在与对侧相同的文字段上。中文没有斜体,渲染效果可能看不出差别,不要用引号或其他装饰替代。 -## 质量线 +## 质量标准 -- 一对文档的完成标准:一位双语工程师只读其中任一文件,得到与另一文件读者完全相同的信息——相同的事实、相同的告诫、相同的语气——并且没有任何多余的内容。 -- 交付前,对照本文自查一遍,并**只读另一侧**再通读一遍、不看源侧对照;没有源文锚着,别扭的表述更容易被听出来。 -- 机械契约(一致性记录、切换行、结构、折行、链接)由 `pnpm run verify-translation-pairing` 和 `doc-sync` 的其余门禁检查——跑门禁;门禁覆盖的不要手工核对。 +- 一对文档的完成标准:一位双语工程师只读其中任一文件,能获得与另一文件读者完全相同的信息(相同的事实、相同的告诫、相同的语气),并且没有任何多余的内容。 +- 交付前,请对照本文自查一遍,并**单独通读对侧文件**,不与源侧对照;不对照原文时,更容易察觉别扭的表达。 +- 机械契约(一致性记录、切换行、结构、折行、链接)由 `pnpm run verify-translation-pairing` 和 `doc-sync` 的其余门禁检查。请运行门禁;门禁已覆盖的内容无需手工核对。 ## 参考资料 本文各规则引用的权威出处,供想了解底层依据的人和 agent 查阅: -- [中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines)——中西文混排空格与标点的社区事实标准。 -- [MDN 简体中文翻译指南](https://github.com/mdn/translated-content/blob/main/docs/zh-cn/translation-guide.md)——与本文同形态的进仓翻译规则文件;空格、标点与术语表实践。 -- [Kubernetes 中文本地化指南](https://kubernetes.io/zh-cn/docs/contribute/localization_zh/)——最大的中文本地化团队的术语首现与标点实践。 -- [Vue.js docs-zh-cn 翻译须知](https://github.com/vuejs-translations/docs-zh-cn/wiki/%E7%BF%BB%E8%AF%91%E9%A1%BB%E7%9F%A5)——逐术语的译/留决策与语气。 -- [zh-style-guide](https://zh-style-guide.readthedocs.io)——社区中文技术文档写作规范,本文借用了它的规则级别分类体系(与 RFC 2119 关键词分级);它聚合了 GB/T 15834/15835、clreq 与各厂商指南。 -- [W3C clreq](https://www.w3.org/TR/clreq/) 与[微软简体中文风格指南](https://learn.microsoft.com/en-us/globalization/reference/microsoft-style-guides)——排版学与厂商本地化的正式基线。 -- GB/T 19682-2005《翻译服务译文质量要求》——国家标准;本文「忠实性」与「术语」两节把它的三项基本要求(忠实原文、术语统一、行文通顺)落成可操作规则。 +- [中文文案排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines):中西文混排空格与标点的社区事实标准。 +- [MDN 简体中文翻译指南](https://github.com/mdn/translated-content/blob/main/docs/zh-cn/translation-guide.md):与本文同形态的仓库内置翻译规则文件;空格、标点与术语表实践。 +- [Kubernetes 中文本地化指南](https://kubernetes.io/zh-cn/docs/contribute/localization_zh/):最大的中文本地化团队的术语首现与标点实践。 +- [Vue.js docs-zh-cn 翻译须知](https://github.com/vuejs-translations/docs-zh-cn/wiki/%E7%BF%BB%E8%AF%91%E9%A1%BB%E7%9F%A5):逐术语的译/留决策与语气。 +- [zh-style-guide](https://zh-style-guide.readthedocs.io):社区中文技术文档写作规范,本文借用了它的规则级别分类体系(与 RFC 2119 关键词分级);它聚合了 GB/T 15834/15835、clreq 与各厂商指南。 +- [W3C clreq](https://www.w3.org/TR/clreq/) 与[微软简体中文风格指南](https://learn.microsoft.com/en-us/globalization/reference/microsoft-style-guides):排版学与厂商本地化的正式基线。 +- GB/T 19682-2005《翻译服务译文质量要求》:国家标准;本文「忠实性」与「术语」两节将其三项基本要求(忠实原文、术语统一、行文通顺)落实为可操作的规则。 diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml index 1ef023ec50..f409941924 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write 2026-07-02-bilingual-docs-and-pairing-gate.md: 764ad5a9345c2a138b56e9cedb54848a5f7d6054 -2026-07-02-bilingual-docs-and-pairing-gate.zh.md: f039fbe3fa44cb379905bbea9a4692af19d71230 +2026-07-02-bilingual-docs-and-pairing-gate.zh.md: c752d76f12f556ce190bf80c4f3a531c0821be8e diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md index f039fbe3fa..c752d76f12 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.zh.md @@ -1,36 +1,38 @@ -# 通过配对兄弟文件与配对门禁实现双语文档 +# RFC:通过配对兄弟文件与配对门禁实现双语文档 + +Status: implemented [English](2026-07-02-bilingual-docs-and-pairing-gate.md) | 中文 -## 背景 +## 问题 -本仓库的 README 与 docs 目录树会被公司内外的人和 agent(智能体)以中英两种语言阅读。没有机制、纯靠手工维护第二语言,正是译文腐烂的方式:一侧继续演进,另一侧默默地说谎,而没有门禁会注意到。对这类不变式,本仓库一贯的答案是把它编码成机械检查(见[质量门禁](2026-06-11-quality-gates.md)与 [doc-sync 强制](2026-06-11-doc-sync-enforcement.md)),因此双语政策随附一道门禁一起交付。 +本仓库的 README 与 docs 目录树会被公司内外的人和 agent(智能体)以中英两种语言阅读。在没有机制的情况下纯靠手工维护第二语言,正是译文腐烂的根源:一侧持续演进,另一侧默默失实,而没有门禁会注意到。对于这类不变式,本仓库一贯的做法是将其编码为机械检查(见[质量门禁](2026-06-11-quality-gates.md)与 [doc-sync 强制](2026-06-11-doc-sync-enforcement.md)),因此双语政策随附一道门禁一起交付。 ## 决策 -- **配对兄弟文件,两种语言同权。**一对文档是三个兄弟文件:英文 `foo.md`、中文 `foo.zh.md`,加一份一致性记录 `foo.i18n.yaml`。没有哪种语言是正典——一篇文档可以先用中文撰写和评审、之后再译成英文,反之亦可;约束这对文件的是两侧必须说同样的话,且配对整体合入(两种语言加记录,绝不单独落一侧)。政策见 [docs/i18n/README.md](../../../i18n/README.md);翻译规则见 [docs/i18n/translation-rules.md](../../../i18n/translation-rules.md);术语真源见 [docs/i18n/terminology.md](../../../i18n/terminology.md)。 -- **旁挂记录两侧 blob hash,使一致性可检查。**`foo.i18n.yaml` 保存两侧文件在上一次确认一致状态下各自的完整 git blob hash。此后改了任一侧而没重新确认配对,都能被机械检测出来——纯内容比较、无需查询历史——而且同一个 PR 里改动的文件也能算出 hash,commit hash 式的记录做不到这一点。重新记录(`verify-translation-pairing --write`)产生一份可评审的 yaml diff:确认一致在 PR 里是一个显式、可见的动作。 -- **`verify-translation-pairing` 加入 `doc-sync`。**门禁([scripts/verify-translation-pairing.ts](../../../../scripts/verify-translation-pairing.ts))强制执行:required 的配对存在;任何已存在的配对完整(三个文件齐全)且一致(两个 hash 都匹配、切换行双向互链、结构签名一致);被排除的文件(生成物或本身即双语的)保持不配对。[scripts/translation-pairing.manifest.json](../../../../scripts/translation-pairing.manifest.json) 中的 `required` 清单是一个棘轮:每个合入的翻译批次把自己的文件加进去,覆盖面只增不减。 -- **翻译是 agent 的工作,由人评审。**进仓的工作流是 [.agents/skills/dsh-translate-docs](../../../../.agents/skills/dsh-translate-docs/SKILL.md),与 [dsh-code-review](../../../../.agents/skills/dsh-code-review/SKILL.md) 同一模式:skill 承载工作流,并把真源让给文档。 +- **配对兄弟文件,两种语言同权。** 一对文档由三个兄弟文件组成:英文 `foo.md`、中文 `foo.zh.md`,以及一份一致性记录 `foo.i18n.yaml`。没有哪种语言是正典:一篇文档可以先用中文撰写和评审、之后再译成英文,反之亦可;约束配对的是:两侧必须表达相同的内容,且配对整体合并(两种语言加记录,绝不单独落一侧)。政策见 [docs/i18n/README.md](../../../i18n/README.md);翻译规则见 [docs/i18n/translation-rules.md](../../../i18n/translation-rules.md);术语真源见 [docs/i18n/terminology.md](../../../i18n/terminology.md)。 +- **伴随记录保存两侧 blob hash,使一致性可检查。** `foo.i18n.yaml` 保存两侧文件在上一次确认一致时各自的完整 git blob hash。此后修改了任一侧而未重新确认配对,都能被机械检测出来(纯内容比较,无需查询历史),而且同一个 PR 内改动的文件也能计算出 hash,commit hash 式的记录做不到这一点。重新记录(`verify-translation-pairing --write`)会产生一份可评审的 yaml diff:确认一致在 PR 中是一个显式、可见的动作。 +- **`verify-translation-pairing` 加入 `doc-sync`。** 门禁([scripts/verify-translation-pairing.ts](../../../../scripts/verify-translation-pairing.ts))强制执行以下规则:required 的配对必须存在;任何已存在的配对必须完整(三个文件齐全)且一致(两个 hash 匹配、切换行双向互链、结构签名一致);被排除的文件(生成物或本身即双语的)保持不配对。[scripts/translation-pairing.manifest.json](../../../../scripts/translation-pairing.manifest.json) 中的 `required` 清单只进不退:每个合并的翻译批次将自己的文件加入其中,覆盖面只增不减。 +- **翻译是 agent 的工作,由人评审。** 仓库内置的工作流是 [.agents/skills/dsh-translate-docs](../../../../.agents/skills/dsh-translate-docs/SKILL.md),与 [dsh-code-review](../../../../.agents/skills/dsh-code-review/SKILL.md) 模式相同:skill 承载工作流,并将文档作为真源。 ## 曾考虑的替代方案 -- **英文为正典源、指纹放在译文内**——本 RFC 最初提出的设计:`.zh.md` 文件携带一条 HTML 注释记录英文源的 blob hash,翻译只沿 EN → ZH 单向流动。评审中修订:团队需要中文先行的撰写方式(先写、先审中文 RFC,再译英文),两种语言同权,而单向正典模型无法表达这一点。覆盖**两侧**的旁挂记录取代了文件内的单向指纹;blob hash 的机制原样保留。 -- **语言目录(`docs/en/` + `docs/zh/`,Kubernetes/ECharts 模式)**——否决:本仓库没有把 locale 映射到路由的文档站框架,挪动每个英文文件会搅动所有既有交叉引用,且 `verify-md-links`/`verify-doc-refs` 将需要路径映射逻辑而不是原样工作。 -- **独立翻译仓库(PingCAP `docs`/`docs-cn` 模式)**——否决:适合有独立发布节奏的文档产品,对 monorepo 自己的文档而言过重;还会把译文置于本仓库门禁够不到的地方。 -- **中英混排单文件(一个文件、两种语言)**——否决:每个 diff 都翻倍,破坏一段一行约定的 diff 工效,且局部不一致不可见。 -- **Commit hash 式记录(MDN `l10n.sourceCommit` 模式)**——否决,改用 blob hash:同一个 PR 内的改动还没有 commit hash,MDN 模式无法表达「与本 PR 引入的状态一致」,且校验它需要 git 历史而非文件内容。 -- **比较配对两侧的 git 时间戳(无记录)**——否决:纯格式化的改动会误报,一次无关改动之后提交的另一侧会漏报;只有内容同一性这个信号与门禁的承诺名实相符。 +- **英文为正典源、指纹放在译文内**:本 RFC 最初提出的设计:`.zh.md` 文件携带一条 HTML 注释记录英文源的 blob hash,翻译只沿 EN → ZH 单向流动。评审中修订:团队需要中文先行的撰写方式(先写、先审中文 RFC,再译英文),两种语言同权,而单向正典模型无法表达这一点。覆盖**两侧**的伴随记录取代了文件内的单向指纹;blob hash 的机制本身保持不变。 +- **语言目录(`docs/en/` + `docs/zh/`,Kubernetes/ECharts 模式)**:否决。本仓库没有将 locale 映射到路由的文档站框架;如果移动所有英文文件,所有既有交叉引用都要随之修改;且 `verify-md-links`/`verify-doc-refs` 将需要路径映射逻辑,而非原样工作。 +- **独立翻译仓库(PingCAP `docs`/`docs-cn` 模式)**:否决。适合有独立发布节奏的文档产品,对 monorepo 自身的文档而言过重;还会把译文置于本仓库门禁触及不到的地方。 +- **中英混排单文件(一个文件、两种语言)**:否决。每个 diff 都翻倍,破坏一段一行约定的 diff 易读性,且局部不一致不可见。 +- **Commit hash 式记录(MDN `l10n.sourceCommit` 模式)**:否决,改用 blob hash。同一个 PR 内的改动还没有 commit hash,MDN 模式无法表达「与本 PR 引入的状态一致」,且校验它需要 git 历史而非文件内容。 +- **比较配对两侧的 git 时间戳(无记录)**:否决。纯格式化的改动会误报,一次无关改动之后提交的对侧文件会漏报;只有内容同一性这个信号才与门禁的承诺名实相符。 ## 业界先例 -带语言后缀的配对兄弟文件是中国大厂的主流约定(ant-design 的 `index.zh-CN.md`/`index.en-US.md`;arco-design 的 `README.zh-CN.md` 加顶部切换行;Apache ShardingSphere 的 387 对 `.cn.md`/`.en.md`)——但这些仓库都没有在 CI 里**强制**配对或一致性;约定纯靠评审维系。一致性自动化存在于中国之外:MDN 的 `l10n.sourceCommit` front-matter 指纹、Vue 的 Ryu-Cho action(监视上游 commit、为陈旧译文自动开 issue/PR)、Kubernetes 的本地化漂移脚本、微软 Azure co-op-translator(CI 中由源 hash 驱动的 LLM 重译)。本设计把两者结合:中文生态的文件布局,加 hash 对门禁,再加一个进仓 agent skill(技能)替代 bot 服务。 +带语言后缀的配对兄弟文件是中国大厂的主流约定(ant-design 的 `index.zh-CN.md`/`index.en-US.md`;arco-design 的 `README.zh-CN.md` 加顶部切换行;Apache ShardingSphere 的 387 对 `.cn.md`/`.en.md`),但这些仓库都没有在 CI 中**强制**配对或一致性检查;约定纯靠评审维系。一致性自动化存在于中国以外:MDN 的 `l10n.sourceCommit` front-matter 指纹、Vue 的 Ryu-Cho action(监视上游 commit,为陈旧译文自动开 issue/PR)、Kubernetes 的本地化漂移脚本、微软 Azure co-op-translator(CI 中由源 hash 驱动的 LLM 重译)。本设计将两者结合:中文生态的文件布局,加上 hash 配对门禁,再加一个仓库内置的 agent skill 替代 bot 服务。 ## 后果 -- 修改已配对文档的任一侧,同一个 PR 就有义务更新另一侧并重新记录配对——门禁把 doc-sync 规则双语化,不变式由 CI(而非评审者的记忆)承载。 -- 每个配对给目录树多添一个文件。记录由机器写入(`--write`),代价是目录噪音而非维护负担;换来的是「谁在何时确认过这对一致」可以从 yaml 的 git blame 直接回答。 -- 两侧说法冲突时,没有机械规则裁决谁赢——由 PR 评审裁决。这是同权的代价,是有意接受的:另一个选项(正典语言)禁止中文先行撰写。 -- 生成文档(`cordis-catalog/`、`tool-catalog/`、`module-graph.md`)暂被排除;计划中的后续工作是让它们的生成器在输出英文的同时输出中文,届时移出排除清单。 -- 推进天然是渐进的:`required` 之外的文档是可见的 backlog(`--list`),不是红的 CI,因此配对按可评审的批次落地,无需一个巨型 PR。新文档是例外——文件名日期在 manifest `requiredSince` 当天或之后的文档,要么连同配对一起合入,要么不合入,因此 backlog 只会缩小。 -- 记录的 hash 兼作更新工具(`git cat-file -p ` 能还原任一侧上次确认的文本,用于基于 diff 的最小更新),所以这套机制从不强迫整篇重译。 +- 修改已配对文档的任一侧,同一个 PR 就有义务更新对侧并重新记录配对。门禁将 doc-sync 规则双语化,不变式由 CI(而非评审者的记忆)承载。 +- 每个配对给目录树多添一个文件。记录由机器写入(`--write`),代价是目录噪音而非维护负担;换来的是「谁在何时确认过这对文档一致」可以从 yaml 的 git blame 直接回答。 +- 两侧说法冲突时,没有机械规则裁决谁赢,由 PR 评审裁决。这是同权的代价,且是有意接受的:另一个选项(正典语言)会禁止中文先行撰写。 +- 生成文档(`cordis-catalog/`、`tool-catalog/`、`module-graph.md`)暂被排除;计划中的后续工作是让生成器在输出英文的同时输出中文,届时将这些文件移出排除清单。 +- 推进天然是渐进的:`required` 之外的文档是可见的 backlog(`--list`),而非红色的 CI;因此配对按可评审的批次落地,无需一个巨型 PR。 +- 记录的 hash 兼作更新工具(`git cat-file -p ` 能还原任一侧上次确认的文本,用于基于 diff 的最小更新),因此这套机制从不强迫整篇重译。 From 1583cb47a088834fd5a698665cde24773575bc4c Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 21:14:47 -0700 Subject: [PATCH 13/17] docs(i18n): reconcile gold pairs with master's EN-side drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 金标译文写于 0710 的 master,英文侧此后有漂移,按最小更新补齐: development.zh 的 Node 引擎下限句、CI 门禁节改写为八任务车道描述、 代码块与英文侧逐字节同步;README.zh 恢复 graph-atlas 链接; style-samples 的目录链接随 events-and-services.md 拆分改指 events.md。 requiredSince 推至 2026-07-14:0705–0713 间已合入的两篇无配对 RFC 成为存量(原分界在其合入时未生效,回溯会红在与本 PR 无关的文件上)。 --- README.i18n.yaml | 2 +- README.zh.md | 2 +- docs/development.i18n.yaml | 2 +- docs/development.zh.md | 22 +++++-------------- docs/i18n/style-samples.md | 4 ++-- ...-bilingual-docs-and-pairing-gate.i18n.yaml | 4 ++-- scripts/translation-pairing.manifest.json | 2 +- 7 files changed, 13 insertions(+), 25 deletions(-) diff --git a/README.i18n.yaml b/README.i18n.yaml index db27519f15..37a95ccdac 100644 --- a/README.i18n.yaml +++ b/README.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write README.md: 53dd3896eb15800125673e7c44f7de02daca9376 -README.zh.md: 5de4c5b6804648f061647d9e315c08a32b42b39b +README.zh.md: 2119dabf0ae2d2e16e274e44fda7cbbaec146dc9 diff --git a/README.zh.md b/README.zh.md index ad568c808d..2119dabf0a 100644 --- a/README.zh.md +++ b/README.zh.md @@ -15,6 +15,6 @@ pnpm run demo:repl # REPL agent demo (needs DEEPSEEK_API_KEY) pnpm run demo:acp # ACP server agent demo (needs DEEPSEEK_API_KEY) ``` -面向开发者:先读[开发指南](docs/development.md),了解本地环境搭建、钩子、环境变量与质量门禁,动手改 package 之前再读[架构设计](docs/architecture.md)。局部上下文见 [packages/](packages/) 与 [vendor/](vendor/)。 +面向开发者:先读[开发指南](docs/development.md),了解本地环境搭建、钩子、环境变量与质量门禁,动手改 package 之前再读[架构设计](docs/architecture.md)和[文档关系图索引](docs/graph-atlas.md)。局部上下文见 [packages/](packages/) 与 [vendor/](vendor/)。 面向 agent:遵循 [AGENTS.md](AGENTS.md)。 diff --git a/docs/development.i18n.yaml b/docs/development.i18n.yaml index c1e557170d..face2eeeaa 100644 --- a/docs/development.i18n.yaml +++ b/docs/development.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write development.md: bd6f6b561480419abea7a42a44b4078e2c59b1cb -development.zh.md: 54bf19765d2b4dc419e6b71684dbcfcd28230541 +development.zh.md: 61b75b8128ac40b4483debff8aeaeabcfe98752f diff --git a/docs/development.zh.md b/docs/development.zh.md index 91b63d7511..61b75b8128 100644 --- a/docs/development.zh.md +++ b/docs/development.zh.md @@ -6,7 +6,7 @@ ## 前置条件 -- Node.js 24 或更新版本。仓库声明 `node >=24`;CI 在 Node 24 和 26 上运行矩阵测试。 +- Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 [Node 引擎下限 RFC](rfc/implemented/process/2026-07-06-node-engine-floor.md)。 - 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`。 - Git。 - 可选:一个 DeepSeek API key,用于 REPL/ACP agent 演示和真实 API 的 e2e 测试。 @@ -63,26 +63,13 @@ lefthook 在 `lefthook.yml` 中配置,作为评审前的本地早期检查点 vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md`。 -这些钩子并不与 CI 完全一致。特别是:`pre-push` 运行不带覆盖率的单元测试,而 CI 运行 `pnpm run test:coverage`;CI 还会运行 echo-agent 和 built-bin 冒烟测试,并在 Node 24 和 26 上运行矩阵。 +这些钩子并不与 CI 完全一致。特别是:`pre-push` 运行不带覆盖率的单元测试,而 CI 运行 `pnpm run test:coverage`;CI 还会运行 echo-agent 和 built-bin 冒烟测试,并在 Node 22.19、24 和 26 上执行兼容性矩阵。 ## CI 门禁 -GitHub 工作流在每个 Pull Request 上运行以下门禁: +无密钥 GitHub 工作流共有八个任务:五条 Node 24 车道分别运行静态门禁、lint、覆盖率、快照回放与产物门禁;三个兼容性任务在 Node 22.19、24 和 26 上运行 `pnpm run check:node-compat`。车道调度器从 `package.json` 展开相互独立的门禁:constraints、typecheck、lint、覆盖率、快照回放、`doc-sync` 各成员、module-graph 新鲜度、`knip`,以及 echo-agent 冒烟测试。 -- `pnpm install --frozen-lockfile` -- `pnpm run constraints` -- `pnpm run typecheck` -- `pnpm run lint` -- `pnpm run doc-sync` -- `pnpm run verify-module-graph` -- `pnpm run test:coverage` -- `pnpm run test:snapshot` -- `pnpm run build` -- `pnpm run hygiene` -- 一个 echo-agent 冒烟测试,检查演示的工具调用、工具结果和 JSONL 输出 -- built-bin 冒烟测试,用纯 `node` 运行发布产物 `lib/bin.js` 入口 - -`pnpm run hygiene` 是 `pnpm run knip && pnpm run publint && pnpm run constraints && pnpm run verify-node-next-types` 的本地简写;CI 还会将 `pnpm run constraints` 作为更早的快速失败步骤单独运行一次,然后在 `pnpm run build` 之后运行完整的 hygiene 脚本。 +`pnpm run build` 供给产物车道;`publint`、`verify-node-next-types` 与 built-bin 冒烟测试等待构建产出。独立的真实 API 工作流使用密钥运行 `pnpm run test:e2e`,并设置 `DSH_E2E_MAX_WORKERS=14`。 ## 日常命令 @@ -98,6 +85,7 @@ pnpm run lint:fix # eslint . --fix pnpm run doc-typecheck # compile checked TypeScript snippets in Markdown docs pnpm run gen-cordis-catalog # regenerate docs/cordis-catalog/events.md + services.md from source pnpm run verify-cordis-catalog # fail if either cordis catalog is stale +pnpm run verify-export-jsdoc # fail if a module-level package export lacks complete JSDoc pnpm run gen-doc-graphs # regenerate generated relationship docs from source and curated graph definitions pnpm run verify-doc-graphs # fail if generated relationship docs are stale pnpm run gen-rfc-index # regenerate the docs/rfc/README.md index tables from the RFC tree diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index 6376b3964f..174a5612ff 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -14,9 +14,9 @@ 依赖约束规范:各类扩展插件仅依赖抽象接口,严禁直接依赖 `dsh-agent-loop`(该主循环支持替换实现);唯一允许的特例是组合包 `dsh-agent-core`,它的职责是组装整套实体主干。 -> This document covers **behavior**; type shapes live in [core-data-structures/](../core-data-structures/core.md), the per-event/service reference in the [generated catalog](../cordis-catalog/events-and-services.md), per-package contracts in the package READMEs ([map](../../packages/README.md)). +> This document covers **behavior**; type shapes live in [core-data-structures/](../core-data-structures/core.md), the per-event/service reference in the [generated catalog](../cordis-catalog/events.md), per-package contracts in the package READMEs ([map](../../packages/README.md)). -本文档描述整体行为逻辑;类型定义存放于 [core-data-structures/](../core-data-structures/core.md);各类事件、服务的详细参考见[生成目录](../cordis-catalog/events-and-services.md);各 package 对外约束协议写在对应包的 README([索引](../../packages/README.md))。 +本文档描述整体行为逻辑;类型定义存放于 [core-data-structures/](../core-data-structures/core.md);各类事件、服务的详细参考见[生成目录](../cordis-catalog/events.md);各 package 对外约束协议写在对应包的 README([索引](../../packages/README.md))。 ## ② 防御模式规则 diff --git a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml index ecbd6f196b..f20250c3ba 100644 --- a/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml +++ b/docs/rfc/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -2026-07-02-bilingual-docs-and-pairing-gate.md: 8731fef46b16cfa20d223575c70774cff780a6aa -2026-07-02-bilingual-docs-and-pairing-gate.zh.md: ce2589498ab16cf5ca2f5cdb3f58d031aeb8298f +2026-07-02-bilingual-docs-and-pairing-gate.md: 1e96622e7fb5694ab61772d68744394ef1aeb53a +2026-07-02-bilingual-docs-and-pairing-gate.zh.md: c752d76f12f556ce190bf80c4f3a531c0821be8e diff --git a/scripts/translation-pairing.manifest.json b/scripts/translation-pairing.manifest.json index 891aae375b..f45659ea4b 100644 --- a/scripts/translation-pairing.manifest.json +++ b/scripts/translation-pairing.manifest.json @@ -1,5 +1,5 @@ { - "requiredSince": "2026-07-05", + "requiredSince": "2026-07-14", "required": [ "README.md", "docs/development.md", From 8befd9b88c295381a86c260e2efc11577fce2965 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 22:45:26 -0700 Subject: [PATCH 14/17] =?UTF-8?q?docs(i18n):=20harden=20the=20pipeline=20p?= =?UTF-8?q?rompt=20=E2=80=94=20switcher=20flip,=20code-comment=20hard=20ru?= =?UTF-8?q?le,=20em-dash=20preference,=20three=20new=20few-shots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/i18n/translation-prompt.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/i18n/translation-prompt.md b/docs/i18n/translation-prompt.md index db707730fa..2082d83da5 100644 --- a/docs/i18n/translation-prompt.md +++ b/docs/i18n/translation-prompt.md @@ -37,9 +37,10 @@ You are a senior technical translator specializing in LLM and agent development ### Structure and Format Preservation - Output a complete translated document that maintains exactly the same structure as the source: heading hierarchy, list shape, table columns, link targets, and code blocks. -- Fenced code blocks must be byte-identical to the source, including comments. Do not translate any content inside code fences. +- Fenced code blocks must be byte-identical to the source, including ALL comments inside them. Do NOT translate comments inside code blocks. This is a hard rule with no exceptions. - Inline code spans (commands, flags, paths, API names, version numbers) must be kept verbatim. Never translate or reformat them. - Every relative link must point to the same target as in the source. Link text is translated; link targets are not. +- Language switcher line: when translating into Chinese, write `[English](source-filename.md) | 中文`. When translating into English, write `English | [中文](source-filename.zh.md)`. Do NOT copy the switcher line from the source file unchanged — you must flip the link direction. - After a closing bold marker `**`, always insert a space before the next character. ### Tone and Style @@ -65,7 +66,7 @@ You are a senior technical translator specializing in LLM and agent development #### When translating into Chinese - Use full-width Chinese punctuation in prose: `,。:;?!()「」`. -- Replace em-dashes (——) with colons, periods, commas, or parentheses as appropriate. Only keep em-dashes when they are truly the best choice. +- Strongly prefer replacing all em-dashes (——) with colons, periods, commas, or parentheses. Keep an em-dash only if no other punctuation works at all. - Use enumeration commas (、) between parallel items, not regular commas. - List item endings: use semicolons or no punctuation. Do not end list items with commas. - Put one half-width space between Chinese text and Latin words/numbers. @@ -113,6 +114,8 @@ After writing ``, re-read it in the target language only, without l **Structure** - Is the heading hierarchy, list shape, and code block content identical to the source? +- Are ALL comments inside code blocks left untranslated (byte-identical to source)? +- Is the language switcher line correctly flipped (not copied from source)? - Are link targets preserved and bold markers followed by a space? **Tone & Style** @@ -184,6 +187,21 @@ Below are representative examples of common problems and their corrections. Foll - Bad: `进仓的 agent 工作流见 .agents/skills/dsh-translate-docs` - Good: `仓库内置的 agent 工作流见 .agents/skills/dsh-translate-docs` +### "For humans" — translate the intent, not the word +- Source: `For humans, start with the development guide` +- Bad: `对于人工读者,请先从开发指南开始`("人工读者"生硬) +- Good: `面向开发者:请先阅读开发指南`("开发者"自然,且中文里冒号在此处更自然) + +### Code block comments — NEVER translate +- Source code block contains: `# REPL agent demo (needs DEEPSEEK_API_KEY)` +- Bad: `# REPL agent 演示(需要 DEEPSEEK_API_KEY)` +- Good: `# REPL agent demo (needs DEEPSEEK_API_KEY)` (keep exactly as-is, byte-for-byte) + +### Language switcher — flip direction +- Source file (English) has: `English | [中文](README.zh.md)` +- Bad (copying source unchanged): `English | [中文](README.zh.md)` +- Good (flipped for Chinese file): `[English](README.md) | 中文` + --- Now translate the following document: From 8a53f3d6f9e74652ebeafd17061e6fdcc0252ed0 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:10:43 -0700 Subject: [PATCH 15/17] =?UTF-8?q?docs(i18n):=20address=20PR=20#172=20revie?= =?UTF-8?q?w=20=E2=80=94=20terminology=20rulings=20and=20register=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按 #172 评审意见整改(修复落在本 stack 上层,随 stack 合入): enforcement frontier 裁定为「执行红线」(与金标样例⑦一致), 「强制边界」入不要译作列,消除 translation-rules 与术语表的矛盾; orphan 裁定为「遗留」(崔),孤立/孤儿均入禁项,orphan branch 仍 沿用 git 官方「孤立分支」;README.zh 推进段与 translation-rules.zh 的门禁句按金标语体重写(崔);style-samples ⑥ 的「文件内容完全一 致」改为准确描述 blob hash 与伴随记录的比对机制(bot)。 --- docs/i18n/README.i18n.yaml | 2 +- docs/i18n/README.zh.md | 2 +- docs/i18n/style-samples.md | 2 +- docs/i18n/terminology.md | 4 ++-- docs/i18n/translation-rules.i18n.yaml | 2 +- docs/i18n/translation-rules.zh.md | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 3c954439ce..f058b57082 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write README.md: 94c8ad9e3a83b490a854dce69b27bd7e13d834b5 -README.zh.md: 4c66da76feff1b1a6c175da62cbd986838b3577e +README.zh.md: 5ed960a4dbf48d3f9b2f681298fd4d7487ca3eaf diff --git a/docs/i18n/README.zh.md b/docs/i18n/README.zh.md index 4c66da76fe..5ed960a4db 100644 --- a/docs/i18n/README.zh.md +++ b/docs/i18n/README.zh.md @@ -44,7 +44,7 @@ - `docs/i18n/terminology.md` 与 [style-samples.md](style-samples.md)——二者本身即为中英对照文档。 - [translation-prompt.md](translation-prompt.md)——自动翻译流水线的 prompt 模板;正文逐字进入模型请求,配对翻译会改变流水线行为。 -**推进**:新文档不等批次——文件名带日期的文档(`yyyy-mm-dd-*.md`,即 RFC)日期在 manifest 的 `requiredSince` 当天或之后,就必须连同配对一起合入,新增的一切生来即是双语。日期早于 cutoff 的文件按定义属于被豁免的存量——包括 cutoff 前夜创建的文件——而文件名日期按 RFC 惯例即首次提出日期,倒填日期绕过 cutoff 是评审可见的违规,不是漏洞。对于存量文档,manifest 中的 `required` 列表是强制边界,不是目标。目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、cookbook、RFC、postmortem……);每个批次合入后把其文件加进 `required`,门禁只进不退。尚未进入 `required` 的文档是 backlog——在 `--list` 中可见——但任何已存在的配对无论在不在清单里都按完整契约检查。给一篇文档配对是一份承诺:此后对任一侧的每次修改都必须带上另一侧,所以边界的扩张要跟上翻译评审的实际投入节奏,不要抢在前面。 +**推进**:新增文档不再等待批量翻译。以日期命名的文档(`yyyy-mm-dd-*.md`,即 RFC),只要标注日期等于或晚于 manifest 里的 `requiredSince` 分界日期,合入时就必须配齐双语配对——所有新文档从创建起就要求双语齐备。日期早于分界的文件按定义属于豁免的存量(包括分界前夜创建的文件);文件名日期按 RFC 惯例即首次提出日期,倒填日期绕过分界属于评审可见的违规,构不成漏洞。对于存量文档,manifest 中的 `required` 列表只是当下的执行红线,并非最终目标;目标是范围内的全量双语覆盖。配对按可评审的批次落地(核心入口文档、实操手册(cookbook)、RFC、事故复盘(postmortem)等);每个批次合入后把对应文件加进 `required`,门禁只向前收紧、不倒退放宽。尚未进入 `required` 的文档是待翻清单(backlog),可通过 `--list` 查看;但任何已存在的配对,无论是否在清单内,都按完整契约检查。为一篇文档建立配对等同于一份长期承诺:此后修改任一侧,都必须同步更新另一侧。因此执行红线的推进节奏要匹配翻译评审的实际投入,切勿超前铺开。 ## 分工 diff --git a/docs/i18n/style-samples.md b/docs/i18n/style-samples.md index 174a5612ff..e97cc331a9 100644 --- a/docs/i18n/style-samples.md +++ b/docs/i18n/style-samples.md @@ -66,7 +66,7 @@ > Comparing git timestamps of the pair (no record) — rejected: formatting-only edits would false-positive, and a counterpart committed after an unrelated edit would false-negative; content identity is the only signal that means what the gate claims. -对比双语文件的 git 时间戳(无哈希记录方案)——不予采纳:仅调整格式的改动会触发误报,无关修改后再提交译文又会造成漏检。只有文件内容完全一致,才能作为门禁可信的校验依据。 +对比双语文件的 git 时间戳(无记录方案)——不予采纳:仅调整格式的改动会触发误报,无关修改后再提交译文又会造成漏检。只有基于内容本身的标识(每侧文件的 blob hash 与伴随记录比对),才能承载门禁所声称的语义。 ## ⑦ 推进策略(长段拆分示范) diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index ae6f24acdb..1da19d30a8 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -90,7 +90,7 @@ | coverage | 覆盖率 | | | | | crash recovery | 崩溃恢复 | | | | | durability | 持久性 | | | | -| enforcement frontier | 强制边界 | | | i18n 配对机制用语:manifest `required` 清单所划的门禁生效范围 | +| enforcement frontier | 执行红线 | | 强制边界 | i18n 配对机制用语:manifest `required` 清单所划的门禁生效范围;与金标样例(style-samples ⑦)一致 | | event | 事件 | | | | | event log | 事件日志 | | | | | event stream | 事件流 | | | | @@ -118,7 +118,7 @@ | mod | 模组 | | | | | model provider | 模型提供方 | | | | | module | 模块 | | | | -| orphan | 孤立 | | 孤儿 | 指英文源已不存在的 `.zh.md` | +| orphan | 遗留 | | 孤儿、孤立 | 指英文源已不存在的 `.zh.md`(如「遗留译文」);进程语境按 OS 惯用语译「孤儿进程」 | | orphan branch | 孤立分支 | | 孤儿分支 | 沿用 git 官方中文翻译 | | pairing | 配对 | | | | | permission | 权限 | | | | diff --git a/docs/i18n/translation-rules.i18n.yaml b/docs/i18n/translation-rules.i18n.yaml index d340ff42b8..048ce5eef7 100644 --- a/docs/i18n/translation-rules.i18n.yaml +++ b/docs/i18n/translation-rules.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write translation-rules.md: 3e99aa5432ccd904f702238e9b802a9ed9bf6832 -translation-rules.zh.md: 0ff2ab43d59c6e0dd07e20e2f1a0a1c28c2f245c +translation-rules.zh.md: 1d8dcb04f1015af2db46c2e25b44f5cd147b6ecc diff --git a/docs/i18n/translation-rules.zh.md b/docs/i18n/translation-rules.zh.md index 0ff2ab43d5..1d8dcb04f1 100644 --- a/docs/i18n/translation-rules.zh.md +++ b/docs/i18n/translation-rules.zh.md @@ -21,7 +21,7 @@ ## 结构保持 -形状由配对门禁强制,译者不需要用流畅度去换结构——在框架内自然行文即可。配对的两个文件必须在以下方面一一对应: +结构一致性由配对门禁负责校验,译者无需为保持结构而牺牲行文的流畅:在既定框架内自然书写即可。配对的两个文件必须在以下方面一一对应: - 标题层级(相同级别、相同顺序;标题的**文字**要翻译); - 列表形态与编号; From 7756ed086937e81e5fb9b9465b5f20c1b8b3be0e Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:34:30 -0700 Subject: [PATCH 16/17] docs(i18n): re-record README pair after master merge --- docs/i18n/README.i18n.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 2c81577523..6764f01a21 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: 81e958c8ae9552222f27b0f9674d4fa0ff2a481c -README.zh.md: 3764a9ade69f3ad99e36ccccbaed1d19d8bbb1f0 +README.md: 30b9e53383ef591898505375662ec94d732de304 +README.zh.md: eac836e7c310945ec345db9974be9f1deaae4c60 From 1d288f1bca81fcda2b2445db585af48a9424a973 Mon Sep 17 00:00:00 2001 From: Ziya <199893125+ZiyaZhang@users.noreply.github.com> Date: Mon, 13 Jul 2026 20:37:21 -0700 Subject: [PATCH 17/17] =?UTF-8?q?docs(i18n):=20address=20ds-review-bot=20r?= =?UTF-8?q?ound-2=20=E2=80=94=20switcher=20placeholders,=20regex=20anchor,?= =?UTF-8?q?=20contract=20completeness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 {{source_filename}}/{{source_filename_zh}} 占位符:切换行指令 可执行化,新配对(源文件尚无切换行)也必须生成(critical)。加粗 后空格规则限定于拉丁字母/数字,不再与全角标点规则冲突。日期匹配 锚定 basename 开头,release-notes-2026-* 类文件不再误判。金标 development.zh 补回 RFC 指引句与 agent 首现括注、pre-push 描述改 为 check:pre-push 调度器实况。术语表补回单文件可执行 RFC 配对在用 的 5 行(VFS/deploy root/peer dependency/serving surface/wheel)。 双语 README 的门禁清单补第 4 条(日期分界强制配对)。 --- docs/development.i18n.yaml | 2 +- docs/development.zh.md | 6 +++--- docs/i18n/README.i18n.yaml | 2 +- docs/i18n/README.md | 1 + docs/i18n/terminology.md | 5 +++++ docs/i18n/translation-prompt.md | 6 ++++-- scripts/verify-translation-pairing.ts | 2 +- 7 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/development.i18n.yaml b/docs/development.i18n.yaml index 1702dcf2a9..1959a44b4d 100644 --- a/docs/development.i18n.yaml +++ b/docs/development.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write development.md: ea5f2e5d08acbaf1dfce4661530218dbf1a051b9 -development.zh.md: d7263d63ce2d3b851d38e633641c0324c9fb0460 +development.zh.md: 9c0cc23373b0f4feba8538fcbd25b38a483e0ba0 diff --git a/docs/development.zh.md b/docs/development.zh.md index d7263d63ce..9c0cc23373 100644 --- a/docs/development.zh.md +++ b/docs/development.zh.md @@ -2,14 +2,14 @@ [English](development.md) | 中文 -本指南覆盖参与 DeepSeek Harness 开发所需的本地环境搭建,并帮助你了解本地钩子、日常检查与 CI 门禁。 +本指南覆盖参与 DeepSeek Harness 开发所需的本地环境搭建、日常工作流与 CI 流程;设计动机与技术权衡请查阅相应 RFC。 ## 前置条件 - Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 [Node 引擎下限 RFC](rfc/implemented/process/2026-07-06-node-engine-floor.md)。 - 启用了 Corepack 的 pnpm。仓库在 `package.json` 中固定使用 `pnpm@11.7.0`;如果 `pnpm --version` 无法通过 Corepack 解析,请先运行 `corepack enable`。 - Git。 -- 可选:一个 DeepSeek API key,用于 REPL/ACP agent 演示和真实 API 的 e2e 测试。 +- 可选:一个 DeepSeek API key,用于 REPL/ACP agent(智能体)演示和真实 API 的 e2e 测试。 ## 首次搭建 @@ -59,7 +59,7 @@ DEEPSEEK_BASE_URL=https://... # optional lefthook 在 `lefthook.yml` 中配置,作为评审前的本地早期检查点: - `pre-commit` 运行对暂存文件的 ESLint 修复、`pnpm run typecheck` 和 vendor manifest 守卫; -- `pre-push` 运行 `pnpm run test`、`pnpm run test:snapshot`、`pnpm run hygiene`、`pnpm run doc-sync` 和 `pnpm run verify-module-graph`。 +- `pre-push` 运行 `pnpm run check:pre-push`,其调度器并发运行单元测试、快照测试、构建、module-graph 新鲜度,以及 `pnpm run hygiene` 与 `pnpm run doc-sync` 的各成员门禁。 vendor manifest 守卫检查 `vendor/*/src` 下的改动是否连同对应的 `vendor/README.md` manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 `vendor/README.md`。 diff --git a/docs/i18n/README.i18n.yaml b/docs/i18n/README.i18n.yaml index 6764f01a21..d9312030c9 100644 --- a/docs/i18n/README.i18n.yaml +++ b/docs/i18n/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -README.md: 30b9e53383ef591898505375662ec94d732de304 +README.md: d600773af2be156f52746c5bbd1853ff2ab46c14 README.zh.md: eac836e7c310945ec345db9974be9f1deaae4c60 diff --git a/docs/i18n/README.md b/docs/i18n/README.md index 30b9e53383..d600773af2 100644 --- a/docs/i18n/README.md +++ b/docs/i18n/README.md @@ -26,6 +26,7 @@ This repo's documentation is read by people and agents both inside and outside t 1. Every file listed as `required` in [scripts/translation-pairing.manifest.json](../../scripts/translation-pairing.manifest.json) has a complete pair. 2. Every pair that exists at all — required or not — is complete and consistent: all three files present, each side's current blob hash equals the recorded one (editing either side without re-confirming the pair goes red), both sides carry the language switcher, and the structural signatures match in order — heading depths, verbatim code blocks (info string and content), table column counts, list kinds, and every link target apart from the switcher. 3. Files listed as `excluded` have no `.zh.md` and no `.i18n.yaml` at all. +4. Every date-named document (`yyyy-mm-dd-*.md`) dated on or after the manifest's `requiredSince` cutoff has a complete pair — new documents merge bilingual from birth. `pnpm run verify-translation-pairing --list` prints the current pairing state of every document in scope — missing, out-of-sync, or ok — and is the work list for translation batches. It never fails; it reports. diff --git a/docs/i18n/terminology.md b/docs/i18n/terminology.md index f5dcb1f779..69f0e170e0 100644 --- a/docs/i18n/terminology.md +++ b/docs/i18n/terminology.md @@ -63,6 +63,7 @@ | thinking | thinking | | | API 字段保留英文;描述模型模式时译为`思考` | | transcript | transcript | transcript(文本记录) | | 指会话渲染给用户或编辑器的完整文本,区别于事件日志 | | waterfall | waterfall | waterfall(瀑布式事件) | | | +| wheel | wheel 包 | | | Python 打包格式 | | worktree | worktree | | | git 工作区概念 | ## 双语类(中英文文本各自使用中英文) @@ -92,6 +93,7 @@ | contract | 契约 | | | 如:`pairing contract` →`配对契约` | | coverage | 覆盖率 | | | | | crash recovery | 崩溃恢复 | | | | +| deploy root | 部署根目录 | | | | | durability | 持久性 | | | | | enforcement frontier | 执行红线 | | 强制边界 | i18n 配对机制用语:manifest `required` 清单所划的门禁生效范围;与金标样例(style-samples ⑦)一致 | | event | 事件 | | | | @@ -124,6 +126,7 @@ | orphan | 遗留 | | 孤儿、孤立 | 指英文源已不存在的 `.zh.md`(如「遗留译文」);进程语境按 OS 惯用语译「孤儿进程」 | | orphan branch | 孤立分支 | | 孤儿分支 | 沿用 git 官方中文翻译 | | pairing | 配对 | | | | +| peer dependency | 对等依赖 | 对等依赖(peer dependency) | | | | permission | 权限 | | | | | persistence | 持久化 | | | | | pipeline | 流水线 | | | | @@ -140,6 +143,7 @@ | runtime | 运行时 | | | | | sandbox | 沙箱 | | | | | service | 服务 | | | | +| serving surface | 对外服务接口 | | | | | session | 会话 | | | | | session event | 会话事件 | | | | | sidecar record | 伴随记录 | | 旁挂记录 | 指与文档同目录的伴随记录文件 | @@ -162,6 +166,7 @@ | tool schema | 工具 schema | | | | | toolkit | 工具包 | | | | | turn | 轮次 | | | | +| VFS | VFS | 虚拟文件系统(VFS) | | | | typecheck | 类型检查 | | | | | vocabulary | 词汇 | | | | | wire format | 协议格式 | 协议格式(wire format) | | | diff --git a/docs/i18n/translation-prompt.md b/docs/i18n/translation-prompt.md index 211d36a175..9978e2d29b 100644 --- a/docs/i18n/translation-prompt.md +++ b/docs/i18n/translation-prompt.md @@ -11,6 +11,8 @@ | `{{source_lang}}` | 源语言名(`English` / `Chinese`) | 由改动侧文件推断:`.zh.md` 被改则为 `Chinese` | | `{{target_lang}}` | 目标语言名(`Chinese` / `English`) | 与 `{{source_lang}}` 相对 | | `{{terminology}}` | [terminology.md](terminology.md) 的完整表格(Markdown 原文) | 渲染时读取仓库当前版本,不缓存 | +| `{{source_filename}}` | 源文档的 basename(如 `foo.md`) | 由流水线从待译文件路径取得 | +| `{{source_filename_zh}}` | 中文侧 basename(如 `foo.zh.md`) | 由 `{{source_filename}}` 派生 | 历史模板的 `{{to}}`、`{{title_prompt}}`、`{{summary_prompt}}`、`{{terms_prompt}}`、`{{imt_style_guide}}` 占位符与 `%%` 分段协议已废弃:本模板按整文档翻译(非分段),输出协议为下方三段 XML。 @@ -40,8 +42,8 @@ You are a senior technical translator specializing in LLM and agent development - Fenced code blocks must be byte-identical to the source, including ALL comments inside them. Do NOT translate comments inside code blocks. This is a hard rule with no exceptions. - Inline code spans (commands, flags, paths, API names, version numbers) must be kept verbatim. Never translate or reformat them. - Every relative link must point to the same target as in the source. Link text is translated; link targets are not. -- Language switcher line: when translating into Chinese, write `[English](source-filename.md) | 中文`. When translating into English, write `English | [中文](source-filename.zh.md)`. Do NOT copy the switcher line from the source file unchanged — you must flip the link direction. -- After a closing bold marker `**`, always insert a space before the next character. +- Language switcher line: the source document's filename is `{{source_filename}}`. When translating into Chinese, write `[English]({{source_filename}}) | 中文` immediately after the H1 heading. When translating into English, write `English | [中文]({{source_filename_zh}})` immediately after the H1. Emit this line even when the source file has no switcher yet (a brand-new pair); when the source does have one, flip the link direction — never copy it unchanged. +- After a closing bold marker `**`, insert a space before the next character when that character is a Latin letter or digit. Never insert a space before full-width (Chinese) punctuation. ### Tone and Style - The translation must read as if originally written in the target language by a native speaker. If an expression sounds like a word-for-word rendering from the source language, rephrase it. diff --git a/scripts/verify-translation-pairing.ts b/scripts/verify-translation-pairing.ts index c0c56ffe46..8297d13fe8 100644 --- a/scripts/verify-translation-pairing.ts +++ b/scripts/verify-translation-pairing.ts @@ -257,7 +257,7 @@ for (const req of manifest.required) { // 2. Date-named documents (RFCs) dated on/after the requiredSince cutoff merge // bilingual: a new RFC lands with its pair or not at all. Deterministic from // the filename alone — no git history, so it holds on shallow CI checkouts. -const DATED = /(\d{4}-\d{2}-\d{2})-[^/]*\.md$/ +const DATED = /(?:^|\/)(\d{4}-\d{2}-\d{2})-[^/]*\.md$/ for (const source of sources) { if (isExcluded(source)) continue const dated = DATED.exec(source)