Ibrahim Harbutlu
Playbook

Why a Passing Build Doesn't Mean Anything Went Live

3 min read

Editorial illustration with sage green shapes representing a Playbook post about the gap between a passing build and a live deploy

For a while, “the build passed” was where I stopped checking. The terminal printed its clean green line, and I moved on to whatever was next. Then I spent real hours confused about why a schema change I was sure I’d finished wasn’t showing up anywhere, because the build I kept re-running was reading whatever sat in my working folder at that second, committed or not. It has no opinion on whether any of that ever left my machine.

Where the confidence came from

I don’t read the code the AI writes for me line by line, so a clean build became my main signal that something was correct. For someone who does read every change, a passing build is one check stacked on top of actually understanding what moved. For me it was closer to the only check I had, which means it was carrying more weight than it was ever built to carry. A build tool checks that the code is valid. It was never checking that the code was mine to call finished.

What “it built” actually tells you

The build step compiles the pages, resolves the imports, and in my case runs the frontmatter through the content schema to catch a missing field or a wrong type before it becomes a live error. All of that happens against files on disk, not against git history. A build can pass with changes still sitting uncommitted, with a commit sitting unpushed, or with a push sitting in a deploy queue that hasn’t finished yet. None of those states look any different from “done” in a terminal that only ever says pass or fail.

The checklist that sits between “it works” and “it’s done”

What actually closes the gap is treating the build as step one of a chain instead of the finish line: build, then confirm the commit genuinely happened and the working tree is clean, then push, then give the deploy a minute or two to finish, then go look at the real public URL rather than the tab that’s already open from testing it locally. That last step matters more than it sounds like it should. A tab you’ve had open since before the change can keep showing a cached version and agree with you that nothing’s wrong, which is a worse failure mode than an obvious error, because it tells you you’re done when you’re not.

The part that’s still on me

None of this is really about git. It’s about the fact that when a tool is doing the typing, “it compiled” starts to feel like “I’m finished” a lot faster than it should, and the discipline to check the actual deployed thing has to come from somewhere other than the tool, because the tool has no way to know what I meant to ship. I’ve written before about testing products I can’t read the code for, and this is the same gap showing up one step earlier in the process, before a buyer is even involved: not whether the thing works, but whether the version I’m looking at is the version anyone else can see.