Release note · August 1, 2026

Word's other linked-object marker

By SybilGambleyyu · DocFence 0.25.0

Not every Word linked-object review question lives in legacy VML. WordprocessingML also has w:objectLink: a compact leaf inside w:object that carries properties for a linked object. It can sit next to familiar OLE/package relationships, but it is not the same evidence as a legacy o:OLEObject Type="Link" marker, an embed, a field, or a generic relationship count.

DocFence 0.25 adds a narrow, privacy-safe inventory for that direct WordprocessingML surface. The aim is simple: make a stored marker review-visible in document CI without spilling targets or metadata into reports, and without pretending a parser can predict what a Word client will retrieve, refresh, render, or activate.

Similar package context, different markup

The Open XML SDK describes w:objectLink as an Office 2007+ leaf whose parent is w:object. Its remarks describe visual properties, the associated server application, and refresh mode of a linked object. That direct parent relationship is important: a loose element name or an OLE relationship elsewhere in a package is not enough to answer the same review question.

The ISO 29500 schema definition is precise. CT_ObjectLink extends the embedded-object properties, requires r:id and w:updateMode, and enumerates the stored modes always and onCall. A standard OLE-object relationship may target data internally or externally under the OOXML Embedded Object Part contract.

Count only the direct marker

DocFence records each direct w:objectLink child of w:object in body, header, footer, footnote, endnote, comment, and glossary stories. Duplicates and Markup Compatibility branches remain distinct stored evidence. A marker outside that direct parent shape does not enter this inventory. Neither do w:objectEmbed, legacy Office VML linked OLE markup, VML image or shape links, DrawingML linked pictures, fields, or broad embedded-object totals.

For a direct marker with r:id, the inventory classifies the resolved relationship as a standard OLE-object relationship with stored external or internal target mode, or as unsupported. A direct marker without r:id remains visible in a separate class. That last case is malformed relative to the schema, but discarding it would hide unusual stored package state from the reviewer.

Let awkward data stay awkward

The public counts separate exact stored w:updateMode="always" and w:updateMode="onCall" values from an unsupported-or-missing mode class. This matters because the Microsoft documentation's illustrative markup displays updateMode="user", while the schema enumerates only the two standard tokens. DocFence does not reinterpret that discrepancy as an automatic update, a valid runtime mode, or a client outcome. It keeps an absent or unexpected stored mode reviewable without silently normalizing it into a reassuring category.

Reports expose only marker/story, mode, and relationship-classification counts. Program and shape identifiers, relationship IDs and targets, field codes, locking metadata, XML markup, story paths, and fingerprints remain private. The private signature retains the full direct marker while normalizing a relationship ID to its stored relationship semantics: a same-count program, field-code, locking, mode, or target rewrite remains review-visible, while an ID-only renumbering with unchanged semantics stays quiet.

Concrete gates for a handoff

A handoff that must not carry this direct markup can say so explicitly:

rules:
  require_no_word_object_links: true

That emits DFP063. A controlled document that deliberately retains an approved marker can instead guard its private baseline:

rules:
  no_word_object_link_changes: true

DFP064 detects a material inventory change. These rules complement the existing relationship and embedded-object gates; they do not replace them.

Evidence, including the coverage limit

The 51-test release suite covers direct-parent scoping, standard external and internal OLE relationships, unsupported and missing relationships, exact standard modes plus unsupported/missing modes, duplicates, body/header stories, Transitional and Strict namespaces, orphan and unparented-marker exclusion, unavailable relationships, same-count field/target rewrites, relationship-ID stability, privacy redaction, and JSON/Markdown/SARIF policy output.

There is an important limit to report plainly. A scan of the Open XML SDK's public test assets found no direct w:objectLink marker in 503 readable package files (two of 505 candidate files produced read errors). A separate scan of all 141 Word packages in the public docx4j VERSION_17_0_3 tree also found none, including five legacy OLE samples. That is not a nonexistence claim. It is why this release calls the work a standards-shaped stored-XML compatibility boundary, not evidence of widespread contemporary Word authoring or runtime interoperability.

Hosted CI passed on Python 3.11 and 3.13 for both the release commit and tag. The wheel and source archive were independently rebuilt from the tagged source with a fixed source date and matched byte-for-byte. Fresh public release downloads passed checksum verification, and an isolated installed wheel reproduced the public automatic and on-call counts without exposing program, field, or target strings.

DocFence does not resolve, retrieve, open, update, activate, evaluate, render, or execute an OLE object. It does not establish that Word will honor a marker, that a target is reachable or safe, or that a visible object is associated with it. Use it as a bounded local review signal alongside appropriate rendering and domain review.

python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.25.0/docfence-0.25.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, source archive, and SHA-256 manifest. The tagged policy reference, threat model, and validation notes define the exact behavior and limits.