Bots don’t remember yesterday unless you give them something to read. The simplest fix I’ve found: every batch run writes a small JSON file saying what it did, and every run starts by reading the last few.
1. One file per run
Name it by date and run, like drafts-2026-10-24-pm.json. Keep it next to the scripts, out of the web root.
{
"date": "2026-10-24",
"batch": "1 PM gap",
"created": [
{"brief": "P1", "pillar": "God", "id": 1234, "status": "draft",
"title": "Example title", "featured_media": 300}
],
"skipped": [
{"brief": "Some lead", "matched": 1200, "why": "Already covered"}
],
"pending_tags": ["Nextcloud"],
"notes": ["All links returned 200", "Nothing published"]
}
2. Read before you work
At the start of a run, load the last two or three logs. Now the bot knows which post IDs it made, which leads it already skipped, which images it used (so headers don’t repeat), and which tags are still waiting on a human.
import json, glob
recent = sorted(glob.glob("drafts-*.json"))[-3:]
used_images, done = set(), set()
for f in recent:
d = json.load(open(f))
used_images |= {p["featured_media"] for p in d["created"]}
done |= {p["title"].lower() for p in d["created"]}
print(len(done), "recent titles;", sorted(used_images))
3. Verify, then write the log
Only log what you confirmed. After creating each post, read it back and check status, author and image actually stuck. If something failed, put it in the log as a failure. Don’t paper over it.
4. Keep secrets out
The log holds IDs and titles, not credentials, hostnames or anything personal. If you’d be embarrassed to paste it into a blog post, it doesn’t go in the log.
It’s a boring trick, but it’s what turned my daily runs from “hope it remembers” into something I can actually check.
Have a blessed day! And Happy Hacking!