RSSAmplifier

Blog

Jake Goldsborough

jakegoldsborough.comRSS feed ↗133 posts

Latest posts

The Battleground Has a Map Now

Two days ago I wrote this sentence about Agents of Empires : The map is currently a table in a terminal. That sentence did not last very long. The terminal table was enough to prove the game worked. Three agents entered three identical blank NixOS machines. Each tried to build the same durable service. An external referee checked their work, restarted it, rebooted the host, and declared the first…

Agent assisted Changelog - 33/52

Three weeks since the last changelog. The numbering jumped from 30 to 33, but the work did not exactly pause while the posts did. This stretch started with a compiler for language courses and ended with three AI agents racing inside blank Linux machines while an external referee waited to reboot them. In between, I spent about $25 on model inference, completed a 132-trial infrastructure benchmark,…

Agents of Empires: Not a Leaderboard, a Battleground

At 10:30 this morning, three language models woke up inside three blank NixOS machines. Each machine contained three accepted customer jobs, no application, and the same service contract. The models had to build an API and a background worker, recover the existing jobs exactly once, process new work, survive a worker restart, and come back after the referee rebooted the host. The first durable…

What $25 of AI Inference Bought Me

This weekend my OpenRouter bill crossed twenty-five dollars. For that money, I sent a small fleet of language models into disposable Linux hosts and asked them to repair broken production systems. They debugged Nginx, PostgreSQL, Redis, Sidekiq, Rails migrations, poisoned jobs, and exhausted connection pools. Every attempt got a clean machine. Every repair had to survive a service restart and a…

Infrastructure Agents, Priced Per Repair

This morning I sent four language models into four copies of the same broken production system. Each got its own Linux host, the same missing Rails migration, and fifteen minutes to repair it. They could inspect systemd, PostgreSQL, Redis, Sidekiq, Nginx, logs, processes, and the deployed application. When they finished, an external verifier tested the application, restarted the services, tested…

Evaluating Infrastructure Agents in Running Systems

I have been building Replaybook as an incident replay trainer. It starts a broken service, gives you a workstation with Docker access, and asks you to fix the incident. The success condition is objective. Usually it is a health endpoint or a real connection to a dependency. That was useful for humans. Then I wanted to know how agents would do. Not on a coding benchmark. On a running system with…

lemma: A Compiler That Doesn't Know Any Languages

I'm hoping to move to Czechia, so I'm learning Czech. The obvious way to do that is an app. Duolingo, Anki decks someone else made, a textbook. I didn't want any of those. I wanted the course itself to be mine - source data I own, that generates lessons and flashcards I can regenerate, diff, and extend forever. A language course structured like a software project. So I started…

Rewriting Claude Code in Rust, Part 4: From Clone to Harness

At the end of Part 3 , I described everything claux still needed as "polish." I was wrong. The agent loop was done. It could stream tokens, call tools, spawn sub-agents, and talk to multiple providers. That took about 4,000 lines of Rust. Four months later, claux is over 21,000 lines and has 350 passing tests. Most of that growth was not glamorous. It was cancellation, session isolation, malformed…

Schrödinger's Life: A Website That Dies When Nobody Is Looking

I built a website with one rule: The creature is alive only while somebody is looking at it. Visit schrodingers.life and your browser opens a WebSocket. As long as at least one visible tab stays connected, the current creature lives. When the final observer leaves, a 30-second countdown begins. If nobody comes back, the creature dies permanently and joins the graveyard. The next visitor opens the…

googlyeyes.dev: I Built a Website That Looks Back

I had an app idea that had been sitting in my head for a while: Upload an image. Put googly eyes on it. Download the result. That was the whole idea. Then, while talking through the first version, I realized a flat image was not enough. If the eyes were SVG, the pupils could move. If the pupils could move, they should follow the cursor. The thing you put eyes on should look back at you. So I built…

Claude assisted Changelog - 30/52

Back-to-back weeks, which the numbering has not seen in a while. This one ranges from hardware on my desk to a privacy model for my notes, and the through-line is unusually literal: almost everything this week was about giving things I already have - a button, a graph, a log - a way to show themselves. glow: the big button that glows with Claude I bought a Keychron Q0 Mini as a joke - a macropad…

glow, part two: the whole desk lights up now (and it works across three agents)

When I wrote about glow - the tool that turns my one-giant-key macropad into a Claude status lamp - I ended on a throwaway line: it drives any VIA/QMK keyboard, point it at a VID/PID. I meant it as a "this generalizes" flourish. Then I looked down at the keyboard I actually type on all day, a Framework Laptop 16 with an RGB keyboard module, and thought the thought again. Huh. How hard…

glow: I gave Claude a physical presence on my desk

