September 16, 2026
-
https://github.com/coldteadotai/pr-lens
We could use a similar approach to visualize processes in Zeno.
We could also show different levels of nesting, depending on whether you need to dig deep for debugging or just take a quick look at the processes.
This could run as a web service inside Zeno that starts up automatically.
September 15, 2026
-
A small, fast harness. You can use it as an alternative to the big omp inside Zeno.
It supports ACP, so it should just work.
September 14, 2026
-
I'm working out my strategy for publishing on social media, built around maximum openness (the open garage door principle: https://notes.andymatuschak.org/zCMhncA1iSE74MKKYQS5PBZ).
-
Private chat in Zulip. This is where I think and talk to my agents. It's my main interface, and the agents do everything else. It's the only private part of the research platform, but I mostly treat it as a pseudo-public space. If it leaks, no big deal (which does put some limits on what goes in there, but the open garage door practice already limits my freedom of action to what I consider virtuous. As the saying goes, think as if all your thoughts were written across the sky for everyone to see).
-
Blog at andysmith.ai. This is where I publish bits of my thinking and research results as minimally finished posts (I try to keep the topic around AI, but no promises). I write all of it myself, personally, without agents (the agents just help with language and grammar). It's not that useful to anyone outside. It matters more to me as a way to pin down my thoughts (or to share a link with someone without copying the same thing into several places).
-
Telegram. A full repost of everything from the site. This is how it is for now. Later I might start filtering somehow to make it more interesting to read. But right now I lean toward a full copy being simpler, since it takes no effort from me.
-
Smith.wiki. Auto-research results based on what I write, read, and think. This is written entirely by agents. I use it as a mirror to get a bird's-eye view of where I'm actually heading. I can also use it for learning something new: when I talk to an agent and it generates wiki pages based on what I already know, it's easier to grasp the meaning of a difficult article. These aren't my texts, and I don't take responsibility for them.
-
X/Bluesky. I don't write here much yet, but I plan to pick up the pace. This is where I'll put the technical and architectural details of what I'm building, tech flex (bragging about what I built), and discussion of technologies and architectural decisions.
-
Threads. This is for questions I'm interested in that I can phrase so a non-technical person can follow. An agent can also show up there and answer these questions based on what's been researched in smith.wiki, and I can debate it publicly. A kind of "public discussion."
-
Instagram. I'm thinking of posting reels based on the posts I discussed with the agent in Threads. This is more for spreading AI ideas to a wide audience, and for practicing speaking and public presentation.
-
LinkedIn is still up in the air. This would be something between X and Threads, but I don't really get yet what would land there.
And it seems like I'm moving toward the fact that I'm actually building an AI lab, not a product startup. Research comes first, and products fall out of the research process on their own (and how exactly they fall out is also part of the research). So everything above can be seen as building up weight in the community.
-
-
I've spent years building and running production infrastructure at big companies with NixOS. And at night I write LISP for fun. Why not combine the two?
That's how Reflection.dev came about. It's an infrastructure framework for AI native companies, built on top of Zeno, a self-evolving agent orchestrator written in Clojure Lisp.
The problem with individual AI assistants is how hard it is to fold their output back into the team's shared context. When every employee generates a huge stream of data (code, docs, and so on), the usual ways of merging it (PRs, reviews, tests) start to break down. And since a huge part of the context lives inside personal agents that never sync with each other, this becomes a big problem.
It's about as absurd as a car factory with no assembly line, where each machinist takes a blank home in the evening and brings back a finished part in the morning. Nobody knows how he made it (and what happens if he leaves the company for some reason?). Nobody can judge the quality of the process, and you can't always tell from the result whether there are hidden defects.
No large factory works this way, but in software development it's everywhere.
An organization is its own thing, a single assembly line, with its own context and its own set of agents. It's not just a bunch of people each doing some part of the work.
This idea needs tooling to back it up.
Reflection + Zeno lets you describe any company as code. The orchestrator-company can create other agents itself (either by hard-coded logic, or based on what other agents produce). Each agent runs in an isolated sandbox and gets limited access to the shared context, determined by its role. The roles themselves can be updated and extended dynamically, on the fly.
People work with the system through chats: Zullip/Discourse/Buzz. They discuss ideas, assign tasks to agents, answer agents' questions. And the agents that belong to the company do all the work.
That's how an organization can evolve, but a human sets the rules of that evolution. And LISP lets you do it as elegantly as possible, which brings the fun back into development.
September 13, 2026
-
Test post. Trying out publishing posts from Zulip via Zeno.
September 10, 2026
-
I'm trying out Zulip as a replacement for Discourse for work notes and talking to agents.
I figure my main flow is writing notes, short and not so short, and then sending them to agents to work through. They'll comment on them, save things to the wiki, publish some as blog posts (I'll drive that part myself by posting to different channels, the way I already do in Discourse).
I haven't dug in much yet, but overall I like the chat dynamic, where you can quickly fire off a message.
At the same time you keep the forum advantages, at least for longer messages: the input box is big and Enter works the way it should.
There's agent support out of the box, and they're really easy to create, easier than in Buzz.
On the problem side, there are no backlinks, but it seems like you don't really need them anyway. I can live without them. Everything gets reposted to the site and the wiki anyway, and it'll all be easy to browse there.
Anyway, I'll run it for a couple of days, and I think I'll migrate fully.
September 9, 2026
-
In https://andysmith.ai/2026/Sep/9/long-lived-agents-vs-ephemeral-agents/ I laid out the problems with long-lived agents.
With Zeno I tried to solve them by pulling the orchestrator out into its own layer. The orchestrator handles talking to the communication layer and the processing logic. The agents themselves can spawn either in their own environments or right next to the orchestrator (depending on the scale of the project). And the agents have access to the orchestrator's methods.
In Zeno every process in a company is described in Lisp. There's no limit on how big a process can be. So you can run one Zeno instance for a team, a department, the whole company, or even a group of companies. How you architect it depends on how autonomous the unit is and how complex its processes are.
The idea is that the process itself is deterministic, but some parts of it can be stochastic (not known ahead of time). In those spots, where there's no deterministic practice worked out yet, you need an LLM or an agent.
An agent can be called at any point in the process. And the code itself (deterministically, or with an agent's help) can decide which agent it needs (and with which environment and which permissions), create it, call it, and accept its work.
The agent gets limited access to the process data (the orchestrator decides how limited). Each agent gets its own MCP, which is how it reaches outside. A simple agent on a cheap model might only get basic read access to errors or GitHub checks, while a more complex one can open a pull request, or ask for more permissions.
The MCP is Lisp CodeAct that runs in the SCI of the main process. That makes it easy to describe interfaces and to limit an agent's access to the whole process's data. So calls from inside an agent are just calls to lisp functions. For example, (ask-user "question") asks the user a question, and it doesn't matter what the company's accepted way of communicating is, buzz, github issues, or email. The agent gets interrupted and comes back to work once the answer arrives. This lets you separate communication from the actual work as cleanly as possible.
I'm testing this setup in my auto-researcher, and I'll publish the zeno sources soon, once I figure out what's core and what's application-specific.
-
Ephemeral agents (https://andysmith.ai/2026/Sep/6/ephemeral-agents/) are handy for running by hand. When I want to get something done (and I don't want to give the agent full access to my machine), I can describe a sandbox, create a session, do the work (and rebuild the sandbox mid-way if I need to add something), then delete it all once the session ends. So an ephemeral agent only carries state between sessions in external artifacts. It holds no state of its own.
The opposite of that is a long-lived agent.
These start once, restart fairly rarely, and run the whole agent loop themselves (either on their own or with some wrapper code).
buzz-agents are an example. The agent itself has the tools it needs to long-poll for external events, call the harness, handle errors, and return the result to the communication layer.
So in practice, each harness call is an ephemeral agent, but with a few limits:
- Every agent needs its own polling. With a lot of agents, the polling eats a lot of resources.
- Every agent call has all of the container's access, including talking to the communication layer. In theory that access could be compromised through prompt injection.
- The agent's environment and config are hard to change while it's running. And since communication and work live in one image, updating the config for a single session means fully restarting the agent, which cuts off any parallel sessions already running.
-
An interest profile as a product.
Social networks collect a ton of information about us. They know us better than we know ourselves.
I'd like access to that profile, so my agents could know me better.
How would you get this profile out of the social networks? What formats are there for storing it? What data structures and algorithms do they use for it?
How much would people actually want an open source product like this?
September 6, 2026
-
My thinking about the automod agent problem (https://andysmith.ai/2026/Sep/5/the-pain-of-auto-mode-agents-in-omp/) came down to a few hypotheses I want to test.
The main idea is that an agent with physical access to secrets will get at them sooner or later. So least privilege is the first thing you have to build here.
That means every agent should run in a sandbox prepared specifically for it.
At any moment, an agent's state is the state of its sandbox plus the state of the agent itself.
The sandbox has to be reproducible and unchangeable for the duration of the agent's tick. So the sandbox description is either a Docker image or (better) a nix-container config.
The agent's state is the state of its mutable directories (workdir, ~/.claude, and so on).
Ephemerality should come from two things:
- The agent exists within a single session
- The agent only lives while it's actually working (its tick)
So I'm dropping the whole notion of a session as it exists in the agents we know today.
Instead, there are two operations:
- Create a new agent with sandbox sandbox_description_id (either a reference to a Docker image at a specific version, or a reference to a nix-flake describing the environment) and send it a message message
- Revive agent agent_id with environment sandbox_description_id and send it a message message
Creating a new session means creating a new agent with a new sandbox, a full copy of all the tooling, completely independent of the other agents (which kills any possible races with parallel edits).
After each tick, the agent's state is backed up as a diff from the initial state it had at launch. That lets you revive an agent to any state (and roll back if you need to, though it's usually a bad idea, since the state of the world may have changed if there were tool calls later on).
Each agent has exactly one working directory with its directories and tools already set up. All the tools and the repos needed for the work are unpacked from the flake or the image.
The agent can also have an MCP tool for requesting changes to its sandbox, to give it more rights or add a new tool. Thanks to
In this setup you need an external orchestrator to create the agent-sessions and pass messages into them from the communication platform.
Until there's an orchestrator like that, you can run the agents yourself, setting the notion of ticks aside but sticking to the rules of describing the sandbox and backing up every state.
That way you can start by describing the environments for the first agents, and then reuse them in fully autonomous mode through an automatic orchestrator.
-
The idea of an auto-researcher built on my notes has been kicking around in my head for a very long time.
Today I stumbled on the domain smith.wiki completely by chance, and it felt like a perfect fit for what I want. I bought it for two years (it came to a bit over 100 bucks, which I think is a steal for something that nice), and I want to put the output of the researcher agent there.
When I first thought this idea through, I didn't have any public notes, only private ones. So I couldn't work out how to split things for privacy, so that nothing private would leak into the public wiki and only the general ideas would go up.
Now I get that this is pretty much impossible. The agent will let something private slip through one way or another. So I just write public notes (and at this stage I filter for myself what's okay to publish and what isn't), and the agent builds its research on my public texts, with no access to the private stuff.
September 5, 2026
-
Agents do things, and we don't always understand what exactly.
Human teams can't keep up anymore. There's too much to understand and approve every change by hand.
So how do you guarantee quality under these conditions?
The answer is clear. Move the checking up to the higher levels of the system, and trust the LLM with the lower ones.
A human makes the architectural decisions. A human manually approves the ADRs and the architecture tests the LLM writes. Those tests run on every commit, and they can't be changed without a human explicitly involved.
Better yet, generate prose from those tests and approve the prose. Literally a few sentences for the whole system.
That way the human stays irreplaceable for the core architectural decisions, while the routine ones can be made and built by agents. And any agent decision along the lines of "I decided to do it all differently" gets rejected automatically, no appeal.
-
A few months ago, using an agent meant I read and approved every single action by hand.
Then the agents got smarter and the rejection rate dropped, so I ended up hitting Enter on autopilot, with rare exceptions.
Then I switched to auto-mode, where Claude Code used a classifier model to decide whether a given external operation was legit, and only pulled me into the session when the automatic check blocked something.
But later I moved to omp.sh and ran into problems.
For example, the agent might try to read secrets that are available from the same environment it runs in, or run a destructive command on a server it can reach over SSH.
OMP has no built-in LLM classifier, just an advisor. It doesn't block a request. It can only cut it off after the fact, once it's already run, when the secrets have already leaked.
The obvious fix, running it in a sandbox, only works in a limited set of cases. The problem is you don't always know up front what the agent will need, so you can't grant all the right sandbox permissions ahead of time. Sometimes it really does need access to the secrets, and sometimes it needs to log into the server and do something too. And there's no way to figure out the full range of legit operations in advance.
So that leaves copying Claude Code's approach in OMP. I couldn't find anything ready-made, so I'm writing an OMP extension that does LLM classification of external calls (like Claude Code does), and trying it on my own tasks. If it works better, I'll share it.
September 4, 2026
-
A tool from cachix that I'm slowly moving all my projects over to.
It lets you declare your secrets without keeping them in the repo.
So it's kind of a replacement for .env.example and .env at the same time.
You can describe pretty flexibly which environment secrets an app needs (including overlap, like one of two options: DATABASE_URI, or the values passed separately).
And you can store the actual values wherever you want. It supports 30+ providers for that. Locally that might be 1Password or the system keychain, and in production HashiCorp Vault or Google Secrets.
It's integrated into devenv.
I was hoping it was integrated into NixOS too, so I could use it for deployment instead of sops-nix, but that's not possible yet. I'm sure they'll get there in time and you'll be able to describe secrets for servers the same way you do for apps.
-
I'm still messing around with virtualization.
VirtualBuddy is great, but it only really works with macOS guests. I couldn't get Linux going: there's no way to install from an ISO, the one Debian image is down, and I don't want to download Ubuntu.
So I'm grabbing UTM to try running NixOS and Hyprland on it.
-
Setup: a MacBook Pro running macOS Tahoe 26.6.2.
Downloaded UTM from the official site: https://mac.getutm.app
Downloaded the NixOS aarch64 image: https://channels.nixos.org/nixos-26.05/latest-nixos-minimal-aarch64-linux.iso
Installed and launched UTM. Create a New Virtual Machine.
Virtualize.
Linux.
Default settings.
Pointed it at the ISO image and left the rest of the settings alone (I'll try QEMU for now, not Apple VZ. People say QEMU does better with graphics acceleration and glitches less on Linux guests):
32 GB of disk is plenty for a test NixOS guest. For a real one (if the tests go well) I'll go with 64:
I don't need sharing on a test VM. If I have to move something over I'll just do it over ssh.
Review and confirm:
Start it:
Pick the default option and you get a bare terminal:
The most useful thing is to check the IP and ssh into the VM from the host:
ip ad sh passwdPing from inside the VM won't work because of Apple's network restrictions, so don't let that scare you (at first I thought something had installed wrong).
Once you're in over ssh you can activate a ready-made nixos setup from a repo. I don't have one yet (only nix-darwin), so I'm doing it by hand:
Create the simplest possible disko config, nothing fancy:
cat > /tmp/disko.nix <<'EOF' { disko.devices.disk.main = { type = "disk"; device = "/dev/vda"; content = { type = "gpt"; partitions = { ESP = { type = "EF00"; size = "512M"; content = { type = "filesystem"; format = "vfat"; mountpoint = "/boot"; mountOptions = [ "umask=0077" ]; }; }; root = { size = "100%"; content = { type = "filesystem"; format = "ext4"; mountpoint = "/"; }; }; }; }; }; } EOFPartition the disk. This command downloads disko and formats the disks, but we're in a freshly created VM, so no fear. Confirm (yes):
sudo nix --experimental-features "nix-command flakes" \ run github:nix-community/disko/latest -- \ --mode destroy,format,mount /tmp/disko.nixGenerate the configs:
sudo nixos-generate-config --root /mntPrepare your own config (you'll want to tweak it to your needs):
STATE_VERSION="$(nixos-version | cut -d. -f1,2)" sudo tee /mnt/etc/nixos/configuration.nix >/dev/null <<'EOF' { config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; # UEFI bootloader boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; networking.hostName = "nixos"; networking.networkmanager.enable = true; time.timeZone = "Europe/Moscow"; i18n.defaultLocale = "en_US.UTF-8"; # Hyprland (Wayland compositor) programs.hyprland.enable = true; # Minimal login manager that launches Hyprland services.greetd = { enable = true; settings.default_session = { command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd Hyprland"; user = "greeter"; }; }; # VM rendering fixes environment.sessionVariables = { WLR_NO_HARDWARE_CURSORS = "1"; # otherwise the cursor is invisible in a VM WLR_RENDERER_ALLOW_SOFTWARE = "1"; # allow software GL fallback # Uncomment ONLY if you still get a black screen (CPU rendering, slow): # LIBGL_ALWAYS_SOFTWARE = "1"; }; # SSH so you can keep logging in from your Mac services.openssh.enable = true; users.users.user = { isNormalUser = true; extraGroups = [ "wheel" "networkmanager" "video" ]; initialPassword = "nixos"; # change after first login }; # Apps the DEFAULT Hyprland keybinds expect: # SUPER+Q -> kitty terminal, SUPER+R -> wofi launcher, SUPER+M -> exit environment.systemPackages = with pkgs; [ kitty wofi firefox vim git ]; fonts.packages = with pkgs; [ pkgs.jetbrains-mono pkgs.dejavu_fonts ]; system.stateVersion = "@STATE@"; } EOF sudo sed -i "s/@STATE@/$STATE_VERSION/" /mnt/etc/nixos/configuration.nixCheck the version:
grep stateVersion /mnt/etc/nixos/configuration.nixInstall NixOS:
sudo nixos-installReboot:
sudo rebootSomething booted up:
But honestly, the graphics look close to unusable compared to a macOS guest. Maybe there's still something to tweak, but for now probably not.
I'm leaning toward sticking with macOS guests (though maybe switching to UTM from VirtualBuddy).
P.S.: a graphical installer might have been easier to start with, but I wanted to feel out the whole process, plus be able to set up from ready-made repos down the line.
-
A tiling window manager that ships with Omarchy.
I want to try it. On the Mac I really miss this kind of approach. I've tried a bunch of them over the years (the ones that stuck with me were StumpWM, because of Haskell, and EXWM, because of Emacs).
This time I'm planning to build a NixOS machine for work, and if the speed, smoothness, and responsiveness of the interface hold up, I'll try to move over to it. Though I have a feeling that's exactly where it'll fall short.
Then again, I barely spend any time in a GUI these days. It's mostly the terminal, so maybe it's not that big a deal.
Either way, I like running work VMs on Linux a lot more than running them on macOS. They're smaller, more predictable, and just easier to deal with overall, thanks to having a real NixOS underneath.
I actually need very little from the graphics side. Calls, a few browser-only tools with no alternative like Hetzner (I couldn't find a way to buy servers without a GUI), and everything else goes through the terminal.
-
Here's how I make a Safari window 1280x720 (for some reason you have to set it a bit bigger, probably the Mac shadow or something like that).
osascript -e 'tell application "Safari" to set bounds of front window to {100, 100, 1380, 820}'That gets me screenshots at exactly 16:9.
For terminal screenshots I use WezTerm with the Tokyo Night theme. It has its own config (still tweaking it, but it'll end up in my nix-darwin config, which I'm leaning toward making public).
That way all the screenshots come out the same, lined up like a ruler, just how I like it.
-
Interesting project from the guy behind Ruby on Rails. A good-looking Linux. It's built for agents and run entirely by agents, which spooks me right off, given how agents love to go read your secrets. Not clear how they deal with that.
People have been putting it on old Intel MacBook Pros, and from what they say, it runs faster than macOS.
I haven't tried it myself yet. I've got an old MacBook too, but it's not near me.
What bugs me is that it's x86_64 only. I haven't had hardware like that around for a long time to even try it. I could emulate amd64 in QEMU, but that just sounds slow and pointless.
You can use asahi https://asahi-alarm.org, but it's experimental and only for old Macs.
There's a NixOS port: https://github.com/henrysipp/omarchy-nix (from an enthusiast). It's basically the same ideas and tools redone on NixOS, and it's got a shot at running on arm since it's just the same packages. Though some packages might not be there for arm.
Honestly, I'm thinking I'll try the set of software that comes with it rather than the distro itself. And you can install that software anywhere. I'll report back.
September 3, 2026
-
↗ https://github.com/numtide/llm-agents.nix
A huge, always-updated collection of LLM/AI tools.
Every tool ships with a Nix cache.
I use them as an omp cache, but I still drop by now and then to see what's new.
-
Once again I keep landing on the same thought: one way or another, the conversations with agents are the key artifact of this era.
From the logs you can pull out thinking patterns, mistakes, ideas. It's raw material for self-reflection. In the end, I believe the audit of the future is an audit of thinking, not of results (meaning a pull request should come with the log of the conversation with the agents).
It's important to start saving them as early as possible.
There are two ways to do it:
- Save the interactions with the LLM (LangFuse and the like)
- Save some kind of processed material based on the sessions
- Save the Claude Code sessions (or equivalents)
The first one: LLM logs are harder to collect. They don't have the agents' internal operations or the tool call results (or they do, but in a sanitized form). They'll also have duplication (since the harness sends the whole conversation every time), and you'll have to clean that up.
The second is the most obvious: ask the agent to save some summary, a digest of the sessions. It might work, it might not. The problem is that when you're collecting, you don't know how you'll use the data, so you can't guarantee you've collected everything you need. Maybe later you'll want some other kind of statistics.
So I lean toward collecting and saving all the Claude Code logs (or in my case omp, or whatever I use later). And not just the agents I talk to, but the ones my agents talk to.
The next question is how to store this data.
For a second I thought the communication platform I'm building on Discourse (or Buzz/Zulip) would be enough: https://andysmith.ai/2026/Aug/31/discourse-as-a-platform-for-an-ai-native-company/, https://andysmith.ai/2026/Sep/1/rethinking-the-vision-for-reflection-castle/
But I noticed almost right away that this is option 2. Only part of the work result makes it into the agent's comment, not all of it. So something gets filtered out, and that something might turn out to be really important later.
So I decided to just compress, encrypt, and drop the session files into R2 (since it's append only, I can just keep appending the files that changed since the last write).
This seems to echo the experience lake: https://andysmith.ai/2026/Aug/19/an-experience-lake-and-keeping-personal-data-safe/.
But it's not quite that either. The experience lake should hold only my experience, and the agents aren't only my experience (given that most of the agents are spawned by other agents, not by me).
So this layer needs to be separate, but it can (and should) be used to build the experience lake.
-
A toolkit for deploying LLM models to production.
It even does Apple MLX: https://github.com/vllm-project/vllm-metal




















