Skip to content

When an AI Agent Edits a Spreadsheet, What Happens to the Workbook?

I asked a deliberately narrow question: when an AI agent opens an Excel workbook and saves it without changing the workbook's content, what changes inside the file?

The answer matters because an .xlsx or .xlsm file is a ZIP package of interdependent parts. A workbook can contain worksheet XML, styles, validations, comments, external links, charts, pivot caches, slicers, macros, custom XML, and relationship graphs. A one-cell edit should not silently rewrite unrelated structures.

I built WolfXL, a Rust-backed Excel engine for Python, around that preservation constraint. To pressure-test the design, I compared its guarded modify path with the headless LibreOffice route bundled in the local Codex runtime installed with ChatGPT Desktop.

The short result:

  • Across five source-identified workbooks, a no-op LibreOffice round trip changed 8 to 151 unrelated OOXML parts.
  • WolfXL changed zero unrelated parts on the same five fixtures.
  • In a source-matched local benchmark, WolfXL was 2.2x to 3.9x faster on the paired tasks and inputs reported below.
  • LibreOffice still covers workflows WolfXL does not, and an isolated idle-footprint probe favored LibreOffice on sampled resident memory.

Every number below points to a compact receipt. The receipts retain unsupported and unfavorable rows.

The preservation test

The test is intentionally boring:

  1. Open a valid workbook.
  2. Request no content change.
  3. Save to a new file.
  4. Compare every OOXML package part against the source.

A changed package part is called package drift here.[^1] A large drift count shows that the save operation reached far beyond the requested no-op.

Results

Workbook fixture WolfXL unrelated drift Bundled LibreOffice unrelated drift
Average by region and quarter 0 8 parts
Validation, protection, and custom XML 0 19 parts
External links 0 14 parts
Pivot chart and slicers 0 31 parts
PowerPivot model 0 151 parts

The preservation result is still operationally important. Agent workflows often open and save the same workbook several times. A broad rewrite on every turn compounds risk, makes reviews noisy, and makes it harder to prove that the agent changed only what the user requested.

The design response: inspect, patch, verify

WolfXL's agent-facing write path uses a guarded transaction:

wolfxl-ops inspect 'input.xlsx' --request-id 'agent-mutation-001' > 'inspect-receipt.json'
wolfxl-ops plan 'mutation-request.json' > 'plan-receipt.json'
wolfxl-ops apply 'mutation-request.json' > 'mutation-receipt.json'

The request names the input, output, allowed operations, and allowed ranges. The apply step writes an isolated temporary workbook, verifies the requested change, checks unrelated package drift, emits an attestation, and atomically publishes the destination.

Unsupported operations, non-ready plans, failed verification, and unrelated drift are stop conditions. The route does not silently switch to another engine.

For ordinary Python code, the API keeps the openpyxl shape:

-from openpyxl import load_workbook, Workbook
+from wolfxl import load_workbook, Workbook
wb = load_workbook("model.xlsx", modify=True)
ws = wb["Inputs"]
ws["B7"] = 0.045
wb.save("model.updated.xlsx")

WolfXL Community is MIT-licensed and available from public PyPI for supported workbook I/O and API fit. Commercial 2.1+ adds current production operations, including the guarded mutation route used in this audit.

Source-matched runtime measurements

Preservation is the primary result. I also measured the process cost of calling a bundled office suite beside a spreadsheet-specific engine.

The local benchmark used:

  • macOS arm64 on the same machine
  • the LibreOffice binary bundled in the inspected Codex runtime
  • WolfXL built from commit 35de4e6914854a2dd3e66f5ee69e71729f606ff4
  • the resulting CPython 3.13 arm64 wheel installed into a clean environment
  • identical fixture inputs per paired task
  • three recorded observations per row
  • separate cold and warm scenarios

Selected paired medians

Task Input WolfXL Bundled LibreOffice Ratio
CSV extraction, agent-task cold 10x4 XLSX 0.303 s 0.667 s 2.20x
Recalculate and extract, cold 10x4 formula XLSX 0.293 s 0.721 s 2.46x
No-op round trip, cold 10x4 XLSX 0.297 s 0.762 s 2.56x
CSV extraction, cold-start scenario 10x4 XLSX 0.333 s 1.111 s 3.34x
CSV extraction, cold 20,000x8 XLSX 0.421 s 1.503 s 3.57x
No-op round trip, cold 20,000x8 XLSX 0.371 s 1.446 s 3.90x

Observed execution times reflect three recorded runs per paired task across cold and warm scenarios.[^2]

Installation and memory

The inspected runtime footprint was:

Runtime Installed bytes
WolfXL benchmark environment 37,524,645
Bundled LibreOffice 423,048,828

Workload peak process-tree RSS favored WolfXL in the rows above, at roughly 56 to 61 MiB versus 104 to 124 MiB for LibreOffice. The isolated footprint probe went the other direction: 53.1 MiB for WolfXL versus 34.5 MiB for LibreOffice. That probe is not a workload-memory ranking, so I am retaining it as a red result rather than hiding it.

The full benchmark contained 70 observations: 67 completed successfully and three recorded an explicit unsupported result for LibreOffice on the WolfXL-specific surgical-edit task. No unavailable result was converted into an estimate.

Why keep LibreOffice at all?

LibreOffice is a capable full office suite.[^3] It handles document and presentation formats, legacy conversion, office-style recalculation, and other workflows outside WolfXL's scope.

The product decision is routing, not replacement:

Need Preferred route
Supported cell, style, formula, or structural edit where preservation matters Guarded WolfXL transaction
Broad office conversion or unsupported legacy format LibreOffice fallback
Unsupported operation with no approved fallback Fail visibly

An agent should know which engine is handling the file, what that engine supports, and whether unrelated state changed before the output replaces the source.

Reproduce it

The exact-source public receipts are:

The measured commit was clean before and after the wheel build, and the wheel was the one used for the published local benchmark.

Try WolfXL

If you have a workbook where a one-cell edit must preserve charts, pivots, links, macros, or custom XML, I would like the hardest sanitized fixture you can share.


[^1]: Package drift reflects internal ZIP re-serialization rather than guaranteed corruption. Office export filters can normalize namespaces, relationship identifiers, calculation metadata, and drawing geometry without altering visible data. Observations are bounded to the five test fixtures and single no-op round trip. [^2]: Observed ratios describe the recorded adapters, builds, fixtures, and modes on macOS arm64 rather than a universal performance ranking. [^3]: Scope boundaries: LibreOffice is a complete office suite handling documents, presentations, and general conversions; WolfXL is a Python-facing spreadsheet engine. In ChatGPT Desktop, LibreOffice acts as a fallback document adapter; OpenAI's private Walnut engine was outside this comparison. LibreOffice parity does not imply Microsoft Excel correctness.