The question people ask about an agent in a spreadsheet is usually about the model: can it read the sheet, can it write the right value. The risk is not there. It is in the container.

A cell in Excel or Sheets is not a named thing. It is an address. D14 means "the fourteenth row", and the moment anyone inserts a row above it, that address points at a different record. A formula is not a value either; it is a small program that happens to display a number. And a number is not a type; it is whatever the sheet decided to store after the number format, the locale and the column's history had their say.

So an agent that writes "successfully" into a spreadsheet has proven almost nothing. What follows is the verification model I actually use when the thing being edited is a workbook someone depends on for money.

Why a workbook is a different risk class

Three properties make a spreadsheet harder to supervise than a document or an inbox.

It is positional. An agent that reasons in rows and columns and a person who reasons in headers and meanings can both be correct about "the third row" and disagree about which record that is once anything above it changes. Merged cells, hidden rows and grouped columns widen the gap: the sheet the agent parsed and the sheet the human sees can genuinely differ, and neither view is wrong.

It holds programs. A value written over a formula does not look wrong. It looks like a number. The workbook silently stops being a model and becomes a snapshot, and nobody notices until next month's figures are quietly missing their inputs.

It coerces silently. Writing into a cell succeeds even when the cell's format turns the value into text, when the locale expects a comma as the decimal separator, when a leading zero is dropped from an identifier, or when a date string is stored as something else entirely. The write call returns OK in all of those cases. The data is now wrong.

An agent that checks its own write response will report success in every one of them.

Four properties an edit has to carry

Before asking whether an agent can be trusted with a workbook, the edit itself has to be describable in four ways.

  1. A named target. A named range, a table column, or a header-matched region. Not coordinates.
  2. A diffable change. Old value, new value, and for a formula, the formula text rather than its result.
  3. Reversible without undo. Undo stops working the moment the file is saved, shared or versioned away. A copy plus a hash is a rollback that survives.
  4. Re-readable. After recalculation, the agent reads back the computed value in the cells it touched — not its own success message.

The fourth is the one that separates a working integration from a demo. The others can be argued about; the read-back is testable.

The verification record

The record I want after every unattended write has five fields, and it is deliberately boring:

{ "target": "Sheet1!tbl_orders[amount]|row=invoice:INV-2291", "intent": {"field": "amount", "value": 184000, "as": "KRW"}, "before": {"file_sha256": "9f2c…", "snapshot_at": "2026-11-15T04:10:22Z"}, "touched": {"range": "F118", "cells": 1}, "after": {"recalculated": true, "readback": 184000, "format": "#,##0", "total_check": {"cell": "F240", "was": 9982000, "now": 10166000, "delta_ok": true}}, "used_range": {"before": "A1:J240", "after": "A1:J240", "shifted": false} } 

touched is the range the agent actually wrote, not the range it meant to write. Those two differ more often than anyone expects — a fill that spilled one row too far, an append that landed on a header — and the difference is invisible in a "write succeeded" log.

total_check is the cell that would move if the change were right. If a total does not move the way the intent predicted, the write is wrong even though it succeeded.

Formula semantics get their own rules

Where a value write is merely risky, writing near formulas is where the expensive mistakes live. Four rules have held up in every case I have seen:

  • Never replace a formula cell with a constant unless the task says to break the formula. Detect it first: read the cell's formula, not its value.
  • Never extend a range and assume autofill respected absolute and relative anchors. Expanding $B$2:B10 by dragging is a different operation from writing =$B$2:B11, and one of them silently changes what the column means.
  • Never write a date or currency without declaring the format you expect. The sheet will accept the string and store something else, then display it plausibly.
  • Never trust a total that was not recalculated and re-read. Cached values in a file that was last opened by a person hours ago are history, not truth.

A practical consequence: the agent's write adapter should refuse to touch a cell whose type is formula unless the request carries an explicit overwrite_formula: true with a reason. That is a permission model, not a prompt.

Operations that are not edits at all

Sorting, filtering and then saving; find-and-replace across a sheet; remove-duplicates; re-saving as CSV. None of these produce a cell-level diff anyone will read, and every one of them can move data across rows or strip formulas, leading zeros and date formats.

