Release note · August 1, 2026

Mail merge is a document dependency, not just a template setting

By SybilGambleyyu · DocFence 0.5.0

A Word template can look like an ordinary document while retaining enough mail-merge state to point at a data source, retain a query or connection configuration, and preserve recipient-selection data. That is not a harmless implementation detail at a controlled handoff. Microsoft documents the prompt shown when a linked mail-merge document would run a SQL query, and says accepting it lets code run on the computer.

DocFence 0.5.0 turns that stored state into bounded, local evidence. It makes mail-merge configuration, external data/header-source relationships, and internal recipient-data parts review-visible without printing source paths, connection strings, queries, table names, field mappings, relationship IDs, or recipient data into JSON, Markdown, or SARIF.

What the package can retain

Mail-merge settings live in Word’s word/settings.xml part. A w:mailMerge configuration can point to an external mailMergeSource, an external header source, and Office Data Source Object (w:odso) details such as connection information, a table name, a query, and mapped fields. The Open XML SDK describes ODSO settings as carrying both connection information and record-selection/mapping state.

Recipient inclusion/exclusion information may be stored separately as an internal recipient-data part. Its presence does not tell us who a recipient is, nor does it prove Word will access anything when the document opens. It is still a material review surface: it binds a template to a source workflow and can retain information a clean handoff should not carry forward.

DocFence counts five things publicly: mail-merge configurations; external data-source relationships; external header-source relationships; internal recipient-data relationships; and recipient-data parts. The private comparison signature includes the relevant stored configuration, normalized relationship semantics, and recipient-data bytes. Values and targets never leave the process.

Fail closed on the contract, not on a guess

When a direct w:dataSource, w:headerSource, ODSO w:src, or ODSO w:recipientData reference appears, DocFence verifies that it names the expected relationship kind and target mode. Data and header sources must be external; recipient-data targets must be internal stored parts. A malformed recognized reference stops analysis rather than becoming a vague package change.

The inventory also retains recognized source or recipient relationships that are no longer referenced by a current w:mailMerge element. That is intentional. A stale external target is still stored state worth reviewing, even when a particular Office version may ignore it.

Choose “none” or “no change”

A clean-handoff policy can prohibit all stored mail-merge state in the candidate:

rules:
  require_no_mail_merge: true

This emits DFP021. A controlled template may legitimately retain an approved merge configuration, however. In that workflow, preserve the baseline and reject a later mutation:

rules:
  no_mail_merge_changes: true

This emits DFP022 when the private inventory changes. Relationship IDs are normalized, so an ID renumbering alone stays quiet. A changed query, source target, mapping, or recipient-data payload does not.

Evidence without source disclosure

The release tests conventional and Strict OOXML relationships, both documented recipient-data relationship spellings, query-only changes, recipient-data changes, residual source relationships, malformed relationship types and target modes, missing internal recipient targets, policy findings, and relationship-ID stability. Unique markers placed in queries, source/header targets, connection settings, mappings, and recipient data are checked not to appear in public output.

The wheel and source distribution were independently built twice from the release commit with SOURCE_DATE_EPOCH; both artifact pairs were byte-identical. The release includes the wheel, source archive, and SHA-256 manifest. I downloaded those public assets, verified their checksums, installed the wheel into a fresh environment, and confirmed both the public aggregate inventory and zero findings for a pure relationship-ID rewrite.

Use the release

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.5.0/docfence-0.5.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 contract is in the policy reference and threat model. The Microsoft explanation of the mail-merge SQL prompt is useful background, but DocFence is not a query runner or a malware verdict. It is MIT-licensed and available on GitHub. For the preceding metadata boundary, read Document metadata is a review boundary, not a generic package change.