docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
/ * *
2026-07-12 03:36:43 +08:00
* Enforce complete English / Chinese pairs , matching structure , and recorded git
2026-07-26 15:06:51 +08:00
* blob hashes for every in - scope document . The manifest contains only explicit
* exclusions , which may have neither a counterpart nor a sidecar .
2026-07-27 00:40:49 +08:00
* ` --list ` reports state ; ` --write <pairs...> ` records the named confirmed
2026-08-08 21:11:19 +08:00
* pairs ( ` --write --all ` records every complete pair ) ; ` --cached <pairs...> `
* checks exact index bytes for hooks . A check or write named with pair paths
* touches only those pairs , so update iteration does not pay for a corpus
* scan . Translation quality remains a review responsibility .
2026-07-14 12:34:14 +08:00
* See ` docs/i18n/README.md ` for the owning contract .
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
* /
2026-08-18 19:00:37 +08:00
import { existsSync , globSync , readFileSync , statSync , writeFileSync } from 'node:fs'
2026-07-15 19:59:00 +08:00
import { basename , join , resolve , sep } from 'node:path'
2026-08-18 19:00:37 +08:00
import {
gitBlobHash ,
gitIndexPaths ,
readGitIndexBlob ,
storeGitBlob ,
} from './translation-pairing-git.ts'
2026-08-08 21:11:19 +08:00
import {
parseTranslationPairingRecord ,
renderTranslationPairingRecord ,
translationPairPaths ,
} from './translation-pairing-record.ts'
2026-07-14 23:09:01 +08:00
import {
2026-08-11 20:09:33 +08:00
languageSwitcherTargets ,
2026-07-14 23:09:01 +08:00
parseTranslationMarkdown ,
2026-07-27 00:40:49 +08:00
parseTranslationPairingCliArgs ,
2026-07-14 23:09:01 +08:00
parseTranslationPairingManifest ,
2026-07-30 21:40:58 +08:00
partitionGeneratedRegions ,
2026-08-09 11:02:16 +08:00
requiresSourceLanguageSwitcher ,
2026-08-19 02:26:57 +08:00
isTranslationPairingManifestExcluded ,
2026-07-26 03:29:11 +08:00
isTranslationScopeFile ,
TRANSLATION_SCOPE_GLOB_EXCLUDES ,
2026-08-19 02:26:57 +08:00
translationPairSourcePredicate ,
2026-07-14 23:09:01 +08:00
translationStructureDiff ,
translationStructureSignature ,
} from './translation-pairing.ts'
2026-08-18 19:00:37 +08:00
import {
2026-08-18 20:05:01 +08:00
hasLanguageSwitcher ,
2026-08-18 19:00:37 +08:00
normalizeTranslationMarkdownLinks ,
translationLinkLocaleViolations ,
} from './translation-links.ts'
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
const root = resolve ( import . meta . dirname , '..' )
2026-07-27 00:40:49 +08:00
let request : ReturnType < typeof parseTranslationPairingCliArgs >
try {
request = parseTranslationPairingCliArgs ( process . argv . slice ( 2 ) )
} catch ( error ) {
console . error ( ` verify-translation-pairing: ${ error instanceof Error ? error.message : String ( error ) } ` )
process . exit ( 2 )
}
const listMode = request . mode === 'list'
const writeMode = request . mode === 'write'
2026-08-08 21:11:19 +08:00
const indexMode = request . input === 'index'
2026-08-18 19:00:37 +08:00
const indexFiles = indexMode ? gitIndexPaths ( root ) : undefined
2026-08-08 21:11:19 +08:00
const contentCache = new Map < string , Buffer | undefined > ( )
/** Read one repository path from the selected worktree or index plane. */
function readRepositoryFile ( file : string ) : Buffer | undefined {
if ( contentCache . has ( file ) ) return contentCache . get ( file )
const content = indexMode
2026-08-18 19:00:37 +08:00
? indexFiles ? . has ( file ) ? readGitIndexBlob ( root , file ) ? . content : undefined
: existsSync ( join ( root , file ) ) && statSync ( join ( root , file ) ) . isFile ( )
? readFileSync ( join ( root , file ) )
: undefined
2026-08-08 21:11:19 +08:00
contentCache . set ( file , content )
return content
}
/** Whether one path exists in the selected content plane. */
function repositoryFileExists ( file : string ) : boolean {
2026-08-18 19:00:37 +08:00
return indexMode ? indexFiles ? . has ( file ) === true : readRepositoryFile ( file ) !== undefined
2026-08-08 21:11:19 +08:00
}
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
2026-07-26 03:29:11 +08:00
/** Discover source Markdown and pairing sidecars before applying the corpus predicate. */
2026-07-19 22:50:49 +08:00
const SCOPE_PATTERNS = [
2026-07-26 03:29:11 +08:00
'**/*.md' ,
'**/*.i18n.yaml' ,
2026-07-19 22:50:49 +08:00
'.agents/notes/**/*.md' ,
'.agents/notes/**/*.i18n.yaml' ,
]
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
2026-08-08 21:11:19 +08:00
const manifestContent = readRepositoryFile ( 'scripts/translation-pairing.manifest.json' )
if ( manifestContent === undefined ) {
throw new Error ( 'scripts/translation-pairing.manifest.json is missing from the selected content plane' )
}
const manifest = parseTranslationPairingManifest ( manifestContent . toString ( 'utf8' ) )
2026-08-19 02:26:57 +08:00
const isTranslationPairSource = translationPairSourcePredicate ( manifest )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
2026-07-03 02:06:57 -07:00
/ * *
* An excluded entry ending in ` / ` excludes the whole directory . The trailing
* slash IS the path boundary — ` docs/tool-catalog/ ` cannot prefix - match a
* sibling like ` docs/tool-catalog-notes/x.md ` — so directory entries in the
* manifest must keep their trailing slash .
* /
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
function isExcluded ( file : string ) : boolean {
2026-08-19 02:26:57 +08:00
return isTranslationPairingManifestExcluded ( file , manifest )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
}
2026-07-27 00:40:49 +08:00
// Enumerate the scope once: the whole corpus, or exactly the named pairs'
// three files (a named pair whose files are absent is caught by the same
// completeness rules that cover discovered remnants).
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
const files = new Set < string > ( )
2026-07-27 00:40:49 +08:00
if ( request . scope === 'pairs' ) {
for ( const anchor of request . anchors ) {
2026-08-08 21:11:19 +08:00
const { source , zh , meta } = translationPairPaths ( anchor )
for ( const file of [ source , zh , meta ] ) {
if ( repositoryFileExists ( file ) ) files . add ( file )
2026-07-27 00:40:49 +08:00
}
2026-08-08 21:11:19 +08:00
// A named worktree anchor with no files still enters the source list so
// an interactive check reports it. An index check accepts a complete
// three-file deletion and still rejects every partial deletion below.
if ( ! indexMode && ! repositoryFileExists ( anchor ) ) files . add ( anchor )
2026-07-27 00:40:49 +08:00
}
} else {
for ( const pattern of SCOPE_PATTERNS ) {
for ( const match of globSync ( pattern , { cwd : root , exclude : TRANSLATION_SCOPE_GLOB_EXCLUDES } ) ) {
const normalized = match . split ( sep ) . join ( '/' )
if ( isTranslationScopeFile ( normalized ) ) files . add ( normalized )
}
2026-07-26 03:29:11 +08:00
}
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
}
const translations = [ . . . files ] . filter ( f = > f . endsWith ( '.zh.md' ) ) . sort ( )
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
const metas = [ . . . files ] . filter ( f = > f . endsWith ( '.i18n.yaml' ) ) . sort ( )
const sources = [ . . . files ] . filter ( f = > f . endsWith ( '.md' ) && ! f . endsWith ( '.zh.md' ) ) . sort ( )
2026-07-27 00:40:49 +08:00
if ( request . scope === 'pairs' ) {
const rejected = request . anchors . filter ( anchor = > ! isTranslationScopeFile ( anchor ) || isExcluded ( anchor ) )
2026-08-08 21:11:19 +08:00
const absent = request . anchors . filter ( ( anchor ) = > {
const { source , zh , meta } = translationPairPaths ( anchor )
return ! [ source , zh , meta ] . some ( repositoryFileExists )
} )
if ( rejected . length > 0 || ( ! indexMode && absent . length > 0 ) ) {
2026-07-27 00:40:49 +08:00
for ( const anchor of rejected ) {
console . error ( ` verify-translation-pairing: ${ anchor } is not an in-scope pair (excluded or outside the documentation corpus; see docs/i18n/README.md) ` )
}
for ( const anchor of absent ) {
console . error ( ` verify-translation-pairing: ${ anchor } names no pair on disk (none of its three files exist) ` )
}
process . exit ( 2 )
}
}
// --write: (re)record both hashes for the requested complete pairs, creating
// missing records. A named pair that cannot be recorded (missing counterpart)
// fails loud; corpus scope (--all) skips pairless sources as before.
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
if ( writeMode ) {
let written = 0
for ( const source of sources ) {
if ( isExcluded ( source ) ) continue
2026-08-08 21:11:19 +08:00
const paths = translationPairPaths ( source )
const { zh , meta } = paths
if ( ! repositoryFileExists ( source ) || ! repositoryFileExists ( zh ) ) {
2026-07-27 00:40:49 +08:00
if ( request . scope === 'pairs' ) {
2026-08-08 21:11:19 +08:00
console . error ( ` verify-translation-pairing: cannot record ${ source } : missing ${ repositoryFileExists ( source ) ? zh : source } ` )
2026-07-27 00:40:49 +08:00
process . exit ( 2 )
}
continue
}
2026-08-08 21:11:19 +08:00
const sourceContent = readRepositoryFile ( source )
const zhContent = readRepositoryFile ( zh )
if ( sourceContent === undefined || zhContent === undefined ) throw new Error ( ` ${ source } : complete pair became unreadable ` )
2026-07-28 04:34:05 -07:00
// A consistency record is also a recovery pointer for the briefing
// generator. Persist both snapshots even when the sidecar text is already
// current, because the bytes may exist only in this working tree.
2026-08-08 21:11:19 +08:00
const record = renderTranslationPairingRecord ( paths , {
sourceHash : storeGitBlob ( root , sourceContent ) ,
zhHash : storeGitBlob ( root , zhContent ) ,
} )
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
if ( existsSync ( join ( root , meta ) ) && readFileSync ( join ( root , meta ) , 'utf8' ) === record ) continue
writeFileSync ( join ( root , meta ) , record )
console . log ( ` verify-translation-pairing: recorded ${ meta } ` )
written ++
}
console . log ( ` verify-translation-pairing: ${ written } record(s) written; run the check to validate the pairs. ` )
process . exit ( 0 )
}
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
const errors : string [ ] = [ ]
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
const state = new Map < string , 'ok' | 'out-of-sync' | 'missing' > ( )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
2026-07-26 15:06:51 +08:00
// 1. Every discovered, non-excluded source merges bilingual.
2026-07-04 05:41:18 -07:00
for ( const source of sources ) {
if ( isExcluded ( source ) ) continue
2026-08-08 21:11:19 +08:00
const { zh } = translationPairPaths ( source )
if ( ! repositoryFileExists ( zh ) ) {
2026-07-26 15:06:51 +08:00
errors . push ( ` ${ source } : in-scope documentation must merge bilingual (docs/i18n/README.md); add the counterpart and record the pair ` )
2026-07-04 05:41:18 -07:00
state . set ( source , 'missing' )
}
}
2026-07-26 15:06:51 +08:00
// 2. Every pair that exists at all is complete and consistent. Anchor on the
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
// union of .zh.md files and .i18n.yaml records so a half-deleted pair is
// caught from either remnant.
const pairAnchors = new Set < string > ( )
for ( const zh of translations ) pairAnchors . add ( zh . replace ( /\.zh\.md$/ , '.md' ) )
for ( const meta of metas ) pairAnchors . add ( meta . replace ( /\.i18n\.yaml$/ , '.md' ) )
for ( const source of [ . . . pairAnchors ] . sort ( ) ) {
2026-08-08 21:11:19 +08:00
const paths = translationPairPaths ( source )
const { zh , meta } = paths
const have = {
source : repositoryFileExists ( source ) ,
zh : repositoryFileExists ( zh ) ,
meta : repositoryFileExists ( meta ) ,
}
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
if ( isExcluded ( source ) ) {
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
if ( have . zh ) errors . push ( ` ${ zh } : ${ source } is excluded from pairing (generated or bilingual-by-construction); this translation must not exist ` )
if ( have . meta ) errors . push ( ` ${ meta } : ${ source } is excluded from pairing; this consistency record must not exist ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
continue
}
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
const missing = Object . entries ( have ) . filter ( ( [ , ok ] ) = > ! ok ) . map ( ( [ k ] ) = > ( k === 'source' ? source : k === 'zh' ? zh : meta ) )
if ( missing . length > 0 ) {
errors . push ( ` ${ source } : incomplete pair — missing ${ missing . join ( ', ' ) } (pairs merge whole: both languages plus the .i18n.yaml record) ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
continue
}
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
2026-08-08 21:11:19 +08:00
const sourceContent = readRepositoryFile ( source )
const zhContent = readRepositoryFile ( zh )
const metaContent = readRepositoryFile ( meta )
if ( sourceContent === undefined || zhContent === undefined || metaContent === undefined ) {
throw new Error ( ` ${ source } : complete pair became unreadable ` )
}
const record = parseTranslationPairingRecord ( metaContent . toString ( 'utf8' ) , paths )
if ( record === undefined ) {
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
errors . push ( ` ${ meta } : malformed consistency record (expected exactly \` ${ basename ( source ) } : <40-hex> \` and \` ${ basename ( zh ) } : <40-hex> \` ) ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
continue
}
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
let consistent = true
for ( const [ file , content ] of [ [ source , sourceContent ] , [ zh , zhContent ] ] as const ) {
2026-07-28 04:34:05 -07:00
const current = gitBlobHash ( content )
2026-08-08 21:11:19 +08:00
const recorded = file === source ? record.sourceHash : record.zhHash
if ( recorded !== current ) {
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
errors . push ( ` ${ file } : out of sync — content no longer matches the pair's last confirmed-consistent state in ${ meta } (bring the other side along, then re-record with --write) ` )
consistent = false
}
}
if ( ! consistent ) {
state . set ( source , 'out-of-sync' )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
continue
}
2026-08-18 19:00:37 +08:00
const sourceText = sourceContent . toString ( 'utf8' )
const zhText = zhContent . toString ( 'utf8' )
const sourceSwitcherTargets = languageSwitcherTargets ( source )
const zhSwitcherTargets = languageSwitcherTargets ( zh )
for ( const violation of [
. . . translationLinkLocaleViolations ( sourceText , {
repoRoot : root ,
sourcePath : source ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
} , zhSwitcherTargets ) ,
. . . translationLinkLocaleViolations ( zhText , {
repoRoot : root ,
sourcePath : zh ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
} , sourceSwitcherTargets ) ,
] ) {
errors . push ( ` ${ violation . sourcePath } : ${ violation . line } : link target ${ JSON . stringify ( violation . url ) } uses the wrong locale; expected ${ JSON . stringify ( violation . expectedUrl ) } ` )
state . set ( source , 'out-of-sync' )
}
// Generated regions must remain byte-identical after paired document paths
// are normalized to one semantic target. The structural signature below
// compares their contents again as part of the whole document; this named
// check rejects any prose, ordering, code, marker, or non-locale URL drift.
2026-07-30 21:40:58 +08:00
let sourceRegions : { regions : string [ ] ; stripped : string }
let zhRegions : { regions : string [ ] ; stripped : string }
try {
2026-08-18 19:00:37 +08:00
sourceRegions = partitionGeneratedRegions ( sourceText )
zhRegions = partitionGeneratedRegions ( zhText )
2026-07-30 21:40:58 +08:00
} catch ( error ) {
errors . push ( ` ${ source } ↔ ${ zh } : ${ error instanceof Error ? error.message : String ( error ) } ` )
state . set ( source , 'out-of-sync' )
continue
}
2026-08-18 19:00:37 +08:00
const normalizedSourceRegions = sourceRegions . regions . map ( region = > normalizeTranslationMarkdownLinks ( region , {
repoRoot : root ,
sourcePath : source ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
} ) )
const normalizedZhRegions = zhRegions . regions . map ( region = > normalizeTranslationMarkdownLinks ( region , {
repoRoot : root ,
sourcePath : zh ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
} ) )
if ( normalizedSourceRegions . length !== normalizedZhRegions . length
|| normalizedSourceRegions . some ( ( region , index ) = > region !== normalizedZhRegions [ index ] ) ) {
errors . push ( ` ${ source } ↔ ${ zh } : generated regions differ beyond paired-document locale paths — regenerate both sides ` )
2026-07-30 21:40:58 +08:00
state . set ( source , 'out-of-sync' )
}
2026-08-18 19:00:37 +08:00
const sourceTree = parseTranslationMarkdown ( sourceText )
const zhTree = parseTranslationMarkdown ( zhText )
2026-08-18 20:05:01 +08:00
if ( ! hasLanguageSwitcher ( zhTree , zhText , sourceSwitcherTargets ) ) {
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
errors . push ( ` ${ zh } : missing language switcher — no link to ${ basename ( source ) } ` )
}
2026-08-18 20:05:01 +08:00
if ( requiresSourceLanguageSwitcher ( source ) && ! hasLanguageSwitcher ( sourceTree , sourceText , zhSwitcherTargets ) ) {
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
errors . push ( ` ${ source } : missing language switcher — no link back to ${ basename ( zh ) } ` )
}
2026-07-14 23:09:01 +08:00
for ( const divergence of translationStructureDiff (
2026-08-18 19:00:37 +08:00
translationStructureSignature ( sourceTree , zhSwitcherTargets , {
repoRoot : root ,
sourcePath : source ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
markdown : sourceText ,
} ) ,
translationStructureSignature ( zhTree , sourceSwitcherTargets , {
repoRoot : root ,
sourcePath : zh ,
2026-08-19 02:26:57 +08:00
isTranslationPairSource ,
2026-08-18 19:00:37 +08:00
repositoryFileExists ,
markdown : zhText ,
} ) ,
2026-07-14 23:09:01 +08:00
) ) {
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
errors . push ( ` ${ source } ↔ ${ zh } : ${ divergence } ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
}
if ( ! state . has ( source ) ) state . set ( source , 'ok' )
}
2026-07-26 15:06:51 +08:00
// Complete the state map for --list: any in-scope, non-excluded document with no pair is missing.
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
for ( const source of sources ) {
if ( ! isExcluded ( source ) && ! state . has ( source ) ) state . set ( source , 'missing' )
}
if ( listMode ) {
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
const order = { 'out-of-sync' : 0 , missing : 1 , ok : 2 } as const
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
const rows = [ . . . state . entries ( ) ] . sort ( ( a , b ) = > order [ a [ 1 ] ] - order [ b [ 1 ] ] || a [ 0 ] . localeCompare ( b [ 0 ] ) )
for ( const [ file , status ] of rows ) {
2026-07-26 15:06:51 +08:00
console . log ( ` ${ status . padEnd ( 11 ) } ${ file } ${ status === 'missing' ? ' (required)' : '' } ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
}
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
const counts = { 'ok' : 0 , 'out-of-sync' : 0 , 'missing' : 0 }
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
for ( const status of state . values ( ) ) counts [ status ] ++
docs: equal-authority pairing with sidecar consistency records
Redesign per review: neither language is canonical. A pair is three
sibling files — foo.md, foo.zh.md, foo.i18n.yaml — and either language
may be authored first (a Chinese-first RFC is as legitimate as an
English-first one). The sidecar record holds the FULL git blob hash of
both sides as of the last confirmed-consistent state, replacing the
in-file one-directional fingerprint; editing either side without
re-confirming the pair goes red. New --write mode re-records a pair
after both sides are brought in line, making the confirmation a
reviewable yaml diff. Pairs merge whole (completeness enforced).
- gate rewritten around pair anchors (union of .zh.md and .i18n.yaml
remnants) so half-deleted pairs are caught from either side; red/green
proven for en-only edit, zh-only edit, missing record, and a record
for an excluded file
- verify-rfc-classification now skips .zh.md counterparts (same RFC,
indexed via its English filename; the pairing gate owns consistency)
- docs/i18n/README.md + translation-rules.md reframed bidirectionally
(terminology table binds both directions; typography section governs
the Chinese side); zh counterparts updated; skill workflow updated
- RFC amended to the shipped design, records the English-canonical
in-file-fingerprint model as considered-and-revised; RFC translated
(docs/rfc/.../2026-07-02-bilingual-docs-and-pairing-gate.zh.md) and
added to the required frontier
- generated docs stay excluded with the follow-up recorded: teach the
generators to emit Chinese, then de-list
2026-07-03 07:41:24 -07:00
console . log ( ` verify-translation-pairing: ${ counts . ok } ok, ${ counts [ 'out-of-sync' ] } out-of-sync, ${ counts . missing } missing (of ${ state . size } in scope) ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
process . exit ( 0 )
}
if ( errors . length === 0 ) {
2026-07-27 00:40:49 +08:00
console . log ( request . scope === 'pairs'
2026-08-08 21:11:19 +08:00
? ` verify-translation-pairing: ${ pairAnchors . size } named ${ indexMode ? 'staged ' : '' } pair(s) consistent; the corpus-wide check still runs in doc-sync. `
2026-07-27 00:40:49 +08:00
: ` verify-translation-pairing: ${ pairAnchors . size } pair(s) checked across all in-scope documentation, all consistent. ` )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
process . exit ( 0 )
}
2026-08-09 15:27:21 +08:00
console . error ( 'verify-translation-pairing: bilingual pairing rules violated (see docs/i18n/README.md):' )
docs: bilingual docs contract, translation skill, and pairing gate
Establish EN->ZH bilingual documentation for the README and docs tree:
- docs/i18n/README.md — the pairing contract: sibling foo.md <-> foo.zh.md,
English canonical, blob-hash source fingerprints, language switchers,
scope/exclusions, and a manifest-driven rollout ratchet.
- docs/i18n/translation-rules.md — how to translate: faithfulness, structure
preservation, terminology discipline over docs/i18n/terminology.md, and
typography rules grounded in MDN/K8s/Vue/clreq conventions.
- .agents/skills/dsh-translate-docs — the committed agent workflow, following
the dsh-code-review pattern of deferring to docs as sources of truth.
- scripts/verify-translation-pairing.ts + manifest — a doc-sync gate: required
pairs exist; every existing .zh.md is fresh (fingerprint = current source
blob), switcher-linked, structure-matched, and non-orphaned; excluded
(generated) docs stay unpaired. --list prints the translation work list.
- RFC (implemented/process) recording the decision and the alternatives.
- Dogfood: README.zh.md and the two i18n docs translated under their own rules.
Gates: doc-sync green including the new gate; red/green proven for stale
fingerprint, orphan, and excluded-file violations.
2026-07-02 23:12:25 -07:00
for ( const message of errors ) console . error ( ` ${ message } ` )
process . exit ( 1 )