I ran an AI agent for six months, then killed it
In February 2026 I installed the LLM agent framework OpenClaw in a container on my homelab server and gave it a name. By August I had shut it down, moved its jobs to plain cron and replaced it with Claude Code, a ttyd/tmux web shell, and ssh. This is the story of the six months in between.
February: the companion era
It began during peak mac mini madness with my first harness OpenClaw and my agent Billy. Billy ran exclusively on OpenAI OAuth, had a lengthy soul.md file, and did almost exclusively unnecessary things.
At 3:59 AM on February 19 Billy woke me to tell me that octopuses have three hearts and blue blood. Twelve hours later he told me about octopuses again. His memory system recorded each drop as an event worth remembering until the daily memory file overflowed into a spill file.
Between the messy crons burning tokens aimlessly I grew a pile of half-finished ambition: a dexscreener.com scanner built with firecrawl to scan crypto coins and markets, an astrological pattern matcher backed by a SQLite database of planetary positions (I was going to test it scientifically, I swear), an RSS media monitor, a morning overview, and a comically persistent journaling reminder system. Some of it worked. Almost none of it was maintained.
Honest summary of the era: I learned the plumbing. I produced almost nothing durable, and it was still a fair trade because of what came next.
June: rebuilding as infrastructure
In mid-June I tore it all down and rebuilt on a different framework, Hermes: an always-on gateway daemon similar to OpenClaw but with session management in SQLite, pluggable memory backends, and MCP tool servers. The difference was that this time I ran it like infrastructure instead of a pet.
The migration itself was the first sign of the change. Nothing moved over by default. At this point I was already using Claude heavily at work as well as through the harness transition so I switched to Anthropic models: Sonnet over API for the agent and Opus via OAuth through the Claude web app for troubleshooting. I quickly learned lab economics and attempted many context compression solutions. Without serious attention to detail, custom harnesses like Hermes are a token inferno.
The cleverest thing Hermes did was mostly not be the intelligence. I wired up a skill so that typing "ask opus" plus a question in Discord shelled out to the official Claude CLI on my box, under my existing subscription, with a read-only tool allowlist. I'm aware workarounds exist to use a subscription plan through a harness to avoid paying API rates but I was determined to set things up correctly on a budget without breaking any TOS.
# what "ask opus <question>" actually ran
cd /root && printf '%s' "$QUESTION" | claude -p \
--model claude-opus-5 \
--allowedTools "Bash,Read,Glob,Grep" \
--output-format text
A second, deliberately scarier variant of the same skill was allowed to actually fix things, and it existed for the days I was away from a keyboard. The gateway's real job was message transport and authorization and the thinking happened with Opus in Claude Code. In hindsight, that division of labor was the future of the whole system announcing itself early.
August: the night the watcher was inside the building
Then came the incident that reframed the project.
Visiting a friend I jumped on their PC and logged into my webshell to kick off a badblocks scan on an RMA replacement USB external drive and found it would silently wedge under sustained scattered writes. There were no SCSI errors, no logs, just an I/O request stuck forever. (That drive saga deserves its own writeup; the short version is that running badblocks against an SMR drive is a stress test that manufactures a failure.) With the drive wedged, I rebooted the Proxmox host thinking it would remount.
The host did not come back.
My setup wrote the drive's fstab entry without nofail and with a nonzero fsck pass number, so systemd did exactly what I had told it to do and blocked boot waiting on a device that was never going to appear.
# the line my script wrote (boot blocks forever if the drive is absent):
UUID=3cd51aae-... /mnt/library ext4 defaults 0 2
# the line it writes now (boot continues after 10s without it):
UUID=3cd51aae-... /mnt/library ext4 defaults,nofail,x-systemd.device-timeout=10 0 0
The frustration was unbearable so I immediately went home to fix it from the physical console, corrected the fstab entry to nofail with a ten-second device timeout, and reformatted the drive. What was learned: the agent cannot sit inside the blast radius it is watching, and you audit fstab before rebooting any host that has ever had a flaky drive attached.
None of that was the gateway's fault. But it forced the question I had been avoiding, which was what it was actually for.
The audit and the quiet decommission
I froze Hermes in late July. Anything new went straight into the system crontab, with a headless CLI call wherever a job needed intelligence. Then I watched for a few weeks to see what I missed.
Almost nothing, it turned out. Chat with the bot? The logs said I almost never DMed it. Scheduling? Cron has done that job reliably for fifty years, and the gateway's scheduler was a reimplementation of it with fewer guarantees. Error output delivery to Discord? The framework's own send command turned out to work with the gateway down. It talks straight to the bot token and needs no daemon at all. A headless CLI call gave me a better model than the gateway brain, on a subscription I already paid for, without an always-on process holding an API key. Memory? Markdown files in a git repo, which is where mine had effectively lived the whole time.
The final push was mundane. After the brain swap, the hosted model would occasionally refuse perfectly ordinary homelab automation it had handled for months, and every refusal meant debugging a personality instead of a program.
On August 11 I shut the gateway down. All eight jobs moved into the root crontab, wrapped in a small notify script that pipes stdout to Discord through the gateway-free send command and escalates errors and security events as tagged error alerts:
# a migrated job in root's crontab:
0 9 * * 0 /usr/local/bin/cron-notify proxmox-health discord /root/proxmox-health-report.sh
# the error branch of cron-notify:
if (( RC != 0 )); then
hermes send --to discord -q \
"⚠️ cron ${LABEL} failed (exit ${RC}): ${ERR:-no stderr}" || true
exit "$RC"
fi
The one interactive feature I genuinely missed, pasting a YouTube link and getting back a summary, I extracted into a standalone workflow.
The epilogue is my favorite part. Three days later the building lost power, the host rebooted, and the gateway rose from the dead. I had stopped the systemd unit but never disabled it, so it auto-started with the host and ran, unnoticed and unneeded, for two days before a routine check caught it. Even the retirement produced a post-mortem:
systemctl stop hermes-gateway.service # what I ran on August 11
systemctl disable --now hermes-gateway.service # what I ran on August 16
stop is an opinion; disable is a decision.
What's left is boring on purpose: a hypervisor, some containers, cron, git, a fifty-line notify script, and Claude Code in a tmux session. The box is quiet most days now. The last time my phone went off in the middle of the night, it was cron telling me exactly which backup had failed and why. Six months ago it would have been an octopus fact.