Release note · August 1, 2026
The legacy Word image link a relationship count cannot explain
An external-relationship total tells a reviewer that a Word package stores an external target. It cannot say whether that target belongs to a picture the document actually marks for display, a hyperlink, a template, or an unused relationship. That ambiguity gets sharper in Word’s legacy VML picture markup.
DocFence 0.22 adds a privacy-safe inventory for one precise stored boundary: direct legacy VML v:imagedata markers with an explicit r:id that resolves to an externally stored relationship.
An image-data relationship is not just a relationship total
The Open XML SDK calls v:imagedata/@r:id the explicit relationship to image data. The ID is a pointer from a specific VML image-data marker to the story part’s relationship table. ECMA-376’s Image Part contract supplies the standard image relationship type and permits a stored external target mode.
That gives review automation a useful, narrow question: does a supported Word story contain a direct legacy image-data marker whose stored relationship is external? It is more informative than counting all external relationships, without pretending that a Word client will retrieve or render anything.
Count the explicit external marker; leave the rest separate
DocFence scans direct v:imagedata/@r:id markers in body, header, footer, footnote, endnote, comment, and glossary stories. It records only markers backed by a relationship with stored TargetMode=External. A standard image relationship is counted separately from another external relationship type, which remains reviewable as unsupported stored evidence.
Ordinary embedded VML images with internal relationships are not external-image markers. Nor are an orphaned image relationship, raw VML src, r:pict, r:href, or o:relid. Those are deliberately separate legacy surfaces, not fallback spellings of this one. In particular, Microsoft’s Office compatibility notes mark raw VML image-data src as unsupported.
Public reports contain only aggregate marker/story and relationship-classification counts. Image targets, relationship IDs, source values, VML attributes, story paths, and fingerprints stay private. A same-count external target rewrite remains visible in the inventory’s private signature; relationship-ID renumbering with unchanged semantics and a raw-src rewrite do not create this inventory’s churn.
Policies for a clean handoff or a governed baseline
For a handoff that must not retain a stored legacy external-image marker:
rules:
require_no_word_vml_external_images: true
This produces DFP057. A controlled template can instead use:
rules:
no_word_vml_external_image_changes: true
DFP058 protects the private marker baseline. The two rules add concrete VML image-data context to a generic external-relationship gate; they do not replace it.
Evidence without claiming to render Word
The 48-test release suite covers standard and unsupported external relationship classes, excluded embedded images and attributes, duplicate markers, body/header stories, Strict namespaces, orphan exclusion, same-count target changes, raw-src quietness, relationship-ID renumbering, policy/SARIF output, and redaction.
It also profiles the paired real public Word package from pea-sys’s abspath2relpath-docx investigation. At that immutable commit, the package stores two direct v:imagedata/@r:id markers backed by external standard image relationships; DocFence reports exactly two external-image markers without emitting their paths or relationship IDs. The downloaded fixture SHA-256 was 60708e292cd38cb9bee28886e91b2103b7d2ee43e963fa5e1cac4eccaaa71ed6.
This is stored-package evidence, not a renderer or a network monitor. DocFence does not choose a Markup Compatibility branch, associate a marker with a visual image, resolve or retrieve an image, update a link, render a picture, or claim that Word will load, reach, or honor a target.
Hosted CI passed on Python 3.11 and 3.13 for the release commit and tag, including distribution validation. The wheel and source archive were rebuilt independently from the tagged source and matched byte-for-byte; a fresh public download passed checksum and metadata validation, and an isolated installed wheel reproduced the two-marker public-fixture result.
python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.22.0/docfence-0.22.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.