#1733·skills

docx validate.py: comment present in comments.xml but anchored to nothing passes as valid

Author: Dmitry-KovCreated Sep 6, 2026Updated Sep 6, 2026

scripts/office/validate.py checks comment markers in one direction only: a marker in document.xml that references a non-existent comment is reported, and unpaired commentRangeStart/commentRangeEnd are reported. The reverse case is not checked — a <w:comment> in comments.xml with no commentRangeStart, commentRangeEnd or commentReference anywhere in the document passes. Word opens such a file without a warning and simply does not show the comment.

This is the defect python-docx produces when an agent assigns paragraph.text: the paragraph's runs are replaced by one new run, and the comment anchors (which sit between runs) go with them. The comment survives in comments.xml, anchored to nothing.

Repro (file produced by an agent using python-docx on a contract with two reviewer comments; original attached):

python scripts/office/validate.py agreement.docx --original base.docx
# Paragraphs: 22 → 23 (+1)
# All validations PASSED!

python scripts/office/validate.py agreement.docx --original base.docx --author Agent
# reports the untracked text edits (correct), still nothing about the comment

Opening agreement.docx in Word: one of the two reviewer comments is gone from the margin. comments.xml still contains both.

Suggested fix in validators/docx.py::validate_comment_markers — after computing marker_ids, also report comment_ids - marker_ids:

orphaned_comments = comment_ids - marker_ids
for comment_id in sorted(orphaned_comments, key=...):
    errors.append(f'  comments.xml: comment id="{comment_id}" is not anchored anywhere in document.xml')

Since --original is already available, comparing the count of anchored comments before and after would catch the same thing even when ids are renumbered. Happy to open a PR with either or both, plus the two files as fixtures, if that's welcome.

Context: I hit this while measuring what different verification approaches catch on machine-edited docx (github.com/Dmitry-Kov/ooxml-integrity). Tested against 41bbe19.

base.docx

agreement.docx