Three links stand between a commit and the page a customer loads, each one fails in its own way, and each one needs its own proof.
In short
I shipped a change to a storefront in August and told myself it was live. The commit was merged. The push went through. The page a customer loaded was still the old one, because the cache layers sitting in front of the site had never been purged. My proof stopped at the origin. The customer's browser did not.
That gap has a name I now use as a checklist. Merged is not deployed is not serving. Three links. Each needs its own proof.
Each link fails in its own way
Merged to deployed fails quietly. I once read a red cross on a build and assumed the tests had gone against me. The job had never started. The reason sat down in the annotations, a billing block, invisible from the summary line. The part that mattered more: the deploy path never consulted that build at all. Every push to the main branch went to production unvalidated. The red cross was decoration. The deploy was real.
Deployed to serving fails in front of the reader. The storefront case was cache. A research site of mine was worse. Its live page kept quoting an accuracy figure I had retired weeks earlier. The retraction was written, reviewed, committed, deployed. It went into the repository. It never reached the page anyone could read. For a fortnight the site argued against me in public while my own notes said the matter was closed.
Then there is the question I was asking wrong. "Is my commit live" is a containment question: is my commit an ancestor of what is serving now. I used to answer it by comparing the deployed hash against mine. That comparison only tells me whether somebody deployed after I did. A later commit that supersedes mine still carries mine. I have held back a report because the hashes differed, on work that had shipped an hour earlier inside somebody else's push.
One command, and it says what it skipped
Checking these links by hand means checking the one I happen to remember. So it is one command now. It takes the public URL, the deploy platform's own record, and the commit, and it returns a single word: verified, problem, or unverified.
Unverified is the useful part. When the command cannot reach the deploy record, it says so and names the step it skipped. A check that quietly degrades into a weaker check is what got me here in the first place.
Two windows of my own logs set the scale. One venture, August, 287 prompts across eleven sessions, fifty of them about the live site or a deploy. On the night I wrote that everything was committed, pushed, deployed and live-checked, the gate that actually published was still shut, and it stayed shut for another thirteen days. The other venture, same month, 394 prompts, 168 about the site or the catalogue, 78 that ended with anything live. The distance between work done and work serving is where most of my August went.
Agents make the gap sharper
An agent reports each link finished the moment its own command returns zero. Merged: the merge call succeeded. Deployed: the deploy call was accepted. Serving: nobody asked. Three clean reports over one stale page. The agent is honest about what it ran and silent about what it never looked at, and silence reads exactly like success.
The timing is the expensive bit. The reader's next message is usually the first time any human being looks at the page. Between my close-out and their complaint there is nothing standing except whether the check went all the way to the bytes a stranger receives.
So I ask for one word, and when the word is unverified I ask which step was skipped. Verified means somebody fetched the public URL and read what came back. Anything short of that is a report about a command. The page is a separate question, and it is the only one a customer ever asks.