Course 04 · 7 lessons

Change things safely

Change something, then put it back. Every write has a way back.

4.1 The rule every write obeys

The one rule behind every write this plugin makes.

A write whose rollback point could not be captured does not happen. That is the whole rule, and it is worth reading twice, because it is stronger than "we take a backup".

The order is what makes it true. The way back is written first and read back to confirm it landed. Only then is your content changed. Do it the other way around and a snapshot that silently failed leaves changed content with no way back — and the next run records the already-changed content as the "prior state", so Undo cheerfully restores the wrong thing.

A refused write says so. Silence would be half the defect, because nothing else on the site would ever tell you a change had been skipped.

A snapshot also records absence as its own fact, distinct from any content. "This option did not exist" and "this option held an empty string" undo to different things, and conflating them is how an undo invents a value nobody typed.

4.2 Apply a fix by hand

Read the exact bytes a fix would write before you agree to it.

A fix from an audit arrives as a proposal, never as a change. The card shows the exact bytes that would be written, and nothing happens until you confirm.

Applying stores the content as this plugin's own data and serves it through WordPress hooks. No theme file is edited, no post content is rewritten, and no physical file is created.

Confirming re-checks that what you previewed is still what would be written. If the page changed underneath you between the preview and the click, the apply stops rather than writing something you never read.

A fix blocked by another SEO plugin says so and stays unapplied. Two plugins writing one output is the situation this screen exists to avoid, not to win.

4.3 Auto-apply, and its limits

Let the daily run fix a short list you pick, and nothing else.

Auto-apply lets the daily run write a fix without asking. It is off until you turn it on, and it works only on kinds you tick.

The allowlist is enforced in the code that does the writing, not in the settings screen. A kind that is not on the list cannot be auto-applied by any route, including a forged form.

Every auto-apply snapshots first, and the newest apply per kind can be reverted from this screen. A run that would change nothing changes nothing and writes no log line — a no-op is not an achievement.

There is a stop switch, and it halts everything at once rather than per kind. If you are unsure what is happening, that is the control to reach for.

4.4 The plan is the run

See the whole run written down before a single page changes.

Before the fix runner changes anything it writes a plan: an ordered, hashed list of exactly what would happen, item by item.

Apply consumes that list and never re-runs discovery. A page that started matching after the plan was drawn is not quietly swept in, and one that stopped matching is reported rather than dropped. The plan you read is the run you get.

A plan is capped, and the cap is set by how many undo records the store actually keeps — never by what would look impressive. A plan that promised more undos than the store retains would destroy the earliest ones with its own later writes, while the receipt still claimed they were recorded.

Which means a large job runs as several plans. The screen says so where you would otherwise wonder why the list stopped.

4.5 The fix runner and its receipt

Run many fixes at once and read an honest receipt afterwards.

The runner itself writes nothing. Every change goes through the module that already owns that data and already knows how to undo it. The runner decides what to ask for and in what order, then reports what came back.

That is not tidiness. Each of those owners has a snapshot, a compare-before-write and a rollback that were reviewed when they shipped. A runner that reached past them to save a function call would be a second, unreviewed writer for the same data — and the first thing it would lose is the way back.

The receipt counts each outcome separately and never rounds them together. A category with nothing to do says nothing to do and contributes zero. Nothing on the screen congratulates you for a run.

Put it all back reverses a run through those same owners, and reports what it could not reverse instead of claiming a clean sweep.

4.6 Automations, and the refused one

The one automation here, and the one we will not build.

There is exactly one automation here: alt text on upload. It is off by default, it names its scope on the screen, it writes a history row for every action it takes, and every row undoes on its own.

Its only scope is filling an alt field that is empty. There is no option to overwrite one somebody wrote, and there will not be.

The second thing people ask for — create a redirect automatically when a 404 appears — is refused. A 404 is not evidence that a page moved; it is evidence that something asked for a URL. Automatically redirecting on that guess sends real visitors somewhere nobody chose, and the rule outlives the mistake.

The refusal is written into the code where somebody would otherwise add it, so the reason survives the person who made the decision.

4.7 How to undo, and where it lives

Where every undo lives, and when it will refuse to run.

Undo lives beside the thing that did the writing, never in one central graveyard. A fix reverts on the Fixes screen, an auto-apply on the Auto-apply screen, a runner batch under Put it all back, a drill edit under Recent link edits, a bulk template fill on the bulk editor, an image restore on the image screens.

The way back is stored as this plugin's own data on this site — plugin options for site-wide content, dedicated post meta for per-page content, and for an optimized image a sidecar copy of the original file. Nothing is kept off-site, so nothing has to be fetched back.

Undo checks before it writes. If you edited the page yourself after the change was applied, the undo stops and tells you, rather than deleting your later edit in the name of reverting ours. That refusal is the feature; clear the field by hand if you still want it gone.

Snapshot stores are capped and the oldest fall off. They are an undo buffer, not an archive — for a record that has to last, use WordPress revisions or a real backup.