They are also the operations an agent is most likely to reach for, because they are the ones a person asks for in a sentence ("clean up the duplicates"). A safe implementation treats them as structural changes requiring a snapshot and a post-check on row identity — not as a series of writes.

A shared workbook, where another person has the file open, is the same class of problem with a shorter fuse: a write can be overwritten by the other editor's save, and no error is raised.

What I would let run unattended

The allow-list is narrow and boring, and that is the point:

  • reading anything;
  • appending rows to the bottom of a log that only grows;
  • filling a designated input column that has data validation on it;
  • building a summary on a new sheet nobody edits by hand.

And the never list:

  • overwriting formula or report columns;
  • deleting rows or columns;
  • sorting or de-duplicating a master table;
  • changing number formats in a report someone presents;
  • writing into a workbook another person has open.

Put the permission model in the workbook

The most useful trick I have found is to stop describing the boundary in instructions and write it into the file.

Protect the formula and report columns. Leave the input columns unlocked. Mark the append region as a real table, not a range with a bold header. Give the agent a named range to write into, and leave data validation on it so a wrong type is rejected by the file rather than by the model's judgement.

The boundary then becomes enforceable by the container, auditable by anyone who opens the workbook, and independent of which agent, prompt or person is on the account that day. Trust stops being a claim about the model and becomes a property of the thing it is allowed to touch.

A minimal version in openpyxl looks like this:

from openpyxl import load_workbook from openpyxl.worksheet.table import Table import hashlib, json, datetime def snapshot(path): return {"file": path, "sha256": hashlib.sha256(open(path, "rb").read()).hexdigest(), "at": datetime.datetime.utcnow().isoformat() + "Z"} wb = load_workbook("orders.xlsx") ws = wb["입력"] # 1. resolve a NAME, never coordinates ref = wb.defined_names["input_amount"] # e.g. 입력!$F$2:$F$500 target = next(ref.destinations) # (sheet, range) # 2. refuse if the cell is a formula cell = ws["F118"] if isinstance(cell.value, str) and cell.value.startswith("="): raise RuntimeError("formula cell — needs overwrite_formula with a reason") # 3. write, then confirm the file's own protection is on ws["F118"] = 184000 ws.protection.sheet = True wb.calculation.fullCalcOnLoad = True # force a recalc on open wb.save("orders.xlsx") 

The fullCalcOnLoad line matters more than it looks. Without a recalculation, the number a human opens tomorrow may still be the cached one from yesterday, and the read-back you performed earlier proved the wrong file state.

The read-back ladder

Verification should climb, not jump. Each rung catches a class of error the one below it misses:

  1. Write acknowledged. The API returned 200. Catches nothing except transport failure.
  2. Stored value equals intended value. Read the cell back as data, not as display text.
  3. Stored type is the intended type. Number stays number, identifier stays text with its leading zero.
  4. Dependent totals moved as predicted. The delta check that turns "it wrote" into "it is right".
  5. Used range did not shift. Catches spills, appends that created phantom rows, and pasted formats.
  6. The file opens clean. A structural check on the saved artifact — no repair prompt, no "we found a problem with some content".

Most agent integrations stop at rung 1 or 2 and then report confidence. The expensive failures live at rung 3 and above, and they are exactly the ones a demo never shows, because a demo is one write into a workbook nobody else uses.

If you want the short version: a spreadsheet will always accept a wrong number politely. The only thing that makes an agent safe here is a named target, a copy you can go back to, and a read-back that proves the result rather than the attempt. Only the last one is new. It is also the one that matters.

If you want to see how the same "prove the result, not the attempt" idea applies outside a workbook — what an assistant can and cannot do on a phone, and where a daily usage limit sits in that model — I keep two public notes:

Disclosure: I use Pickle, a phone-side AI assistant app, and I am not its vendor. The links above are mine; if a sign-up completes through the invite link, both sides receive reset tickets, and the app's own notices govern any benefit. Nothing in this article is a paid placement, and the verification model described here is what I run on my own workbooks.