Skip to content

docx_io split - Slice 1: extract settings.py (CLI/settings config) #72

Description

@LegalMarc

Design doc (read in full first): docs/design/docx_io_package_split.md — §2 (target structure), §4 Slice 1.

Slice 1 of 5 of the docx_io.py package split — the lowest-risk slice (pure config, zero python-docx/lxml dependency), already near-fully covered by tests/test_docx_io.py.

Scope

Move the CLI/settings configuration surface verbatim into a new marcut/docx/settings.py:

  • CLI_ARG_PAIRS, CLI_ARG_MAP, CLI_CLEAN_ARG_PAIRS, CLI_CLEAN_ARG_MAP, FIELD_TO_CLI (declared from docx_io.py:25);
  • _normalize_metadata_field_key();
  • MetadataCleaningSettings (docx_io.py:118) with all its methods (from_preset, from_cli_args, from_environment, to_cli_args, etc.).

This class has no python-docx/lxml/zipfile dependency — it is pure dataclass + dict logic and must be importable without touching a real document.

Package naming decision (needs a call in the PR)

The design doc proposes the package at marcut/docx/. Note that docx_io.py imports the third-party python-docx library as docx (from docx import Document, docx_io.py:9). Under Python-3 absolute imports a sibling marcut/docx/ package does not shadow the third-party docx, so it is technically safe — but it is a readability footgun. Decide in this PR whether to follow the doc (marcut/docx/) or use a less collision-prone name (e.g. marcut/docx_pkg/), and apply that choice consistently across all five slices. Document the decision in the PR description.

Import-path preservation

Consumers today: cli.py:9 (from .docx_io import CLI_ARG_PAIRS), pipeline.py:13 (from .docx_io import DocxMap, MetadataCleaningSettings), plus 8 test files. To avoid touching call sites in this slice, add a re-export shim in docx_io.py (from .docx.settings import MetadataCleaningSettings, CLI_ARG_PAIRS, ...) so existing from .docx_io import ... references keep working. (The full shim is finalized in Slice 5; this slice only needs the settings symbols re-exported.)

Acceptance criteria

  • Settings/CLI-mapping surface moved verbatim to marcut/docx/settings.py (or agreed package name).
  • docx_io.py re-exports the moved symbols so no consumer import breaks.
  • tests/test_docx_io.py passes with only import-path updates (if any) — no behavior edits.
  • Golden-file harness (#70) diffs to zero.
  • One real marcut redact run against a sample-files/ fixture, .docx + report JSON diffed against a pre-slice baseline → no difference.

Verification loop (design doc §3.3, run every slice)

  1. PYTHONPATH=src/python python3 -m pytest tests/test_docx_io.py tests/test_metadata_scrubbing.py tests/test_pipeline.py tests/test_url_redaction.py tests/test_failure_scenarios.py tests/test_security.py -q — green with only import-path edits.
  2. Golden-file harness from #70 — empty diff.
  3. marcut redact --in <sample-files fixture> --out ... --report ...; diff .docx + report JSON vs pre-slice baseline.

Plus the standard gate: full pytest -q, swift build, swift test, bash scripts/release_preflight.sh.

Dependencies

Blocked by #70 (golden harness must exist and be green first). Independent of the other slices — may land before or after B2/B3.


Land as its own PR; do not combine with other issues in this set. Do not reopen design-spike #25.

Metadata

Metadata

Assignees

No one assigned

    Labels

    afkAutonomous workflow-loop eligible

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions