Design doc (read in full first): docs/design/docx_io_package_split.md — §3 "Behavior-Parity Verification Plan", specifically §3.2 item 1.
This is the prerequisite gate for the entire docx_io.py package split. No extraction slice (#72–#76) may begin until this golden-file harness exists, is committed, and is green against the current (unsplit) docx_io.py. This issue adds tests only — it does not move any code.
Why this comes first
docx_io.py (2463 lines, one DocxMap class from line 325) is on the redaction/metadata-scrubbing critical path. A subtle behavior change during extraction could silently leak unredacted content or leave PII in metadata and still "save successfully". The golden-file harness is the single artifact that proves parity after each slice.
Scope
Build a characterization harness that runs the current DocxMap end-to-end (load → scrub_metadata → harden_document → apply_replacements → save) against a representative fixture set and snapshots the output as committed golden fixtures.
Fixture set must include (per §3.2.1): plain paragraphs; tables incl. nested tables; headers/footers; footnotes; endnotes; text boxes/drawings; content controls (w:sdt); tracked-changes already present on load; embedded OLE objects; hyperlinks; comments (visible + hidden/deleted); and mail-merge fields.
Snapshot for each fixture (per §3.2.1):
- (a) the extracted
.text / .index from _build() (docx_io.py:1509);
- (b) the full unzipped part listing plus each part's parsed+canonicalized XML (normalize/canonicalize — never raw bytes — to avoid false diffs from non-deterministic ZIP ordering or timestamps);
- (c)
self.warnings.
Commit these as golden fixtures. The harness must be runnable as a single pytest target and diff to zero against current main.
Non-negotiable requirements
- Canonicalize XML before snapshotting. Raw-byte comparison will produce false diffs from ZIP ordering/timestamps and make the harness useless as a parity oracle.
- The harness must be reusable by every later slice — later issues will run it before and after their change and assert an empty diff. Design it to be invoked that way (e.g. a documented pytest target or helper), and document the invocation in the issue's own README/docstring.
- Do not modify
docx_io.py in this issue. Tests and fixtures only.
Acceptance criteria
Verification gate (all PRs in this set)
PYTHONPATH=src/python python3 -m pytest -q
swift build --package-path src/swift/MarcutApp
swift test --package-path src/swift/MarcutApp
bash scripts/release_preflight.sh
Dependencies
None. Blocks all extraction slices (#72, #73, #74, #75, #76).
Land as its own PR; do not combine with other issues in this set. Do not reopen design-spike #25.
Design doc (read in full first):
docs/design/docx_io_package_split.md— §3 "Behavior-Parity Verification Plan", specifically §3.2 item 1.This is the prerequisite gate for the entire
docx_io.pypackage split. No extraction slice (#72–#76) may begin until this golden-file harness exists, is committed, and is green against the current (unsplit)docx_io.py. This issue adds tests only — it does not move any code.Why this comes first
docx_io.py(2463 lines, oneDocxMapclass from line 325) is on the redaction/metadata-scrubbing critical path. A subtle behavior change during extraction could silently leak unredacted content or leave PII in metadata and still "save successfully". The golden-file harness is the single artifact that proves parity after each slice.Scope
Build a characterization harness that runs the current
DocxMapend-to-end (load→scrub_metadata→harden_document→apply_replacements→save) against a representative fixture set and snapshots the output as committed golden fixtures.Fixture set must include (per §3.2.1): plain paragraphs; tables incl. nested tables; headers/footers; footnotes; endnotes; text boxes/drawings; content controls (
w:sdt); tracked-changes already present on load; embedded OLE objects; hyperlinks; comments (visible + hidden/deleted); and mail-merge fields.Snapshot for each fixture (per §3.2.1):
.text/.indexfrom_build()(docx_io.py:1509);self.warnings.Commit these as golden fixtures. The harness must be runnable as a single pytest target and diff to zero against current
main.Non-negotiable requirements
docx_io.pyin this issue. Tests and fixtures only.Acceptance criteria
DocxMapend-to-end pipeline and snapshots (a) text/index, (b) canonicalized part XML + part listing, (c) warnings.docx_io.py.Verification gate (all PRs in this set)
PYTHONPATH=src/python python3 -m pytest -qswift build --package-path src/swift/MarcutAppswift test --package-path src/swift/MarcutAppbash scripts/release_preflight.shDependencies
None. Blocks all extraction slices (
#72,#73,#74,#75,#76).Land as its own PR; do not combine with other issues in this set. Do not reopen design-spike #25.