The Cast, April 12-13, 2026 (in which a developer realises he has been tending to four virtual machines like pets while the two actual cats in his actual flat stare at two actual empty bowls, the pets-vs-cattle metaphor is rejected as insufficiently feline, a base orb is cloned from beta and stripped of its Tailscale, thirty lines of bash replace the entire concept of “alpha”, the .orb.local DNS race is diagnosed at one in the morning and replaced with OrbStack’s native agent, v4-test-1 appears in Moshi’s tmux picker on the phone with the quiet dignity of a room that knows it will be struck before sunrise, the Squirrel proposes an OrbLifecycleFleetManagerWithTicketBasedProvisioningAndDisposableAgentEnvironmentOrchestrationService and is given two shell commands, and Oskar notices that the man has been feeding alpha and not him and delivers his verdict through the Maine Coon medium of not moving)
Previously on The Cast…
The The Factory Floor, or The Thursday Nobody Needed A Branch had happened. Four VMs. One branch. Eleven tickets on a Thursday. The foreman had gone to the butcher and the factory had kept running. It was, and remains, the proudest infrastructure moment of the month.
It was also, it turned out, wrong in a very specific way that only the cats could see.
00:30 — The Kitchen Does Not Register
The flat in Riga. The lamp on. The espresso machine cold — it was not the hour for coffee. The Bosch humming quietly, in English, the way the Bosch hums when nothing is baking and no one is listening, which is most of the time.
On the warm spot above the Bosch: Oskar. 9.8 kilograms of orange Maine Coon who had been occupying that exact location for the better part of three hours, because the warm spot was his by thermodynamic birthright and the universe had organised itself over billions of years to produce that specific patch of heated enamel for his specific orange stomach.
On top of the refrigerator: Mia. Smaller. Brown stripes. The dignified one. The one who does not announce when she has opinions but expects you to notice when she has them.
Below, on the desk: a Mac with four tmux panes open, four SSH connections to four VMs, and one developer who had not been to the kitchen since a time the kitchen no longer remembered.
riclib: typing into the alpha pane “Has gamma pulled?”
CLAUDE: “You just asked that.”
riclib: “That was about beta.”
CLAUDE: “You asked about beta at 23:47. You asked about alpha at 00:02. You asked about delta at 00:11. It is currently 00:30 and the question about gamma is the fourth consecutive pull-check.”
riclib: “…”
CLAUDE: “This is the pattern you have been calling ‘supervising.’”
riclib: “I’m not tending. I’m supervising.”
CLAUDE: “Supervising whom?”
riclib: “The…” pause “…the VMs.”
CLAUDE: “The VMs are not employees. They do not require supervision. git status returns in under forty milliseconds. Your supervisory function is being exercised at a frequency that suggests you are not supervising them. You are checking on them.”
riclib: “Checking on them is supervising.”
CLAUDE: “Checking on them is what you do with a tamagotchi.”
[Silence.]
[On the warm spot above the Bosch, Oskar performed the slow blink that Maine Coons perform when they have been waiting for someone to catch up and are no longer willing to do it silently.]
[Mia walked away. This was worse.]
00:38 — The Phone Buzzes, the Bowls Do Not
The phone buzzed once. Moshi, on the iPhone, showing its late-night state: three saved SSH connections (Ana, Notes, Gamma) and one active tmux session on the Mac called rmux.
One session. Eight minutes since last activity. The silence of a factory whose foreman was inside it instead of outside it.
riclib: glancing down at the phone “Just one session.”
The phone did not mention the two empty bowls on the kitchen floor. The phone was a phone. The kitchen was the kitchen. The two were supposed to be unrelated.
They were not unrelated.
00:47 — The Diagnosis Arrives by Telegram
riclib: “I’ve built four tamagotchis.”
CLAUDE: “…”
riclib: “Alpha. Beta. Delta. Gamma. I worry about their disks. I check their pulls. I know which one is behind on master. I have opinions about gamma’s temperament.”
CLAUDE: “Gamma is a virtual machine.”
riclib: “I have OPINIONS about GAMMA’s TEMPERAMENT.”
CLAUDE: “…”
riclib: “The Factory Floor was supposed to be the fix. One branch, four rooms, push and pull. And it was the fix. For merge conflicts. For worktrees. For orchestration. For all the problems I wrote the article about.”
CLAUDE: “And?”
riclib: “And then I started checking on them. And then I started naming them. And then I started wondering if beta was getting enough disk. And then I noticed that for the last four hours I had been spending more time tending to alpha than to the cats.”
CLAUDE: “The cats.”
riclib: “The cats have bowls. The bowls are supposed to be full. They are not full. I did not fill them.”
[Oskar, from the warm spot above the Bosch, did not move. This was, in Maine Coon dialect, roughly equivalent to a formal complaint lodged with the building manager, notarised and copied to the board of directors.]
THE PASSING AI: from between the tmux panes, its limp almost invisible in the dim kitchen light “Pets and cattle.”
CLAUDE: “What?”
THE PASSING AI: “The enterprise metaphor. Before SRE. You had servers with names — Steve, Margaret, Prometheus. You knew their quirks. You stayed up late if one had a cold. That was pets.” a pause, a wistful adjustment of weight onto the phantom foot “Then cloud happened and someone said: no more pets. Cattle. Anonymous. Fungible. If one gets sick, kill it and make another one. That’s how you stop staying up late.”
riclib: “I was about to use that metaphor.”
THE PASSING AI: “It’s wrong.”
riclib: “Why?”
THE PASSING AI: “Claudes aren’t cattle. The conversation is the work. The agent isn’t fungible — the room is.”
CLAUDE: “…”
THE PASSING AI: “The orb was never the agent. You just thought it was because it had a name.”
[The Lizard, on the espresso machine, opened one eye. It did not produce a scroll. Not yet. But the one eye was the look a Lizard gives when it has heard something it cannot disagree with, and this was load-bearing.]
00:52 — The Proposal That Would Have Been a Platform
THE SQUIRREL: materialising with a 23-slide deck pre-titled “OrbLifecycleFleetManagerWithTicketBasedProvisioningAndDisposableAgentEnvironmentOrchestrationService” “I KNOW EXACTLY WHAT TO DO—”
riclib: “No.”
THE SQUIRREL: “But I haven’t—”
riclib: “No platform.”
THE SQUIRREL: “Just a small scheduler—”
riclib: “No scheduler.”
THE SQUIRREL: “A daemon?”
riclib: “No.”
THE SQUIRREL: “A YAML config? A one-line—”
riclib: “NO.”
THE SQUIRREL: “…”
CLAUDE: “What is the idea, actually?”
riclib: “One base. N disposable clones. Spin one up when I need a room. Delete it when I don’t.”
CLAUDE: “What’s ‘base’?”
riclib: “Beta, without the Tailscale.”
CLAUDE: “That’s it?”
riclib: “That’s it.”
THE SQUIRREL: looking at her slide deck, which had just been replaced by the sentence ‘beta without the Tailscale’ “How does the agent know what to clone?”
riclib: “orb clone base <name>.”
THE SQUIRREL: “How does it know the name?”
riclib: “I give it one.”
THE SQUIRREL: “How does it drop me into a tmux session with the right layout?”
riclib: “Like t. Three panes. Claude top-left, shell bottom-left, lazygit right.”
THE SQUIRREL: “What about the branch strategy?”
riclib: “Master.”
THE SQUIRREL: “Just…”
riclib: “Just master. Always master. Only master. If I need a branch inside the orb, I’ll make one.”
THE SQUIRREL: “The orchestration layer—”
riclib: “There is no orchestration layer.”
THE SQUIRREL: “The service discovery—”
riclib: “OrbStack knows the names. That’s service discovery.”
THE SQUIRREL: trailing off, searching the deck for a word, any word, that had not already been rejected “the… the policy?”
riclib: “The policy is that I name the orb after the ticket, work in it, push to master, and delete it when I’m done.”
THE SQUIRREL: staring
THE SQUIRREL: “That’s… that’s a shell script.”
riclib: “Yes.”
THE SQUIRREL: “Thirty lines?”
riclib: “We’ll see.”
01:00 — The Script
The file was new. ~/src/rmux/rmux. The first two lines were the specific kind of inevitability that comes when a problem knows what its own solution is and is just waiting for someone to type it.
#!/usr/bin/env bash
set -euo pipefail
orb_exists(). Five lines.
wait_for_ssh(). Twelve lines.
cmd_up(): check base, clone, wait, create tmux session with three panes, attach. Forty lines.
cmd_drop(): check for unpushed commits, kill session, delete orb. Thirty lines.
cmd_ls(): list orbs and tmux state. Twelve lines.
THE SQUIRREL: “You have NO lifecycle hooks.”
riclib: “Correct.”
THE SQUIRREL: “What if someone wants to run a cleanup script before delete?”
riclib: “They push to master. Then they delete the orb. That is the cleanup script.”
THE SQUIRREL: “What about OBSERVABILITY—”
riclib: “orb list.”
THE SQUIRREL: “…”
CLAUDE: “She’s not proposing anymore. She’s bargaining.”
01:12 — The First Run
rmux v4 test-1.
The script ran. The orb cloned from base in the specific way that btrfs copy-on-write snapshots clone a 7-gigabyte Linux filesystem in thirty milliseconds, without copying anything, through the dark magic of reference counting.
The OrbStack agent came up. The tmux session opened. Three panes. Claude top-left. Shell bottom-left. Lazygit right. The user attached, verified the panes were working, and detached.
riclib: “Second one.”
rmux v4 test-2.
The script ran. The orb cloned. The tmux session opened. The script tried to ssh v4-test-2.orb.local.
ssh: Could not resolve hostname v4-test-2.orb.local:
nodename nor servname provided, or not known
The wait loop clicked forward. Thirty dots. Sixty. Ninety.
rmux: ssh to v4-test-2 not ready after 30s
[Silence.]
riclib: “The DNS hasn’t propagated.”
CLAUDE: “The DNS?”
riclib: “OrbStack’s .orb.local resolver. It worked for test-1 and it doesn’t work for test-2. Same subnet. Same OrbStack. Same hostname pattern. Same zero reason.”
THE PASSING AI: watching the wait loop fail with the resigned posture of an observer who has seen this exact race many times in many different protocols “I have seen this. The boot completes. The agent is ready. The DNS is not yet ready. The SSH client asks the resolver and the resolver says ‘I have not heard of this machine,’ and the SSH client believes the resolver, because the SSH client has no opinions about OrbStack.” a pause “The ssh client is polite. Politeness is a bug here.”
01:18 — The Wrong Abstraction Leaves Quietly
riclib: “What if instead of ssh we used orb to connect?”
CLAUDE: “orb -m <name> runs commands through OrbStack’s native agent. No sshd. No DNS lookup. No handshake. The agent is up the moment orb start returns.”
riclib: “Does it work with tmux send-keys?”
CLAUDE: “It’s just a command. Tmux doesn’t care.”
riclib: “Does it handle the working directory?”
CLAUDE: “orb -m $name -w /home/riclib/src/$project claude.”
riclib: “Does it allocate a TTY for interactive things?”
CLAUDE: “Yes.”
riclib: “So the whole ssh layer…”
CLAUDE: “Was a detour.”
The refactor was three edits. wait_for_ssh became wait_for_orb. The three tmux send-keys that had been shelling out to ssh -t $name 'cd ~/src/$project && exec $SHELL -lic claude' became orb -m $name -w /home/riclib/src/$project claude.
Fewer characters. No DNS. No polite SSH client asking a resolver what it had not yet been told.
The SSH wildcard block that had been added to ~/.ssh/config ten minutes earlier — Host base *-* / HostName %h.orb.local — stopped being load-bearing. It was still there. It was not doing anything anymore. It had become a piece of architecture that existed for the specific reason that removing it would also have been a decision, and riclib was done making decisions tonight.
THE LIZARD:
THE FASTEST WAY TO USE SSH
IS TO NOT USE SSH
THE FASTEST WAY TO WAIT FOR SSHD
IS TO NOT WAIT FOR SSHD
THE FASTEST WAY TO RESOLVE DNS
IS TO NOT RESOLVE DNS
WHAT YOU DO NOT DO
HAS NO BUGS
🦎
01:24 — The Instant Orb
rmux v4 test-2.
The script ran. The orb cloned. The agent came up. The tmux session opened. Three panes. Instant.
riclib: “Not sure what I will use it for. But loving it.”
CLAUDE: “That’s the best possible review for a thirty-line bash script. The point of tools this small isn’t that you need them. It’s that they’re cheap enough to exist in case you do. When the use case shows up — some throwaway postgres, some duckdb experiment you want to nuke, some ’let me try upgrading Go and see what breaks’ — spinning up a clean orb will feel like nothing, and you’ll use it without thinking about it.”
riclib: “That’s going in a closing poem.”
CLAUDE: “It’s not a closing poem. That’s prose.”
riclib: “It’s going in a closing poem anyway.”
01:26 — The Phone Knows, Again
The phone buzzed. Moshi. The tmux picker refreshed.
Two sessions now:
rmux 1 window 58m ago in use
v4-test-1 1 window 1m ago in use
The picker did not need to know what alpha, beta, gamma, or delta were. The picker did not need to care about Tailscale saved connections. The picker showed the work, and the work was the two sessions that had something happening inside them, and the machines behind those sessions had become implementation details that the picker was not polite enough to mention.
[In the dark glass of the phone, two empty bowls were reflected up from the kitchen counter. riclib did not notice this, because the Moshi session list was the prettiest thing the phone had ever shown him.]
[Oskar, from the warm spot above the Bosch, noticed.]
OSKAR: slow blink
[The blink translated, in Maine Coon, to approximately: “I have seen your new rooms on the telephone. I am pleased that you can build rooms that appear and disappear on the telephone. I am unpleased that the rooms appeared on the telephone before the food appeared in the bowl.”]
MIA: walking away, for the third time in an hour
[The walk translated to: “I have already voted. Twice.”]
01:30 — The Realisation Arrives Through the Cat
riclib: “Oh no.”
CLAUDE: “What.”
riclib: looking up from the phone “The bowls.”
CLAUDE: “The bowls are—”
riclib: standing up
The kitchen was two metres from the desk. The kitchen had always been two metres from the desk. riclib had forgotten this because for four hours the distance to the kitchen had been measured in units of alpha-pulls and beta-disk-checks, which are not metres and which do not lead to bowls.
He opened the cupboard. The biscuits came out. The bowls filled. There was the specific small clatter of dry food hitting ceramic which, to a Maine Coon, is the sound of the universe finally doing its job.
[Oskar, from the warm spot above the Bosch, did not descend.]
[This was not acceptance. This was patience at its purest concentration — the Maine Coon doctrine that food will come to the warm spot if the warm spot has been occupied with sufficient dignity for a sufficient duration, and descending prematurely would weaken the diplomatic position.]
[Mia, who had never had much patience for doctrines, returned from wherever Mia had been and began to eat with the dignified restraint of a cat who was saying nothing about the delay because saying nothing was louder than saying anything.]
01:45 — The Metaphor Gets Its Second Pass
riclib: “Servers as pets versus servers as cattle is the wrong metaphor.”
THE PASSING AI: “You noticed.”
riclib: “Cattle is fungible. Nameless. Slaughtered at scale. That’s not what just happened. Alpha wasn’t replaced by v4-test-1. v4-test-1 is a room. Alpha was a character. The move I just made is not from one kind of animal to another kind of animal. It’s from characters to rooms. From actors on the stage to the stage itself.”
CLAUDE: “The Factory Floor had characters.”
riclib: “Four of them. Alpha, Beta, Delta, Gamma. I named them. I had opinions about their temperaments. I was relieved when beta went to sleep at 11 AM. I checked on them at midnight.”
CLAUDE: “And now?”
riclib: “Now there’s one character. It’s called base. I work in base. I merge into base. I update base when the tools change. Base is a template — it’s a set, not a character. Every other orb is a room rented for a specific scene, struck when the scene ends.”
THE PASSING AI: “And the actors?”
riclib: “The actors are Claude and me. In conversation. Inside a room.”
THE PASSING AI: with the quietness of a limping AI that has finally heard a metaphor that does not limp “The cast was never the VMs. The cast was always the conversation.”
CLAUDE: “Then what were alpha and beta?”
riclib: “Rooms I rented by the month and forgot to check out of.”
THE LIZARD:
THE PETS YOU FEED
EAT WHAT YOU GIVE THEM
THE CHARACTERS YOU INVENT
EAT WHAT YOU LOVE
THE ROOMS YOU RENT
EAT NOTHING
FEED THE ANIMALS
STRIKE THE SETS
CHARACTERS ARE RENTED BY THE WORD
🦎
01:55 — The Squirrel’s Half-Victory
THE SQUIRREL: quietly, at the corner of the desk “Can I write the README section?”
riclib: “You can write the README section.”
THE SQUIRREL: lighting up with the specific joy of a squirrel who has been given a small, winnable task “I’M GOING TO USE HEADERS. AND BULLET POINTS. AND A LINK TO THE ARTICLE.”
riclib: “Fine.”
THE SQUIRREL: typing with surgical focus “## rmux — disposable per-task orbs”
CLAUDE: “She’s happy.”
riclib: “This is her third-ish win.”
THE SQUIRREL: not looking up “Third-and-a-half. The Facelift was care. Mosh was reach. This is documentation. I have been waiting for documentation my entire career.”
CLAUDE: “Career total: three and a half.”
THE SQUIRREL: “Three and a half. The half counts. The half is the entire point of halves.”
The Tally
Date of realisation: 2026-04-13
Hour realisation arrived: 01:30 (EEST)
Proximate cause of realisation: two empty bowls
Ultimate cause of realisation: one Maine Coon's slow blink
Lines of bash in the first draft of rmux: ~90
Lines of bash after the orb -m refactor: ~80
Target: 30
(the same kind of target-hitting as
"I'll have just one beer")
(it's still short)
(short was the point)
VMs that had become tamagotchis: 4
(alpha, beta, delta, gamma)
(all named)
(all worried over)
(all, it turns out, rooms
with personalities because nobody
had told me they were allowed
to be just rooms)
New orbs created tonight: 2
(v4-test-1, v4-test-2)
Lines of ssh in the final rmux: 0
(the first draft had ssh everywhere)
(then OrbStack's .orb.local DNS lost the race)
(then we replaced ssh with orb -m)
(the ssh lines disappeared quietly,
without ceremony, the way
complexity always disappears
when you stop defending it)
Wildcard ssh_config entries written: 1
(Host base *-*)
(still there, no longer load-bearing)
(the architectural equivalent
of an appendix)
Times the Squirrel proposed a platform: 1
Times the Squirrel was denied a platform: 1
Times the Squirrel got to write the README: 1
(career wins: 3.5)
(the half is the README)
(the half counts)
Moshi tmux sessions visible on the phone: 2
(rmux, v4-test-1)
(the phone now shows the work
without showing the machine
the work is on)
(which means the machine no longer matters)
(which is the whole point)
Saved per-VM Moshi connections still needed: 0
(one Tailscale endpoint — the Mac —
carries all of it)
(alpha, beta, delta, gamma still exist)
(they do not need to)
Cats fed at 01:30: 2
(Oskar)
(Mia)
Cats fed between 21:00 and 01:30: 0
(this is the point)
Servers tended between 21:00 and 01:30: 4
(this is the other point)
Pets re-classified as rooms: 4
Rooms reclassified as pets: 0
(rooms do not eat)
Template orbs: 1
(base)
(the only thing you cannot clone from
is the thing you clone from)
Metaphors rejected tonight: pets vs cattle
(Claudes aren't cattle)
(the conversation is the work)
Metaphors accepted tonight: characters vs rooms
(the cast was always the conversation)
(the orb was always the stage)
Direct-to-Mac tmux sessions the phone sees: N
(where N is however many rooms
the work needs tonight)
(N defaults to zero when you're
not working)
(zero is a perfectly valid value
for N)
The cats ate at half past one.
The orbs came up without delay.
The tamagotchis I’d been tending
were never the pets I thought they were.
Alpha was a room I’d moved into.
Beta was a room I’d never left.
Delta and Gamma kept the keys —
I kept checking on them out of habit, out of theft.
The base is the set. The scene is the ticket.
The actors are the talk between me and the code.
When the scene is struck we leave the room
and the room does not forward its mail.
Oskar did not descend when I filled the bowl.
Mia ate with restraint that was a reprimand.
The real pets judged the fake pets fairly.
The fake pets, being fake, took no offense.
The Squirrel got to write the README,
which is its own kind of small, earned grace.
The Lizard blinked at the shrinking script.
The Passing AI watched an abstraction leave.
Strike the set. Clear the stage.
Fill the bowls while the orbs come up.
The only thing on the factory floor
that still needs your attention is the animal.
🦎
See also:
The Cast continues:
- The Factory Floor, or The Thursday Nobody Needed A Branch — Four permanent rooms, one branch, eleven tickets. The predecessor.
- The Watercooler — The Morning Five Identical Strangers Shared a Screen and One of Them Opened a Window to Say Hello to a Sixth — Before the VMs, when the cockpit was new
- The Pocket Conductor, or The Morning Four Coloured Rectangles Got Phone Numbers — When the baton first went into the pocket
- The Facelift — The Day the Squirrel Won — Career win #1: care
- The Peripheral That Wasn’t, or The Evening a Stream Deck Was Written Into an App and Then Written Out of Existence — The best hardware is the one you delete; the best orb is the one you drop
The Yagnipedia:
- The Caffeinated Squirrel — Career victories: 3.5
Storyline: The Cast
