Legal Document Translation Skill

SkillDocs & knowledge

Translate legal documents from any language into English while preserving .docx formatting and translating track changes and headers/footers. Use this skill whenever the user asks to translate a legal document, contract, deed, agreement, or any formal legal text into English. Also trigger when the user mentions translating .docx files that contain legal content, or asks for a "format-preserving translation" of a legal document. This skill covers all legal domains: finance, M&A, corporate, IP, real estate, regulatory, consumer, taxes, litigation, SaaS and more. Even if the user just says "translate this contract" or "translate this into English", use this skill if the document is legal in nature.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Legal Document Translation Skill skill

What this skill tells your AI

The instructions your AI receives, as published by lawve-ai/awesome-legal-skills in skills/en-us-legal-translation-wouter-van-den-berg/SKILL.md and read by ahel’s review.

Translate legal documents from any language into publication-quality English while preserving all original .docx formatting (fonts, styles, headers, tables, numbering, etc.).

Pre-step checkpoint — read this whole file before doing anything

This skill's discipline depends on you actually reading SKILL.md, not just having it loaded in context. Before performing any step (Step 1 through Step 11), post a single short confirmation line in chat: "Understanding of skill discipline is confirmed, now initiating translation process." (use this exact wording). Do NOT print the technical details (Hard Rules location, validator names, step files) — the user does not want a wall of internal-state text. The act of writing the confirmation line is what proves you are at the right place; keep it terse.

If, while you are about to type the line, you realize you cannot from memory name (a) where the Hard Rules block lives, (b) which validators auto-invoke from apply_translations_textmatch.py (there are four), or (c) the file containing the step you are about to perform — STOP, Read('SKILL.md') again slowly, then post the one-line confirmation. Internal verification is required; user-facing display of that verification is not.

Compaction-resume trigger — treat as session start

If this turn began from a compacted transcript (signs: a system message describing prior work, a "summary" preface, a "This session is being continued from a previous conversation that ran out of context" header, or any context indicating that work has progressed without you having Read('SKILL.md') in this turn), you MUST treat the resume as session start. Compaction summaries are NOT a substitute for the actual rules. A summary may compress a 100-line rule into one line, drop the qualifier that bites in the case at hand, or omit the appendix that contains the answer to the failure mode you are about to hit.

Concretely, on every compaction-resume, before any tool call:

  1. Read('SKILL.md') in full.
  2. Read() the active step doc you are about to operate on.
  3. Read() any lexicon / sub-lexicon you were using before compaction.
  4. Post the one-line "Understanding of skill discipline is confirmed, now initiating translation process." before resuming work.

This is not "re-reading what you already read"; it is reading what you have NOT read in this turn. The Mandatory Reading Order applies on every compaction-resume, identically to first session start. Never trust a compaction summary's paraphrase of a rule — if the summary names a rule, go to the file and read the rule's exact text before applying it.

Do not ask the user — these are absolute defaults

The following are non-negotiable defaults. Do NOT pause to ask the user about them. Proceed silently with the default; only switch if the user has already given an explicit instruction in their original request. If you find yourself drafting a clarifying question about any of these, stop — the question is the wrong move:

  1. US English is the standard. Always translate into US English. The only switch to UK English is if the user already said so explicitly in their request (phrases like "translate into UK English", "use British English"). Do not ask whether to use UK or US. Do not pre-emptively confirm. Just translate into US English and, if you want, mention in the delivery message that UK English is available on request.

  2. Sequential, single-context translation is the only mode. When translating one document, or multiple documents in one session, just proceed sequentially in the main context window. Do NOT ask "shall I proceed sequentially?" or "the skill mandates sequential — how would you like me to proceed?" — sequential is the only mode. Only ask the user if THEY explicitly request sub-agents / parallelism, in which case warn them about quality risk and recommend sequential.

  3. All 11 steps for one document, then start the next. When translating multiple documents, complete the full pipeline (Steps 1 through 11, including final repack and validation) for Document 1 before beginning Step 1 of Document 2. Do NOT translate two documents in parallel batches, do NOT defer Document 1's repack to "do them together." Each document is its own sequential run.

  4. 35-paragraph batch cap is mandatory (enforced by validate_translations.py). Do not ask whether to use a larger batch.

  5. en_runs on every definitions-section paragraph is mandatory (enforced by validate_en_runs.py). Do not ask.

  6. Auto-invoked validators always run. Do not ask whether to skip a gate. Do not pass override flags unless the user has explicitly approved (e.g. --allow-bold-loss for known-acceptable bold loss).

  7. Per-document refresh is mandatory. When starting a new document in the same session, re-Read('SKILL.md'), re-Read() each step file as you arrive at it, and re-Read() the relevant lexicons and sub-lexicons. Do not ask.

  8. Compaction-resume re-read is mandatory. If the turn began from a compacted transcript, Read('SKILL.md') and the active step doc before any tool call. Compaction summaries are NOT a substitute for the actual rules (see "Compaction-resume trigger" subsection above). Do not ask.

  9. Chat-mode does not relax discipline. In Chat mode (no workspace folder, no auto-managed todo list), the same 11 steps, the same paragraphs.json checkpoint, the same per-batch validator, and the same Mandatory Reading Order all apply identically (see "Chat-mode discipline" in Anti-drift safeguards). Do not ask whether shortcuts are acceptable in Chat — they are not.