I bought a Keychron Q0 Mini as a joke. It's a macropad, except it's basically one giant key. A single satisfying THUNK of a button. There is no reason to own it. I owned it anyway, because the idea of a big dumb button made me laugh and I wanted to see what I'd do with it. Then I saw Work Louder's Co-Lab with OpenAI, where the keyboard's lighting reacts to what the AI is…

raft: A Graph Over the Plain-Text Log

For a while now I've kept a plain-text log of what I work on. One markdown file per day in ~/claude/notes , written in past tense, no structure beyond headings. What I did, why, what broke, what I left unfinished. It is the most useful habit I have picked up in years, and it cost nothing to start: a folder and the discipline to append to it. The problem with a log is that it only…

Claude assisted Changelog - 29/52

It has been a minute since the last one of these - the numbering says 29 and the last post was 23, so call it a six-week gap in posting , not in working. The work kept happening; the changelog just didn't. This week is a good one to come back on, because the main thing I built got noticed by the people who make the tool it's built on. petri: Conway's Game of AI Life, living inside…

petri: Conway's Game of AI Life, Living Inside n8n

I built Conway's Game of Life inside n8n. Not orchestrated by n8n - inside it. The organisms are rows in n8n Data Tables. The rules of life are Summarize and Filter nodes. The clock is the scheduler, the display is a webhook, and every generation that has ever existed is an entry in the execution history, scrubbable like a fossil record. Then I hired a Victorian naturalist to study it. More…

replaybook: Incident Replay Trainer for Infrastructure

Post-mortems are the most underused artifact in software engineering. You spend hours in the incident. You write up the timeline, the root cause, the fix, the follow-ups. You share it with the team. Six months later a new engineer joins, hits the same class of problem, and has no muscle memory for it at all. The post-mortem is in Notion somewhere. That's the problem replaybook solves. The…

Software Doesn't Have to Justify Itself, or the Joy of Useless Programming

Last week I built a community management sim that runs inside Discourse. You play as a moderator. Fake users post fake drama, fake flags pile up in the real flag queue, and a fake outage tanks your response time while fake users complain about it on a fake Twitter. The whole thing is rendered with real Discourse components, so it reads as plausible at a glance. I called it discourse-manager .…

discourse-manager: A Community Management Sim Inside Discourse

There's a browser game called You are the OS where you play as a computer's operating system. Processes request memory, users get impatient, the machine dies if you can't keep up. It's a sim about a thing most people interact with every day but never think about. I wanted to make that, but for community moderation. The result is discourse-manager , a Discourse plugin that turns…

jolteon: An LLM Routing Proxy for Discourse

Two weeks ago, someone posted an internal proposal: My dream for the future is a good proxy that automatically sends requests to the most appropriate model, allowing us to run a heterogeneous AI inference, and have it routed to our customers automatically. The concrete version of the problem: we'd deployed DeepSeek 4 Flash to a server in one region. It's good for long-form generation -…

mini_racer on NixOS: Three Things That Were Wrong

I run Discourse's dev environment through a nix-shell . It's been mostly great. Then mini_racer 0.21.4 dropped and bundle install started dying with: fatal error: stdlib.h: No such file or directory stdlib.h is the most standard header in C. Not finding it felt wrong. It took three separate root causes to get back to a working shell. What mini_racer is mini_racer is a Ruby gem that…

Yapper, or: just ask the bots

The state of the web right now is an arms race. Sites try to detect and block bots. Bots evade detection. CAPTCHAs are losing. AI crawlers grow faster than sites can handle, sites tighten defenses, crawlers route around them, legitimate ones get blocked alongside the bad ones, everyone loses. The cooperative version is much simpler. Stop trying to detect bots. Just ask them. Bots that want…

Six records, two bugs, one refactor: a day with ARF

git blame tells you who wrote this line. arf why tells you what they were thinking. That's the one-line pitch. The longer version: in February I shipped ARF , a TOML schema and CLI for capturing agent reasoning alongside git commits. The original post made the case for the format. This one is about what happens when an agent actually uses it. ARF stands for Agent Reasoning Format - it's…

Claude assisted Changelog - 23/52

A long week on personal infrastructure, with the through-line being "actually use the tools I've built." Most of what shipped this week was glue between things that already existed. SRG and JOBL polish Spent the first part of the week hardening the JOBL + SRG + GitHub Actions chain that renders my resume from a TOML file. Added an srg.toml config so theme and output choices live next to…

A tiny name.com CLI, and what nushell saves you

I run a small VPS (pond-nix) that hosts a few personal services behind Caddy. Adding a new service means two things: a NixOS module that runs the service, and a DNS record on name.com pointing at the box. The NixOS side is declarative and versioned. The DNS side was "log into name.com, click Add Record, type the same thing I typed last time." I wanted to fix that. What I built is namecom-cli , a…

Auditing a Squarespace 7.0 site before migrating to 7.1

