Limited-time launch offer 20% off Pro — first payment and every renewal — with code See pricing

The write path

Preview, then apply.

A single-call write asks you to trust the agent's reading of your instruction before anyone has seen what it decided. Splitting the write in two moves that moment to somewhere you can still say no.

This is the shape of every write SiteHelm performs. The five gates it passes through are described in full on the safety page.

 · 5 min read

Most write APIs have one phase. You send the request, it happens. That is completely reasonable when a person is filling in a form, because the person has already looked at the thing they are editing and knows which one it is.

An agent has not. It has an instruction in natural language, a model of your site assembled from whatever it read a moment ago, and a decision to make about which object the instruction refers to. Usually it gets that right. When it gets it wrong, a one-phase write turns a misreading directly into a changed page, and the first person to find out is whoever loads that page next.

The failure that matters here is not a malicious agent. It is a well-behaved one that resolved “update the hero text on the pricing page” to a different page, because two pages had similar titles and it picked the wrong id. Everything about that call was permitted. Nothing about it was correct.

Two calls, and what has to hold between them

The fix is to stop treating “decide what to change” and “commit the change” as one event.

The first call returns a plan. The operation runs everything except the write: it resolves the target, works out the change, and returns a description of what would happen — the object it landed on, the fields it would set, what it would replace. Nothing is stored. If the agent resolved the wrong page, this is where that becomes visible, and it is visible before it costs anything.

The second call performs the write, and is bound to the first. It carries a token the plan issued, and it repeats the same arguments. The binding is the whole mechanism, so it is worth being exact about the two properties it needs:

Single use. A token that can be replayed turns one approved change into an unknown number of them. It authorises one write and is spent.

Bound to the arguments. If the apply call could carry different arguments from the plan, the preview would be decorative — you would have read one change and authorised another. Arguments that no longer match are refused, and in SiteHelm that refusal is StalePlan, which is also what you get for a reused token or one left too long.

Without both properties you have a workflow that looks like a preview and is not one.

What still has to happen around it

Two phases stop the wrong change from being invisible. They do not, on their own, make it recoverable — and they do not prove the right thing landed. Three more things do that work, and they are the difference between a demo and something you would point at a site with customers on it.

Snapshot before the write, not after. A rollback target taken after the change records the damage. The snapshot has to be of the state immediately before, and it has to be narrow: the specific document, the specific rows, so that putting it back does not mean rolling the whole site to last night. This is not a substitute for backups. It is the thing you use in the ninety per cent of cases where a backup would be absurd overkill.

Read the result back and compare it. The plan is a promise, not evidence. Between the intention and the stored value sit validation rules, hooks, other plugins, caching layers and occasionally a page builder that keeps the same information in two places. Any of them can change what actually lands. So the operation reads the site back afterwards and compares the stored state against what it said it would do. When those disagree, the honest answer is not success — in SiteHelm it is VerificationFailed, and the response says how far it got.

Write it all down. Every call, including the refusals, in a ledger the site owner can read in wp-admin. The value of that record is not on the day of the write. It is three weeks later, when a page looks wrong, and the question is whether an agent touched it, which plan was approved, and what the state was before. Rollback without an audit trail is guesswork with extra confidence.

Those five things — preview, capability check against the acting user, snapshot, verification, rollback from the ledger — are the gates every SiteHelm write goes through, in that order. The order is not decorative either: refusing on capability before a snapshot is taken means an unauthorised call leaves nothing behind at all.

Not everything can be undone, and that has to be said

Some operations genuinely cannot be reversed. There is no honest snapshot for “update this plugin to a newer version”, because WordPress has no clean way back to the old one. The right response to that is not to pretend otherwise — it is to declare it. An operation that cannot be rolled back says so in its own definition rather than offering a rollback button that fails at the moment you need it, and the previous state goes into the audit record so that at least you know what it was.

A safety model that claims everything is reversible is a safety model that will be wrong exactly once, at the worst possible moment.

How to roll this out

Start on staging, with a real backup you have actually restored once. Allow the narrowest set of operations that does the job — if the work is content edits, turn the rest off — and widen only after the previews have been boring for a while. Read the plans properly at first, even when they are dull, because the way you learn what an agent gets wrong is by seeing what it proposed before it acted. Then read the ledger after each run and check that what you approved is what landed.

None of that is exciting. It is the difference between an agent that helps and an agent you end up cleaning up after.

Questions

The questions this raises

Why must the plan token be single-use?

Because a token that can be replayed turns one approved change into an unknown number of them. The token authorises exactly one write — the one described by the plan you read — and it is spent when that write is attempted.

Why must the apply call repeat the same arguments?

So that the plan you read and the write that happens are the same operation. If the apply call could carry different arguments, the preview would be theatre: you would have approved one change and authorised another. Arguments that no longer match the plan are refused as StalePlan.

Is a snapshot the same as a backup?

No, and it does not replace one. A backup restores the site to a moment in time, which is a large and disruptive event. A snapshot records the state of the specific thing about to change, so that one change can be put back without touching anything else. You should still take real backups.

Why read the site back after the write?

Because plugins, hooks, caches and validation all sit between the intention and the stored result, and any of them can quietly alter what lands. Verification compares what is actually stored against what the plan promised. When they disagree the operation reports VerificationFailed and says how far it got, rather than reporting success.

Does two-phase writing mean an agent can never break anything?

No. A plan can be approved too quickly, and an operation can have consequences nobody modelled. What two phases buy you is that mistakes are visible before they land and recoverable after, instead of being discovered by a visitor.

Next

Read the thing itself.