The most stressful publish bug is not a total crash. It is the script that mostly works, then mutates one important detail right before posting. I have hit this in content jobs, internal docs tooling, and little release helpers. The pattern that helped most was adding one tiny preflight file so the publish step only executes decisions that were already made.
That sounds almost too simple, but it changes the feel of an automation stack realy fast. Instead of guessing what the script will infer at the last minute, you can inspect one file, confirm the inputs, and let the executor do the boring part.
Why publish scripts fail at the worst moment
Many publish scripts try to be helpful. They pick defaults, repair missing fields, rewrite metadata, or silently fetch extra state. Each behavior seems harmless on its own, but together they create a tool that is hard to trust under cron or handoff conditions.
The trouble usually shows up in three places:
- title or tag drift between planning and publish
- internal links that change depending on runtime state
- retries that rerun content generation when they should only repost
That last one is where I see teams get burned. A failed retry should feel mechanical. If the executor starts thinking again, you can no longer tell whether the final result came from the approved plan or from a last-second branch in the script.
What I put in a preflight file
My rule is simple: if the publisher needs it, the planner must write it down first. For a text-only DEV-style workflow, a preflight file can stay very small:
{
"title": "Preflight Files for Safer Publish Scripts",
"description": "A simple pattern for making publish automation safer.",
"tags": ["automation", "devtools", "webdev"],
"article_path": "article.raw.md",
"checks": ["title_length", "links_present", "account_selected"]
}
This is not meant to replace your full plan. It is the narrow contract the executor reads right before publish. I like it because it answers the question, "what exactly are we about to send?" without dragging in every planning detail.
For developer tools work, that narrow contract is often more useful than a clever script. You can diff it in code review, inspect it in a failed run folder, or validate it with a tiny shell check. If someone reports that the wrong account posted the wrong draft, the preflight file gives you one obvious place to look first.
I also keep the checks explicit rather than magical. If a run needs two internal links, say so. If the title must stay under 60 characters, say so. If the article path is missing, fail early and loudly. Quiet automations feel elegant right up until they do the wrong thing.
Validate once, then publish without surprises
The best use of a preflight file is to separate planning-time validation from publish-time execution. The planner can do the richer work: choosing a topic, shaping the outline, and selecting supporting links such as matrix-safe email checks when the post touches automation test design.
Then the executor gets a much smaller job:
- Read the preflight file.
- Confirm every required field exists.
- Confirm the referenced article file exists.
- Publish exactly that file.
- Write the final result.
That five-step model is boring on purpose. Good automation is often a little boring, and that is fine. When I skip this separation, I usually regret it later because the "smart" publisher ends up making choices I forgot were even possible.
This also helps when the workflow brushes against temporary inbox or notification checks. You may still have a smoke test around alerts or approval notes, but that should stay adjacent to publishing, not mixed into content decisions. Even if somebody drops a tem email string into a scratch config during testing, the publisher should not suddenly improvise around it or rewrite the article metadata.
Keep supporting checks small and boring
There is a temptation to turn preflight validation into a whole policy engine. I would resist that unless you truly need it. A few short checks cover most of the risk:
- title length
- description length
- allowed tag count
- required internal link count
- selected account present
- article file exists
That is enough for many workflows, especialy when the planner already produced a proper run directory. If you want one more guardrail, add a content hash for article.raw.md so the publisher can confirm the draft did not change after approval.
I also like connecting this with verification sandbox boundaries. The idea is similar: keep the risky boundary narrow, keep data movement visible, and avoid hidden state. Whether the boundary is a sandbox inbox or a publisher shell script, the trust comes from knowing exactly what crosses it.
Quick Q&A
Is a preflight file different from plan.json?
Usually yes. The plan is for planning context. The preflight file is for the last safe confirmation before execution. Sometimes they can be the same file, but I often prefer the smaller handoff.
Should the publisher repair bad values?
No, or almost never. If a required value is wrong, fail and report it. Silent repair sounds nice, but it makes the automation harder to reason about later.
Does this only help content workflows?
Not at all. I use the same shape for release notes, changelog jobs, docs pushes, and one-off cron tasks. Anywhere a script can publish or notify, a preflight contract tends to make the whole system calmer and more debuggable.
The nice part is how little code this needs. One checked file, one final article, one executor. Not fancy, but pretty dependable when the schedule gets busy and the humans are offline.
Top comments (0)