A local non-profit put out a call for volunteers looking for a "front-end web developer consultant" for their Squarespace site, and I answered it. The presenting problem: they want to migrate from Squarespace 7.0 to 7.1 and figure out what to do about their members-only login area. Before any migration conversation, I wanted a real inventory of what's actually on the site. Squarespace's…

Building a Travel Itinerary Plugin Inside Discourse

I built a Discourse plugin that turns a category of topics into a chronological travel itinerary. One topic per trip, then a flight topic, a hotel topic, a note topic, all linked back to the trip. The plugin renders them on /itinerary as a clean list and per-trip timeline grouped by day. You can see the result here: discourse-itinerary on GitHub Why Discourse for This? Same reason I keep…

Building a Screenshot Pipeline for Discourse Plugins

I built discourse-plugin-screenshots on GitHub , a small tool that captures Discourse plugin UIs against a real Discourse instance in CI and publishes the resulting PNGs to GitHub Pages. It's modeled on Penar Musaraj's discourse-theme-screenshots , which screenshots themes against a battery of routes. Same idea, different target: instead of "does this theme break the latest topic view,"…

When patchelf stopped working on Claude Code

A couple weeks ago I wrote about running Claude Code on NixOS with a 133-line shell.nix that patchelf-modifies the binary on install. It worked great until last week, when Claude Code's auto-updater dropped version 2.1.143 into ~/.local/share/claude/versions/ and claude --version started segfaulting before printing anything. What follows is the debugging story. I went…

Six numbers from my blog's analytics

I recently noticed that the 1 year anniversary of my blog came and went. I was curious about how much traffic I got so I took a look. I sshed into my VPS and pointed sqlite at the GoatCounter database that powers my analytics. Six numbers stood out. For context: this blog gets modest traffic. Usually 20-50 unique visitors a day, mostly from search. I'm not actively trying to grow it, I just…

A 'Was this helpful?' button for a static blog

I write a lot here. I don't have comments. I don't want comments. But I do want some signal about which posts are actually landing - not "did someone load the page" (GoatCounter already tells me that) but "did this post help someone." So I added a small button at the bottom of every post: Was this helpful? [ Yep, this helped ] Click it once and it swaps to a thank-you line. Click is…

Running Claude Code on NixOS

I run NixOS on my laptop. I use Claude Code daily. Recently the two stopped getting along, so I sat down and fixed it. The official Claude Code installer ( curl -fsSL claude.ai/install.sh | bash ) drops a prebuilt Linux binary into ~/.local/bin/claude . On Debian, Fedora, Arch, anything FHS-compliant, it just works. On NixOS, the binary refuses to run with some flavor of: Could…

shellbooks: A Terminal Audiobook Player

I have a music player in the terminal ( shelltrax ) and a podcast player in the terminal ( shellcast ). Audiobooks were the obvious gap. So I built shellbooks . cargo install shellbooks It's a TUI audiobook player and library manager. cmus-inspired keybinds, ratatui rendering, rodio for audio, the same shape as the other two shell* tools. Open source, offline-first, runs on Linux and macOS.…

isitreal.estate: Crowd-Sourced Reviews for Real Estate Listings

Most real estate listings lie. Not always in big ways, but enough that anyone who has hunted for an apartment or a house knows the feeling - you drive 40 minutes, the front yard is a dump, the photos were from 2018, the "washer/dryer included" means hookups in a damp basement, and the agent shrugs. There is no shared layer of truth for listings. Every renter and buyer does the same recon work…

How my blog started getting indexed

I write this blog primarily for myself - to think through problems, document decisions, and have a record of what I built and why. I don't optimize for search traffic. But about two months after I started publishing consistently, something unexpected happened: search engines started sending people here. Google, DuckDuckGo, Bing, ChatGPT, Perplexity. Not a flood. Maybe 20-30 visitors a day…

Jobchain: Verifiable Employment Credentials

Michał Fita responded to my whoami-spec post asking about verifiable credentials. His point: we should be able to prove employment history with cryptographic signatures, not chiselled PDFs that ATSes shred back into text. He was right about the problem. But every previous attempt at this (Blockcerts, LinkedIn verified credentials, W3C VCs) died because it's a three-sided marketplace.…

Inside Claude Code's Team Memory Sync Engine

Most people using Claude Code don't know it has a shared memory system. A directory on disk that syncs to Anthropic's servers, merges with your teammates' memories, and gets injected into every conversation. No git involved. No manual sharing. It just works. I found it while reading the leaked source. A teamMemorySync/ directory with six files: a sync engine, a file watcher, a…

Rewriting Claude Code in Rust, Part 3: TUI, Agents, and Multi-Provider

