Throw It Away

A person keeps a glowing golden core while an elaborate machine dissolves into blue fragments.

In July I built a tool called Magpie to produce my daily briefing. I already had an agent doing this for me, and I wanted to see how much of that work I could turn into a more predictable program. The idea was to fetch a collection of feeds, classify the stories, and use the interesting ones to put together a briefing. I already had a useful briefing to compare it with.

When I made that comparison I found a fairly obvious problem. The lead story in the existing briefing wasn't in any of Magpie's feeds. Magpie had also produced a lot of research papers, which wasn't quite what I was looking for. I could have spent more time adjusting the scoring and adding filters to improve the selection, but that wouldn't have helped with the missing story. It hadn't been in the inputs in the first place.

The agent producing my existing briefing had found that story through iterative search. To get a similar result from Magpie I would have to add the ability to search beyond its feeds, figure out what else was worth looking into, and continue exploring. At that point I was heading toward rebuilding an agent loop in Go, which seemed like a fairly strange way to replace an agent loop with something simpler. So, I stopped working on Magpie, deleted the local repository, and went back to using the briefing I already had.

Magpie had gone through implementation and review before that comparison showed me how poorly I'd understood what made the existing briefing useful. I could have turned the results into another round of work. But building it had already taught me something worth knowing, and I didn't need to keep building it to make the experiment worthwhile.

I've been building software for about thirty years, so trying something and deciding to throw it away is pretty familiar. Agentic coding has made it much cheaper to try things, and I can get an idea a surprisingly long way into implementation before finding out whether it does what I want. Software experiments can now be so elaborate as to feel like completed work. Once something looks finished, it's easy to get attached and start thinking about what to improve next, without asking whether I still need it. The old advice about treating servers like cattle rather than pets is starting to feel applicable to the code itself. Just because I built it doesn't mean I have to keep taking care of it.

Earlier this year I retired Puck, the personal assistant I wrote about in March. Puck had been useful to me, and its briefing was part of my daily routine. It also had its own server, database, scheduler, and collection of skills, all of which existed to do work that I could increasingly do with a general-purpose harness. In April I replaced Puck's runtime with Claude Code, a handful of skills, and remote control.

This involved going through what Puck actually did, rather than just copying all of its skills into a new directory. The new setup already handled artifacts, scheduling, and remote access. Some skills weren't worth bringing along, and others contained workflows or domain knowledge that I wanted to keep. I needed to rebuild those skills to fit the tools I was using now. There were also assumptions about how Puck worked mixed in with those instructions, and copying everything would have meant carrying those assumptions into a system where they didn't apply.

I was able to retire the server, database, and custom scheduler while keeping the useful workflows. I kept the repository too, although I was no longer running the system it described. After replacing Puck I gradually ported its knowledge-base concepts into Memento, where they became part of a general-purpose knowledge base. Puck had given me a useful assistant for a while. I could keep using what I'd learned without continuing to maintain the infrastructure I'd originally built around it.

Something similar happened with code review. A script in my dotfiles grew into agentic-code-reviewer, or ACR, which I wrote about in January. It automated multiple reviews and summarized their overlapping findings. Then I added the ability to post them to GitHub, because copying and pasting got old pretty quickly too. Since then the reviews built into coding harnesses, or run through skills, have gotten good enough for my needs. The reason I built ACR was to get useful reviews without so much manual work. I no longer need a separate Go project to do that.

Sometimes removing the code wasn't enough. Last year I wrote about agents reimplementing features I had already removed. I would delete a feature, but leave its description in CLAUDE.md, which was loaded into each new session. Then some helpful future agent would see that description and put the feature back. I had removed it from the code while continuing to tell agents that it belonged there.

Old instructions are instructions just as much as new instructions. In those sessions, the agents had no reason to know that I'd changed my mind. I can add more explanation, but if the instruction no longer applies then removing it can be more useful than clarifying it. This was part of sorting through Puck's skills as well. I wanted to keep what I'd learned about the work without turning every old rule and implementation detail into a requirement for the replacement.

What still needs to exist

A useful question when I'm looking at one of these tools is whether I'd still need it if the models and their harnesses got dramatically better. If I built it because an agent was struggling with a task, I should expect to revisit it. The problem may go away, or the harness may have a better way to handle it.

Better models don't remove every reason for software to exist. A shared service still needs to control who can do what and honor the behavior other systems depend on. I might replace all of its code, but those obligations remain.

For my personal tools I can often just stop using something and see if I miss it. A shared system requires more care, because other people and processes may depend on the behavior I'm thinking about removing. I still need to understand those dependencies and find out whether the replacement actually works.

It's easy to respond to a rough edge by building another feature or wrapper now that implementation is so cheap. I can also stop. Sometimes I can retire the infrastructure and keep the useful workflow, or the harnesses get good enough to handle the work and I get the benefit without the maintenance. With Magpie I'd already learned what I needed to learn, so I threw it away and moved on.