If the user explicitly overrides any of these, follow the user — but never invent a clarifying question.

Multi-document workflow

If you translate more than one document in the same Claude session, treat each document as a fresh workflow start. Even when the documents are similar (same project, same parties, same domain), the per-document refresh is non-negotiable:

  1. Complete all 11 steps for Document 1 before starting Document 2. Do NOT batch the translations across documents (translate Doc 1 + Doc 2 in interleaved batches), do NOT defer the repack of Document 1 to "do them together later," and do NOT split verification or the final delivery between documents. Each document is its own sequential run from Step 1 (setup) through Step 11 (validate). Only after Document 1 is delivered as a finished .docx does Step 1 of Document 2 begin.
  2. Re-Read('SKILL.md') at the start of each new document, in full. Do not assume the previous document's reading is still active in your working memory.
  3. Re-Read() every step file when arriving at the corresponding step of the new document. Pre-flight banners apply per-document.
  4. Re-Read() every applicable per-language sub-lexicon and English reference lexicon at Step 3 of each new document. Sub-lexicon Avoid-column entries that were the right answer for Document 1 may not be the right answer for Document 2 if the domain shifts. Calque drift is the predictable failure mode here.
  5. Treat the per-batch validator state file (.validate-state.json) as document-scoped. Each document gets its own workdir; the state file lives there.

Sub-lexicon and step-file rereads are part of the document setup, not the session setup. Skipping them because "I just read this for the previous document" is exactly the drift this skill is designed to prevent.

Do not ask the user how to proceed when multiple documents are in scope. Sequential, complete-document-first is the only mode (see "Do not ask" catalog above). Just begin Document 1 from Step 1.

IMPORTANT: Single-document workflow — no agent parallelization

This skill is designed for one document at a time, translated by Claude in its main context window. Sequential single-context translation is the default and only mode of operation. Do not ask the user "shall I proceed sequentially?" — sequential is what the skill does. Just start Document 1, finish all 11 steps, then start Document 2 if there is one.

The only situation that requires the user's input is when the user explicitly asks for sub-agents or parallelization. In that case:

  1. Stop and ask the user before deploying any agents — do they really want this? They probably don't.
  2. Warn clearly that agent-based parallel translation is likely to reduce quality: agents lack the full-document context needed for consistent terminology, defined-term tracking, and cross-reference handling. Inconsistencies between agent outputs are difficult to detect and fix.
  3. Recommend translating documents sequentially in the main context window.

If the user did not explicitly request agents, the question never arises — silently proceed sequentially.

The golden rule: original-as-base with text matching

The formatting of a .docx lives in paragraph properties (styles, numbering, indentation, spacing) set on each <w:p> element in word/document.xml. These properties are fragile — any re-serialization through Python's XML parsers can corrupt them in ways that look fine in XML but render wrong in Word (scrambled numbering, wrong heading levels, lost indentation).

The approach that works reliably: use the original source-language .docx as the formatting base and only replace the text runs (w:r elements) inside each paragraph. The paragraph structure, styles, numbering, spacing, indentation — everything stays untouched from the original. Only the words change.

Crucially, the replacement must be done by matching paragraphs by their source-language text content, not by index position. Paragraph extraction can introduce small index offsets (empty paragraphs counted differently, field codes, nested content). Text matching handles any offset automatically, and has been verified to produce zero style/numbering mismatches across all tested documents.

Table and container paragraphs are first-class citizens. Legal documents routinely contain paragraphs nested inside tables (w:tbl/w:tr/w:tc/w:p), text boxes, and structured document tags — signature blocks, form fields, schedules with tabular data, and party detail tables all use these. Both extraction and application MUST use recursive paragraph search (not just direct children of w:body) to find and translate these paragraphs. Failing to do so leaves signature blocks, schedule tables, and form fields in the source language.

Architecture overview

