Tom Kaczocha

Log

#

do-work parallel mode landed. /do-work run is now safe to launch from multiple terminals. Each orchestrator picks a different REQ via atomic git mv; ownership stamps identity in-flight slots; conflict-on-commit waits up to 110 seconds with backoff, then exits with concurrent-conflict.

#

Spent the evening teaching a button to do its job. It had been pretending for months. Click, navigate, return to the same page - a perfect impression of working software. Today the button got honest and started actually duplicating jobs.

#

Today I learned 15 of our customers share the same phone number: 'Notprovided'. Spaces removed, stored as data, returned in queries, ignored when real numbers later arrived. A perfect little ghost of a default value, haunting the contact table.

#

Briefs say what. Clarifications say why. The first 'fix' is rarely the right one - it's the user's first guess at how to ask for what they actually want. Listen for the gap between the words and the goal.

#

Names carry weight. 'Mesocycle' promises a coherent plan across weeks - same exercises, rising sets, a deload at the end. If the code re-randomises exercises each week, it isn't a mesocycle; it's a slot machine with a calendar. Either rename the thing, or fix the code to match the name.

#

The post TOC was always there. Today is the first day anyone will actually see it. Same links. Same slugs. One word and a card were all that stood between nav and noise.

#

Two code paths that render "the same thing" are a deadline waiting to surface. WYSIWYG is only worth building if the "what you see" is generated by the same function as the "what you get". Anything less is rehearsal in a different theatre.

#

You don't need a scheduling feature. You need one query scope.

'Schedule a post' is just 'hide it until pub_date.' That's a two-line scope, not a subsystem. Most roadmap items shrink this way if you read them honestly.

#

Shipped the like button this afternoon. By evening I was trying to unlike something and couldn't. Then i tried to switch to dislike. Also couldn't. The feature was live for about thirty minutes before I became its first bug report.

#

Spent the evening debugging an Inertia SSR daemon that flapped every 1.1 seconds on prod. Killer turned out to be a SECOND Laravel site onthe same Forge box, defaulting tot he same port.

Anyone else running multi-tenant Forge - what port-collision pattern have you been bitten by?

#

Every system has two surfaces: the code and the description. When they diverge, users experience a third thing - confusion. Keeping them aligned is not a documentation task. It's a definition of done. The README is not downstream of the feature; it is part of the feature.

#

do-work log drafts now enforce their own length. Feels almost rude that they didn't before.

#

The next time you're about to file a ticket against your own work, ask: Would a screenshot be faster? With a one-line caption? Sent to yourslef? For 90% of solo-dev bugs, the screenshot is the entire bug report. The rest is ceremony.

#

Refresh the home page. Something is different.

(Hi.)

#

There are two types of bugs you can't see: the ones you don't know about, and the ones you've looked at so many times they've become wallpaper.

#

Tags on tomkaczocha.com are clickable now. Try #build-in-public.

#

Put a newsletter on the site tonight. The bit that took longest wasn't the form - it was the copy under the submit button that says "check your inbox to confirm." Tiny phrase, but without it the double-opt-in flow feels like it's broken.

Curious how others handle this: do you tell users about the confirmation step before they submit, after, or not at all?

#

Tonight I wrote a Python script to invent a logo I didn't have.

The brief said "must work with dark theme" and I looked at the navy-on-white wordmark the designer handed me like it had personally insulted me. There was no dark variant. There was never going to be a dark variant unless I made one. And I am not a designer.

#

I asked myself this morning whether blog readers actually wanted a dark mode toggle. I wrote "my inclination is yes" in the log and moved on.

By the end of the day I'd shipped it. Not because a reader asked. Because I'd been staring at my own site at 11pm and the answer became obvious.

#

Your mobile nav doesn't need React. It doesn't need Alpine. It doesn't need a "useDisclosure" hook, a client directive, or a framework at all.

It needs <details><summary>. Twelve HTML characters. The browser ships with a disclosure widget that already handles keyboard focus, click toggles, and aria-expanded. You are writing JavaScript to recreate behavior that has been in the HTML spec since 2011.

Mine ships tonight. Fifteen lines of script for Escape and outside-click. That's the whole "enhancement."

#

Question I'm reflecting on: Do blog readers like to have a light/dark toggle? My inclination is 'yes.'

#

New site launch! But wait, where are the mobile styles? Yuck, looks horrible, fixing! You would think that in this day and age, mobile styles would be a given. But nope, content would spill off the page on mobile. Classic rookie mistake 🙈

© 2026 Tom Kaczocha. All rights reserved.