1ef9451e89
The pure render layer now emits data-src-start/data-src-end (source char offsets from BlockWithRange) on every LIVE-source rendered block, in BOTH modes — the contract the webview's selection→source mapping (SLICE-4) walks the DOM for. Per spec §6.1 INV-36 / §7.2 SLICE-2. - trackChangesModel: shared `srcAttr(blk)` helper; threaded through renderOp + renderReviewOp + the renderReview loop (removed blocks → "" / no data-src, as they have no live source). renderPlain switches from a single whole-document markdown pass to per-block `<div data-src-start/end>` wrappers — bare divs (no cw- class) so the off/clean preview stays visually clean while becoming a selection→source surface. Pure, vscode-free, deterministic (extends INV-22). - unit (test/trackChangesModel.test.ts): data-src offsets equal splitBlocksWithRanges in both modes; removed + proposal blocks carry none; off-mode stays cw--free; determinism. 200 unit + 47 host E2E green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>