Tag: Ai
プログラマ道 (puroguramā-dō)
プログラマ道1.
Companion piece to the 100x post. That one was the framing argument: AI tooling is +0.99 with a wielding bonus, not a multiplier. This is the ground-level version. How I actually drive the thing day to day, what I will not delegate, and why none of this is new.
I drive Claude every day. Across Woosmap services in Python, a music app in Go and SwiftUI on the weekends (Tunes), a SNES toolchain in Python (a816, xdds), and a fair amount of 65c816 ROM hacking. The tool is real. It does not flip the table on the discipline an engineer needs. It raises the floor a notch and rewards the wielder. What the wielder is actually doing, when it works, is the part nobody writes down.
The 100x engineer, and the unit nobody defines
The 100x engineer is back in the discourse. This time the pitch is that an engineer with the right AI tooling can do the work of a hundred. Sometimes the number is 10x, sometimes it is 100x, occasionally someone goes wild and writes 1000x. The number is always round and the unit is always missing.
What are we counting?
If a 100x engineer using Claude can do 365 days of work in 3.65 days, whose 365 days? A staff engineer shipping platform infrastructure? A junior wiring up CRUD endpoints? My grandmother on a good day? The denominator is doing all the work in that sentence and nobody ever writes it down.
The complete machine, fading
My iPod 5.5g is old enough to drink alcohol in any country that has a drinking age. I bought it used, swapped the battery and the disk for an SD card mod, and it still does the one thing it was sold to do: play music. No firmware update has ever taken a feature away. No company has decided the device is too old to deserve syncing. Apple, to their credit, still ships iTunes and Music with iPod sync on macOS. But even the day they stop, the iPod will keep playing whatever is already on the disk. The original purpose has not eroded.
Tag: Claude
プログラマ道 (puroguramā-dō)
プログラマ道1.
Companion piece to the 100x post. That one was the framing argument: AI tooling is +0.99 with a wielding bonus, not a multiplier. This is the ground-level version. How I actually drive the thing day to day, what I will not delegate, and why none of this is new.
I drive Claude every day. Across Woosmap services in Python, a music app in Go and SwiftUI on the weekends (Tunes), a SNES toolchain in Python (a816, xdds), and a fair amount of 65c816 ROM hacking. The tool is real. It does not flip the table on the discipline an engineer needs. It raises the floor a notch and rewards the wielder. What the wielder is actually doing, when it works, is the part nobody writes down.
Tag: Discipline
プログラマ道 (puroguramā-dō)
プログラマ道1.
Companion piece to the 100x post. That one was the framing argument: AI tooling is +0.99 with a wielding bonus, not a multiplier. This is the ground-level version. How I actually drive the thing day to day, what I will not delegate, and why none of this is new.
I drive Claude every day. Across Woosmap services in Python, a music app in Go and SwiftUI on the weekends (Tunes), a SNES toolchain in Python (a816, xdds), and a fair amount of 65c816 ROM hacking. The tool is real. It does not flip the table on the discipline an engineer needs. It raises the floor a notch and rewards the wielder. What the wielder is actually doing, when it works, is the part nobody writes down.
Tag: Productivity
The 100x engineer, and the unit nobody defines
The 100x engineer is back in the discourse. This time the pitch is that an engineer with the right AI tooling can do the work of a hundred. Sometimes the number is 10x, sometimes it is 100x, occasionally someone goes wild and writes 1000x. The number is always round and the unit is always missing.
What are we counting?
If a 100x engineer using Claude can do 365 days of work in 3.65 days, whose 365 days? A staff engineer shipping platform infrastructure? A junior wiring up CRUD endpoints? My grandmother on a good day? The denominator is doing all the work in that sentence and nobody ever writes it down.
Tag: A816
25 years to a complete machine
Since around the year 2000 I have been piling features into a French Final Fantasy IV translation patch. Variable-width fonts in dialog, in battle messages, in menu descriptions. Redrawn battle, load/save, main, and two-column magic menus. An expanded inventory of 0x48 slots rendered through a paged window instead of the static grid the original engine assumed. Most of these were features the SNES ROM hacking scene of the era said could not be done on real hardware. Other hackers eventually pulled off equivalents on other titles, fair enough; modifying a compiled ROM is more convoluted than editing source code, but not impossible. Twenty-five years on, “impossible” reads as a fair approximation of how hard, not of whether.
Tag: Ff4
25 years to a complete machine
Since around the year 2000 I have been piling features into a French Final Fantasy IV translation patch. Variable-width fonts in dialog, in battle messages, in menu descriptions. Redrawn battle, load/save, main, and two-column magic menus. An expanded inventory of 0x48 slots rendered through a paged window instead of the static grid the original engine assumed. Most of these were features the SNES ROM hacking scene of the era said could not be done on real hardware. Other hackers eventually pulled off equivalents on other titles, fair enough; modifying a compiled ROM is more convoluted than editing source code, but not impossible. Twenty-five years on, “impossible” reads as a fair approximation of how hard, not of whether.
Tag: Romhacking
25 years to a complete machine
Since around the year 2000 I have been piling features into a French Final Fantasy IV translation patch. Variable-width fonts in dialog, in battle messages, in menu descriptions. Redrawn battle, load/save, main, and two-column magic menus. An expanded inventory of 0x48 slots rendered through a paged window instead of the static grid the original engine assumed. Most of these were features the SNES ROM hacking scene of the era said could not be done on real hardware. Other hackers eventually pulled off equivalents on other titles, fair enough; modifying a compiled ROM is more convoluted than editing source code, but not impossible. Twenty-five years on, “impossible” reads as a fair approximation of how hard, not of whether.
Tag: Snes
25 years to a complete machine
Since around the year 2000 I have been piling features into a French Final Fantasy IV translation patch. Variable-width fonts in dialog, in battle messages, in menu descriptions. Redrawn battle, load/save, main, and two-column magic menus. An expanded inventory of 0x48 slots rendered through a paged window instead of the static grid the original engine assumed. Most of these were features the SNES ROM hacking scene of the era said could not be done on real hardware. Other hackers eventually pulled off equivalents on other titles, fair enough; modifying a compiled ROM is more convoluted than editing source code, but not impossible. Twenty-five years on, “impossible” reads as a fair approximation of how hard, not of whether.
Tag: Cloud
The complete machine, fading
My iPod 5.5g is old enough to drink alcohol in any country that has a drinking age. I bought it used, swapped the battery and the disk for an SD card mod, and it still does the one thing it was sold to do: play music. No firmware update has ever taken a feature away. No company has decided the device is too old to deserve syncing. Apple, to their credit, still ships iTunes and Music with iPod sync on macOS. But even the day they stop, the iPod will keep playing whatever is already on the disk. The original purpose has not eroded.
Tag: Hardware
The complete machine, fading
My iPod 5.5g is old enough to drink alcohol in any country that has a drinking age. I bought it used, swapped the battery and the disk for an SD card mod, and it still does the one thing it was sold to do: play music. No firmware update has ever taken a feature away. No company has decided the device is too old to deserve syncing. Apple, to their credit, still ships iTunes and Music with iPod sync on macOS. But even the day they stop, the iPod will keep playing whatever is already on the disk. The original purpose has not eroded.
Tag: Macos
Higgins: a neurosymbolic menubar buddy
Higgins is a local assistant that lives in the menubar. A Qwen 2.5 7B model runs on-device via MLX, a SQLite triple store remembers things across sessions, and a small collection of tools — AppleScript runners, EventKit bridges, gh CLI wrappers — lets him actually do work on the Mac. No cloud, no subscription, no data leaving the machine.
The name is a nod to Magnum P.I.’s reserved English major-domo. The vibe was aspirational; most of the engineering effort went into making sure he doesn’t cheerfully hallucinate your dentist appointment into 2023.
Tag: Mlx
Higgins: a neurosymbolic menubar buddy
Higgins is a local assistant that lives in the menubar. A Qwen 2.5 7B model runs on-device via MLX, a SQLite triple store remembers things across sessions, and a small collection of tools — AppleScript runners, EventKit bridges, gh CLI wrappers — lets him actually do work on the Mac. No cloud, no subscription, no data leaving the machine.
The name is a nod to Magnum P.I.’s reserved English major-domo. The vibe was aspirational; most of the engineering effort went into making sure he doesn’t cheerfully hallucinate your dentist appointment into 2023.
Tag: Swift
Higgins: a neurosymbolic menubar buddy
Higgins is a local assistant that lives in the menubar. A Qwen 2.5 7B model runs on-device via MLX, a SQLite triple store remembers things across sessions, and a small collection of tools — AppleScript runners, EventKit bridges, gh CLI wrappers — lets him actually do work on the Mac. No cloud, no subscription, no data leaving the machine.
The name is a nod to Magnum P.I.’s reserved English major-domo. The vibe was aspirational; most of the engineering effort went into making sure he doesn’t cheerfully hallucinate your dentist appointment into 2023.
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Tunes
iTunes Match worked great for years: you uploaded your library, Apple matched what it could, and you had access to everything from any device. But Apple is clearly moving everyone toward Apple Music, and iTunes Match has been slowly rotting. The writing was on the wall.
I didn’t want to subscribe to Apple Music. I wanted to keep my library, my ratings, my play counts, my playlists, all the metadata accumulated over 20 years. So I built my own streaming setup: a Go backend that serves the library over HTTP, and SwiftUI apps that play it on iOS, macOS, and tvOS.
Tag: Vector-Tiles
Freddie part 2: from tiles to map
In part 1 I covered the hard problems: COG multi-resolution, SDF raster smoothing, and Barbapapa topology-preserving Laplacian smoothing. Freddie could generate good-looking 10m land cover vector tiles. This post is about what happened next: killing the algorithm I spent a week perfecting, solving a surprisingly dumb storage problem, and wiring the tiles all the way through to the map SDK.
Barbapapa is dead
I killed Barbapapa a few weeks after shipping it.
Scaling Freddie to 10m landcover
Serving vector tiles from 10-meter resolution land cover data. What breaks when you 100x the input resolution, and how topology-preserving smoothing fixes the ugly parts.
Background
Freddie is our tile server for land cover data. It reads GeoTIFF raster files (pixels classified as wood, grass, built-up, water, etc.) and serves them as vector tiles or raster tiles over HTTP. Nothing fancy. Read pixels, make shapes, encode, serve.
The original setup used ESA WorldCover at ~100m resolution. Native resolution sits around z8 in Web Mercator, so serving z0–z8 tiles was straightforward. Sample pixels, run-length encode, merge adjacent faces of the same class, encode to MVT. Done. It just worked, and I didn’t think much about it.
Tag: Linux
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Tag: Rust
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Tag: Swiftui
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Tree: a browser that remembers where you came from
Every browser has tabs. Linear, flat, disposable. Open thirty of them researching one topic and they sit in a row with no indication that twelve of them came from the same Wikipedia article. Close the wrong one and the context is gone.
Tree is a macOS browser that replaces tabs with a tree. Every page knows its parent. Cmd+Click a link and it becomes a child node of the current page. The sidebar shows the full hierarchy: research paths branch naturally, and you can always trace back to where you started.
Tag: Wgpu
The most useless way to port a macOS app
I grew up fascinated by projects like GNUStep, Haiku, Etoile, Wine, and ReactOS. Engineering feats, all of them. They reverse-engineer or reimplement entire operating system APIs so that software written for one platform can run on another. And they almost always end up in the same place: impressive technically, starved for contributors, forever chasing a moving target they can never quite catch.
I never liked the state of the Linux desktop either. Not because it’s bad per se, but because it’s fragmented. A KDE app on GNOME looks alien. Firefox rolls its own everything. GTK and Qt will never agree on anything. Every toolkit draws its own widgets, manages its own text rendering, handles its own accessibility story. The result is a desktop that feels like a coalition of independent projects rather than a coherent system.
Tag: Docker
Multi-arch Docker builds in GitHub Actions
We needed ARM64 containers. Our Python services run on mixed infrastructure: amd64 in CI and some production clusters, arm64 on newer nodes. Building on one arch and emulating the other with QEMU was painfully slow and broke native extensions. So we added proper multi-arch builds to our GitHub Actions CI.
It took a week to get right. Then five more fixes over two weeks as each failure mode revealed itself in production. This is what went wrong and how we fixed it.
Migrating Python containers to Wolfi and uv
Our Python services ran on ubuntu:24.04 with pip-installed dependencies. It worked, but the images carried hundreds of packages we never used, Trivy scans were noisy with OS-level CVEs, and builds were slower than they needed to be. Over a couple of months we migrated to Chainguard’s Wolfi base image and uv for dependency management. This is how it went for the maps service, the one that renders static map tiles with a C++/Python hybrid stack.
Tag: Github-Actions
Multi-arch Docker builds in GitHub Actions
We needed ARM64 containers. Our Python services run on mixed infrastructure: amd64 in CI and some production clusters, arm64 on newer nodes. Building on one arch and emulating the other with QEMU was painfully slow and broke native extensions. So we added proper multi-arch builds to our GitHub Actions CI.
It took a week to get right. Then five more fixes over two weeks as each failure mode revealed itself in production. This is what went wrong and how we fixed it.
Tag: Go
Full-text search and lyrics in a Go music server
The Tunes server started as a way to stream my music library from a Raspberry Pi. It’s accumulated features since then. Two recent additions changed how I interact with it day-to-day: accent-insensitive full-text search across the entire library, and lyrics, both embedded from audio files and fetched from LRClib.
The search problem
Searching a music library is harder than it sounds. You want “bjork” to match “Björk”. You want “cafe” to match “Café”. You want “creme” to match “Crème Brûlée” in an album title. And you want it fast enough that results appear as you type.
Tunes
iTunes Match worked great for years: you uploaded your library, Apple matched what it could, and you had access to everything from any device. But Apple is clearly moving everyone toward Apple Music, and iTunes Match has been slowly rotting. The writing was on the wall.
I didn’t want to subscribe to Apple Music. I wanted to keep my library, my ratings, my play counts, my playlists, all the metadata accumulated over 20 years. So I built my own streaming setup: a Go backend that serves the library over HTTP, and SwiftUI apps that play it on iOS, macOS, and tvOS.
Tag: Python
Migrating Python containers to Wolfi and uv
Our Python services ran on ubuntu:24.04 with pip-installed dependencies. It worked, but the images carried hundreds of packages we never used, Trivy scans were noisy with OS-level CVEs, and builds were slower than they needed to be. Over a couple of months we migrated to Chainguard’s Wolfi base image and uv for dependency management. This is how it went for the maps service, the one that renders static map tiles with a C++/Python hybrid stack.
A map style compiler in Python
Generating Mapbox GL GL style JSON from Python code instead of editing 3,000-line JSON files by hand. Hierarchical style resolution, a Django-style filter DSL, injection-based layer ordering, and a Go sprite generator called from Python via ctypes.
The problem with style JSON
A Mapbox GL GL style is a single JSON file that describes everything about how a map looks. Background color, road widths at every zoom level, label fonts, icon placement, landcover tints, building extrusion heights. All of it.