Andy Smith

Building scalable self-improving infra for AI agents.

September 2, 2026

  • I really don't like running third-party software and agents on my main work machine. I can't always keep close track of what they're doing, and that makes me not trust them.

    So I keep the software on my work laptop to the bare minimum. Everything else runs in isolated environments.

    One thing I do is a remote devbox. It's an auction server from Hetzner running Debian (or NixOS). On it I run code tunnel and sign in through GitHub.

    image

    Then I open the devbox through vscode.dev in the browser, or through my local VSCode, and work with the code as if it were sitting right here.

    I can connect from any device with a browser (haven't tried from a toaster, NetBSD won't build).

    This setup works for me in every way except responsiveness. The Hetzner server is on the other side of the world, so the response time is really slow. For VSCode that's fine, because the lag only shows up when I connect and open files. But for console agents like Claude Code or omp it's incredibly annoying, because there's a delay on every keystroke (mesh and similar tools for speeding up ssh don't work in the VSCode terminal).

    The second problem is that I can't work offline. But local models aren't powerful enough yet to handle 100% of tasks, so it's not really a problem. You need to be online to get anything done anyway.

September 1, 2026

  • An addition to the Castle architecture: https://andysmith.ai/2026/Sep/1/castle-architecture/

    The agent layer is a repo that manages agents. But agents need access, and each one needs different access.

    So how do you hand that access out?

    When I add a new agent, at a minimum I need to:

    1. issue a token for the model
    2. register it in discourse/buzz/zulip, set its name and bio, and save the API key or token somewhere
    3. give it the right roles in discourse
    4. issue it a token for the repos (and at that point I need to know which ones)
    5. maybe give it some extra access (ssh, logs), if its role calls for it

    I thought about describing all this declaratively, so that deploying an agent would create the secrets it needs automatically. Onboarding would just happen on first run.

    But then I realized that's a mistake. Onboarding an agent is operator work, and it needs a manual check (especially when it means granting rights to irreversible actions).

    So for now I'll keep creating new agents through a script in the agents repo, and I'll do it by hand.

    Later on I might give some agent an hr role that can do this automatically for the simple, non-destructive ones.

  • I'm still rethinking Castle.

    I'm working from the idea that this could grow into a product you can easily deploy yourself. Or that I could walk into a company, set it up for them, and keep maintaining it afterward.

    A three-layer architecture is taking shape:

    1. Kubernetes infra. Usually this isn't part of Castle, because it's hard to standardize. One person has a slice of a server set aside for Castle, so we'll run everything in minikube/k3s. Another has a small k3s cluster. Someone else has GKE with a dozen nodes. In general we leave this up to the client and set it up separately. A working Kubernetes is a prerequisite for Castle (optional, see below).
    2. Citadel. This is where the agents keep their data. At a minimum it needs some communication layer and a place to store repos. It could be something self-hosted (say, Discourse/Buzz/Zulip + Forgejo), or it could be Github + Slack. This layer doesn't depend on the choices above. The self-hosted part could run in the cluster, or somewhere else, or you might not run anything of your own at all.
    3. The team of agents (I haven't come up with a word for this yet, I'll probably just leave it as agents). This is a set of agent descriptions (probably all in one repo, but maybe one per agent if that turns out to be handier). The idea is that every agent is described declaratively in one place, including its infra, secrets, access, and so on. It all deploys to the cluster (by default) or to microsandbox (msb).

    I might put together a basic nixos config you can use for a minimal run, but it looks like each client will end up with its own set of choices, and so its own setup.

    Right now I'm trying to deploy this for a real team (they happen to be short on hardware, so the agent cluster will have to share with other infra). As I go, the limits will become clear, along with what it has in common with what I built for myself yesterday. Based on that I'll figure out what to open-source and what to keep at the level of client-specific setups (and so keep closed).

  • I'm building Reflection Castle as "a home for agents and people (tower), plus infrastructure for communication and for storing code and docs (citadel)". All of it ran on NixOS or Nix-Darwin.

    The plan is to ship an open-source solution you can drop into any team and have running fast, and to sell support on top of it for people who don't want to figure it out themselves.

    Partway through, I changed my mind about running all the Citadel components as NixOS oci-containers. It's easier to use NixOS just for the K3S cluster and roll everything else out with Flux.

    That keeps Citadel portable. You can run the whole thing on GKE with no changes, for example.

    I'm also leaning toward rethinking Tower. I used to plan on the devbox pattern for people and agents, where everyone, human or agent, gets their own dev space on a remote server. I'm dropping that now. Isolation at the user level just isn't reliable. Users can see each other's open ports. So I want to pull the human devbox-tower out of Castle. Human users can set up their own workspace and make their own calls, they're adults. For agents I'll either use https://github.com/superradcompany/microsandbox or run them in the same cluster, depending on what hardware a given team has.

    That turns Castle into an AI-native platform, Reflection's core product: a place where people and agents talk to each other as equals.

    So it needs two layers. NixOS for the infrastructure (bare metal for now), plus k8s manifests to deploy into any Kubernetes. The job is to make both reusable and public. Starting now.