Original .docx (source language)
        │
        ├──▶ Extract paragraphs → paragraphs.json (text + formatting metadata)
        │                              │
        │                              ▼
        │                     Translate all paragraphs (fill in "en" field)
        │                              │
        │                              ▼
        │                     Validate translations (character-ratio check)
        │                              │
        │                              ▼
        └──▶ Apply translations ◀──────┘
             (text-match onto original document.xml,
              replacing only w:r elements,
              scanning for source-language remnants,
              then post-process in-place)
                    │
                    ▼
              Final .docx (English, identical formatting to original)

There is no intermediate "translated document.xml" step. Translations go directly from the JSON onto the original. This eliminates the paragraph count mismatch problem that caused cascading formatting corruption in earlier approaches.

Hard rules. Non-negotiable. Enforced by the skill's gates.

These five rules apply to every step of the pipeline, not just Step 4. Each step file ends with an Internal compliance check that asks you to confirm you have respected these rules. Deviating triggers gates that will block your work; complying upfront is always faster than running into a gate.

Hard rules. Non-negotiable. Enforced by the skill's gates.

  1. One document at a time. Complete the entire pipeline (Steps 1 through 11) for one document before starting the next. Never bundle translations across documents into one paragraphs.json, and never run two translation pipelines in parallel "for efficiency". Translation quality is per-paragraph attention; the workflow is structured around it.

  2. ≤35 paragraphs per batch (hard cap, enforced by validate_translations.py). Translate at most 35 paragraphs, then run validate_translations.py paragraphs.json BEFORE writing the next batch. Skipping batches is exactly the failure mode the skill is designed against — when the task feels laborious, the instinct is to bundle, and the result is output with errors that early validation would have caught. The validator's state file enforces a hard cap of 35 newly-translated paragraphs per invocation; bulk validation of more than 35 paragraphs blocks unless --accept-large-batch is passed.

  3. Step 5 (apply) verifies complete validation coverage. Apply blocks if any paragraph with non-empty en has not been validated by validate_translations.py. There is no way to skip Step 4b's per-batch validation and still get past Step 5.

  4. Read every paragraph's complete text field. Do not use summarization, sampling, or "translate the gist" shortcuts — every word must be in your context window during translation.

  5. Populate en_runs for every definitions section paragraph. Apply blocks if any paragraph in a detected definitions section lacks en_runs. See rule 3 below for the structural cues that identify definitions sections and how to populate en_runs.

Mandatory reading order

This skill's discipline depends on you reading the right file at the right step. The full procedural detail for each step lives in skill-docs/, organized as eight files. Before performing each step, you MUST Read('skill-docs/0X-...md') in full. You MUST not skim. You MUST not skip a step file. You MUST not paraphrase a step from memory.

Each step file ends with a per-step Internal compliance check; you MUST complete that check before moving on. If at any point you find yourself executing a step without having Read the corresponding step file in this session, STOP — Read the file now, then continue.

The reading order is:

  1. skill-docs/01-setup-and-extract.md — Steps 1+2: convert + extract paragraphs
  2. skill-docs/03-lexicons-and-segments.md — Steps 3+3b: identify document type, read lexicons, scaffold en_segments for TC
  3. skill-docs/04-translate.md — Step 4: translate every paragraph (the heaviest step)
  4. skill-docs/04b-translate-gates.md — Steps 4b+4c+4d: per-batch validation, cross-references, lexicon compliance
  5. skill-docs/05-apply.md — Step 5: apply translations onto the original
  6. skill-docs/06-postprocess-and-reorder.md — Steps 6+7: post-process and reorder definitions
  7. skill-docs/08-aux-and-quality.md — Steps 8+9: auxiliary XML files and quality check
  8. skill-docs/10-repack-and-validate.md — Pre-repack hooks + Steps 10+11: repack into .docx and final validate

Each file should be Read()d when you arrive at the corresponding step in the workflow. They are not appendices.

Lexicon priority — cross-language reference wins on cross-language conventions

The skill's lexicons fall into two layers and they do NOT have equal authority. You MUST read both at Step 3, but on questions of cross-language English convention the cross-language reference always wins:

  • sub-lexicons/<language>-<domain>.md — language-specific term mappings. Authoritative on how a source-language term renders in English in its native context. Example: the Japanese sub-lexicon maps 条 → "Article (Art.)" correctly for legislative citations such as 民法第30条 → "Article 30 of the Civil Code". The mapping is correct in its scope.
  • references/<domain>.md (general-legal.md, finance-banking.md, energy-infrastructure.md, trading-capital-markets.md, etc.) — cross-language English conventions. Authoritative on how English legal writing handles a convention regardless of source language: Section (US default) vs Clause (UK) vs Article for internal cross-references, defined-term capitalization, "et al." vs "etc.", date and currency formats, comma usage in lists, abbreviation style, and so on.

