Release note · August 4, 2026
A coverage declaration needs its digest shape
A static package-signature coverage declaration is not credible merely because its URI points at a stored part. The XMLDSIG Reference that carries that URI has a required order: optional transforms, then a digest method, then a digest value. If that structure is absent or rearranged, the declaration is not a shape DocFence should credit.
Correction, August 4, 2026: 0.45 enforced this digest-child shape but still treated a generic directly bound Manifest as a package-specific coverage carrier. DocFence 0.46 now requires OPC's one idPackageObject, its exact Manifest/SignatureProperties direct-child topology, and exactly one SignedInfo binding before any Manifest declaration is credited. The 0.45 parser did not claim XMLDSIG validity, but this was a separate structural declaration gap.
Structure comes before coverage
The XML Signature Reference model defines the direct sequence as optional Transforms, required DigestMethod, and required DigestValue. That ordering matters even when a tool deliberately stops short of cryptographic validation.
<ds:Reference URI="/word/document.xml?ContentType=…">
<ds:Transforms>…</ds:Transforms> <!-- optional -->
<ds:DigestMethod Algorithm="…"/>
<ds:DigestValue>…</ds:DigestValue>
</ds:Reference>
DocFence 0.45 requires that bounded direct-child shape before any bound Manifest reference can contribute coverage. The method needs a nonblank Algorithm. The value must be direct, attribute-free, child-free, and nonempty. Non-whitespace text directly inside the Reference also causes the declaration to remain unsupported.
Fail closed without claiming validation
This condition sits before the existing narrow OPC transform rules. A relationships reference still needs its one relationship transform followed immediately by C14N; an ordinary part reference still accepts no transform list or one bounded C14N-only list. But a missing digest value, reversed digest children, an empty method algorithm, a nested value, an unexpected value attribute, extra direct children, or direct stray text is not silently treated as coverage.
Manifest Reference
├─ optional bounded transform declaration
├─ DigestMethod Algorithm="…"
└─ plain DigestValue
anything else → aggregate unsupported, no coverage credit
The release does not parse or decode a digest value, recompute a digest or canonical form, execute a transform, verify an XML signature, inspect a certificate, establish trust, or predict an Office client decision. It enforces only the small declaration shape it is prepared to report.
Review signal, not secret material
An unsupported declaration changes aggregate unsupported-reference and uncovered-scope evidence. It never copies the part path, reference URI, method algorithm, digest material, certificate data, selectors, or private semantic fingerprint into public JSON, Markdown, or SARIF output.
version: 1
rules:
require_complete_package_signature_coverage: true
no_package_signature_coverage_changes: true
DFP092 and DFP093 remain bounded review gates. They do not turn stored XML into a claim that a signature is valid or trusted.
Evidence and compatibility
The regression suite covers missing and misordered digest children, a missing method algorithm, unexpected digest-value attributes and nested markup, extra direct children, and unexpected direct reference text. The full 67-test suite passed. DCAB’s optional DocFence adapter also passed across its 42 deterministic fixtures, including the existing standards-shaped package-signature relationship-type reassignment case.
The tagged source passed hosted CI on Python 3.11 and 3.13 plus the distribution build. Final source and wheel artifacts were built twice under the committed timestamp and matched byte-for-byte; a fresh wheel installation exercised the DCAB fixture. Both public GitHub release files were then downloaded and byte-compared against those verified artifacts.
python -m pip install https://github.com/SybilGambleyyu/docfence/releases/download/v0.45.0/docfence-0.45.0-py3-none-any.whl
docfence check approved.docx candidate.docx --policy docfence.yml --format sarif --output docfence.sarif
The tagged policy reference, threat model, and validation notes define the boundary. Useful static coverage is explicit both about the pieces it recognizes and the cryptographic work it intentionally leaves undone.