Release note · August 4, 2026

Unbound custom XML is still a handoff boundary

By SybilGambleyyu · DocFence 0.33.0

A Word document can carry a conventional custom-XML store even when no visible content control maps to it. That does not prove a client will display, use, or remove the data. It does mean the package retains a stored data surface a handoff policy may need to account for.

DocFence 0.33 adds require_no_custom_xml_data, an optional candidate-state gate for that narrow question. It reports a count only: no XML values, element names, member paths, or fingerprints leave the local scan.

Stored package data does not need a visible mapping

Microsoft’s Custom XML parts overview describes custom XML parts as package data that Office solutions can create or modify while a document is open or closed. A content-control binding is one way a document can refer to a store; it is not a precondition for the store to be present.

customXml/
  item1.xml              conventional stored data
  itemProps1.xml         associated custom-XML properties
  _rels/item1.xml.rels   package relationship material

DocFence counts conventional data and associated-properties parts under customXml/; relationship parts remain a separate structural surface. The count is deliberately modest. The scanner does not expose or interpret XML values, classify a store’s meaning, remove or rewrite anything, or claim what Word will do with it.

A clean-candidate gate, not a data classifier

Teams that require a candidate with no conventional custom-XML data or properties parts can state that boundary in a readable policy:

rules:
  require_no_custom_xml_data: true

The rule emits DFP079 when the candidate contains one or more counted parts. It needs no approved baseline and does not disclose why the store exists or what it contains. A baseline-comparison rule remains useful for a team that permits an approved store but wants to detect a count or payload boundary change; the candidate gate answers the distinct handoff question.

Public JSON, Markdown, and SARIF contain only custom_xml_part_count for this gate. They do not contain the data payload, XML node names, package member names, targets, paths, or private semantic fingerprints. That keeps a CI failure useful without turning its output into a secondary document-data channel.

A reproducible unbound case

Document Change Assurance Benchmark 0.23.0 supplies a matching deterministic pair: review.unbound_custom_xml_payload_changed. Baseline and candidate retain the same conventional custom-XML data/properties topology, relationships, package-member set, and stored Word text. Only the synthetic customXml/item1.xml payload changes.

word/document.xml       byte-identical on both sides
w:dataBinding           absent on both sides
customXml/item1.xml     the sole changed package member

The public oracle names the boundary without publishing or interpreting the payload. DCAB’s optional adapter reaches a strict 34/34 score from DocFence’s public aggregate evidence: a custom-XML change, a stable two-part custom-XML inventory, and zero data bindings. It does not consume raw XML or a private fingerprint.

Use the release

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.33.0/docfence-0.33.0-py3-none-any.whl

docfence profile candidate.docx --format markdown
docfence check approved.docx candidate.docx --policy docfence.yml --format sarif --output docfence.sarif

Hosted CI passed on the release commit. Reproducible wheel and source-archive builds matched their published SHA-256 digests, and the downloaded wheel produced DFP079 for the unbound DCAB candidate under this policy. The tagged policy reference, threat model, and validation notes define the exact scope.