fix(docx-core): resolve tracked move paragraph marks safely - #989
Conversation
Native paragraph resolution handled ordinary insertion/deletion marks but ignored equivalent moved-to/moved-from marks, leaving empty moved endpoint containers after projection. Resolve the matching move marks without changing content-only move paragraph ownership, and prevent bookmarks local to discarded endpoints from being rescued onto unrelated surviving content. Complete named-range fixtures, terminal and table-cell controls, selective foreign histories, and an actual compareDocuments case establish native/AST parity. Full bounded root pre-submit passes. Fixes: #985
Independent dynamic Opus 5 review reproduced a regression where rejecting a moved-to paragraph mark deleted a local bookmark pair even though its untracked content survived and merged forward. Harvest local endpoint pairs only when all substantive content is selected insertion/move-to markup. Apply the same guard to the inherited AST gap rather than using parity with that gap as an oracle. Two red-to-green surviving-content controls and a real two-author selective-resolution case raise the focused move suite to eighteen passing tests. Ref: #985
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
LLM gate (advisory)All evaluated rules passed - 8 pass, 0 warn, 0 error, 8 skipped, 16 total FindingsNone. All 16 rules (8 evaluated, 8 skipped)
|
…raph-marks-20260917
|
Advisory adjudication for head The canonical-emission completeness warning concerns a revision consumer change, not a new write-time emission surface. Consumption is verified by the new complete-range native/AST paragraph parity controls and the built-code real public NVCA Accept/Reject smoke. All six local gates and the required 21-test corpus replay pass on this head, and fresh dynamic Opus review approves it. The warning is adjudicated as not applicable to an emission rollout, not silently counted as PASS. Residual consumer limitations are recorded separately in #941 and #991; Word projections remain UNVERIFIED. |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Comparison-package parity controls execute native code but their coverage excludes docx-core sources, leaving the CI report blind to the new move-mark and selected-bookmark branches. Add direct native tests with independent expected paragraph and bookmark projections, including middle/terminal endpoints, fully selected insertion content, empty/untracked/mixed survivors and foreign move history. Preserve all runtime behavior and revision-selection boundaries; do not make coverage green by changing exclusions or production code. Ref: #985, #941
Independent dynamic review showed the loop headers were measured but wrapper-nested bookmark harvesting could be reverted with all tests green. Add source and destination cases with live counterparts outside selected wrappers, an unpaired spanning start, and accept-side empty/untracked/foreign/mixed survivors. The strengthened suite passes sixteen controls; reverted harvesting fails two cases and removing local pairing fails one, independently executed rather than inferred. Correct destination conformance citations and explicitly document the inherited authorless range-end test selection. Runtime and filter policy remain unchanged. Ref: #985, #941
Preserve reviewed history while incorporating main's independently bounded public ILPA annotation cases. Repeat final integration gates and review before pushing this focused runtime repair; do not rewrite or bypass protected history. Ref: #985
The independent integration review validated resolved output but found that the new native consumer fixtures omitted the schema-required range-start date. Add a fixed valid UTC date to the actual endpoint helper so these regressions start from schema-valid OOXML rather than accidentally malformed input. All sixteen control inputs and resolved outputs now pass the repository MCE-aware schema gate, and the test helper keeps moveFrom content as w:t. Preserve selectors, IDs, text, survivor guards and every mutation discriminator; no production code or timeout changes. Ref: #985, #941
|
Final local release evidence for head
Fresh CI/Codecov and actual advisory verdicts still required. Automerge is not armed, and this is not post-merge proof. Exact-merge own clean build/full gates/public real-document smoke, local visual evidence where meaningful, and production exact-SHA verification will follow merge. |
Keep the native move fix current with the independently shipped terminal-mark cleanup without rewriting reviewed history. Re-run release gates against the combined source before shipping. Ref: #985
Latest-main integration and final-head release verificationExact head Independent dynamic Claude Opus5 at this exact head: APPROVE. Actual20 core +51 parity/cleanup controls pass, 32 newly regenerated actual-helper schema packages pass, and source-vs-both-parent interaction probes found no new regression. Complete collected 19,287-byte analysis Fresh built public API smoke: source SHA-verified against this head's NVCA Management Rights Letter manifest. Native and AST Accept/Reject match the corresponding original/revised text; actual LibreOffice dispatches on unresolved tracked input, compared against independently imported original/revised identity controls, each match 33/33 paragraph/heading texts. Tracked, native Accepted and native Rejected packages schema-validate 3/3. Local public-only log Limits remain explicit: #973 terminal-reader move structure is not fixed; #941 spanning/unpaired annotation cases and #991 foreign co-located revision-history handling remain separate. Native preserves untouched pre-existing empty property containers while AST may remove them; no universal byte-for-byte property parity claim. All Word projections remain UNVERIFIED. Normal push only; automerge remains unarmed until this head's CI and actual advisory verdicts finish. Exact-merge clean-build smoke/local meaningful renders/production exact-SHA proof still follow after merging. No hosted API or protection mutation. |
Post-merge smoke passedMerged and freshly built in an isolated detached worktree: Own locked dependencies and all six mandatory local gates passed: build, workspace lint, full suite 3,496 passed / 47 documented platform or opt-in skips, spec coverage, conformance citations and conformance document. Actual smoke process exit0 collected. Real-world fixture: public NVCA Management Rights Letter, SHA-verified against this exact merge's manifest. Fresh built public compare API emits a genuine tracked paragraph move. Native and AST Accept/Reject match the corresponding source text. Actual LibreOffice dispatches on the unresolved tracked comparison, against independently imported original/revised identity controls, each match 33/33 paragraph/heading entries. Tracked/native Accepted/native Rejected packages pass repository MCE-aware schema validation 3/3. Required corpus 21/21 and all23 reviewed rows also passed at the tree-identical premerge head and in CI. Visual evidence: fresh original/revised/Accept/Reject PDFs and physical page-two PNGs generated from this exact merge. Accept PNG is byte-identical to revised, Reject PNG byte-identical to original. Both projections inspected in-session and all four images opened locally. The moved paragraph's revised order and original restoration are visible; this is target-page evidence, not all-page/font/Word certification. Local-only artifacts: Production docs/redirect deployment READY, actual Limits remain: #973 terminal LibreOffice move structure, #941 spanning/selective range annotations and #991 foreign paragraph-mark history are not repaired. Word Accept/Reject remains UNVERIFIED, and open-cleanly is not a projection oracle. Worktrees retained because other follow-ups remain open; no cleanup or close-out. Local log: First 50 log linesLast 50 log lines |
Summary
Resolve selected moveFrom/moveTo paragraph marks through the existing native mark-based break policy, matching complete-range Accept/Reject projections without retaining empty moved containers. Preserve local bookmarks around untracked or foreign surviving content; the AST path receives the same independently justified guard.
Why / scope
Native PhaseA treated only del/ins marks as break revisions while comparison projection also handled moves. A reduced parity discrepancy was confirmed using complete named ranges, content wrappers and schema-valid packages, including terminal and cell cases. A fresh reviewer found the first bookmark guard discarded anchors around surviving text; independent red/green controls repair that in both engines.
One concern, no public APIs, arbitrary content-based paragraph deletion, hosted API work or protection changes. Existing inherited cross-paragraph bookmark and selective orphan-range-end behavior is not represented as fixed. Foreign endpoint preservation is asserted; a fully valid selective move-group resolution contract is not newly claimed. LibreOffice terminal-container limitation remains separate in #973. Word Accept/Reject UNVERIFIED.
OpenSpec: focused bug repair, no new capability or architecture shift. Relevant OOXML source/test claims use edition5 citations. Complete packages reuse shared synthetic fixtures; inline markup is the scenario under test. No web/UI visual changes.
Verification at a99b143
npm run buildnpm run lint:workspacesnpm run test:run(comparison575 passed/11 skipped, core1318 passed/1 skipped; render verifiers passed)npm run check:spec-coveragenpm run check:conformance-citationsnpm run check:conformance-docFresh main integration verification at b5f326a
Normal merge (no rewritten reviewed history) with mainca618780/PR988 retains both parents' changes.
Residual section-on-move, selective range-end and spanning-bookmark characterizations are explicitly retained in open941: #941 (comment) . Convergence with the existing ins/del section-break policy is not general reader/Word section fidelity. Inherited foreign paragraph-mark property history is now separately tracked in991 and is not claimed repaired here.
All local gates passed before each push. Base freshness is rechecked before arming automerge. Exact-merge public smoke and production-docs merge-SHA verification remain required after landing.
Fixes: #985
Ref: #941, #973, #982, #986