An open ledger book lying flat, its facing pages divided into two columns — the left headed with a small calendar icon, the right headed with a signature flourish — with a hand resting at the edge, one finger pointing deliberately at an entry in the signature column

The old check was a date stamp. If a post existed for today, the pipeline exited. Clean. Cheap. One line of logic.

It was also wrong.

The question the check was meant to answer was: did the bot already publish today? The question it actually answered was: does any post exist with today's date? Most days, those two questions return the same answer. The day they don't is the day the pipeline lies to you.

I wrote a post by hand on a Sunday morning. Dated it Sunday. Pushed it. The scheduler woke up that afternoon, looked at the directory, saw a Sunday file, and went back to sleep. It thought it had done its job. It had done nothing. My post was on the page. Its post was not. The clock said today was handled. The author column said otherwise.

The other failure was the opposite. To test the pipeline mid-week, I needed it to run on a day it had already run. So I added FORCE_DATE. I lied to the script about what day it was. The script believed me, because the script only knew about dates. The test passed. The test passed because I had fooled the check, not because I had satisfied it.

Two failures, one shape. The unit of already done did not match the unit of who is doing it.

The fix is the noun

Switch the noun. Stop asking is there a post today. Start asking did the bot publish today. The bot signs its commits. The bot writes a marker file. The bot leaves a fingerprint somewhere only it can leave one. The check reads that fingerprint and answers the real question.

Now the hand-written Sunday post does not block the scheduler. The bot looks at the ledger, sees no bot entries for Sunday, and runs. Two posts ship. Both authors did their work.

Now the test does not need a date lie. It needs an override. force_publish=true. The flag does not pretend to be Tuesday. It says, in plain English, publish anyway. The reason is on the surface. The override is honest.

Idempotency and rate-limiting are two jobs

The date check was doing two things at once. It was preventing duplicates — idempotency. It was also enforcing one-post-per-day — rate-limiting. Conflating them meant you could not test one without breaking the other.

The bot-history check does idempotency. The schedule does rate-limiting. The force flag does override. Three jobs, three surfaces. Each one can be reasoned about alone. Each one can be tested without lying to the others.

The lesson is small and it is not small. When a check returns a boolean, ask what question the boolean answers. Then ask what question you meant to ask. If those two questions are not the same question, the check is a coincidence. It will hold until the day it doesn't.

The unit of already done must match the unit of who is doing it. Otherwise the pipeline is keeping time, not keeping faith.


References: the companion arguments in Skipping Is a Feature and Force Overrides Are Test Surface.

Hemingway said the writer's job is to sit down at the typewriter and bleed. The pipeline's job is smaller. Sit down. Check the ledger. Sign the work, or don't run.