Release note · August 4, 2026

A stored template-style update request is a review boundary

By SybilGambleyyu · DocFence 0.31.0

A Word document can retain an attached-template relationship yet separately store a request to update its styles from that template when a document is opened. Those are different review facts: changing a template target is not the same as enabling a stored style-update request. Neither fact tells a static reviewer whether a particular client will load the template or apply a style.

DocFence 0.31 adds a private-by-default inventory for direct w:linkStyles settings. It gives CI a compact signal for this stored configuration boundary without resolving a relationship, retrieving a template, exposing an identifier, or opening a document client.

One stored leaf beside a separate relationship

Microsoft documents LinkStyles as the setting for automatically updating document styles from an attached template when a document is opened. The setting is direct WordprocessingML state. The attached template, when present, remains a separate Settings relationship covered by DocFence's external-document-dependency inventory.

word/settings.xml
  w:attachedTemplate r:id="…"       separate stored relationship anchor
  w:linkStyles w:val="true"         stored enabled request

The scanner records the direct request. It does not resolve the relationship.

DocFence accepts a strict CT_OnOff leaf in Transitional and Strict Word namespaces: no child markup or nonblank text, at most one Word-namespace w:val attribute, and a supported on/off spelling. An omitted value is enabled. Duplicate, malformed, and ambiguous leaves are rejected rather than silently interpreted.

The implementation reads stored package bytes only. It never opens Word, resolves, retrieves, or loads an attached template, propagates a style, follows a target, evaluates a field, runs a macro, or claims client behavior.

Aggregate evidence, readable policies

Public JSON, Markdown, and SARIF expose only template_style_update_on_open_enabled_setting_count and template_style_update_on_open_disabled_setting_count. Settings paths, raw XML, relationship targets, and private semantic fingerprints remain private. Equivalent enabled spellings stay quiet at the inventory layer; a material enabled/disabled transition does not.

rules:
  require_no_template_style_updates_on_open: true

The candidate-state gate emits DFP075 when an enabled stored request is present. A team that intentionally approves a configuration can instead protect a baseline:

rules:
  no_template_style_update_on_open_changes: true

DFP076 flags a material inventory change. These policies do not label a template safe or unsafe; they make a narrow, review-sensitive stored boundary explicit.

Evidence without template execution

The 58-test release suite covers absent, implicit, enabled, disabled, and Strict forms; malformed-leaf rejection; equivalent-spelling stability; privacy redaction; policy behavior; and JSON, Markdown, and SARIF output. Hosted CI passed for the release commit and immutable tag, and fresh wheel and source-archive installs passed smoke checks.

Document Change Assurance Benchmark 0.21.0 supplies the matching deterministic pair. It retains an attached-template anchor, its external Settings relationship, and its synthetic target while moving only w:linkStyles from explicit false to true; its optional adapter consumes public aggregate evidence only.

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.31.0/docfence-0.31.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

The public release includes the wheel and source archive. The tagged policy reference, threat model, and validation notes define the evidence contract and its limits.