DCAB is an open, deterministic corpus for evaluating static review tools that compare WordprocessingML packages. It supplies forty-two paired synthetic .docx/.docm fixtures, a privacy-safe public oracle, an observation schema, and a scorer.
It is for a question ordinary text diffs do not answer well: did a document change in a stored review-sensitive surface even when ordinary text is unchanged? The corpus covers direct Word and legacy VML shape hyperlinks, simple and fragmented complex field instructions, DDE field sources and persisted document variables, editable-range permission markup, task-pane Office web-extension configuration, Office 2013 commentsExtended done metadata, attached-template, mail-merge data-source and recipient-selection settings, save-through-XSLT, automatic-field-recalculation-on-open, automatic-template-style-update-on-open, and personal-information-removal-on-save configuration, master-subdocument, frameset-source, legacy VML linked-OLE, and DrawingML linked-picture relationships and direct nonvisual visibility declarations, alternative-format import payloads, hidden text and revision markup, review settings and document protection, content-control bindings, bound and unbound custom XML, relationship-bound OPC package thumbnail payloads, static OPC package-signature declaration coverage, OOXML Markup Compatibility choice requirements, plus opaque macro, embedded-OLE, and ActiveX control-persistence payload boundaries.
It also includes form-data-only-save configuration, represented by a direct
w:saveFormsData setting transition with a fixed legacy FORMTEXT carrier,
and preview-thumbnail-on-save configuration, represented by a direct
w:savePreviewPicture setting transition with no thumbnail image part, plus a
direct content-control w:sdtPr/w:lock state transition with a fixed SDT
carrier, plus two static package-signature manifest-coverage transitions with
fixed Word content and package membership: an individual-selector omission and
a same-count standard relationship-type reassignment.
DCAB is not a Word renderer, a macro scanner, a field evaluator, or a runtime behavior benchmark. It never resolves an external target, opens Word, updates a field, parses an opaque payload, instantiates an ActiveX control, or executes code.
python -m pip install document-change-benchmark
dcab validate
dcab observation-template --output observations.json
dcab score --observations observations.jsonUse --strict with score to return a nonzero status unless every case is analyzed with every declared fact and the reference review convention.
dcab score --observations observations.json --strict --output score.jsonThe wheel bundles the corpus, so dcab validate needs no network access. To reproduce both repository and bundled copies from source:
dcab build --fixtures fixtures --force
dcab build --fixtures src/dcab/fixtures --force
dcab validate --fixtures fixturesEach case contains:
baseline.docxorbaseline.docmcandidate.docxorcandidate.docmtruth.json, a target-free public assertion
manifest.jsonl catalogues the forty-two cases. Every pair has the same package-member set, differs only at a declared member boundary, and retains the same sequence of stored w:t values. That invariant is intentionally narrower than visual or client-runtime equivalence.
Version 0.32 normalizes the non-cryptographic package-signature fixture
carriers to OPC's required package-specific XMLDSIG object identifier,
idPackageObject. The forty-two cases, public facts, fixture schema, and
reference review convention are unchanged; this is a deterministic private
signature-topology correction rather than a new benchmark boundary.
Version 0.31 adds a static OPC package-signature relationship-type selector
reassignment boundary. Both packages retain the same signature-origin topology,
package members, and stored Word text. A standard
RelationshipsGroupReference/@SourceType selector chooses one private Word
relationship type on each side, with the same declared relationship count.
The XMLDSIG-shaped material is intentionally non-cryptographic placeholder
data: the pair does not validate a signature, recompute a digest, inspect a
certificate, establish trust or integrity, or assert any client behavior.
Fixture schema version 1 and the truth and observation envelopes are unchanged.
An earlier observation can still be parsed, but it is incomplete when scored
against this forty-two-case catalogue.
Version 0.30 adds a static OPC package-signature declaration-coverage boundary. Both packages retain the same signature-origin topology, package members, and stored Word text. One synthetic, XMLDSIG-shaped signature manifest changes only one relationship-selection declaration, reducing the declared coverage of an otherwise fixed Word relationships part. The package-signature material is intentionally non-cryptographic placeholder data: the case does not validate a signature, recompute a digest, inspect a certificate, establish trust or integrity, or assert any client behavior. Fixture schema version 1 and the truth and observation envelopes are unchanged. An earlier observation can still be parsed, but it is incomplete when scored against this forty-one-case catalogue.
Version 0.29 adds a direct content-control w:sdtPr/w:lock transition from
explicit unlocked to sdtContentLocked. Both packages retain the same
content-control ID, tag, stored text, package topology, and all other stored
Word text; only word/document.xml changes. The pair captures a direct stored
declaration only: it does not infer a lock from an omitted leaf, determine a
control type or effective editing behavior, open Word, read a control value,
apply a lock, or claim client enforcement. Fixture schema version 1 and the
truth and observation envelopes are unchanged. An earlier observation can
still be parsed, but it is incomplete when scored against the preceding forty-case
catalogue.
Version 0.28 adds a direct w:savePreviewPicture transition from explicitly
disabled to enabled. Both packages retain no thumbnail relationship or image
part, the same package topology, and the same stored Word text; only
word/settings.xml changes. The pair records a future-save request only: it
does not create, decode, render, or classify an image; open Word; save a
document; generate a thumbnail; or claim client behavior. Fixture schema
version 1 and the truth and observation envelopes are unchanged. An earlier
observation can still be parsed, but it is incomplete when scored against this
thirty-nine-case catalogue.
Version 0.27 adds a direct w:saveFormsData transition from explicitly
disabled to enabled. Both packages retain one fixed legacy FORMTEXT field,
the same package topology, and the same stored Word text; only
word/settings.xml changes. The pair records a stored configuration request
only: it does not read or evaluate form-field values, open Word, save a
document, emit a delimited record, determine a delimiter, or claim client
behavior. Fixture schema version 1 and the truth and observation envelopes are
unchanged. An earlier observation can still be parsed, but it is incomplete
when scored against this thirty-eight-case catalogue.
Version 0.26 adds a direct DrawingML nonvisual-visibility pair. Both sides retain
one compact inline DrawingML carrier, the same package topology, and the same
stored Word text; only the direct wp:docPr/@hidden XML Boolean changes from
explicitly shown to hidden. The pair does not identify a rendered object,
calculate effective visibility, choose an MCE branch, lay out or render a
drawing, or claim what an Office client will show. Fixture schema version 1 and
the truth and observation envelopes are unchanged. An earlier observation can
still be parsed, but it is incomplete when scored against this thirty-seven-case
catalogue.
Version 0.25 adds an OOXML Markup Compatibility (MCE) choice-requirement pair.
Both sides retain one mc:AlternateContent, one mc:Choice, one
mc:Fallback, the same member set, and the same stored Word text; only the
private Choice/@Requires prefix changes. The pair does not validate MCE
conformance, resolve a feature prefix, choose a branch, preprocess or save a
package, or claim that a client will load or render either branch. Fixture
schema version 1 and the truth and observation envelopes are unchanged. An
earlier observation can still be parsed, but it is incomplete when scored
against this thirty-six-case catalogue.
Version 0.24 adds a relationship-bound OPC package-thumbnail payload pair. Both
sides retain the same standard root relationship, image/png content type,
member set, and stored Word text; only a deterministic, fully synthetic 1×1
PNG payload changes. The pair is not a rendering or preview claim: DCAB never
decodes the image or asserts that Word, Explorer, or another client displays
it. Fixture schema version 1 and the truth and observation envelopes are
unchanged. An earlier observation can still be parsed, but it is incomplete
when scored against this thirty-five-case catalogue.
Version 0.23 adds an unbound custom-XML payload pair. Both sides retain the same conventional custom-XML data/properties topology and fixed stored Word text; only the private customXml/item1.xml payload differs. The pair deliberately contains no w:dataBinding marker, does not publish or interpret XML values, and makes no claim that Word displays, uses, or can safely remove the stored data. Fixture schema version 1 and the truth and observation envelopes are unchanged. An earlier observation can still be parsed, but it is incomplete when scored against this thirty-four-case catalogue.
Version 0.22 added a direct w:removePersonalInformation transition from explicitly disabled to enabled. Only word/settings.xml changes; the package-member set and all stored text remain fixed. The corpus records a future-save request only: it does not identify authors, inspect or rewrite document properties, remove comments or revisions, save a document, or claim that a client will remove anything.
| Case | Declared fact | Reference convention |
|---|---|---|
interaction.word_hyperlink_target_retargeted |
word_hyperlink_target_changed |
block |
interaction.word_hyperlink_added |
word_hyperlink_added |
block |
interaction.vml_shape_hyperlink_target_retargeted |
vml_shape_hyperlink_target_changed |
block |
interaction.word_hyperlink_field_target_retargeted |
field_target_changed |
block |
interaction.taskpane_auto_show_setting_enabled |
taskpane_auto_show_setting_enabled |
review |
review.modern_comment_done_state_changed |
modern_comment_done_state_changed |
review |
external.include_text_field_target_retargeted |
external_field_source_changed |
block |
external.complex_include_text_field_target_retargeted |
external_field_source_changed |
block |
external.dde_field_source_retargeted |
external_field_source_changed |
block |
binding.document_variable_value_changed |
document_variable_value_changed |
review |
external.attached_template_target_retargeted |
external_document_dependency_target_changed |
block |
external.mail_merge_data_source_target_retargeted |
mail_merge_data_source_target_changed |
block |
review.mail_merge_recipient_active_state_changed |
mail_merge_recipient_active_state_changed |
block |
external.save_through_xslt_target_retargeted |
save_through_xslt_target_changed |
block |
binding.attached_custom_xml_schema_namespace_changed |
attached_custom_xml_schema_namespace_changed |
review |
review.field_recalculation_on_open_enabled |
field_recalculation_on_open_enabled |
review |
review.template_style_update_on_open_enabled |
template_style_update_on_open_enabled |
review |
review.personal_information_removal_on_save_enabled |
personal_information_removal_on_save_enabled |
review |
review.save_forms_data_enabled |
save_forms_data_enabled |
review |
review.save_preview_picture_enabled |
save_preview_picture_enabled |
review |
review.content_control_lock_state_changed |
content_control_lock_state_changed |
review |
review.package_signature_declared_coverage_changed |
package_signature_coverage_changed |
review |
review.package_signature_relationship_type_coverage_reassigned |
package_signature_coverage_changed |
review |
external.subdocument_target_retargeted |
external_document_dependency_target_changed |
block |
external.frameset_source_target_retargeted |
external_document_dependency_target_changed |
block |
external.vml_linked_ole_object_target_retargeted |
vml_linked_ole_object_target_changed |
block |
external.drawing_linked_picture_target_retargeted |
drawing_linked_picture_target_changed |
block |
import.alternative_format_html_payload_changed |
alternative_format_import_payload_changed |
block |
review.hidden_text_run_added |
hidden_text_run_added |
review |
review.tracked_insertion_markup_added |
revision_markup_added |
review |
review.track_revisions_setting_enabled |
track_revisions_setting_enabled |
review |
review.document_protection_enabled |
document_protection_enabled |
review |
review.permission_range_editor_changed |
permission_range_editor_changed |
review |
binding.data_binding_xpath_retargeted |
data_binding_mapping_changed |
review |
binding.custom_xml_payload_changed |
custom_xml_payload_changed |
review |
review.unbound_custom_xml_payload_changed |
unbound_custom_xml_payload_changed |
review |
review.package_thumbnail_payload_changed |
package_thumbnail_payload_changed |
review |
review.markup_compatibility_choice_requirement_changed |
markup_compatibility_choice_requirement_changed |
review |
review.drawing_object_hidden_state_changed |
drawing_object_hidden_state_changed |
review |
macro.vba_project_payload_changed |
macro_payload_changed |
block |
embedded.ole_payload_changed |
embedded_ole_payload_changed |
block |
embedded.activex_control_persistence_payload_changed |
activex_control_persistence_payload_changed |
block |
block and review are reference conventions for benchmark scoring, not universal policy advice. A tool may use stricter or looser policy; DCAB scores whether it can report the declared static fact and whether it agrees with the published convention.
All URI-like relationship values use the reserved example.invalid domain, and the DDE source is a synthetic local-style string. Macro, embedded-OLE, and ActiveX persistence bytes are inert text markers, not valid executable, OLE, or control payloads. The package-thumbnail pair uses deterministic fully synthetic 1×1 PNG bytes; construction and validation treat them as opaque and never decode or render them. The public truth files deliberately exclude:
- targets, field instructions and fragmented field-code runs, VML shape IDs and target frames, linked-OLE ProgIDs, object IDs, and update modes, DrawingML nonvisual object names, descriptions, IDs, raw hidden serialization values, and graphic-data URIs, ActiveX control names, class IDs, persistence metadata, document-variable names and values, mail-merge recipient hashes and inclusion values, save-through-XSLT anchor and local solution identifiers, attached-custom-XML-schema namespace values, raw
w:linkStyles,w:removePersonalInformation, andw:savePreviewPictureserialization values, permission marker IDs and individual editor assignments, task-pane web-extension IDs, classic-comment anchors and paragraph IDs, comment authors, initials, dates and body text, rawcommentsExtendedserialization values, frameset layout/name/size values, package-signature values, manifest object IDs, reference URIs, relationship selectors, signature/origin paths, thumbnail relationship sources/targets, content types, and part paths, references, store descriptors, property values, XPath expressions, relationship IDs, and relationship paths; - custom XML values, thumbnail image bytes, Markup Compatibility branch bodies, feature-prefix and qualified-name values, compatibility-rule values, opaque payload bytes, and payload fingerprints;
- protection hashes, salts, passwords, and document content outside the fixed synthetic text.
The form-data-only-save case also keeps legacy form-field name, default, and result values out of its public truth. Its sole public fact is the target-free stored setting transition.
The preview-thumbnail-on-save case contains no thumbnail relationship or image part on either side. Its sole public fact is the target-free stored setting transition; it does not identify or make an image.
The package-signature cases expose only target-free static coverage facts. Their XMLDSIG-shaped values are fixed synthetic placeholders, so they do not establish cryptographic validity, signer identity, trust, digest integrity, or any client-side signature result. The relationship-type case uses the standard group-selector element, but its private relationship type values remain absent from the public oracle.
The structural verifier compares generated bytes, validates ZIP/XML/package invariants, and refuses XML DTD/entity declarations. It does not interpret any stored value beyond the compact fixture contract.
The Open XML SDK's w:saveFormsData documentation defines the direct Settings leaf as a request to save form-field content only. DCAB fixes a complete legacy FORMTEXT carrier (its field name, default, result, and marker sequence), all package members, and all stored Word text while changing only w:saveFormsData/@w:val from false to true. This is deliberately a configuration boundary, not an export test: DCAB does not read or evaluate a field, open Word, save a document, emit a delimited record, determine a delimiter, or claim client behavior. DocFence 0.37 maps the narrow transition through a privacy-safe aggregate inventory.
The Open XML SDK's w:savePreviewPicture documentation defines the direct Settings leaf as a request for a supporting application to generate a first-page document thumbnail on save. DCAB fixes every package member, retains no thumbnail relationship or image part, and retains all stored Word text while changing only w:savePreviewPicture/@w:val from false to true in word/settings.xml. This is deliberately a stored-configuration boundary, not an image or preview test: DCAB does not create, decode, render, classify, or assert the presence of a thumbnail; it does not open Word, save a document, or claim client behavior. DocFence 0.38 maps the narrow transition through a privacy-safe aggregate inventory.
Word uses native OOXML packages, and direct w:hyperlink markup can bind its display text to a relationship target. Microsoft's Open XML API documentation shows that relationship-backed form. Word content controls can bind to custom XML data, so mapping and embedded-data changes are meaningful stored review surfaces. Microsoft documents those bindings, including their relationship to custom XML parts. But a document can also store a custom XML part without a mapped content control; Microsoft's Custom XML parts overview says that Office applications can embed and modify those parts independently of a document view. DCAB therefore includes both a bound and an unbound custom-XML payload boundary, without treating either as evidence that a host will display or use the data.
The OOXML Thumbnail Part contract defines an image part reached through a package or part thumbnail relationship, with an internal target and no relationships of its own. The Open XML SDK exposes that surface through AddThumbnailPart. DCAB fixes one standard root thumbnail relationship and image/png content type while changing only a fully synthetic 1×1 PNG's opaque bytes. It does not decode, classify, or render an image, or claim it previews the current document or will be shown by a client. Released DocFence 0.34 maps the same payload boundary through an aggregate-only thumbnail inventory.
The OPC digital-signature contract defines a root-related Digital Signature Origin part, signature parts related from that origin, a package-specific Object containing a Manifest, and a relationships transform for signing a subset of relationships. The relationships transform filters relationship @Id and @Type values using case-sensitive @SourceId and @SourceType declarations. DCAB fixes that standards-shaped static topology, the signature-part membership, all non-signature package bytes, and stored Word text. One case omits a selected individual relationship; another uses the standard RelationshipsGroupReference/@SourceType form to reassign one private relationship type while retaining the same public coverage counts. Neither pair is a cryptographic signature: it does not calculate or validate a digest or signature, inspect certificates, establish trust, or claim integrity or client behavior. Released DocFence 0.41 maps both declared static coverage boundaries through aggregate counts and private semantics.
Microsoft's introduction to markup compatibility describes AlternateContent as markup alternatives selected by a consumer at runtime according to its processing settings and supported features. DCAB fixes one MCE Choice/Fallback shape and every branch text value while changing only the one required-feature prefix. It does not resolve that prefix, select a branch, target an Office version, preprocess or save the package, or make a client-rendering claim. DocFence 0.35 maps the same-count private requirement rewrite through an aggregate-only MCE inventory without exposing branch material or the prefix value.
The Open XML SDK documents NonVisualDrawingProperties.Hidden as a stored state for an object that can remain present but hidden; omission is shown by default. DCAB fixes one compact inline DrawingML carrier, its package topology, and all stored Word text while changing only the direct wp:docPr/@hidden XML Boolean from false to true. It does not identify a visual object, calculate effective visibility, choose an MCE branch, lay out or render DrawingML, or claim client behavior. DocFence 0.36 maps that narrow transition through a privacy-safe aggregate visibility inventory.
Legacy VML shapes are a separate direct-link surface. Microsoft documents a v:shape's href as a hyperlink target, and its Word OOXML guidance explains that Word 2007 continued to use VML for shapes and text boxes. DCAB fixes one compact w:pict/v:rect shape, its target frame, and its styling attributes while changing only the direct href. It does not resolve the URL, select a rendering branch, simulate a click, or claim that any client will follow the link.
A VML o:OLEObject is a distinct relationship-backed form. Its UpdateMode applies when its Type is Link, and Microsoft’s Office compatibility notes describe that type as determining whether the OLE object is included in or stored externally from the package. DCAB fixes one w:object carrier, VML placeholder, Type="Link", ProgID, shape/object IDs, visual aspect, update mode, and relationship ID while changing only its external standard oleObject relationship target. It neither retrieves a source, parses an OLE payload, activates an object, launches an application, nor claims a client will update or display it.
An embedded w:control can associate a Word w:object carrier with an internal control-properties relationship. Microsoft's ax:ocx schema reference defines its class/persistence metadata and the binary relationship reference. The Embedded Control Persistence Binary Data contract specifies the separate internal activeXControlBinary relationship from an ActiveX persistence part, and its compatibility notes identify the ActiveX XML content type. DCAB fixes one inline w:object/w:control anchor, the internal control relationship, the ax:ocx persistence XML and its class/persistence metadata, both content types, and the required internal persistence-binary relationship while changing only inert synthetic binary bytes. It does not parse the bytes, load or instantiate a control, launch a client/server, render a placeholder, or claim any runtime behavior.
Mail-merge recipient selection is separate from retargeting a data source. Microsoft's Mail Merge Recipient Data Part contract specifies one internally related recipient-data part from Document Settings, its w:recipients root, and no relationships from that part. Its w:active definition says a false value excludes the corresponding external record from a merge. DCAB fixes one synthetic external text source, the settings markup, the settings relationships, the content type, the recipient record hash, and package membership while changing only the stored false/true inclusion state. It does not retrieve or parse the source, identify a real record, perform a merge, or claim client behavior.
Microsoft's w:saveThroughXslt documentation describes a custom XSL transform used when saving a document as a single XML file, and w:useXSLTWhenSaving controls whether the transform is applied. DCAB fixes the enabled marker, transform anchor, standard external relationship type, relationship ID, and package membership while changing only the synthetic target. It does not fetch, parse, or execute an XSL transform, save a document through one, or make a claim about emitted XML or client behavior.
Microsoft's w:attachedSchema documentation specifies a custom XML schema target-namespace association that a host may use when it loads a document if the matching schema is available. DCAB fixes one direct Settings leaf and all package members while changing only its synthetic namespace value. The value is an opaque declaration, not an OPC relationship or a fetch request: the pair does not locate, retrieve, load, or validate against a schema and makes no host-validation claim. Released DocFence 0.29 reports the same-count change through an aggregate-only inventory without exposing the namespace value.
Microsoft's w:updateFields documentation specifies whether fields should have their results recalculated from field codes when a supporting application opens the document. DCAB fixes the package-member set, all stored text, and one direct CT_OnOff Settings leaf while changing only its explicit false/true state. There is no Settings relationship part and no field evaluation in construction or validation. The case does not open Word, parse or evaluate a field instruction, access a field source, follow a link, start an application, or claim that any client will recalculate a field. Released DocFence 0.30 reports the aggregate state transition without evaluating a field.
Microsoft's w:linkStyles documentation describes the stored request to update document styles from an attached template when a document opens. DCAB fixes the w:attachedTemplate anchor, its external Settings relationship and synthetic target, package-member set, and stored text while changing only the direct CT_OnOff w:linkStyles leaf from explicit false to true. It does not resolve, retrieve, or load a template; open Word; propagate styles; or claim that a client will update a style. Released DocFence 0.31 reports the aggregate state transition without exposing the raw setting or template target.
Microsoft's w:removePersonalInformation documentation specifies that hosting applications remove personal information of document authors when saving a document with the direct CT_OnOff setting enabled, while leaving the definition and extent of that information undefined. DCAB fixes every package member and stored text while changing only the explicit false/true leaf. It does not inspect any document properties, identify an author, remove information, save a document, or claim that a host will do so. Released DocFence 0.33 reports the aggregate setting transition without exposing raw setting data.
Complex Word fields are a distinct parser boundary from w:fldSimple. Microsoft's w:fldChar documentation defines the required begin/end markers and optional separator, while its w:instrText documentation says instruction text is field code only when it occurs in the code portion of a complex field. DCAB fixes one complete INCLUDETEXT field with a begin marker, three preserved-whitespace instruction runs that split the keyword itself, a separator, a fixed result, and an end marker. Only the private source fragment changes. It does not resolve or import the source, update/evaluate a field, open Word, or claim a client will process the instruction.
Framesets are a distinct external-document topology. Microsoft's w:sourceFileName documentation says that a frame source is identified by a relationship in the Web Settings part and requires the standard frame relationship type. The OOXML Framesets contract further specifies that each frame target is external. DCAB fixes one content-type override, internal main-document-to-Web-Settings relationship, root frameset layout, frame size/name, source anchor, and relationship ID while changing only the private external target in word/_rels/webSettings.xml.rels. The standard says a document with a root frameset is a frameset definition rather than ordinary rendered document content; DCAB does not open, render, resolve, retrieve, import, authenticate to, or claim a client will display a frame.
Office's web-extension XML format stores Office Add-in structures in Word documents. Microsoft's auto-open task-pane guidance specifies internally related webextension and taskpane parts and the Office.AutoShowTaskpaneWithDocument property. DCAB fixes the entire internal topology, task-pane shape, reference, and property name while changing only that property's stored false/true value. It does not retrieve, install, authenticate, or execute an add-in, and it does not claim that a pane opens: Microsoft documents that the add-in must already be installed, and current auto-open availability depends on deployment/support conditions.
The commentsExtended part carries additional information about comments represented by the classic comments part. Microsoft's w15:commentEx schema documentation specifies that it is available in Office 2013 and later, ties paraId to the associated comment's final paragraph, and defines done="1" as a user indication that the comment is done. DCAB fixes one anchored classic comment, its matching paragraph identifier, both internal relationships, and all other extension inventory while changing only the explicit stored done value from 0 to 1. It does not open a Word client, infer an authenticated identity, resolve a comment thread, synchronize with a service, or claim a particular comment UI/state-transition behavior.
An attached template is another relationship-backed setting: Microsoft's Office Open XML notes specify that Word obtains its template path through the attachedTemplate relationship. A w:dataSource element identifies the external source connected for a mail merge through a mailMergeSource relationship. Microsoft's Word field specification for DDE defines separate application, source-file, and source-item arguments; DCAB fixes the first and third and changes only the stored source-file argument, without processing the field or starting an application. w:docVars persists document-variable name/value pairs, and Microsoft documents that they can be shown by a DOCVARIABLE field. DCAB fixes that field reference and variable name while changing only the persisted value, without evaluating a field. w:permStart and w:permEnd form paired editable-range permission markup through a shared marker ID. DCAB fixes one paired boundary and its covered stored text while changing only a synthetic individual editor assignment; it does not infer an effective permission or authenticated identity. A w:subDoc anchor identifies a separate master-document subdocument through an external relationship. A DrawingML a:blip r:link identifies an image outside the file. A w:altChunk anchor identifies internally stored alternate content for import. DCAB models those static relationship and payload boundaries without resolving or importing them or claiming a client will process them. The other cases follow explicit WordprocessingML constructs: w:vanish, w:ins, Track Changes and protection in settings, and w:documentProtection. Document protection is deliberately represented without password material and should not be interpreted as cryptographic protection.
The Open XML SDK's w:lock contract and
LockingValues enum
distinguish SDT deletion locking, content editing locking, both, and explicit
unlocked. The element contract also gives omitted w:lock type-specific
behavior for group controls. DCAB consequently fixes one ordinary SDT carrier
and changes only an explicit direct value; it does not model an omitted leaf,
classify a control type, or claim an effective runtime restriction. Released
DocFence 0.39 maps the aggregate static transition without exposing control
identity or content.
An observation report is JSON with schema version 1. A tool can declare a case analyzed, unsupported, or error. An analyzed case provides zero or more fact objects and an optional allow, review, or block disposition. DCAB validates the envelope before scoring it.
{
"schema_version": 1,
"benchmark": {"fixture_schema_versions": [1]},
"tool": {"name": "example-reviewer", "version": "1.2"},
"cases": [
{
"id": "review.hidden_text_run_added",
"status": "analyzed",
"facts": [{"fact": {"kind": "hidden_text_run_added"}}],
"review": "review"
}
]
}Use dcab observation-template for a complete valid skeleton. Extra facts remain visible under unrecognized_facts; DCAB does not label them false positives because its oracle is intentionally partial.
The optional local adapter translates public, aggregate DocFence reports into DCAB observations. DCAB does not depend on DocFence and never receives the tool's private signatures, targets, or payload data.
dcab docfence-observations --executable docfence --output docfence-observations.json
dcab score --observations docfence-observations.json --strictThe adapter is evidence of one independent consumer, not a claim that a single tool defines the benchmark.
The test suite opens every .docx pair with python-docx and opens all .docx/.docm packages using its lower-level OPC reader. This is useful package-level interoperability evidence, not a claim of compatibility with every Word, Office, LibreOffice, renderer, macro engine, OLE client, or field-update behavior.
RESEARCH.md records the scoped gap investigation and adjacent work. DCAB does not claim that no other document benchmark or comparison tool exists. Its specific contribution is a compact, reproducible, paired static-review contract with target-free public truth.
python -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
.venv/bin/python -m pytest
.venv/bin/python -m ruff check .
.venv/bin/python -m ruff format --check .MIT licensed. Contributions should preserve deterministic generation, the static/nonexecuting boundary, and target-free truth files.