When the two appear to disagree, the cross-language reference wins. The Japanese sub-lexicon's 条 → "Article" is a citation mapping; references/general-legal.md says internal cross-references in a contract take "Section" in US English (the default) or "Clause" in UK English (e.g. 本契約第3条 → "Section 3 of this Agreement" under the default US variant, → "Clause 3 of this Agreement" under UK, never "Article 3 of this Agreement"). The reference rule scopes the sub-lexicon mapping to legislative citations only — it does not contradict the sub-lexicon, it tells you when the sub-lexicon's mapping does and does not apply. The same logic applies for every cross-language convention: when a quality-check finding flags an "Article 3" inside an internal reference and the sub-lexicon offers the Article mapping, the QC finding is correct, not a false positive — read references/general-legal.md before treating it as one.

Always read the relevant references/*.md before relying on a sub-lexicon mapping for a cross-language convention. If you only consulted the sub-lexicon, you have only half the answer.

Pipeline overview

High-level summary of what each step does. Detail in the step files.

#StepActionFile
1Set upConvert .doc→.docx if needed, unpack to a workdirskill-docs/01-setup-and-extract.md
2Extractextract_paragraphs.py produces paragraphs.json with formatting metadataskill-docs/01-setup-and-extract.md
3LexiconsIdentify document domain, load English references and per-language sub-lexiconsskill-docs/03-lexicons-and-segments.md
3bScaffold(TC documents only) Build en_segments skeleton for fragmented TCskill-docs/03-lexicons-and-segments.md
4TranslateFill en and en_runs for every paragraph, ≤35 per batchskill-docs/04-translate.md
4bPer-batch validatevalidate_translations.py after each batchskill-docs/04b-translate-gates.md
4cCross-refsResolve broken cross-references in translated textskill-docs/04b-translate-gates.md
4dLexicon compliancelexicon_compliance.py pre-apply scanskill-docs/04b-translate-gates.md
5Applyapply_translations_textmatch.py (auto-invokes 4 validators)skill-docs/05-apply.md
6Post-processpost_process.py (terminology, spacing, US English, etc.)skill-docs/06-postprocess-and-reorder.md
7Reorderreorder_definitions.py for documents with definitionsskill-docs/06-postprocess-and-reorder.md
8Aux filesTranslate headers/footers/comments/footnotes/endnotesskill-docs/08-aux-and-quality.md
9Quality checkquality_check.py for source-language remnantsskill-docs/08-aux-and-quality.md
10Repackrepack_docx.py (auto-invokes validate_apply --strict)skill-docs/10-repack-and-validate.md
11ValidateFinal integrity check on the .docxskill-docs/10-repack-and-validate.md

Anti-drift safeguards

The discipline this skill enforces is the result of repeated post-mortems. Drift is the failure mode where you (the operator) start a translation with the skill loaded, then over the course of a long job begin paraphrasing rules from memory, skipping per-batch validation, or deciding a step "doesn't apply this time." The end state is output that looks plausible but has subtly wrong terminology, lost tracked changes, or missed definitions formatting.

The defenses are layered and they are non-optional:

  1. Mandatory step-file reads. Each of the 8 skill-docs/0X-...md files must be Read in full at the step it covers. Each ends with an Internal compliance check the operator must complete.

  2. Hard Rules apply skill-wide. The 5 Hard Rules above are not just for Step 4. Every step's compliance check asks you to re-confirm them.

  3. Auto-invoked gates. apply_translations_textmatch.py auto-runs four pre-apply validators (validate_en_runs, validate_segment_shapes, validate_reject_all, then validate_apply --strict after applying). repack_docx.py auto-runs validate_apply --strict again. post_process.py auto-runs strip_noop_tracked_changes.py. None of these can be skipped from the CLI.

  4. Per-batch validation. validate_translations.py enforces a hard cap of 35 newly-translated paragraphs per invocation. The state file .validate-state.json makes batch coverage auditable.

  5. Skill-gate semantics. A gate firing produces a SKILL GATE FIRED — INTENTIONAL BLOCK, NOT A SCRIPT ERROR banner. This is the script doing its job, not the script breaking. Do NOT work around a gate by patching the script or skipping the validator — fix the input (usually paragraphs.json) and re-run.

  6. Script-integrity errors. Any script that exits with a FILE INTEGRITY CHECK FAILED — script truncated banner indicates a corrupted local install of that script. STOP — re-install the skill from the .skill / .zip archive before re-running the affected step. Do NOT work around the failure by skipping the step, calling the script through a wrapper, or treating the result as "optional." Every script in the skill carries the integrity check; a failure on any one of them is a hard install-side problem that can only be fixed by re-installation.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
691
Forks
88
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
legal-translation-us
Source
github.com/lawve-ai/awesome-legal-skills