Always-on personal compute is back — Mac minis humming on shelves, tiny servers under the TV, VPSes nobody asked for. They could be more than file dumps. This 5,000-word investigation surveys the patterns developers commonly use to put AI agents on always-on hardware, exposes the failure modes of each, and presents a production-tested architecture that turns your idle box into a digital buddy who works while you’re at dinner with your family.
The Quiet Return of Always-On Personal Compute
A small revolution has been unfolding on shelves and under desks. The desktop machine that sat dormant when you weren’t at it — that’s becoming a thing of the past. On October 29, 2024, Apple announced the M4 Mac mini — the first redesign of the line in over a decade, in a 5×5-inch form factor, starting at $599. Apple reported Mac segment net sales of $33.7 billion in fiscal 2025, up from $29.98 billion the year before, a roughly 12% year-over-year increase. The redesign was followed by a wave of Reddit, YouTube, and Hacker News threads documenting “I leave my mini running 24/7” rigs for ML inference, home automation, and always-available development. Hetzner, OVH, and other VPS providers continue to advertise dedicated developer-targeted boxes for the price of a couple of dinners a month.
This hardware is everywhere. The question is what to do with it. From voice assistants that only work when you remember to invoke them, to dashboards that demand you remember to check them, the always-on box has been criminally underused. It should be doing work for you, not waiting to be asked.
Below, we examine the technical patterns developers have been reaching for to put AI agents on this hardware, dissect their failure modes, and provide a roadmap for a production-grade alternative.
The Personal AI Assistant Gap
The global AI agents market is projected to reach $50.31 billion by 2030, growing at a 45.8% CAGR according to Grand View Research, with comparable forecasts from MarketsandMarkets ($52.62 billion at 46.3% CAGR) and BCC Research ($48.3 billion at 43.3% CAGR). But this growth is heavily concentrated in cloud-hosted, web-accessed assistants. For developers wanting their own assistant — running their own tools, on their own machine, in their own networks — the tooling has lagged.
The consequences compound. An assistant that forgets isn’t really an assistant — it’s a stateless function call dressed in a chat UI. An assistant that can only act when you’re at the keyboard isn’t reclaiming your time — it’s just relocating it. And an assistant that needs --dangerously-skip-permissions to do anything useful isn’t safe — it’s a footgun pointed at your home directory.
What an Always-On AI Buddy Actually Has to Do
Most existing patterns tackle one or two of these requirements. Few tackle all five:
- Persistent context: A buddy that remembers the file you discussed yesterday
- Proactive work: An agent that runs builds, edits repos, and watches deploys while you’re away
- Safe autonomy: Permission gates that allow safe operations and ask before destructive ones
- Reachable surface: A chat interface that’s already in your pocket
- Resilient lifecycle: Survives reboots, network blips, and accidental kills
Common Patterns and Their Limits
1. The Polling Daemon (The Most Common Mistake)
Architecture:
- A long-running script polls the chat platform’s REST API every 5–10 seconds
- New messages trigger
subprocess.run([claude, "-p", prompt, "--dangerously-skip-permissions"]) - Output is captured and posted back as the bot’s reply
Observed Failures:
- Cold-Start Tax: Each message triggers a fresh
claudeboot — Node runtime startup, MCP plugin discovery, model warmup. Anecdotally, several seconds elapse before the first token of any reply. - Memory Loss: Each
-pinvocation starts from zero. Yesterday’s conversation is gone. To recover continuity, developers paste prior context into prompts manually — recreating, badly, what Claude Code already does for free. - Permission Disabled: Because the spawned process is non-interactive and the daemon can’t synchronously answer prompts,
--dangerously-skip-permissionsbecomes the only path forward. - API Pressure: Polling burns Discord/Telegram rate budget continuously even when nothing is happening.
Real-World Cost: In a polling daemon I deployed in early 2026, every single message triggered a fresh claude invocation — many spawns per active day, each costing seconds of latency, a fresh model warm-up, and a complete reload of MCP servers. Conversation continuity: zero.
2. Custom Bot Framework + Direct API
Approach:
- Use the platform’s native library (
discord.js,python-telegram-bot, etc.) - Maintain conversation history in your own storage layer
- Call the Anthropic Messages API directly with explicit context windows
Trade-offs:
- Ecosystem Loss: Plugins, skills, MCP servers, the entire Claude Code tool surface — gone, or you reimplement each one. This includes the discord/telegram chat plugins themselves.
- Agent Loop Reimplementation: Tool dispatch, retry logic, prompt caching, subagent coordination — all on you. Code that already exists upstream.
- Permission System Reimplementation: Reviewing tool calls before execution, presenting prompts to the user, persisting decisions — all you.
- Maintenance Burden: Every new MCP server, every Claude Code feature update, has to be re-integrated into your custom layer.
Cost-Benefit: Justified only when you need control over agent behavior at a level Claude Code doesn’t expose — multi-tenancy, custom tool gating, regulatory compliance contexts. For most personal-assistant use cases, this is a YAGNI violation.
3. Bare Interactive claude --channels (The Closest Miss)
Approach:
- SSH into the always-on box, run
claude --channels plugin:discord@…interactively, leave the terminal open
Why It Almost Works:
- The
--channelsflag activates real WebSocket gateway connections via the chat plugin’s MCP server - Inbound messages auto-push as turns; conversation memory is preserved naturally
- Permission system works as designed; prompts route to chat with 5-letter approval codes
- Plugins, MCP, the whole ecosystem — all available
Why It Fails in Production:
- Lifecycle Fragility: SSH disconnects kill the session. Browser tab closes, reboot happens, accidental
Ctrl-C— gone. - No Supervision: If Claude crashes (rare but real), no automated recovery.
- No Boot Persistence: Reboot the box and you’re SSHing back in to manually start it.
- No Liveness Signal: Nothing tells you the bot is dead until you DM it and get nothing back.
Diagnosis: The shape is correct; the plumbing is missing.
Deep Technical Analysis: The Persistent Bot Architecture
The architecture that addresses all five gaps is, in essence, Pattern 3 with proper plumbing. The key insight: you don’t have to build a chat bot at all. You have to keep Claude alive and out of the way. Everything else is upstream.
Architectural Overview
| |
Component Responsibilities
- Init System: Keeps the supervisor alive across reboots. Respects watchdog signals. Hands off PID-1 supervision concerns.
- Supervisor: A 120-line program (mine is Python; Bash, Go, or anything works) whose entire job is: “Is the tmux session up? Is Claude the foreground command in its pane? If not, fix it.” Nothing else.
- Tmux: The persistent-session abstraction. Survives SSH disconnects, survives the supervisor (with the right
KillMode), enables directtmux attachfor live debugging. - Claude: Does all real work. The
--channelsflag turns the chat plugin into a primary input source; every inbound message becomes a turn in Claude’s existing prompt loop with full context preserved. - Chat Plugin: Handles platform-specific gateway protocol, access control (allowlist/pairing), message chunking, typing indicators, and crucially, the permission-reply protocol for human-in-the-loop approvals.
Best Practice:
- Treat the supervisor as PID 1 thinking writ small: maximum simplicity, maximum robustness.
- Push state into Claude wherever possible. The supervisor should derive everything from filesystem inspection.
- Never let the supervisor talk to the chat platform directly. That’s the plugin’s job.
The Supervisor: Smallest Useful Watchdog
The supervisor’s loop is a single-threaded, side-effecting routine. The conceptual core:
| |
The claude_alive check leans on three small tmux queries:
| |
Implementation Note: The foreground command can appear as claude, node, or bun depending on how Claude was packaged and which child process is currently active. Match all three; otherwise transient plugin activity will register as false-positive “Claude is dead” detections.
What the Supervisor Deliberately Does Not Do:
- No retry/backoff math: A failed
tmuxcommand logs and waits for the next tick. No state machines. - No state file: Anything the supervisor needs across restarts must be derivable from the filesystem.
- No threads, no async: A single-threaded loop with an interruptible sleep is enough. The
threading.Eventexists solely so SIGTERM can wake the loop early.
Mitigation for Custom Needs: If you need watchdog metrics, custom restart policies, or multi-bot support, write a slightly bigger supervisor. The shape stays the same. Resist the urge to use a process manager (supervisord, pm2) — they hide the model from you.
Init System Configuration: Three Directives Doing Real Work
For systemd-user (other init systems have direct equivalents):
| |
| Directive | Purpose | Tuning Notes |
|---|---|---|
Type=notify | Async readiness signal | Tmux session creation takes a beat; this prevents systemd reporting active before bot is genuinely up |
KillMode=process | Only kill named PID | Without this, SIGKILL on supervisor reaps the entire control group, including tmux server |
Restart=always | Auto-restart on any exit | Combined with RestartSec=10, gives 10s recovery on supervisor crash |
WatchdogSec=120 | Liveness deadline | Should be 3–4× supervisor tick interval (TICK_SEC=30) to absorb transient stalls |
NotifyAccess=main | Restrict notify socket | Defense-in-depth; only the main supervisor process can signal readiness |
Best Practice:
- For macOS, the equivalent in
launchdusesKeepAliveforRestart=alwaysand theWatchPathsmechanism for liveness. - For minimal deployments without an init system, even a
cron @rebootplus apgrep || startshell wrapper covers the basics.
Wiring Claude to the Chat Platform: The --channels Pattern
This is the piece where most of the work has been done by upstream. The exact magic:
| |
What --channels Actually Does
Without --channels | With --channels |
|---|---|
| Plugin is a regular MCP tool source | Plugin opens a WebSocket gateway connection |
Claude can reply if instructed manually | Inbound messages auto-push as <channel> notifications |
| Plugin’s gateway never connects | Plugin actively listens, dispatches, receives |
| Bot is effectively deaf | Bot is a real listener with full context flow |
Setup Workflow (Discord example):
Create bot in Discord Developer Portal
- Enable Message Content Intent (privileged intent, but free for bots in <100 servers)
- Generate bot token
- Invite bot to a server you share with it
Configure plugin
1 2 3/plugin install discord@claude-plugins-official /reload-plugins /discord:configure $DISCORD_BOT_TOKENPair your account
1/discord:access pair ABC123 # 6-char code from initial DMLock down access
1/discord:access policy allowlist # post-pairing hardening
Privacy Trade-off: The Message Content Intent gives the bot access to all messages it can see. Only enable it on bots you control. For multi-tenant deployments, scope per-channel.
The same pattern applies to Telegram, Slack, IRC, Matrix — any platform with an MCP plugin supporting --channels. Swap the plugin name; the rest of the architecture works unchanged.
Permission Architecture: Trust by Design
This is the piece that distinguishes a real assistant from one running with the brakes off. The goal: non-destructive commands run silently; destructive ones ask, with prompts routing to chat.
Layer 1: Static Allow/Deny Lists
In ~/.claude/settings.local.json:
| |
Critical Configuration Points:
defaultMode: acceptEditsauto-approvesEdit/Write/NotebookEdit. File edits in your own workspace are routine; gating each one is miserable. Deny list still catches writes to system paths.- Chat plugin MCP tool patterns belong in allow list. Without
mcp__plugin_discord_discord__reply(or the equivalent for your platform), every chat reply triggers a permission prompt — making the bot effectively unusable. - Anything not on
allowordenyfalls through to “ask”, where the chat plugin’s permission-reply protocol takes over.
Layer 2: PreToolUse Hook for Compound Commands
Static Bash(...) patterns can’t classify compound forms. Bash(git log *) matches git log --oneline, but does not match cd /tmp && git log --oneline — because the literal command starts with cd.
This is where a PreToolUse hook earns its keep. Skeleton structure:
| |
Hook Design Principles
- One-sided output: When the hook auto-approves, it says so. Otherwise it’s silent. The hook never denies — that’s the deny list’s job.
- Conservative classification: When in doubt, defer. False-positive prompts are cheap; false-negative auto-approvals are expensive.
- Subshell rejection: Anything with
$(...), backticks,<(...), or>(...)skips the hook entirely. You can hide arbitrary code in a substitution. - Redirect filtering: Writes to
/etc,/boot,/sys,/vardefer regardless of verb safety.
Verb Categorization:
| Category | Examples | Handling |
|---|---|---|
| Safe | ls, cat, grep, find, awk, git status|log|diff | Auto-approve |
| Subcommand-safe | git, systemctl, tmux, npm, pip | Auto-approve only with whitelisted first-args |
| Hard-deny | rm, mv, dd, chmod, kill, make, bash, python3 -c, ssh, sudo, docker | Never auto-approve |
The exact membership of each category is yours to decide. My version is conservative — python3 --version is allowed, python3 -c is not. Yours might be looser or tighter. The interesting design choice is the shape: silent for safe, ask for novel, deny for catastrophic.
Conversation Continuity Across Restarts
When the supervisor respawns Claude — for any reason — the new Claude starts fresh by default. Conversation memory: gone.
Claude already solves this; you just have to ask. The relevant flag: --resume <uuid>.
Implementation Pattern
| |
Each Claude session is autosaved to ~/.claude/projects/<encoded-cwd>/<session-uuid>.jsonl. The most recently modified JSONL is, by definition, the session you want to continue.
Recovery Flow on Graceful Restart:
- systemd sends SIGTERM to the supervisor
- Supervisor’s signal handler triggers
stop_session() stop_session()sends/exitto Claude inside tmux- Claude flushes its session JSONL to disk
- Supervisor exits cleanly
- systemd starts a new supervisor instance
- New supervisor scans
~/.claude/projects/<cwd>/, picks the latest JSONL - Spawns Claude with
--resume <that-uuid>— same conversation, new process
Verified Behavior: After sending several Discord messages and then systemctl restart on the supervisor, the resumed Claude correctly recalled prior context: which files were discussed, which permissions were granted, what the user asked for last.
Production Pitfalls and Mitigations
Four production-grade issues showed up between “it works on my machine” and “it survives SIGKILL”. All have one-line fixes once understood.
1. KillMode=control-group Erases Your Bot
Failure Mode:
Default systemd kills the entire control group when a unit stops. Tmux daemonizes its server into the supervisor’s cgroup the first time tmux new-session runs. SIGKILL on the supervisor reaps the tmux server with it — the session goes away, your conversation is lost, and “supervisor restart preserves bot state” becomes a lie.
Mitigation:
| |
systemd now only kills the named process. The tmux server keeps running independently. The next supervisor instance finds the existing session and resumes monitoring. Journal logs:
| |
Caveat — read the systemd docs first. The official systemd.kill(5) manual states: “It is not recommended to set KillMode= to process or even none, as this allows processes to escape the service manager’s lifecycle and resource management.” That warning is appropriate for ordinary services; in our case, the entire point is for tmux to deliberately escape the supervisor’s lifecycle so the user-facing assistant outlives any supervisor crash. This is a knowing trade-off, not a misconfiguration. Document it in your unit file with a comment so future-you (or future-team) doesn’t undo it.
2. The Workspace Trust Dialog Blocks Startup
Failure Mode:
On first launch in any directory, Claude prompts: “Do you trust the files in this folder?” Reasonable for interactive sessions, catastrophic for headless supervisors — Claude blocks before the chat listener activates, so messages stack up unanswered.
Mitigation:
Persist the answer once via ~/.claude.json:
| |
Set once, never re-prompts. If the file is rebuilt or the project key recreated under a different path, the prompt returns — the supervisor doesn’t re-set automatically.
3. Manual Tmux Input Disrupts Channel Mode
Failure Mode:
Inbound chat messages auto-push as channel notifications — as long as nobody types into the tmux pane. The moment you tmux attach and type anything (or tmux send-keys a query), Claude’s TUI switches to “manual input mode”: the next inbound message lands in the input box rather than auto-flowing as a turn. It sits there until someone presses Enter.
Mitigation:
This is upstream Claude TUI behavior; no supervisor-side fix exists. Operational workaround: if you tmux attach to peek, don’t type. Detach with Ctrl-b d. Auto-flow stays intact.
4. Some “Deny” Patterns Get Silently Dropped
Failure Mode:
The classic fork-bomb pattern Bash(:(){ :|:& };:*) looks like it belongs in your deny list. Claude’s settings parser rejects it as invalid syntax (the parens collide with the Bash(...) form) and silently skips the rule. Other deny patterns still apply, but you’ve added a phantom safeguard.
Mitigation:
Validate every deny pattern by inspecting Claude’s startup log for [settings] warnings. A pattern that fails parsing produces:
| |
Fix syntax or drop the rule entirely.
Adapting the Pattern to Your Needs
The supervisor I wrote is not the point. The shape is. Six places where your needs probably diverge:
1. Different Chat Platform
- Telegram, Slack, IRC, Matrix — if there’s an MCP plugin supporting
--channels, the rest of the design works unchanged. - Action: Swap
plugin:discord@…forplugin:telegram@…; change the access policy file; done.
2. Different Supervisor Language
- Bash works fine. Go works fine. Anything that can run subprocesses and read directories works.
- Action: The interesting code (
latest_session_id, the main loop) is ~30 lines in any language. Pick what’s already on your box.
3. Different Init System
- systemd’s
Type=notifyis useful but not load-bearing. macOSlaunchd, OpenRC, runit — all work. - Action: For minimal deployments,
cron @reboot+ apgrep || startwrapper covers the basics.
4. Different Permission Posture
- My allow list trusts the assistant to read freely but ask before writes outside the workspace. Yours might trust less (whitelist specific repos) or more (allow
python3 -cbecause you’ve sandboxed the box). - Action: Tune the
SAFE_VERBS,HARD_DENY, andSUBCOMMAND_SAFEtables in your hook.
5. Different Deployment Scope
- Solo bot: my approach. Team-shared bot: needs a multi-user access policy in the chat plugin’s
access.json, audit logging of permission decisions, clear ownership of who can approve destructive ops. - Action: Bigger access policy file, optional audit hook, possibly a separate review channel.
6. Different Memory Expectations
- I’m fine with conversation resetting on supervisor SIGKILL (mid-turn loss). If you’re not, drive autosaves more aggressively or implement supervisor-side checkpoint pings.
- Action: Most users won’t need to. If you do, plumb checkpoint persistence into the supervisor’s main loop.
Push-back: Don’t go back to --dangerously-skip-permissions because the hook felt like work. The hook is a one-time investment that pays off every single day the bot is running. Every prompt that lands in your DM is the cheapest possible audit log.
The Road Ahead: Toward Always-On Personal AI
The personal AI infrastructure landscape demands a paradigm shift toward:
1. Standardized Persistence Patterns
- Common contracts for session resume across agent frameworks (currently each agent rolls its own)
- Filesystem-based session state as a first-class API (vs current ad-hoc JSONL files)
- Cross-restart conversation continuity as a default-on feature
2. Permission System Maturity
- Hook-based dynamic classification standardized across platforms (we’re early days here)
- Cross-vendor agreement on permission-reply protocols (Claude’s 5-letter code system is excellent; should be ubiquitous)
- Audit logs for permission grants/denials as a built-in capability
3. Hardware-Native Always-On Agents
- Mac mini and similar small-form-factor hardware as a recognized deployment target for personal AI
- Optimized power profiles for “mostly idle, occasionally active” agent workloads
- Local-first AI infrastructure that doesn’t assume cloud availability
4. User Empowerment
- Unified dashboards for “what is my agent doing” (currently: tail journalctl + tmux attach)
- One-click pause/resume for autonomous agent loops
- Behavioral anomaly detection — agent behaving outside historical patterns
As demonstrated by the Mac mini renaissance and the rapid adoption of personal compute, the substrate is here. The agent infrastructure is catching up. Through layered defenses combining static allowlists, hook-based dynamic classification, chat-mediated permission grants, and supervised lifecycle management, developers can reclaim hours from their day — one autonomous task at a time.
Recommended Stack by Component
| Component | Recommended Choice | Key Properties |
|---|---|---|
| Always-On Hardware | Apple Mac mini M4 / VPS (Hetzner CX22+) | Low idle power, reliable uptime |
| Init System | systemd-user (Linux) / launchd (macOS) | Watchdog support, auto-restart |
| Persistent Session | tmux 3.3+ | Mature, ubiquitous, scriptable |
| AI Runtime | Claude Code 2.1+ with --channels mode | Native chat-platform plugin support |
| Chat Platform | Discord (free for personal use) | Mature MCP plugin, mobile-first |
| Permission Hook | Python 3.10+ stdlib | Zero deps, easy to audit |
| Conversation Storage | Claude’s built-in JSONL autosave | No additional infra |
Best Practices for Builders
For Solo Developers
Start with Pattern 3, then add the supervisor
- Run
claude --channelsinteractively first; verify the chat round-trip works end-to-end - Only then wrap with the supervisor — debugging two layers at once is painful
- Run
Build the hook incrementally
- Start with an empty
SAFE_VERBS. Every command claude tries that you’d want auto-approved becomes a list addition. - Within a week, you’ll have a stable allowlist matching your actual workflow.
- Start with an empty
Use
tmux attachearly and often- Live observation of your bot working is the most useful debugging tool you have
- Detach without typing to preserve channel mode
For Team Deployments
Multi-User Access Policy
- Use the chat plugin’s
access.jsonwith explicitallowFromlists - Implement per-channel scoping with
requireMentionto limit blast radius
- Use the chat plugin’s
Audit Logging
- Hook permission decisions to a logging endpoint
- Surface destructive op approvals in a separate review channel
Operational Playbooks
- Document the
tmux attachworkflow for on-call engineers - Define escalation criteria for “bot has been wrong about X for Y hours”
- Document the
Conclusion: Reclaiming Time from the Always-On Box
The lesson I keep relearning is that the platform is usually further along than I think. I started by writing a polling daemon because I was thinking “Claude is a CLI; I’ll wrap it.” The right question was: “What does Claude Code already support that I should be using?”
The answer was --channels, the official chat plugins, the permission-reply protocol, --resume, and the hook system. Five pieces of infrastructure that were already there, doing the work I was about to do badly in 300 lines of polling code.
What’s left is a thin layer of Unix glue: keep tmux up, keep Claude inside it, hand off conversation IDs across restarts. The interesting code lives upstream, where someone else maintains it. The “bot” is mostly a watchdog plus a configuration choice.
The buddy’s been running for a while now. It drafts things while I’m not at the desk. Watches builds. Pings me when something genuinely needs my eyes. I’ve spent fewer evenings staring at my phone wondering if a deploy went through. My weekends have a few more hours in them than they used to.
The always-on box on my shelf — the one I bought to host whatever — finally feels like it’s worth the electricity.
If you have an always-on machine, you have a buddy waiting to be activated. The pattern is small. The trade-offs are knowable. The time it gives back is real.
Build it. Tune it. Lean on it.
Stay autonomous, stay supervised.
References
All references below were verified live as of May 2026. URLs are the canonical, primary sources for the claims and code referenced in this article.
Claude Code & The Plugin Ecosystem
- Claude Code Documentation — Official Claude Code documentation portal (Anthropic).
- Claude Code on GitHub — Source repository for the Claude Code CLI.
- Discover and install plugins through marketplaces — Plugin discovery and installation reference.
- claude-plugins-official Marketplace — The Anthropic-managed directory of official Claude Code plugins.
- Discord Plugin README — The plugin’s setup guide, including the
--channelsflag, intents, pairing flow, and exposed tools. - Discord Plugin Source Tree — Full source for
server.ts, access skills, and configuration.
Model Context Protocol (MCP)
- modelcontextprotocol.io — Official documentation hub for MCP.
- MCP Specification (latest) — Authoritative protocol definition.
- MCP Specification Repository — Source of the specification, including draft revisions.
Always-On Personal Compute
- Apple Newsroom: Mac mini with M4 Announcement (Oct 29, 2024) — Official announcement, specs, and pricing for the redesigned Mac mini.
- Apple Mac Revenue (Statista) — Quarterly Mac segment revenue history.
- Hetzner Cloud — Pricing for developer-targeted VPS instances.
AI Agents Market Forecasts
- Grand View Research — AI Agents Market Report — $50.31B by 2030 at 45.8% CAGR.
- MarketsandMarkets — AI Agents Market — $52.62B by 2030 at 46.3% CAGR.
- BCC Research — AI Agents Market — $48.3B by 2030 at 43.3% CAGR.
Persistent Session Management
- tmux(1) Manual Page — Authoritative reference for
new-session,respawn-pane,has-session,list-panes, etc. - tmux GitHub Wiki — Getting Started and Advanced Use, including respawn semantics.
Systemd Configuration
- systemd.kill(5) Manual — Definitive reference for
KillMode(control-group, mixed, process, none) and the documented warning aboutKillMode=process. - systemd.service(5) Manual —
Type=notify,Restart=,WatchdogSec=directive documentation. - sd_notify(3) Manual — Readiness and watchdog signal protocol used by
Type=notifyservices. - journalctl(1) Manual — Per-unit log inspection.
Chat Platform Documentation
- Discord Developer Portal — Bot creation, intents (including Message Content Intent), and OAuth scopes.
- Discord.js Documentation — Underlying library used by the discord plugin.
- Telegram Bot API — For Telegram-platform variants of this pattern.
Source Code (Reference Implementation)
- persistent-claude-daemon (GitLab) — The supervisor implementation discussed in this article.
A note on statistics in this article. All cited market figures and dates come from the linked sources. Personal observations (latency anecdotes, deployment specifics, “the buddy’s been running…”) are explicitly framed as such and reflect a single deployment — your mileage will vary.
About the Author
Syed Hasibur Rahman is a physics-turned-AI engineer specializing in geospatial AI systems and ethical technology development. He builds and breaks small tools to keep them honest, and runs his own digital buddy on a VPS in a datacenter he’s never visited.
Originally published on May 10, 2026.
