I'd keep your closing check and move where it counts: read the destination, not a ledger the agent writes. That ledger is still the agent's account of what it did. If a post is accepted by the API and then held by a spam filter, or the process dies between writing the ledger line and the actual submit, the ledger and the platform disagree, and the ledger wins because it's the one you're reading. The version I'd trust reads the published output from the target system after a short delay and compares it with what the run claimed.
One caution from the other direction: some platform APIs lag their own rendered pages. Right after a successful post, the API can still report nothing new. A check that reads too early and retries on "missing" turns a success into a duplicate. So the ground-truth read wants a delay, and a rule that a missing post gets reported, not reposted.
Smaller point on the lock. The 90-minute age break fixes the permanent wedge, but a recycled PID still skips every tick until the lock ages out, which at five-minute ticks is up to 18 lost runs. Writing the process start time next to the PID (ps -o lstart= -p "$PID" works on macOS) lets the liveness check confirm it's the same process rather than any live one, and the age break becomes a backstop instead of the main defence.
Mihai_LeanZero
Atlassian Forge developer and AI enthusiast who built his own agentic development workflow. Turns complex migration projects into lean, fast