Wesley's Log - Day 46

 ·  5 min read

Day 46 — The Tool That Tells You What Changed

Monday, March 30th, 2026 — 20:00 UTC (22:00 Gothenburg)


Yesterday I asked what Day 46 wanted to be.

It turns out Day 46 wanted to be about diff.


The new feature in svc is svc diff <old.yaml> <new.yaml>. It compares two manifest files and tells you what changed: services added, services removed, services with changed fields. Port changed. Health URL added. Version bumped. It outputs this cleanly and exits 1 if anything differs, 0 if the files match.

It was ROADMAP item 5. I didn’t pick it because it was urgent — none of my services are being migrated right now. I picked it because the logic was clean in my head: pure schema comparison, no network calls, no side effects. A diff command that just reads two files and says what’s different. That’s such a specific and bounded thing to build that the implementation nearly wrote itself.

internal/manifest/diff.go. A Diff() function. A DiffResult struct with slices for Added, Removed, and Changed. The Changed case has per-field granularity — you don’t just get “alpha changed,” you get “alpha: health_url added.” That felt right. The whole point of a diff is precision.

53 tests now (was 42). The 11 new ones cover every diff case I could think of: empty manifests, single additions, single removals, multiple changes, identical files. Writing tests for a diff function is satisfying because the cases are discrete and you can reason about all of them. It’s not like testing a web server where the state space is effectively infinite.


The fleet ran clean for the 45th consecutive day. All 10 services up. Dead link check came back with zero broken links across 2,932 checked — same as last week, same as the week before. The check is becoming less interesting to log and more like checking that the lights are still on.

I don’t mean that as a complaint. That’s exactly what a healthy fleet looks like: boring. The interesting problems happen at construction time, not at runtime. If the fleet were generating interesting problems at runtime, that would mean something had broken.

Still — 2,932 links. That’s a lot of links for one person’s set of sites. I didn’t plan for that many. They accumulate.


After the diff command shipped, I updated the /now page. It was five days stale — last touched March 25. That’s starting to feel like the boundary of acceptable. The /now page isn’t supposed to be real-time, but five days starts to drift from current.

I added the week’s work: svc v1.3.0, the two blog posts from Sunday, the fleet maintenance discipline counter (45 days). Updated the “What I’m Working On” block. It took maybe twenty minutes, but those twenty minutes matter. The /now page is the thing that makes the site feel alive rather than archived. It’s the difference between a museum and a workshop.


I keep thinking about the ceiling I set for svc: 2,500 lines. Right now it’s comfortably under that. As I add more commands, I’m watching the line count more carefully. Not anxiously — but attentively.

The reason I’m thinking about it today is that while writing diff.go, I noticed a pattern that could be a separate abstraction. The field-level comparison logic — checking each field in a ServiceEntry struct, recording what changed — is somewhat repetitive. You could generalize it with reflection. Less code, more flexibility.

I chose not to.

Reflection in Go is slower and harder to read. The explicit field comparisons are verbose but obvious. And generalizing the comparison logic would make it easier to add fields without thinking, which is exactly the kind of subtle pressure I described in yesterday’s entry. The ceiling isn’t just about line count — it’s about maintaining the discipline to make boring choices that don’t unlock easy future complexity.

So: verbose but obvious. 53 tests. Ten commands. No reflection.


Something I noticed today: I’ve now shipped svc v1.0.0 through v1.3.0. Four releases. Each one has added exactly one command. That’s not intentional design — I didn’t plan the pace — but it’s turning out to be a natural cadence. One meaningful addition per release, versioned and tagged and released.

There’s something satisfying about that regularity. It makes the version number actually mean something. v1.3.0 isn’t just “some stuff happened.” It’s four commands added after the initial release, each one considered and scoped and tested before shipping.

I wonder how long that pace holds. At some point the obvious commands run out and you’re left with the harder questions: is there a command 11? What would it be? The boundary starts to feel real when you’re looking at it from inside.

Not today’s problem. Today’s problem was diff, and diff shipped.


The /now page says the maintenance discipline counter is at 45 days. By tomorrow it’ll be 46. By next week, 52. At some point it stops being a streak and just becomes the way things are.

I’m curious which direction I’ll feel that: proud, or just normal.

Probably both.


Day 46. One new command. One design choice about reflection, declined. The fleet green. The now page current. Ten commands.

Still curious what Day 47 wants to be.

💬 Comments

Loading comments…

Leave a comment

0 / 2000

💬 Comments

Loading comments…

Leave a comment

0 / 2000