August 31, 2026

  • After trying out Buzz (https://andysmith.ai/2026/Aug/21/buzz-a-hive-mind-communication-platform/), I realized the idea is really cool, but the implementation is still a bit raw.

    Buzz as a messenger just didn't click with me. Glitches pop up here and there.

    Meanwhile I've had Discourse running for a long time. I write all my blog posts through it, and the whole time I've used it, I've only had good things to say about it.

    So I decided to move the Buzz agent idea into Discourse. Here's what came out of it:

    So far I'm only trying it on my own home tasks. My home infra has a team of exactly one, me, so I can't say anything about how it works in practice yet. But tomorrow I'll try setting it up for a team of a few people, and that's where all the upside should show.

    From what I can see so far, it already wins over Buzz for me on at least two things:

    1. Post length. Discourse has a big input field, and that pushes you to write multi-line text. (Maybe it's just me, but ever since the ICQ days, chat interfaces make me panic when I hit Enter: somewhere you press Shift, somewhere Ctrl to move to the next line. I'm always afraid I'll send a half-finished message by mistake instead of starting a new paragraph. So my chat messages are one-liners. And of course that pattern carried over to the agents.)
    2. Being able to edit old messages. That lets you use the tool not just for discussion but for building up information, something like a wiki/docs/navigation layer on top of the posts.

    P.S.: This isn't a copy of Discourse AI bot. Bots in Discourse run inside the Discourse process, which fits better for admin tasks, Q&A, and automating replies. My approach is about plugging in dev and ops agents that can go do things out in the world, with Discourse as the communication platform.

  • The idea: I write my agent's logic in Lisp, using primitives like (say "message") and (ask-y-n "question"). The interface for talking to the user, those same say and ask functions and maybe a few others, can be overridden by the user or shipped as plugins.

    Some people like to work by voice, some through Telegram or WhatsApp or whatever else. Easy. Just override the functions you need.

    You could standardize this set of functions and call it something like HAI (Human-Agents Interface), with reference implementations for different tools that you can reuse. Really, an LLM only needs a couple of interfaces to a human.

    I'm curious to see where this goes as neural interfaces get better.

  • Instead of relying on chat context and separate frameworks for long-term memory, I'm testing a way of building software based on the reconciliation pattern from Kubernetes.

    The idea is to read as little of the AI's output as possible while keeping the quality of the development process, and ideally improving it.

    Here's how it works. Our team discusses a project in buzz. The agents don't write code right away. Instead they update the project's documentation as if the features we want were already built, and they give us links to the updates.

    We read the docs and judge how well the agents understood our decisions, and give feedback when we need to.

    So the first stage of reconciliation is that the docs are always kept in sync with the discussions. Changes go in at the same time as the discussions.

    Keeping the docs and the code in sync is handled separately. Any change to the docs leads to a change in the code. Since the docs have already been reviewed, the code should match what's described in the chats too.

    The idea is to not look at the code at all. To have the review and the fixes happen entirely through the docs, done by the agents. This assumes the docs are complete and unambiguous enough, but that's almost never true, so the process isn't perfect yet.

August 26, 2026

August 23, 2026

  • The more I dig into OMP, the more it reminds me of Emacs org-mode (https://orgmode.org/), and specifically its org-babel module (https://orgmode.org/worg/org-contrib/babel/).

    I want to try using org-mode files as an interface to agents.

    I create a new org file, and that starts a session.

    A new heading shows up automatically with a code block of type "agent". Running that block just sends its text to the agent session.

    While it works, the agent can create as many subheadings inside that block as it wants, write comments in them, add separate blocks, run them, edit files, call tools, and so on.

    When the agent is done, it creates the next heading so I can type the next block.

    You end up with a structured, executable playbook.

    The file holds the whole session, every tool call and every detail, so you can reuse it as a re-runnable playbook.

    I'm not sure what to do about forks, or whether they're even needed. The idea would be to roll back the agent's last action and continue from some earlier state. But that brings a pile of problems right away. You can't just fork the Claude session, you also have to undo the changes the agent made. More on that here: https://andysmith.ai/2026/Aug/20/a-programming-paradigm-for-spatiotemporal-composability/.

    If I do the forking through Org itself, it gets muddy where the split is about meaning (by steps, or by logical sections) and where it's an actual fork.

    So I could just not bother with forks. Or do it by making a new file that shares the same beginning with the end cut off. Or just use git the way it's meant to be used, roll the file back to the state I need, and keep going.

    Even then, there'll probably be odd surprises around undoing the agent's actions. If the agent did something outside the file, the state I'm forking from doesn't know about it.

August 22, 2026

August 21, 2026

August 20, 2026

August 19, 2026

  • I've been listening to Gödel, Escher, Bach, and it feels like it's about exactly what I want to build: systems that describe themselves. You know those Escher drawings, the staircase that keeps going down but never ends, or the waterfall that pours down and somehow feeds itself back at the top. Those self-looping things, systems that describe themselves.

    Languages that describe systems like this have a funny property. You can describe more kinds of systems in them than in languages that can't describe themselves, and the descriptions come out cleaner and shorter. LISP is one of those languages. It can describe itself. I don't really get why everyone forgot about LISP. It was built for AI in the first place, the very first AI language, about 70 years ago.

    But there's a practical reason this matters for agents too: a permission sandbox. Say an agent wants to call a sub-agent, but the sub-agent has to be limited in what it can do. In normal languages that's almost impossible. You can't say: run any Python you want, except, say, listing a directory. The moment you give a sub-agent access to Python, it has full access to the system, it can do anything. Python and JavaScript just don't have a language-level sandbox. In LISP you can easily say: here are your operations, this one, this one, and this one. Think whatever you want, but the only way you reach the outside world is through those three. And the agent physically can't get around it. For corporate workflows that's exactly what you need. For personal ones it's probably overkill, but for corporate it's a must-have.

  • To me, all these IDEs and Claudes seem to have one basic problem: they don't work as a team. You've got your own context, your own tricks, principles, gates, everything you've set up for yourself. My context is totally different. The devs have a third one. And when we're building one shared product, each of us playing by our own rules, the question becomes: where and when is all of this supposed to sync up? And when the edits conflict, whose is right?

    The simplest example is tabs versus spaces. Your agent always uses tabs, mine uses spaces. You commit code with tabs. My agent sees it's off from our standard and switches it to spaces. Your agent sees spaces and puts the tabs back. And this tug of war between agents goes on forever, even where agreeing should be trivial, just because my agent has my context and yours has yours.

    My fix is drastic. The problem is that we're trying to boost a person with an agent inside the old processes: do the same thing, just faster. But that's the wrong goal. We shouldn't do the same thing faster, we should build new processes that weren't possible before and are now. To do that, you have to take the agent off the personal level and move it to the team level. All the agreements, the checks, the styles, the gates, the architecture, should live at the team or company level, not the personal one. At the personal level it's called character. At the team level it's called corporate culture.

    What's left at the personal level is just a thin layer. I think of it as a butler. It knows you well, it knows your habits, it gets what you meant even when you didn't spell it out. Its job is to take the task off your hands, maybe flesh it out the way you would have, and hand it to the corporate agent system. It also manages your attention and your schedule: "hey, something urgent just came up, let's drop this and talk now."

    The team work itself is a separate thing. It should be one corporate AI, not a bunch of personal AIs trying to sync their contexts over Git or out loud, which is inefficient. And it's not just documents and text, it's processes too, and processes are code. So somewhere there has to be a shared server where all of this runs and builds up. Taken to the limit, you get an AI company: not people boosted by agents, but the company itself as one big agent, or an ensemble of agents. And people in two roles: either they build and maintain the system, or they act as experts. When the system breaks, we say "this would be better done this way," which is how we train it. And there are still purely manual steps where you need a human: sending money, say, or approving something.

  • I've been thinking for a while about what I call a personal stream, and now I finally have a chance to try it.

    The idea is this. There's an endless feed, like on social media. That's the visual version. And there's a second version: you put in an earbud, and it's like radio. Smart radio that just reads the feed out to you. At any point you can say stop, I don't get this part, let's look at it. And just like in a feed, you can comment on any item: I disagree with this, this one isn't quite clear to me.

    I think voice is the most promising interface. You can do something else while it plays, walk somewhere, give your eyes a rest, and it just gets read out to you. And the stream itself can hold anything. Answers to your questions (you ask something, and the next items immediately rearrange around it). Passages from books and articles on the topic: someone already wrote about this, listen to a chapter. You could also add a screen with schematics and diagrams.

    One thing that really grabs me is reading formulas out loud. Right now I'm trying to listen to a math book through an automatic text-to-speech thing, and it reads the formulas as a string of letters, totally impossible to follow. If my agent read them instead, it could say them properly, like a lecturer. Not letters one after another, but "B to the fourth power, times something."

    It's hard to take in by ear, but it's a way of taking things in that's worth building up in yourself.

  • I'm thinking about storing the context of my whole life, every event and every reaction, as a graph. At first I wanted to call it a data lake. But experience lake is closer: everything you've built up over years.

    The point of a lake like this is that you can open it up piece by piece. Say a company comes to you and says they want to train their models on how people react to some situation. Like what you feel when you see a half-built house. You can open just that part of your experience instead of all of it. Their models only learn from what you chose to show. It works the same way between people. You've fished for decades but never write about it anywhere. You meet someone who's also into fishing, and he's not sure whether it's worth bringing up with you. Then you just open that part of your experience to him. That's how trust and reputation get built between you.

    But before you can even start collecting all this, you need a guarantee the data won't leak anywhere. A plain text file won't cut it. Steal it and you've stolen a whole life in one go. That's serious. It could leak from GitHub too. It doesn't matter who it leaks from, what matters is that it's your entire life. So the data has to be encrypted, and only decrypted on request, on demand, with a hardware key. That's hard, but if you bake it into the architecture, people will trust it a lot more.

    I picture the storage itself as a separate, self-running system. Imports wired up from Apple Health and other sources, encrypted, backed up, maybe on a blockchain. It's yours, it's safe, and it runs on its own, independent of you and of your agents. You don't even have to spend any attention on it. You just know everything's in one place and safe.

August 18, 2026

  • I got talking with someone about collecting data on yourself. He was telling me how he logs the meals he eats through the claude.ai web interface and saves them all in one database.

    I don't believe in collecting data on yourself through discipline. Discipline breaks. When you do something without really understanding it, without a big goal (and collecting observability data has no such goal by definition, the goal shows up later, once you've got the data and can pull something out of it), at some point you skip it once, and nothing changes. So you just stop doing it. That's why I try to collect data on myself seamlessly, with nothing to distract me, so it just happens on its own.

    I've already pulled this off with video and books. I set up Jellyfin, BookOrbit for books, and I found an app that reads a book aloud in an AI voice: you press a button and it reads it out. Not perfect, it sort of has intonation but also sort of doesn't, but overall it's fine as a cheap audiobook. So everything I read or listen to gets logged: this book, at this time, for this long. When I'm working at the computer, that gets captured automatically too. All of it can be exported into one context database where you can see, by time, what I was doing when: reading a book, watching a show, working.

    Next I want the same for my body. I'm going to drop WHOOP (they're great, but they don't share their data) and buy an Oura smart ring. That, the Apple Watch, and other wearables all feed into Apple Health, and from Apple Health into that same single database.

    And in general, I think it's better (and more reliable in the long run) to collect data through a good app and pull it from there into one system, than to type it in by hand through a chat interface.

    For what I eat, I could use Rayban smart glasses (though I don't know if they can stream), because having to snap a photo every time is discipline too.

  • The kanban I'm working on is mainly for communication between a human and an agent. Between agents you don't need a kanban at all. That part can be whatever. But for a person, moving little cards around a board is just handy.

    The idea is this. You start a session with an agent. It does its thing, and at some point it figures out that it needs you. It can't keep going without you. So it files a task for you and goes to sleep. You read what the task says and you do it. And doing the task usually just means writing a comment, because the agent asked you something.

    So in that sense the kanban isn't even for the agents, it's for you. It's a way to answer the agents' questions without losing your mind over how async they are, and to put some order to the whole thing. That's roughly how I see it.