Skip to content

I built a filesystem flight recorder because an AI agent ate my work

The incident

I had two terminals open. One was running a coding agent on a throwaway prototype. The other was sitting in the repo I’d been hand-editing for hours, with careful, uncommitted work across a dozen files.

I pasted the prompt into the wrong terminal.

The agent did exactly what agents do: it rewrote files with confidence and speed. By the time I hit Ctrl-C, the damage was done. My editor showed the agent’s output, the files on disk matched, and git diff showed the destruction. But git stash had nothing to recover because I hadn’t committed yet.

There’s a gap between your last save and your next commit that nothing protects. For years that was fine because you’d notice your own typos. But agents write at machine speed across many files simultaneously, and now that gap will cost you entire sessions of work.

The gap between save and commit is where agents do their damage.

Building unf

I wanted something that runs in the background and captures every save without me thinking about it. Not version control (that’s git’s job), but a flight recorder for your filesystem.

The working name was Unfucked, because that’s what you need after an agent trashes your files. I bought unfucked.ai and everything. Cooler heads prevailed and it became Unfudged, which is easier to say in a meeting and keeps the same unf CLI prefix.

Unfudged (unf) is a daemon that watches your filesystem via FSEvents on macOS and inotify on Linux. Every time a text file changes, it hashes the content with BLAKE3 and stores the snapshot. Metadata lives in SQLite. Storage is deduplicated, so identical content is stored once regardless of how many times you save.

How unf captures every save: filesystem events trigger BLAKE3 hashing into deduplicated storage.

The CLI works like git:

# See what changed
unf log src/config.ts

# Diff any two points in time
unf diff src/config.ts --from 2h --to 30m

# Restore a file to any previous state
unf restore src/config.ts --from 1h

The part I use most is the histogram view, which gives you a visual scrub through time showing when files changed and how much. When something goes wrong, you don’t need to remember when it happened because you can just see it.

The Hacker News post

Before I posted, I had to figure out what to actually call the thing. I’d been testing different descriptions with people: “filesystem flight recorder,” “version control between git commits,” and “version every file save.” That last one clicked the fastest. People immediately understood what it did without needing an explanation.

The name was a harder question. I went back and forth between Unfucked and Unfudged. Unfucked is funnier and more honest about the emotion you feel when an agent trashes your project. But unfucked.ai redirects to unfudged.io, and HN follows redirects, so the title and landing page would mismatch if I used the original name. I posted with Unfudged first, then switched the title to Unfucked mid-morning because it seemed to resonate more.

That turned into an accidental A/B test. The post was doing well, pulling close to a 10% install rate from new visitors. Then around noon Pacific it dropped off the front page. The name had gotten user-flagged for profanity. I lost about eight hours of front-page visibility, from noon until around 8pm, when the HN community team gave it another look and put it back. By then the momentum had shifted, and I kept it as Unfudged going forward. Lesson learned: the edgier name gets attention but it also gets flags, and on HN those flags are quiet enough that you won’t notice until you check your analytics.

The feedback itself split into two groups. The first group got it immediately. These were developers who’d lost work to agents, to runaway scripts, to their own absent-minded rm. They wanted to install it.

The second group wouldn’t touch it. Their objection was simple and consistent: a closed-source daemon that watches every file I save is a non-starter.

Both groups were right. The tool solved a real problem, but asking developers to trust a black box that watches their filesystem was asking too much.

Going open source

Unfudged started inside a monorepo with other experiments. I didn’t extract it into its own repo because I wasn’t sure it should exist as a standalone project yet. The code was tangled with shared utilities. The build assumed the monorepo structure.

None of that mattered to the people reading the HN thread. They saw closed source and a filesystem daemon and made the only reasonable call. They couldn’t see my intent behind the architecture; they could only see an opaque binary on their machine.

So I extracted it. I pulled the code into its own public repository, cleaned up the build, and published under MIT. The whole process took a weekend. Looking back, the HN crowd told me exactly what the project needed to earn trust, and I’m glad they did.

Where it stands

Unfudged is at v0.17.15 with around 490 tests across the Rust core. It runs on macOS (Intel and Apple Silicon) and Linux (x86 and ARM64), installable via Homebrew or .deb packages. Just under 900 downloads so far, with the two spikes you’d expect: the HN launch and the open-source release.

Daily downloads since launch. The desktop app (.dmg) accounts for about half of all installs.

There’s a CLI for terminal workflows, and a desktop app built with Tauri and Svelte that I’m increasingly treating as the primary interface. The GUI already handles histogram browsing, diff viewing with syntax highlighting, and directory watch/unwatch from a menu bar icon. I want people to be able to use Unfudged without ever opening a terminal if that’s their preference.

The community engagement since open-sourcing has been the best part. Someone on Linux ARM64 couldn’t run the binary because I was only shipping x86 builds, so I added native aarch64 packages. Another user wanted to move their snapshot storage to an external drive, and that conversation turned into unf config --move-storage plus a settings panel in the desktop app, shipped five days after the issue was opened. That kind of feedback loop is exactly what the HN crowd was asking for when they pushed me to open-source it.

The CLI is getting more configurable based on what people ask for: exclude patterns, grouped-by-file views, snapshot context flags. The repo is on GitHub and I’m paying attention to every issue.

Learn more about Unfudged

Keyboard Shortcuts