The twin of the W5-E/W8-B rsidR fabrication bug: when python-docx saves a Word-authored document under reproducible=True, it synthesises w14:paraId and w14:textId on paragraphs whose source had no such attribute. Word treats paraId as a stable per-paragraph identifier; fabricating one at save-time breaks 'compare documents' and collaborative-editing rebase logic. Paragraph-alignment.docx, preserve-custom-xml.office.docx, and preserve-styles-with-effects.office.docx all surface this diff in the W8-F audit. Expected to go GREEN once paraId stamping is constrained the same way rsidR stamping now is.
Library verdicts: python-docx: — docxjs: —
| Feature id | docx/paraid-reproducible-save |
|---|---|
| Format | docx |
| Category | round-trip |
| Spec | ecma-376-5-part-1 § 17.3.1.33 w14:paraId |
| ID / part | Predicate | XPath | python-docx | docxjs |
|---|---|---|---|---|
paraid-not-fabricatedword/document.xml | existAt least one <w:p> in the body must remain without a w14:paraId attribute. Fails today — python-docx stamps every paragraph under reproducible=True. | //w:p[not(@w14:paraId)] | — | — |
No render assertions declared.
scripts/gen_paraid_reproducible_save.py
#!/usr/bin/env python3
"""Generate ``fixtures/docx/paraid-reproducible-save.docx``.
Loads the Word-authored paragraph-alignment.docx and re-saves it with
``reproducible=True``. Current python-docx will fabricate a
``w14:paraId`` on every paragraph that didn't carry one in the source
— the tombstone manifest fails when that happens. Once the
paraId-stamping fix lands (the twin of the W8-B rsidR fix), this
generator's output becomes assertion-compliant.
"""
from __future__ import annotations
from pathlib import Path
from docx import Document
_REPO_ROOT = Path(__file__).resolve().parent.parent
_SRC = _REPO_ROOT / "fixtures" / "docx" / "paragraph-alignment.docx"
_OUT = _REPO_ROOT / "fixtures" / "docx" / "paraid-reproducible-save.docx"
def main() -> int:
doc = Document(str(_SRC))
_OUT.parent.mkdir(parents=True, exist_ok=True)
doc.save(str(_OUT), reproducible=True)
print(_OUT)
return 0
if __name__ == "__main__":
raise SystemExit(main())
{
"$schema": "../manifest.schema.json",
"id": "docx/paraid-reproducible-save",
"title": "Reproducible save: w14:paraId/textId not fabricated on paragraphs that lack them (KNOWN FAILING — python-docx bug)",
"format": "docx",
"category": "round-trip",
"roles": [
"authoring"
],
"summary": "The twin of the W5-E/W8-B rsidR fabrication bug: when python-docx saves a Word-authored document under reproducible=True, it synthesises w14:paraId and w14:textId on paragraphs whose source had no such attribute. Word treats paraId as a stable per-paragraph identifier; fabricating one at save-time breaks 'compare documents' and collaborative-editing rebase logic. Paragraph-alignment.docx, preserve-custom-xml.office.docx, and preserve-styles-with-effects.office.docx all surface this diff in the W8-F audit. Expected to go GREEN once paraId stamping is constrained the same way rsidR stamping now is.",
"spec": {
"source": "ecma-376-5-part-1",
"clause": "17.3.1.33",
"element": "w14:paraId",
"notes": "w14:paraId and w14:textId are Word 2010+ attributes scoped to the http://schemas.microsoft.com/office/word/2010/wordml namespace. They mark paragraph and run identities so collaborative-editing features can track moved/edited content across revisions. python-docx's DocumentPart.before_marshal(reproducible=True) synthesises them deterministically (hash of content) when absent — same shape as the 2026.05.2 rsid generation, same fidelity bug: an already-identified paragraph shouldn't be re-stamped, but neither should an unidentified one be given a fresh identifier. The W8-B fix scoped rsidR to runs that already carry one; this manifest pins the paraId twin."
},
"fixtures": {
"machine": "docx/paraid-reproducible-save"
},
"round_trip": {
"library": "python-docx",
"source_fixture": "docx/paragraph-alignment",
"notes": "Source is the Word-authored paragraph-alignment.docx (one <w:p> with no w14:paraId in the source XML). Runner loads and re-saves it; assertion checks that no w14:paraId was fabricated."
},
"generator": {
"python": "scripts/gen_paraid_reproducible_save.py"
},
"assertions": [
{
"id": "paraid-not-fabricated",
"part": "word/document.xml",
"namespaces": {
"w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
"w14": "http://schemas.microsoft.com/office/word/2010/wordml"
},
"xpath": "//w:p[not(@w14:paraId)]",
"must": "exist",
"description": "At least one <w:p> in the body must remain without a w14:paraId attribute. Fails today — python-docx stamps every paragraph under reproducible=True."
}
]
}
Fixture file not found on disk.
No rendered reference is available for this case.