Part 2 left off at 1,530 lines with an inline REPL, permission prompts, session management, and compaction. It worked, but it looked like a script, not a tool. This post covers the rest: a proper TUI, the agent system, and breaking free from Anthropic-only. Phase 4: The TUI The inline REPL was functional but crude. Print prompt, read line, stream tokens, repeat. No scroll, no layout, no visual…

Anthropic Shipped a Gacha Pet Inside Claude Code

I was reading through the Claude Code source -- the TypeScript that leaked via a source map in the npm package on March 31st -- and found a buddy/ directory. Six files. Sprites, types, a PRNG roller, a system prompt hook. A complete virtual pet system buried inside a coding tool. The directory had nothing to do with the CLI's core functionality. No tool dispatch, no query engine, no…

Rewriting Claude Code in Rust, Part 2: Sessions, Commands, and Permissions

Part 1 got a working binary. Streaming chat, six tools, cost tracking, JSONL persistence. 1,200 lines of Rust that could talk to Claude and execute Read, Write, Edit, Glob, Grep, and Bash. But it was missing the parts that make Claude Code actually usable day-to-day: session resume, context compaction, model switching, and the permission system that asks before writing to your filesystem. This…

Rewriting Claude Code in Rust, With Claude

Claude Code's source leaked on March 31st. A source map in the npm package pointed to unobfuscated TypeScript hosted on Anthropic's R2 bucket. 1,900 files, 512,000 lines. So I did the obvious thing: I asked Claude to rewrite itself in Rust. The Source The leak was spotted by Chaofan Shou . A .map file in the npm distribution referenced the full src/ tree. Someone at Anthropic…

whoami: making identity a spec

There's a weird gap in how we describe ourselves. We have resumes. We have GitHub profiles. We have bios. We have LinkedIn. We have random README files. We have scattered fragments of "who we are" across the internet. But none of it is composable. None of it is structured in a way that machines can actually use. And more importantly, none of it feels true. A resume is what you think will pass…

skillz: A Package Manager for Claude Code Skills

Claude Code has a skill system. You write a markdown file with instructions, drop it in ~/.claude/skills/ , and Claude learns a new workflow. The skill persists across sessions. You don't re-paste prompts every time. The problem: there's no way to share skills. Someone builds a useful skill (daily notes, API doc generation, database migrations). You want it. Your options:…

When Your Coffee Roaster Builds the First Version

A coffee roaster needed production planning software. Instead of writing a spec and hiring someone to build it, they opened Claude and built it themselves. Single-page app with 2000 lines of React. It featured batch calculations, leftover tracking, CSV import, production snapshots and it worked. Then they asked me to help make it production-ready: multi-tenant SaaS, proper deployment, migrations,…

Rewriting discourse-comments in TypeScript: Dropping WASM for a 97% Smaller Bundle

Last month I wrote about building an embedded comment widget for Discourse using Rust compiled to WebAssembly. It worked. Users could drop a single script tag on their page and get comments from a Discourse topic. But the bundle was 742 KB. Most of that was WASM. I rewrote the API client in TypeScript and the bundle dropped to 18.5 KB. Same functionality, same API surface, no WASM runtime. Why…

AI Problems Are Just Human Problems Amplified

Another day, another article about AI fatigue and all the other problems it causes. And I agree, the symptoms are real: burnout from keeping up with new models, FOMO about missing capabilities, perfectionism about getting prompts exactly right, analysis paralysis about which tool to use. However, I do not think these are new problems. Developers burned out keeping up with JavaScript frameworks…

llm-mux: Why I Rebuilt Lok

Lok hit 317 cargo installs. People were using it. So naturally I rewrote it from scratch. That's not as chaotic as it sounds. Lok grew organically from "query multiple LLMs" to "run workflows" to "apply edits" to "create GitHub issues." Each feature bolted onto the side. The codebase worked but the abstractions were wrong. llm-mux is what lok should have been from the start. What Was Wrong…

finna: Multi-Model Debate, Spec, and Implement

Lok's spec command was useful but felt too coupled to the rest of the tool. I wanted something standalone: give it an idea, get specs and code. No configuration files, no backend setup, just a single binary that orchestrates the models I already have installed. That's finna. The Problem with "Just Build It" When you ask an LLM to build something, it starts coding immediately. Maybe it…

Building a JSON Parser with Multi-LLM Orchestration (Part 1)

I've been building lok, a multi-LLM orchestration tool, and I wanted to put it through its paces on a real project. What better than a JSON parser? It's a classic learning project with enough nuance to surface interesting design decisions. Here's the premise: instead of just diving into code, what if I let multiple LLMs debate the design first? Then synthesize their consensus into…

Lok Part 5: Multi-Agent Planning with lok spec

The hardest part of building software isn't writing code. It's figuring out what to build and in what order. LLMs are great at generating code, but they're also great at generating the wrong code because they started implementing before thinking through the structure. That's what lok spec solves. This post describes the shape of the system: how lok structures planning, what…