fix(word-addin): author and resolve tracked edits so cards work on Word for Mac desktop
WHY THIS MATTERS On Word for Mac (16.112), Accept/Reject on a Mike edit card silently failed: the card errored with the generic "Word couldn't update this change" while the redline stayed pending, forcing users to double-accept from Word's Review tab. Replicated live in the real host before fixing. WHAT THE MAC HOST ACTUALLY DOES (live-probed, OOXML-verified) 1. insertText(Replace) under TrackAll applies the DELETION immediately and untracked - the .docx holds only w:ins, no w:del - so the deletion half of a replacement never exists as a revision. The "exactly one Added + one Deleted" ownership proof can then never succeed, every resolution layer refuses honestly, and the card degrades. (Superset of the Microsoft-acknowledged, still-open office-js#5188; Windows and web track the pair correctly.) 2. Split operations - insertText(after) + delete() on the match - DO produce a real tracked deletion (w:del with w:delText in the file), but its text reads EMPTY through every JS surface (#5188 proper). 3. The desktop-only Word.Revision API (WordApiDesktop 1.4, document.revisions) reliably lists all revisions and accept()/reject() work; compareLocationWith() reports each replacement's Delete revision as Adjacent to exactly its own Insert. 4. Retained cross-batch range proxies intermittently die with GeneralException at Document._GetObjectByReferenceId. HOW THE FIX WORKS 1. Authoring: replacements queue insertText(..., After) + match.delete() instead of insertText(Replace) - the only form every host records as a full Added+Deleted pair (also the pattern production Word add-ins use; both public Mac bug reports were filed against the Replace form). Pure deletions just delete(). 2. Resolution: where WordApiDesktop 1.4 is supported, the document-level fallback reads Word.Revision objects instead of getTrackedChanges. The ownership proof adapts to the empty-text bug in two provable steps: exact text match first; an empty-text Delete may stand in for the edit's deleted side only when it is the SOLE pending Delete in the document, or when adjacency to the edit's uniquely matched Insert singles it out (AdjacentBefore/After - split authoring writes the insertion immediately beside the deletion). Anything ambiguous still aborts untouched. 3. Restore: the same Revision-surface match re-links cards after a task pane reload (batched and single-edit paths), holding no revision proxies - resolution re-verifies at decision time. 4. Error honesty: when the document-level fallback reaches a semantic "changed" verdict, that now outranks a dead-proxy GeneralException from the anchor pass, so the card reports why instead of the generic failure. Silent catch sites also log their errors. The e2e mock mirrors the new authoring: insertText still materializes the revision pair (the mock is a web-host model), range.delete() is tracked (no-op after an insert; a Deleted-only group for pure deletions), and a pure deletion no longer fabricates an empty Added revision. Spec write expectations move from location "Replace" to "After". Verified live on Word for Mac 16.112: two same-paragraph spelling fixes resolve from their cards (adjacency disambiguation picking the right empty-text Delete), accept-all drains the Review tab to zero, Direct-mode auto-accept and a Formatted heading revision resolve, and the document's final text was confirmed via body + OOXML reads. The web path is untouched (body-level getTrackedChanges fallback unchanged; the desktop path is capability-gated), and the full hermetic suite passes. Trade-off: split authoring renders a replacement as adjacent Deleted + Added runs rather than one combined replace mark - visually near-identical, and the standard shape other legal redlining add-ins produce. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JN4mcnhSK7xpxzF2b3WFkE
| Repository | open-legal-products/mike |
|---|---|
| Author | Amal <mamalanand3@gmail.com> |
| Authored | |
| Committed | |
| Parents | 673ab898 |
| Stats | 6 files changed , +324 , -44 |
| Part of | Make Word edit approval reliable across hosts |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-438d6e1e.md
from inside the repo you want the change in.