Release note · August 1, 2026

Visible Word content can have an invisible source of truth

By SybilGambleyyu · DocFence 0.6.0

A content control can look like ordinary Word text while retaining an XML mapping that tells Word where the value belongs—or where it should come from. That distinction matters at a controlled handoff. A reviewer may approve the visible words while missing the document’s stored data/view connection.

DocFence 0.6.0 makes that connection review-visible without turning a CI report into a document-data leak. It inventories standard content-control XML mappings, their storage-ID state, associated custom XML parts when the package establishes the association, and identifiers that cannot be matched. It does not print XPath expressions, namespace-prefix mappings, storage IDs, part names, or XML values.

A content control is not always its own source of truth

The Open XML SDK describes w:dataBinding as the information that maps a structured document tag to an XML element in a custom XML data part. When Word finds the mapped element, the stored value can replace the content control’s current run content. Word’s XMLMapping model makes the same boundary explicit: it links content-control text to XML data in the document data store.

That is useful for templates and generated documents. It is also a separate review surface. A handoff may need to establish that no such mappings remain, or to establish that an approved mapping and its bound data did not change.

Evidence without pretending to be Word

DocFence recognizes direct w:sdtPr/w:dataBinding declarations in the document stories it already reviews. For a nonempty w:storeItemID, it associates the mapping with a custom XML data part only through the package’s internal customXmlProps relationship and its ds:datastoreItem identifier. It accepts conventional and Strict forms, plus the established Word-compatible properties vocabulary found in real packages.

The public inventory contains only five counts: mappings; mappings with a storage ID; mappings without one; referenced custom XML data parts; and unmatched storage IDs. A nonempty ID that cannot be associated remains explicit review evidence rather than a guessed target. A mapping without an ID is also counted, but DocFence does not evaluate its XPath and does not guess which custom XML part Word could select.

Recognized properties relationships used for a binding must be internal and point to a valid storage-properties root. If that contract is malformed, analysis fails closed. The tool never evaluates XPath, updates a content control, renders the document, interprets the XML payload, or decides whether a mapping is expected or safe.

Choose “none” or “no change”

A clean-handoff policy can prohibit stored mappings entirely:

rules:
  require_no_data_bindings: true

This emits DFP023 whenever the candidate has a recognized mapping declaration. For an approved template that intentionally uses data bindings, preserve the baseline and reject a later mutation instead:

rules:
  no_data_binding_changes: true

This emits DFP024 if the private inventory changes. For an identified storage ID, the comparison includes the paired custom XML data and properties payloads privately, so a bound-data mutation is visible without revealing it. If every custom XML mutation must block a handoff, combine this gate with no_custom_xml_changes.

What was tested

The release tests conventional and Strict OOXML, Word’s established properties-root spelling, mappings without a storage ID, unmatched IDs, multiple controls that point to one data part, mapped-data mutations, relationship-ID renumbering, malformed properties roots and target modes, policy findings, Markdown/JSON/SARIF output, and redaction markers.

I also profiled an independent OOXML Reference Corpus data-binding package. It reports one content control, one mapping, one referenced custom XML part, and no unmatched ID—without reproducing the package’s document or XML material.

The wheel and source archive were independently rebuilt twice from the release commit with SOURCE_DATE_EPOCH; both artifact pairs were byte-identical. The public release contains the wheel, source archive, and SHA-256 manifest. I downloaded those assets, verified the checksums, installed the wheel in a fresh environment, and repeated the external-package profile.

Use the release

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

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

The full boundary is in the policy reference and threat model. DocFence is not a template engine or a rendering verdict; it is local, bounded evidence about stored OOXML state. It is MIT-licensed and available on GitHub. For the preceding mail-merge boundary, read Mail merge is a document dependency, not just a template setting.