Digestable

Short takes on building well in the age of AI.

On Craft2026

Generate With Taste

With AI, everyone thinks they can just generate their way to a product. Generate the image, the logo, the icon, the code. The cost of making something dropped to nearly zero.

So the thing that separates builders is no longer access to the tools. Everyone has the tools. It's taste. It's standard.

Years ago, back when we still lifted half our answers off Stack Overflow, my rule was copy with taste. Study what's good, borrow the shape of it, then run every choice through your own standard. The tools changed, so now it's generate with taste. Same judgment, new verb.

When a model can spit out a hundred versions in a minute, the hard part is knowing which one is right and killing the other ninety-nine. Whoever is orchestrating the loop, deciding what ships and what gets thrown out, is doing the real work.

The tools generate. Taste decides. Your standard is the line you refuse to ship below.

TasteAICraftStandard

On Rigor2026

Eyeball It

Everyone is using AI now. Here's the piece most people skip.

Lately I run two agents side by side: Claude Code and Codex, each one checking the other's work. One writes, the other tries to tear it apart. It catches a lot.

But two models agreeing isn't the same as being right. They can be confidently wrong together.

So at the end of every loop, I eyeball it. And I mean that literally. I run the thing myself, by hand, end to end, dev tools open the whole time. I watch the console, read the network calls, and inspect the actual response: the payload, the status code, the token. Not the summary of the output. The output.

Eyeballing something usually means guessing at it. Here it means the opposite: the look is the check.

The eyeball is the last gate no agent gets to skip. The models generate and cross-check. The human confirms it's real.

Read the full story: Claude Code and Codex, side by side
VerificationAIRigorEyeball

On Security2026

Audit It Again

I opened an endpoint on purpose. Temporary, to get past something, and I'd close it right after. Then the work moved on and I forgot it was there.

Years later it bit me. No clever exploit. The endpoint was there, it answered, and someone found it before I did.

So the habit now isn't only for what I'm building. It's for what's already out there, running fine. An audit isn't a launch task. It's maintenance.

Running fine only means nobody has looked yet.

And it isn't in the developer 101. We test what we're writing, review what we're merging. Nothing in that covers a service nobody has opened in three years.

So I point the models at my own code. Read the route table, count what still answers without a token, then attack it instead of describing it. Every guard gets broken on purpose before I trust any of it.

And take note, attackers adapt. Every new frontier model is a better tool for them too, running all day against code written before any of this existed.

So that's the rule now. A new top tier model lands, that's the trigger: it reads what I already shipped before it touches anything new. I want to find it before they do...

And yes, I'm talking to you. Whatever you shipped that's still live, still quiet, still running fine. Go run the audit. Right now.

SecurityAuditAIAuth

On Proof2026

Watch It Fail First

A lot of people don't even write tests anymore. They just vibe-code it and hope it holds. The ones who do usually stop one step too early.

You know the moment. 14 out of 14 passing, all green, ship it. That green feels like safety. It isn't.

A test that's green the moment you write it has proven nothing. It might assert nothing at all. So before I write a line of the fix, I write the test and watch it go red. Not any red. Red for the exact reason I predicted.

On the fintech systems I work on, the rule is simple: every new behavior has to fail before I make it pass. For a bug, that failing test pins it. The repro fails with the exact wrong output: expected 400, got 415. When it turns green, I know I fixed that exact thing and not something next to it.

The red is the proof the test can actually catch what it's guarding. Then I tag each test with the requirement it proves. Red, then green, then evidence. That's the whole gap between having tests and trusting them.

TDDTestingRigorProof

On Migrations2026

Keep the Dump

For years the fight was code first or database first. People asked which camp you were in like it was a personality trait.

My take now, with AI writing half the schema: do both. The code owns the model, EF migrations, domain entities in script, all of it. The database stays the source of truth for what actually shipped.

The habit that actually saved me sits underneath both: I keep a full SQL dump of the database in sync. One plain file with the whole schema, refreshed every time a migration changes it.

You are generating a hundred entities in script, fine. The dump is what makes environments cheap. Point it at an empty database and load. Dump, load, done. A fresh env, a new branch, a teammate's laptop, the same one file every time.

Migrations describe the change. The dump captures the result. The more AI speeds up the schema, the more that snapshot is what keeps every environment honest.

MigrationsPostgreSQLEFBackend