A fix applied to the live page is not a fix: locking rebuilt pages against the generator that re-creates the error
A correction made in June was live-wrong again in October, because the build engine that renders the page was never updated. The fix was a server-side lock that refuses writes to the rebuilt pages.
In June we corrected a line of copy on the homepage of a home and living brand I look after. Four country shops, the same template, one edit each. Checked live, screenshotted, closed.
On 14 October I opened the French homepage for an unrelated content audit, and the old version was back. Not partially. Exactly as it had read before June, both on the page and in the stored copy underneath it.
Nobody had undone that fix. A redeploy had.
The fix went to the page, not to the thing that writes the page
These shops are not hand-built. Behind them sits a build engine: a folder of content definitions plus a deploy script that renders each page and pushes it over the WordPress REST API. In June I edited the live page. I never touched the content definition the engine renders from.
So for four months the setup carried two versions of that homepage. The correct one was live. The wrong one was in the source. The engine was dormant, which is the only reason it looked like a fix at all. The first time somebody ran it again, it did precisely what it had been told to do.
Infrastructure people have a name for the gap between what a system is declared to be and what it currently is. Martin Fowler calls the discipline that closes it infrastructure as code: the definition is the truth, the running thing is just an output, and you never repair the output. Marketing stacks are full of generated outputs that nobody treats that way. Pages built by a migration script. Ad copy assembled from a feed. Localised legal text produced by a template. All of it gets corrected where it is visible, because that is where the complaint arrives.
As Nassim Nicholas Taleb writes in Skin in the Game: “Bureaucracy is a construction by which a person is conveniently separated from the consequences of his or her actions.” A dormant generator is the same construction in software. It never meets what it overwrites.
What I shipped was a lock, not a note
The obvious answer is to update the engine. I could not, cleanly: the old engine exists in more than one place, including a YAML version on a drive that is not mounted on the machine I work from. Fixing every copy of it is a project, and the exposure was live right now.
So the guard went in server-side, where it does not care which engine calls it. On each of the four shops, the rebuilt pages, the guide index and the single-post template are on a protected list. Writes to them through the REST API come back 423 Locked. Page-builder metadata saves are refused. A filter on wp_insert_post_data keeps the stored content, title, status and slug no matter what the write asked for. The only way through is a header carrying an unlock key, and the only things that send it are the current deploy scripts.
A second rule rejects any write anywhere on the site, including the pages the engine still legitimately updates for promotions, that contains the retired strings. That one returns 422 rather than silently accepting the payload. I also dropped a do not redeploy file into each old engine folder, which is the note. Notes are for people. People were never the problem.
The guard immediately caught something I would have missed
Restoring two of the markets from backup failed. The guard refused the write, and it was right: WordPress keeps a plain-text copy of page content alongside the page-builder data, and that hidden copy still carried the retired strings. Nothing on the site rendered them. They were stored anyway, one search-and-replace away from coming back. We scrubbed them in the same write.
I would not have looked there. The rule did, because the rule checks payloads rather than appearances. That is the difference between a check and a habit, and it is the same reason I have come to prefer a hard block over a good intention in the tooling I build for my own work.
Why this keeps happening in marketing specifically
Because our corrections are nearly always to an artefact. A price that is wrong on a shop, a promotion that is still visible after its end date, a measurement that counts the wrong thing. We fix the thing the customer sees, mark it done, and move on, because the customer seeing it was the emergency.
I wrote earlier this month about a promotion that died silently across four country shops, and the same shape is underneath it: an artefact changed by hand while the process that produces it stayed the same. The deeper version of that lesson is the one I keep relearning from automation — a task that is safe to run twice is a task that cannot drift away from its own definition.
Operators with twenty years of reps are not immune to this. We are, if anything, more exposed, because we are fast at the artefact. The judgement that matters is knowing which lever actually holds, and “I edited the live page” is not a lever. It is a screenshot.
The rule I would write on the wall
A correction is not finished until the pipeline that produced the error cannot produce it again. If you cannot reach the pipeline today, make the output refuse to be overwritten, and make the refusal loud.
Four months of being right is not the same as being fixed. It is just the generator being asleep.
Sources & further reading
External
Martin Fowler, “Infrastructure as Code” — the definition is the source of truth, not the running system.
WordPress REST API Handbook and the wp_insert_post_data filter reference — where a server-side write guard actually hooks in.
RFC 4918, section 11.3 — the 423 Locked status code, and why it is the honest answer to a blocked write.
Google SRE Book, “Monitoring Distributed Systems” — on noticing a condition instead of trusting that it stayed fixed.
Related posts
Price governance in ecommerce: how a promotion died silently on four country shops for a month
My assistant created the same task three days running. The fix has a name: idempotency.
Claude Code mods vs skills: a skill is a suggestion, a mod is a guarantee
The death of generic AI: why deep domain expertise is the only real leverage left