Update for the week ending on Friday, Jan 9, 2026
mtlynch.io
- Worked on my December retro
- Rename my
start-new-retro-> tonew-retroto match other similar scripts I use
Refactoring English
- Continued working on motivation chapter
- Worked a little on “Why Improve Your Writing?” chapter
- Re-submitted The Most Popular Blogs of Hacker News in 2025 to HN and was finally successful
- Rewrote some of the parts I felt were weak
- Investigated a huge spike in my hosting costs
- I got a notice I was running out of credits on Bunny, my CDN
- Monitoring showed my bandwidth served had shot up
- I initially thought it was LLM scrapers, but then I checked the logs and saw a ton of requests for a 3.3 MB file coming from the same IP.
- I viewed top IP clients, and the top 3 were all just Googlebot.
- It turned out that Google was indexing every possible view of HN Popularity Contest for every possible time range
- The solution was to just add this to my
robots.txt:Disallow: /tools/hn-popularity/*start=* Disallow: /tools/hn-popularity/*end=* - That solved it. Bandwidth consumption dropped to almost nothing after that
Popularity Contest
- Changed code to reprocess the data on every pipeline commit
- I used to worry about BigQuery costs, but HN data on BigQuery is free
- Switched package management in the pipeline scripts to uv
- uv just plays more nicely with Nix
- Made some metadata updates/fixes
- And accepted third-party contributions
- add antocuni.eu
- add daniel.lawrence.lu to domains-meta.csv
- Add emschwartz.me metadata
- add glthr.com metadata
- Add igorstechnoclub.com
- Add miloslavhomer.cz
- Add newslttrs.com
- Correct the bio and topic info for danielchasehooper.com
- Update domains-meta.csv to add personal blog (philippdubach.com)
- Update domains-meta.csv with https://dvsj.in
LLM Sandbox
I created a sandboxing solution for LLM agents.
I’ve mostly been using Cline, and I like that it’s transparent in what the agent does and gives you fine-grain control over approvals. But a friend showed me his more vibe-code style of just firing off a task and letting the agent do it unsupervised, and it looked better than my workflow.
I thought I’d try it for a few narrow use cases where Cline wasn’t a fit, but I liked it so much that I’m migrating away from Cline.
My initial sandbox was just me provisioning a new Ubuntu VM on my system and installing the LLM as an unprivileged user. But it got tedious copying files back and forth because I didn’t want to expose my SSH keys / agent inside the VM. I decided to just risk running my SSH agent as a different user, but it was still a huge hassle because my user and the LLM user would keep clashing over file permissions in the repo, especially the .git repo, even though they were in the same user group.
Next, I tried creating a NixOS-managed VM with an auto-provisioned user, but it quickly grew too complicated.
The thing I made today that I really like is a solution around rootless podman containers (and I’ve never used podman before, just Docker). But I like it a lot. I can run sb-llm and it:
- Automatically spins up the podman container and mounts my local directory
- Errors out if the directory contains secrets (which in my case is always
.envfiles) - Mounts my LLM agent settings from my host’s home directory (all the container agents share a single home directory with the agent’s settings)
- Loads the NixOS dev shell if one is available in a
flake.nix - Loads the LLM agent
I can also run sb-llm bash to start a bash shell to explore and verify the sandbox works.
I ran into issues because git worktrees hardcode my local filesystem paths. I started down a path of trying to mirror part of my local filesystem structure inside the container, but I realized it was easier to just not support git worktrees and require the client (me) to create independent clones.
MeshCore
- Wrote some unit tests to meshcore.js
- Gave feedback on a third-party PR to meshcore-open
Howdy, Neighbor
Howdy, Neighbor is an open-source MeshCore client I created because there weren’t any aside from the CLI.
- Stopped working on it because someone published meshcore-open, which is mostly the same idea but way better execution than mine.
- Added timestamps to messaging interface
- Improved JS object parser tests
- Drop the
outPathLenfield- It makes sense in C where arrays don’t know their own length but not in Dart
- Fixed the copy of outPathLen from JS
- Fixed flutter analyze bugs
- Pulled flutter subdirectory to project root
- Renamed ‘Serial’ to ‘USB’ in the UI
- Prevented the app from swallowing all errors in try/catch
- Simplified e2e tests and split them into separate files
meshcore-protocol
MeshCore protocol is an idea I had that came out of working on Howdy, Neighbor. I realized so many clients are reimplementing the protocol, often with bugs, so it would be nice to have a single, well-tested implementation with language bindings for C, Python, JavaScript, etc.
- Created a skeleton implementation
- Added a C formatting check in CI
- Switched CI from Woodpecker to Nix CI
- I’m the first Nix CI customer on Codeberg
- Syd helped me a bunch by adding custom support for Codeberg and helping me improve my Nix build to work well with the CI
- Tightened up strictness of parser
- Treat unterminated strings as fatal errors
- Added a check for invalid lat/lon and tested for it
- Added Dart bindings and then fixed them so clients don’t have to recompile the C code
- Added a WASM build for JavaScript clients
- Worked on adding Python bindings
- Migrated howdy-neighbor to use the meshcore-protocol library
Little Moments
Little Moments is an open-source web app I’m working on to replace the current family photo sharing app (TinyBeans) I used (which I strongly dislike).
- Made a tiny amount of progress on the design doc
ScreenJournal
ScreenJournal is basically Goodreads, but for TV and movies. Or letterboxd, but focused on small communities.
- Started adding support for “save review as draft”
- This is currently all AI-written, as I wanted to test my AI sandboxing setup.
PicoShare
PicoShare is a minimalist web-based file sharing tool I’m working on. I’m often frustrated that I can’t just send someone a link directly to a file because every file-sharing service tries to re-encode images/video or wrap their own viewer around other files, so I’m making a simple self-hostable tool that lets you upload files and share them with other people.
- Let the custom domain name expire and fixed links on my blog and on weeks.mtlynch.io
Michael’s weekly updates
- Fixed my weekly git activity aggregator script
- I realized it doesn’t work if I’m a few days late in writing a weekly snippet.
Misc
- Created a custom command called
servethat spawns a temporary web server and opens - Had a call with another indie developer
- Set up my annual due payment for Codeberg