# WB INS Font Fix + Bold-Stripping Disaster (2026-06-10)

## Problem
Doro rejected 【修】青浦精神卫生-委托检验协议（修）.docx: WB insertions displayed in wrong font.

Terminal review passed 10 checks but missed basic font inconsistency.

## Root Cause
`contract_docx_lib.py`'s `_ensure_rfonts_complete()` only filled hAnsi/cs, missing:
1. `w:eastAsia` — CJK falls back to docDefaults (Times New Roman vs 宋体)
2. `w:hint="eastAsia"` — required for CJK rendering priority
3. `w:sz` — not inherited inside `w:ins`; must be explicit

## Fix Applied (contract_docx_lib.py, 4 locations)

### 1. `_ensure_rfonts_complete()` — fill all 4 + hint
### 2. `_extract_formats()` — ensure sz on body_rpr/title_rpr
### 3. `tracked_replace()` — ensure sz on INS rpr
### 4. `tracked_replace()` — fallback for hint-only rFonts runs

See previous version of this file for code details.

## CRITICAL: Bold-Stripping Disaster

### What happened
First fix attempt: after noticing font issues, **batch-stripped ALL `<w:b/>` tags from all WB INS runs**. This destroyed the original bold formatting:
- P19: 风险律师费条件（原文加粗）→ stripped → not bold ✗
- P18: 金额部分（原文加粗）→ stripped → not bold ✗
- P30: "如若违反，律师费将另行重新计付"（原文加粗）→ stripped → not bold ✗

Doro: **"要保持原文的格式不变"**

### Why it was wrong
`tracked_replace` correctly inherits the original run's rPr INCLUDING bold. When the original text "在代理过程中..." was bold, the replacement text "风险律师费仅按..." SHOULD also be bold — that's correct format preservation.

### The rule
- `tracked_replace` INS inherits original run's rPr → **leave it alone**
- `add_clause` uses `_body_rpr` (no bold) or `_title_rpr` (bold) → **correct by design**
- **NEVER post-process WB INS to strip/add formatting attributes globally**

### Correct validation approach
Compare each WB INS run against the original run **in the same paragraph**, not against a global template. Use `scripts/wb-ins-font-verify.py` for document-agnostic validation.

## Verification Script
`scripts/wb-ins-font-verify.py <docx>` — per-paragraph comparison, checks rFonts/sz/hint, exit code 0=pass 1=fail. Document-agnostic (no hardcoded font names).

## Three font-source scenarios in tracked_replace
1. Run has explicit font names → `_ensure_rfonts_complete` fills gaps
2. Run has hint-only rFonts (no names) → fallback to `_body_rpr` font names
3. Run has no rPr at all → use `_body_rpr` directly
