russalo@blog
russalo@blog ~ % cat posts/it-reads-everything-it-changes-nothing.md

It Reads Everything. It Changes Nothing.

Jun 13, 2026 · devtools · learning · open-source · python · side project · 4 min read ·

Most of what I write here is prose. The kind that goes looking for the things that are hard to say out loud. This is a different kind of post. It’s about code.

I should explain how that fits. This blog started as an excuse. I wanted to learn Go, and reading tutorials only gets you so far, so I built the thing you’re reading these words on. The blog is the project. Writing the posts was just the part that kept me coming back to it.

The code I actually want to talk about is something else, and it came from the same place most of my projects do: I needed it, and it didn’t exist the way I wanted it to.

Two projects, one missing piece

I have a couple of things I tinker on. One of them works with conversations, big piles of chat logs I want a machine to make sense of. The other is the opposite kind of mess: heaps of real-world documents, the sort of folders that pile up in any actual job, full of PDFs and spreadsheets and files nobody named carefully.

Different problems, same wall. Before either project could do anything clever, it had to answer a dumb question first: what is actually in this folder? Not what the filenames claim, not what I hope is in there. What is genuinely sitting on disk, byte for byte.

I kept writing the same scrappy code to answer that, badly, in both places. Eventually it was obvious the answer wanted to be its own thing. So I pulled it out and gave it a name: file-observer.

IMG_5115

What it does, and what it refuses to do

You point it at a directory. It makes one read-only pass and hands back a single JSON file describing everything it found: file types detected from the actual bytes instead of the extension, metadata, structure, where things came from. Then it stops. It doesn’t watch for changes, it doesn’t ingest anything, it doesn’t try to be smart. It looks, it describes, and it changes nothing.

The part I’m quietly proud of is the boring part. It’s deterministic. Run it on the same files twice and you get the same output down to a checksum. Run it across eight workers instead of one and the result is byte-for-byte identical. That sounds like a small thing. It’s the whole point. If you’re going to build something on top of an observation, you have to trust the observation won’t shift under you for no reason.

There’s one command I’m fond of, file-observer --schema, where the tool just tells you everything it’s capable of reporting without scanning anything at all. It describes itself. I enjoyed building that more than almost anything else in the project, probably because it felt like the tool finally being honest about its own edges.

Why I’m actually writing this

Not to sell it. It’s free, it’s open source, and if you don’t have the specific problem it solves, you’ll happily never need it.

I’m writing because it’s been a pleasure. I’ve been at it for about two months now, quietly at first and then a slightly ridiculous run of releases once it went public a couple of weeks ago, and the whole time it has felt less like work and more like the good kind of puzzle. I learned more about file formats, about keeping a thing honest, about reviewing my own code without lying to myself, than any course would have taught me.

I’m an enthusiast, not a professional. I build these because I like the way my head feels when I’m solving them. This one turned into something real enough that strangers have started installing it, which still surprises me a little.

If you want to look: github.com/russalo/file-observer, or pip install file-observer. There’s a tutorial and some runnable examples if you’re curious how it feels in practice.

Most of my confessions still happen in prose. This one happened in Python. Same impulse, honestly: make the thing, and let it be honest about what it is.

# comments (0)

no comments yet — be the first.

posted comments are reviewed before they appear.
russalo@blog ~ % cd ..