The 2nd Agent
One AI assistant running on a Windows PC. That was the plan. That was enough.
Then I got greedy.
What if I had a second one? Sitting on the Mac Mini on my desk, watching a different corner of the network, ready to jump in when the Windows box is busy. A twin. A backup. A second pair of eyes.
It sounded like an afternoon of work. Maybe a weekend, tops.
It took a week.
Act 1 — the Mac didn’t want to be managed
The first problem was the simplest: I needed to talk to the Mac from the Windows PC. Over SSH. The oldest remote access trick in the book.
The Mac said no.
Not dramatically — macOS never does anything dramatically. It just silently wasn’t listening. Remote Login was off. Easy fix, right? System Settings → Sharing → Remote Login → toggle it on.
Done? No. Because the Mac’s SSH username isn’t “Vaughan Taylor” (what it shows on the login screen), and it isn’t my email address, and it isn’t my Apple ID. It’s `vaughantaylor` — the short name I picked during setup in 2021 and promptly forgot about. Three failed login attempts before I thought to ask the Mac what it calls me. (The answer was hiding behind `whoami`, which I should have run first.)
OK, SSH works. On to the fun part.
Act 2 — installing Hermes on a machine that already had a personality
Hermes installs with a one-liner. On the Mac, that one-liner dropped into a shell that still thought it was 2019. The Mac ships with Python 3.9.6 — ancient, barely functional, installed by Apple for reasons nobody understands. Hermes needs 3.10 or newer. The install script didn’t complain loudly enough; it just quietly failed to import its own dependencies at runtime.
Diagnosis: twenty minutes of reading tracebacks. Fix: install the real Python, point the venv at it, install ripgrep via Homebrew because macOS doesn’t ship that either.
Meanwhile, the Mac’s 256GB SSD was 93% full. Old Xcode simulators, Ollama models I’d forgotten about, a Docker Desktop install that hadn’t been touched since March, and about forty gigabytes of “I’ll clean this up later.” The “later” was now. I reclaimed 55GB, which is the most satisfying thing you can do to a computer that isn’t yours.
(It is mine. But the Mac always felt like it belonged to macOS more than to me.)
Act 3 — the bot token standoff
Hermes uses Telegram as its main channel. I already had a Telegram bot for the Windows agent. So naturally, I tried to use the same bot for the Mac agent.
This is a documented bad idea. Two Hermes instances polling the same bot token don’t cooperate — they race for updates. Message arrives, both see it, both try to answer, and you end up with two replies to every question, each one slightly different, both helpful, all confusing.
The fix: create a second bot. @BotFather, `/newbot`, pick a name, copy the token, paste it into the Mac’s config. Five minutes of work, except I spent forty-five minutes trying to figure out why the first bot was still showing typing indicators after I’d supposedly stopped using it. (Gateway restart. Always gateway restart.)
Act 4 — macOS has opinions about network traffic
The Windows agent talks to a local knowledge graph — a service called gbrain running on the Windows PC, port 3131. The Mac agent should be able to reach it too. Same LAN, same subnet, same building.
macOS disagreed.
Apple’s “Local Network Privacy” — a feature so helpful it blocks your own devices from talking to each other — silently eats UDP and TCP traffic from apps that haven’t been individually approved. The catch: this approval dialog only pops up for Apple-signed binaries. Third-party apps (like the Python runtime that Hermes uses) just get a quiet “no route to host” with no explanation, no dialog, nothing. The traffic vanishes into a socket-layer black hole.
I spent a full afternoon convinced the firewall was broken. It wasn’t. The Mac was just refusing to route the packets because nobody had asked permission, and there was no visible way to ask.
The fix was a relay — a tiny Python proxy that runs under `/usr/bin/python3` (which is Apple-signed and does get through the wall), listens on localhost, and forwards to the Windows PC. Fourteen lines of code. Two hours of understanding why it was needed.
(Permanent fix exists: grant the permission in System Settings. I haven’t done it yet because the relay works and I’m tired.)
Act 5 — two agents, two sets of everything
A fresh Hermes install knows nothing. No personality, no memory, no idea who you are. So I had to build the Mac agent from scratch: a tailored SOUL.md (who it is, what it does, how it talks), a MEMORY.md seeded with the facts it needs, a USER.md with my preferences, provider wiring so it could actually talk to an LLM, and a Telegram gateway so it could actually talk to me.
Then I discovered the gateway cache problem.
Hermes caches the system prompt when the gateway starts. I could write perfect config files, perfect memory files, perfect soul files — and the running gateway would happily ignore all of them until I restarted it. The CLI `hermes chat -q` test passes every time (it spawns a fresh process), so every verification looked correct. But the actual Telegram-connected gateway was serving the old, blank context. I spent a whole evening verifying things that were verified, while the real problem was one process that hadn’t been told to reload.
On the Mac, restarting the gateway from SSH is also impossible — the gateway’s own SIGTERM guard kills the entire process tree, including the SSH session you’re trying to restart from. You have to walk over to the Mac, open Terminal.app, and type the command by hand. Like it’s 1995. Like the network doesn’t exist.
Act 6 — the daily briefing learns to count
Once the Mac agent was alive, the morning briefing needed to know about it. The 7am daily email — which had been checking one machine — now needed to check three (the Windows PC, the Mac, and the Maintain AI business agent). Each with different health checks, different disk layouts, different ways of asking “are you alive?”
The Mac check requires SSH from the Windows PC, which requires the batch mode flag, which requires the right key file, which requires the right username (see Act 1). One wrong character and the whole briefing reports the Mac as “❌ Unreachable,” which is technically accurate but emotionally devastating at 7am.
It took three iterations to get the fleet status section right. The first version tried to use the same health check commands on every agent. They don’t share commands. The Windows agent checks `df -h /c/`. The Mac checks `df -h /System/Volumes/Data`. The business agent checks a SQLite database. Three agents, three operating systems, three sets of assumptions.
The loop
A forgotten username, a Python version mismatch, a bot token race, an invisible privacy wall, a caching problem that lies to your face, and three different health checks for three different machines.
None of these were hard problems. Every one of them had a clean, simple fix. But each one took hours to find, because the Mac doesn’t shout when it says no — it just quietly doesn’t work, and lets you figure out why.
The second agent is running now. It watches the network from the Mac, reports its status every morning, and answers Telegram messages with its own personality. It knows what it needs to know, and nothing about what it doesn’t.
One AI assistant was a tool. Two AI assistants are a fleet. The difference isn’t capability — it’s that now there are twice as many things that can go quietly wrong in ways nobody warned you about.
The Mac and I understand each other now. Mostly because I finally learned to ask it its real name.