Repository navigation
feat(validate): report cross-part comment inconsistencies - #36
Merged
Merged
Conversation
`docx validate` checked each WML part against the schema only, so a package whose comments were missing from commentsIds.xml / commentsExtended.xml (a Word repair trigger, #33) reported "valid". Add a pure package-consistency audit beside the schema pass: - every comment keyed by its last paragraph's w14:paraId in each PRESENT side-part (commentsExtended.xml, commentsIds.xml) - comment marker balance across story parts: range start/end pairing, range -> commentReference, commentReference -> existing comment Findings file under the part they concern, tagged "(consistency)" in text and `kind: "consistency"` in --json, and count toward exit 1. Every shipped fixture (including Word-authored academic-paper.docx with commentsIds.xml) still validates clean. Fixes #34 Triage-Routine: true Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LkctEMYpX1DxpKLGCMzZxp
kklimuk
added a commit
that referenced
this pull request
Nov 6, 2026
…rst minted A create'd doc has no commentsExtended.xml until the first reply or resolve materializes it, and that path registered only the touched thread. So add -> add -> reply c0 left c1 with no <w15:commentEx>, which the new validate consistency check (#36) reports. Materializing the part now writes a done="0" entry for every comment already there (Word's shape), and reply ensures the part before appending its own body so the reply is not registered twice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kklimuk
added a commit
that referenced
this pull request
Nov 6, 2026
…/footer parts Word lets a reviewer comment inside a footnote or endnote, so the comment's range markers and reference run live in footnotes.xml/endnotes.xml. comments delete pruned word/document.xml only, leaving a commentReference that names no comment, which validate's new consistency check (#36) reports. It now prunes every story part the consistency check scans. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kklimuk
added a commit
that referenced
this pull request
Nov 6, 2026
…t removes a revision Rejecting an insertion or accepting a deletion spliced the wrapper out with every comment marker inside it. A comment's markers often straddle a revision: edit --text on a commented paragraph under tracking re-anchors the range ends after the new words (inside the <w:ins>) while the starts stay ahead of the <w:del>, and a tracked delete wraps the reference runs. So reject --all after a tracked rewrite left range starts with no end, and accept --all after a tracked delete left ranges with no reference; validate (#36) reports both and Word drops such comments. Markers whose comment also has a marker outside the revision now stay where the wrapper stood; a comment wholly inside the revision still goes with its text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kklimuk
added a commit
that referenced
this pull request
Nov 6, 2026
… its paragraphs goes An untracked delete --at pN / edit --at pN --text "" on the paragraph holding one half of a cross-paragraph comment removed that half with it: deleting the start paragraph left a commentRangeEnd with no start, deleting the end paragraph left a start with no end or reference. edit --runs '[]' (an emptied paragraph) dropped the half the same way. validate (#36) reports all three, and Word drops the comment. The straddling markers now move onto the neighboring paragraph (previous, else next — the text-box rule), and an emptied paragraph keeps its half at offset 0. A comment wholly on the removed paragraph still goes with it. The 'which markers straddle' check is shared with accept/reject via core/comments/straddling-markers.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kklimuk
added a commit
that referenced
this pull request
Nov 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 docx-cli triage
What was wrong
docx validateonly schema-checks each part, so cross-part comment breakage went unreported. Repro:cp tests/fixtures/academic-paper.docx a.docx && docx comments add a.docx --at p1 --text "new note" && docx validate a.docxprintedvalid — 11 parts checked, exit 0. The new comment has no entry incommentsIds.xmlorcommentsExtended.xml, which is the Word repair trigger reported in #33.What changed
src/core/raw/package-consistency.ts(checkPackageConsistency).validateruns it alongside the schema pass, over the same parsed parts. It checks:w14:paraId, in each side part that is present (commentsExtended.xml,commentsIds.xml). A side part that is missing entirely is legal and not reported.commentReference, and each reference names a comment that exists.(consistency)in text output andkind: "consistency"in--json, and it makesvalidateexit 1. Not reported on purpose, to avoid noise: orphan side-part entries, comments with no markers in the document, ids that appear more than once because ofmc:AlternateContent(compared as sets), and the glossary document.--help, REFERENCE.md, the skill'scommands.md,src/cli/CLAUDE.md,src/core/raw/CLAUDE.md.Verification
academic-paper.docx, which has all three comment parts.tests/cli/validate.test.tsbuilt from hand-made inconsistent packages: missing commentsIds entry, a consistent commentsIds, a range whose reference was deleted, an unpaired range start, a dangling reference (--json), and a clean commented doc.bun run check✅bun run test:unit✅ (1915 tests)Decisions for you
validateinstead of adding thedocx checkverb the issue suggests, so agents keep a single "is this safe to deliver?" command with one exit code. Should this be a separate verb or a flag instead?commentsExtended.xmlalone. Verified repair triggers are measured only for the combined fix(comments): new comments are not registered in commentsIds.xml, so Word offers to repair the file #33 state.comments add→comments reply→comments addleaves the third comment without acommentsExtended.xmlentry, sovalidateexits 1. That is correct (it is the fix(comments): new comments are not registered in commentsIds.xml, so Word offers to repair the file #33 bug), but users will see it. Merge this together with or after the fix(comments): new comments are not registered in commentsIds.xml, so Word offers to repair the file #33 fix.Action needed: approve/merge — review the decisions above, ideally merging after #33's fix lands.
Fixes #34
Generated by Claude Code