Skip to content

Minimize a reproducible workbook failure

wolfxl-minimize reduces an .xlsx failure into a smaller, deterministic reproducer without Excel automation. It keeps a candidate only when two observations reproduce the baseline failure signature exactly.

Use an existing corpus or oracle command by putting the literal {workbook} argument where it expects the workbook:

wolfxl-minimize failing.xlsx minimized.xlsx \
  --signature-regex 'AssertionError: (?P<signature>[^\n]+)' \
  -- python scripts/my_oracle.py '{workbook}'

Commands run directly, never through a shell. A non-zero exit means failure. Without --signature-regex, the exit code is the signature. The command, captured output, workbook path, sheet names, cell values, and raw failure signature are not written to the journal. Predicates receive temporary copies, never the source path; changing or replacing a predicate input aborts the run. Command output passes through a separate bounded, file-backed relay. The parent never waits for output EOF beyond the command deadline and always terminates and reaps the relay. On POSIX it also makes a best-effort kill of the managed process group. Commands that daemonize, detach, or create a new session are unsupported in v1; WolfXL guarantees its own return deadline, not containment of a process that deliberately escapes the managed group.

For a stable WolfXL load exception, use the internal predicate:

wolfxl-minimize failing.xlsx minimized.xlsx \
  --load-failure --allow-cooperative-predicate

Command predicates have a hard wall-clock deadline: WolfXL can terminate and reap their process group. Plain Python callables and the in-process load predicate cannot be safely preempted, so v1 rejects them unless the caller explicitly accepts cooperative deadline checks. A cooperative predicate must return control itself; use a command predicate whenever a hard deadline is required.

Python callers can provide a semantic predicate directly:

from pathlib import Path
from wolfxl.minimizer import MinimizationBudget, minimize_workbook

def still_fails(candidate: Path) -> str | None:
    # Return one stable, specific signature when the target failure occurs.
    # Return None when it does not.
    ...

result = minimize_workbook(
    "failing.xlsx",
    "minimized.xlsx",
    still_fails,
    allow_cooperative_predicate=True,
    budget=MinimizationBudget(max_attempts=256, max_seconds=120),
)

The output is created with no-clobber semantics. Its sibling minimized.xlsx.min.json records the source and output SHA-256 hashes, every candidate hash and outcome, budget use, and whether the run reached a fixed point. It intentionally records structural hashes instead of private workbook content or local paths. The receipt distinguishes a tested reduced_candidate from an exact_source_fallback; the latter preserves the observed ZIP bytes when no canonicalized reduction retained the failure. Its predicate record also distinguishes deadline_enforced=true isolated commands from explicitly accepted deadline_enforced=false cooperative predicates.

Conservative boundary

This first slice can drop independent worksheets and remove rows/cells from plain worksheet parts while preserving coordinates and recalculating the used range. Sheet deletion always retains a visible worksheet, preserves each workbook view's active and first-displayed sheets by identity, and synchronizes the common docProps/app.xml worksheet count/order. Active sheets and packages whose extended sheet metadata cannot be updated safely are preserved. It fails closed on encrypted, macro-enabled, binary, externally linked, or unsupported workbook relationships. Sheets with drawings, tables, merged cells, validations, conditional formatting, hyperlinks, controls, grouped/array formula members, or their own relationship parts are preserved rather than rewritten. Omitted view indices are treated as their OOXML default of sheet zero, and a removed first-displayed tab falls back to the first surviving visible tab. Synthesized used-range dimensions retain worksheet schema order after sheetPr.

max_attempts, max_seconds, compressed input bytes, total uncompressed bytes, output bytes, command-predicate runtime, and command output capture are all bounded. Use --predicate-max-capture-bytes to lower the command-output ceiling. If an attempt/time budget is exhausted, the best already-confirmed candidate is emitted with complete=false and a precise stop reason. A predicate that changes its answer for identical bytes aborts the run before artifacts are published. Each ddmin phase checks deterministic chunks and their complements; sheet, row, and cell phases then repeat until a complete pass accepts no reduction before the receipt can report fixed_point. Serialization, artifact writes and fsyncs, and the final source-integrity read also count against max_seconds; crossing the deadline there downgrades the persisted receipt to complete=false and stop_reason=time_budget.