Skip to content

fix(docx-compare): filter header/footer relationships from sectPrChange snapshots #944

Description

@stevenobiajulu

Consequence first

The sole tagged comparison spine emits schema-invalid section-property change snapshots when the prior section has header/footer relationships. A conforming consumer sees w:headerReference or w:footerReference inside the historical w:sectPr nested under w:sectPrChange, but that inner element is CT_SectPrBase and cannot contain relationship-bearing header/footer references.

This is not an ordering defect and is not part of #941's paragraph-move markup scope.

Reproduction on current main

Reproduced at 6a7bb7a35178153cc0e971285b2dc7421a8478df using only the repository's public ILPA fixtures:

  • tests/test_documents/redline/ILPA-Model-Limited-Partnership-Agreement-WOF_v2.docx
    • SHA-256 7880ad250513d23be064a5c71ef79aecb2bf3d870c45fa070256d5388ac74455
  • tests/test_documents/redline/ILPA-Model-Limited-Parnership-Agreement-Deal-By-Deal_v1.docx
    • SHA-256 46be28b42853da50eba3e24df944d04dd34893f56539258d53bd69b4b33547d7

Compare those files with compareDocuments() using a fixed author/date, extract word/document.xml, apply the repository's MCE preprocessing, and validate with:

xmllint --noout --nonet \
  --schema spec-compliance/ecma-376/validation/wml-document-transitional.xsd \
  document.xml

There are exactly 6 first-failure schema diagnostics in this class. One representative emitted shape is:

<w:sectPrChange w:id="1480" w:author="Public Investigation" w:date="2026-08-23T00:00:00Z">
  <w:sectPr>
    <w:footerReference w:type="even" r:id="rId56"/>
    <w:footerReference w:type="default" r:id="rId50"/>
    <w:pgSz w:w="12240" w:h="15840"/>
  </w:sectPr>
</w:sectPrChange>

The other first failures are in comparison-authored w:sectPrChange revisions 1915, 20075, 20161, 20446, and 20485.

Schema premise

The vendored Transitional WML schema establishes:

  • CT_SectPrChange contains an optional w:sectPr of type CT_SectPrBase (wml.xsd:959-967).
  • CT_SectPrBase contains only EG_SectPrContents (wml.xsd:1636-1641).
  • Only live CT_SectPr adds EG_HdrFtrReferences before those contents (wml.xsd:1642-1649).

So header/footer references are legal in the live outer w:sectPr, not in its prior-state snapshot.

Root-cause localization

packages/docx-compare/src/tagged/taggedTreeSerializer.ts clones every original section child except a prior sectPrChange in both snapshot paths:

  • section-scope applyPropertyDelta (~552-570)
  • paragraph-property sectPr delta (~653-668)

By contrast, packages/docx-core/src/primitives/track-changes-emitter.ts already excludes w:headerReference, w:footerReference, and nested w:sectPrChange from buildSectPrChangeElement snapshots (~16-20, ~245-285). The tagged path has drifted from that typed helper/policy.

Acceptance criteria

  • Both tagged section-delta paths use one schema-derived/shared CT_SectPrBase snapshot policy.
  • Inner w:sectPrChange/w:sectPr snapshots exclude w:headerReference, w:footerReference, and nested w:sectPrChange; live outer section references remain correctly relationship-bound.
  • Header/footer relationship differences that cannot be represented by w:sectPrChange are explicitly surfaced as unrepresented rather than silently discarded.
  • Minimized section fixtures plus the public ILPA pair validate against the vendored schema for this class.
  • Accept All and Reject All preserve the intended section/header/footer projections and every retained relationship resolves to the correct part.
  • Tests use the shared OOXML fixture helpers and carry the required ECMA-376 conformance citations.

Non-duplicates / related

No private or purchased-template document was accessed for this reproduction. Microsoft Word was not touched.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcomparisonDocument comparison / redline pipelinefixtracked-changesTracked changes, comments, revision markers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions