fix(docx-core): make accept all paragraph removal mark-based, not content-based (closes g5)#342
Conversation
…tent-based (closes G5) The TS engine over-deleted a paragraph whose only content was inside w:del (or w:moveFrom) but whose paragraph MARK was untracked — text deleted from a pre-existing paragraph, which Word/LibreOffice keep (empty) on accept. This is the exact accept-side mirror of the reject over-deletion fixed in #337 (G4), pinned as the differential's G5 gap. Accept is now purely mark-based on BOTH accept entry points: drop a paragraph iff its mark is PPR-DEL (<w:pPr><w:rPr><w:del/>). The content-based all-w:del/w:moveFrom drop heuristic is removed from acceptAllChanges (trackChangesAcceptorAst.ts) and the primitive acceptChanges (accept_changes.ts) in lockstep, with their now-dead helpers (paragraphHasOnlyRemovedContent, containsRun, isWElement, the locals sets). - Flip [LEAN-HELP-08] (G5) from characterized divergence to agreement; with G5 closed, every G-case (G1-G5) agrees Lean <-> engine, no KNOWN gap remains. - Add a targeted regression exercising BOTH accept paths over four shapes (PPR-DEL drop, del-only keep, moveFrom-only keep, pPrChange-snapshot ignore), asserting the two paths agree. - OpenSpec: new make-accept-paragraph-collapse-mark-based change ([ACCEPT-MARK-01..04]); revise the pending harness + broaden-lean-accept G5 scenarios to agreement; ROADMAP records G5 closed. Lean is unchanged (its accept keep-empty, broadened in #340, was already faithful). Full scoped docx-core suite: 1347 passed / 3 skipped.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
LLM-Based Quality GateOverall: ✅ PASS (6 pass · 0 warn · 8 skipped · 14 total)
Full checklist questions
Estimated cost (this run): $0.0146 — 44,811 input + 445 output tokens (≈4 chars/token) on |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
✅ Post-merge smoke passedMerged: Steps
Real-world fixtures
Log: Cleanup
|
Summary
Makes the TS engine's Accept All paragraph removal purely mark-based — the symmetric accept-side mirror of #337's reject fix (G4). Closes G5, the last characterized gap in the Lean↔TS helper differential.
A paragraph whose only content is inside
w:del(orw:moveFrom) but whose paragraph mark is untracked means text deleted from a pre-existing paragraph — which Word, LibreOffice, and the (broadened, #340) Leanacceptall keep as an empty<w:p>. The TS engine over-deleted it via a content-based heuristic. Accept now drops a paragraph iff its mark isPPR-DEL(<w:pPr><w:rPr><w:del/>).Changes
acceptAllChanges(trackChangesAcceptorAst.ts) and primitiveacceptChanges(accept_changes.ts): removed the content-based all-w:del/w:moveFromdrop heuristic on both accept entry points in lockstep; kept only the mark-basedPPR-DELdrop (strict direct-child traversal, so aw:delnested in aw:pPrChangesnapshot is ignored). Removed now-dead helpers (paragraphHasOnlyRemovedContent,containsRun,isWElement, the locals sets).[LEAN-HELP-08](G5) flipped from characterized divergence to agreement; module header records no KNOWN gap remains. With G5 closed, every G-case G1–G5 agrees Lean ↔ engine.make-accept-paragraph-collapse-mark-based([ACCEPT-MARK-01..04]); pending harness + broaden-lean-accept G5 scenarios revised to agreement;verification/ROADMAP.mdrecords G5 closed.Lean is unchanged (its accept keep-empty, broadened in #340, was already faithful).
Verification
@usejunior/docx-coresuite: 1347 passed / 3 skipped (+4 new tests, zero regressions).leanHelperDifferentialexe;tsc --noEmitclean;openspec validate --strict✅; spec-coverage + allure-labels + allure-quality 0 errors.Closes G5. Deferred follow-up: PR-B (wire the LibreOffice accept/reject oracle voter into the harness).