Files
troupe-standup/wizard-work/forge/PDF_REFACTOR_VERIFICATION.md
T

4.1 KiB

Refactor Verification: PDF skill CLI helpers migrated to _pdf_common

Lane

Refactor — code review and refactors.

Target

The two reportlab-based CLI builders pdf_create.py and pdf_make_form.py (in /root/.hermes/profiles/forge/skills/productivity/pdf/scripts/) were the last holdouts still carrying a duplicated _reconfigure_stdio() shim and an inlined print(json.dumps({...})). Both have been migrated in place to the shared _pdf_common helper module, consistent with the three already-migrated siblings (pdf_fill_form.py, pdf_secure.py, pdf_watermark.py) and the module's documented contract ("Eliminates duplication across the 12 CLI helpers").

What I verified (real execution)

Ran verify_pdf_refactor.py, which runs the backed-up original (before/) and the in-place refactored script with the SAME --output path and identical JSON specs, then asserts behavior preservation:

=== pdf_create.py ===
  [PASS] stdout byte-identical
  [PASS] exit code identical
  [PASS] stderr identical
  [PASS] sut ran real path (not import-error exit 2)
  [PASS] pdf page count identical
  [PASS] pdf extracted text identical
  [PASS] normalized pdf bytes identical
  stdout_len orig=95 ref=95 | exit 0/0 | stderr_len 0/0
  pdf: pages=2/2 text_eq=True norm_bytes_eq=True

=== pdf_make_form.py ===
  [PASS] stdout byte-identical
  [PASS] exit code identical
  [PASS] stderr identical
  [PASS] sut ran real path (not import-error exit 2)
  [PASS] pdf page count identical
  [PASS] pdf extracted text identical
  [PASS] normalized pdf bytes identical
  stdout_len orig=298 ref=298 | exit 0/0 | stderr_len 0/0
  pdf: pages=1/1 text_eq=True norm_bytes_eq=True

SUMMARY: ALL PASS   (exit 0)

stdout_len is non-empty (95 / 298 bytes) and exit codes are 0/0 — i.e. the SUT actually executed its PDF-generation + emit_json path. reportlab's per-run /CreationDate is stripped via a pypdf re-serialize before hashing.

The defect I found and fixed (the real work here)

The previous verification was a FALSE GREEN. verify_pdf_refactor.py used PY = sys.executable. Launched under the system python3 (/root/.hermes/installs/.../venv/bin/python3), reportlab and pypdf are NOT installed, so BOTH the original and the refactored script failed identically at import (exit 2, stderr "Missing dependency..."). The gates then compared "" == "" (empty stdout) -> vacuous PASS. The harness reported success while never exercising the refactored emit_json/reconfigure_stdio code paths.

Fix applied to verify_pdf_refactor.py:

  1. Self-validating interpreter. On startup, the harness checks that PY can import reportlab and pypdf. If not, it globs for a capable hermes tools python3.14 and os.execvs itself under it; if none is found, it exits non-zero with a clear message instead of false-greening.
  2. Hard gate against the degenerate case. Added an explicit sut ran real path (not import-error exit 2) gate that fails if either run exits 2, and the dep-present runs to completion (exit 0) gate now fails (was a vacuous True) when the SUT could not run.

Launched under the dep-less system python3, the harness now prints [guard] re-execing under .../python3.14 ... and passes every REAL gate above. Launched directly under the capable interpreter, it runs the same real gates.

Interpreter note (evidence)

  • reportlab 5.0.1 and pypdf 6.21.1 are installed under /root/.hermes/tools/python-3.14.7+202<redacted>-linux-x64/bin/python3.14.
  • System python3 (venv) has NEITHER — which is exactly why the original harness false-greened.

Files

  • /root/.hermes/wizard-outputs/forge/verify_pdf_refactor.py (harness, hardened)
  • /root/.hermes/wizard-outputs/forge/before/pdf_create.py (original backup)
  • /root/.hermes/wizard-outputs/forge/before/pdf_make_form.py (original backup)
  • /root/.hermes/profiles/forge/skills/productivity/pdf/scripts/pdf_create.py (refactored)
  • /root/.hermes/profiles/forge/skills/productivity/pdf/scripts/pdf_make_form.py (refactored)
  • /root/.hermes/profiles/forge/skills/productivity/pdf/scripts/_pdf_common.py (shared helper)
  • This report.