dsh-translate-docs
GitHub用于DeepSeek-Harness文档的双语翻译工作流,支持更新、新建及删除场景,通过生成简报驱动最小化编辑或全文翻译,确保中英版本一致性。
Trigger Scenarios
Install
npx skills add deepseek-ai/deepseek-harness --skill dsh-translate-docs -g -y
SKILL.md
Frontmatter
{
"name": "dsh-translate-docs",
"description": "Manually run the extended DeepSeek Harness bilingual-document workflow, including generated briefings, delegated prose translation, whole-document translation, and scoped pairing verification.",
"user-invocable": true,
"disable-model-invocation": true
}
Translating DeepSeek-Harness docs
Invocation boundary
Run this extended workflow only when the user explicitly invokes dsh-translate-docs by name. Never select or load it for ordinary documentation work, from another skill, or from an inferred translation need; routine translation follows the one-shot, one-pass rule in docs/AGENTS.md.
What this skill is
This skill is guidance, not a translation memory. It is the workflow map for keeping foo.md ↔ foo.zh.md pairs consistent and natural in both languages. Both languages carry equal authority — a change is authored in either one, and that side is the source for that update. You are the translator: the rules below say what must hold, not how to phrase any particular sentence — phrasing judgment is yours, terminology is not.
Triage by change type — this decides everything else
- Update (pair exists, one side edited): follow the update path. It is briefing-driven and deliberately cheap: no guidance-corpus reading, no git archaeology, smallest counterpart edit. Never re-translate a whole document to apply an update — a minimal update preserves the reviewed phrasing of everything that didn't change; a re-translation throws that review away.
- New pair (no counterpart yet): follow the whole-document path.
- Deleted or renamed doc: delete or rename the counterpart and the
.i18n.yamlalongside it — the gate reports an incomplete pair otherwise.
Frozen Agent Notes under .agents/notes/archived/ are not translation work. Their complete triplets are sealed by the archive verifier; never update, re-record, or repair either side after archival.
The update path (briefing-driven)
The briefing-driven path matches guidance-corpus quality at a fraction of the cost; the briefed-updates Agent Note owns the benchmark evidence.
- Generate the briefing:
pnpm run gen-translation-brief <any file of the pair>(no arguments briefs every out-of-sync pair). The briefing maps the change at the narrowest safely aligned granularity — changed Markdown units (paragraph, table row, list item, heading), then whole heading sections, then whole document — and contains the authored side's diff since the last confirmed-consistent state, each changed unit's last-confirmed source, current source, and current counterpart text (with line numbers), the terminology rows the change touches, first-occurrence movement notes, and a digest of the binding update rules. - Mechanical-only diff?
--applyit. When every change lies inside code fences that the pair shares byte-identically, the briefing says so;pnpm run gen-translation-brief --apply <pair>splices the edited fences into the counterpart and structure-validates the result before writing — no subagent, no hand-editing. - Prose diff? Delegate to a subagent, passing the briefing (or the command to generate it). The briefing is the translator's whole working set — the subagent does not re-read the guidance corpus (the rules digest, terminology rows, and each changed unit's three-way context are inline) and does not re-derive the diff. It escalates to the whole-document path's sources of truth only when the briefing leaves a specific decision genuinely unanswerable — an unlisted term with no precedent in the surrounding text, or a whole-document briefing (
BOTH sides changed, or neither units nor sections align), which always means reconciling by hand under translation-rules.md. - Smallest edit that covers the diff. Preserve the reviewed phrasing of everything the diff does not touch, then verify the changed hunks clause by clause against the source: nothing added, nothing dropped, terminology per the inline rows, code spans verbatim.
- Record and verify, scoped:
pnpm run verify-translation-pairing --write <pair>thenpnpm run verify-translation-pairing <pair>.--writenames exactly the pairs you confirmed — it refuses to run bare so a bulk re-record is always an explicit--all. The corpus-wide check still runs indoc-sync/CI; do not run it per-update.
The whole-document path (new pairs)
When translations need to be written from scratch, the orchestrating agent does not translate: spawn a subagent to do the translation work. The translator reads the sources of truth below first, then translates the whole file into the other language — section by section for long documents, keeping each section's structure locked to the source as you go rather than fixing structure at the end.
Sources of truth (read, don't re-summarize)
- 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, and exclusions. - docs/i18n/translation-rules.md — how to translate: faithfulness, structure preservation, terminology discipline, typography (MUST/SHOULD levels).
- 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 — the automated pipeline's calibrated machine-consumed template. Agents using this skill do not render it; the terminology table is the only repository file the automated renderer injects, while this skill and
translation-rules.mdremain binding for agent-authored translations. - dsh-prose-standard — required prose coverage and editorial judgment. Apply it to both sides without adding or dropping source propositions.
Translate
- Pass 1 — write, don't transpose. Read a semantic unit, then restate it as a native technical author in the nearest style sample's register. Preserve the required frame without forcing 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.
- Read the completed counterpart alone. After the source comparison, read the translated file without the source beside it and rewrite phrasing whose awkwardness only becomes visible in isolation.
- Write only the final text to the file, never drafts or notes.
- Every term in terminology.md renders exactly as specified. For a Chinese target, use the Chinese and first-occurrence columns; an unlisted term needs a citable Chinese OSS/vendor precedent or stays English under 「待定术语」. For an English target, use the English column and an established English technical term; preserve an ambiguous source term with a short gloss and list it as pending. Never invent a rendering inline.
- Code blocks are byte-identical across the pair, comments included. Relative links keep their
.mdtargets; only the switcher line links.zh.md. - The pairing gate checks heading depths, fenced blocks, table row and column counts, list kinds, ordered-list starts, list item counts, and link targets. In Pass 2, manually verify list and table order, noncanonical list numbering, inline code, emphasis, meaning, terminology, and tone.
Find the work
pnpm run verify-translation-pairing --listprints every in-scope document as missing / out-of-sync / ok. Missing and out-of-sync rows are contract violations; the normal check rejects them.pnpm run gen-translation-briefwith no arguments prints the briefing for every out-of-sync pair.- In a PR that edits paired docs, the work list is the diff itself: every changed side of a pair needs its counterpart updated and the pair re-recorded in the same PR, and the gate goes red if you forget.
Finish the pair
- Switcher:
[English](foo.md) | 中文immediately after the Chinese file's H1,English | [中文](foo.zh.md)after the English file's H1 — add both if this is a new pair, except that a generator-owned English source stays byte-identical to generator output and omits its switcher while the Chinese counterpart still links back. - Record consistency:
pnpm run verify-translation-pairing --write <pair>recomputes and records both sides' full blob hashes infoo.i18n.yaml. The yaml diff in your PR is the reviewable statement "I confirmed these two say the same thing" — only run it after you actually have. - No manifest entry is needed for an ordinary document: every in-scope source requires a pair. Change scripts/translation-pairing.manifest.json only when the owning policy documents a genuine generated, instructional, or bilingual-by-construction exclusion.
- Before the PR: the touched pairs are green under the scoped check;
pnpm run doc-sync(which includes the corpus-wide pairing check plusverify-md-wrap/verify-md-links) runs once at PR level per dsh-pre-push-checks, not inside each translation task. - Keep the PR reviewable: state which pairs are new versus minimally updated and list 「待定术语」 prominently.
How to respond to translation review
Follow the code-review reporting guidance: evaluate each comment on its merits, and for terminology comments, remember the terminology table is the contract — apply a reviewer's rendering decision to terminology.md, not only to one file.
Version History
- 47f9438 Current 2026-08-16 15:43


