mineti.dev

Why you need a machine that never sleeps

seed · Aug 9, 2026

Two problems

A note I type on my phone at a bus stop becomes a commit in a git repository a few minutes later, with every one of my devices asleep. It took a server costing about €9 a month to make that sentence true, and the same server fixed a second problem I had filed as unrelated.

The first problem was my knowledge base. I have kept an Obsidian vault since 2021, and for most of those years the pattern was manual at both ends: I wrote the notes by hand and retrieved them by hand, through search, backlinks, and opening one note to find the next. What changed recently is not the notes but the interface to them. I have been reshaping the vault along the lines of Andrej Karpathy’s LLM wiki spec:1 raw sources stay immutable in their own layer, a wiki of interlinked pages sits on top of them, and the model does the writing and the bookkeeping — “you never (or rarely) write the wiki yourself.” Retrieval stops being a search and becomes a question, and a good answer gets filed back as a new page instead of scrolling out of a chat window.

That shift changes what the vault needs from the machine underneath it. A manual vault only has to be open when I am reading it. A vault whose main reader and writer is a model needs something to run that model against it: ingesting sources, updating the pages a new note touches, checking for contradictions and orphans. None of that happens on a laptop that spends the day closed.

Obsidian Sync2 keeps the vault consistent across my devices, but sync only happens between clients that are running. Close the notebook, pocket the phone, and the vault stops converging; it exists as a coherent whole only in the moments when some device happens to be awake. Three consequences follow. There is no continuous history — Sync keeps version snapshots, but nothing like a commit log. There is no backup outside the sync system itself. And, the one that now mattered most, there is no way for anything else to read the vault: the assistant the new pattern depends on has no vault to look at unless one of my devices is open.

The second problem looked unrelated. My personal projects live on a notebook running WSL inside Windows, and the way I build them has shifted to long-running AI coding agent sessions — the working style I described in an earlier article. Those sessions die with the notebook lid too. Away from the desk all progress stops, and there is no such thing as checking on a task from a phone, or letting an agent keep working while I am somewhere else.

Both problems are the same problem. The vault needs a peer that is always online; the projects need a session that never closes. Neither needs the machine to be large.

One small server, two jobs

The answer is a small cloud VPS at Hetzner — a few cores, a few gigabytes of RAM — running Ubuntu and doing both jobs at once. That €9 buys the machine and nothing else: the assistant subscription that makes any of it useful is a separate line item, and a larger one. Anyone pricing this should count both.

A notebook and a phone, grouped as my devices, share a private Tailscale mesh with an always-on server, drawn as a dashed boundary. Outside the mesh, notes merge through Obsidian Sync, the server commits the vault to a private GitHub repository, and the agent reaches task, mail, and calendar services — all outbound, the only connections that cross the boundary.
The dashed line is the private mesh: devices and server sit inside it, and nothing outside it can open a connection inward. Every arrow crossing it points outward — notes merging through Obsidian Sync, vault history going to GitHub, and the everyday services the agent reaches on my behalf.

The defining property of the setup is that the server is dark to the internet. The cloud firewall is default-deny inbound; the only thing allowed through is Tailscale’s UDP port, carrying the encrypted mesh that connects my devices to the server.3 SSH exists only inside that mesh, so there is no public port to find, scan, or brute-force. If the mesh ever fails, the provider’s web console is the out-of-band way back in.

The vault gets a resident peer

The server joins the same Obsidian Sync mesh as my devices — headlessly, via Obsidian’s official command-line client,4 running as a system service that survives reboots and needs no session attached. From the vault’s point of view it is just another device, one that never sleeps. Any two devices now sync through a peer that is always online.

Then the server does what my devices never could: it puts the vault under version control. Every fifteen minutes a timer commits whatever changed and pushes to a private GitHub repository. That is the bus-stop sentence from the top of this piece, and this timer is what makes it true. It is worth being precise about what that history is and is not — the commits are machine-made on a clock, with no messages worth reading, so git log here is not a narrative of how my thinking evolved. It is a backup that can be rewound to any fifteen-minute slice, which is a more modest thing. The two layers stay cleanly separated: Obsidian Sync handles multi-device merging of notes, git handles history and backup. And because the server is the only machine that ever commits, merge conflicts are impossible by construction. One writer, no races.

The vault also becomes something an agent can work with, which is what the wiki pattern was asking for all along. An agent on the server can read the notes, answer from them, and file what it learns back as new pages at any hour. In practice this is on demand rather than automatic: the wiki operations live in dedicated skills5 — packaged instructions an agent loads when they are relevant — and I invoke them when I have sources to ingest or want the pages tidied. A timer that does the upkeep unattended is the obvious next step, and does not exist yet.

One boundary was drawn before any of this went live: a private folder of the vault never reaches the server at all, and is excluded a second time in .gitignore so it could not reach GitHub even if the sync configuration regressed. The cost is that this folder is recoverable only from my devices and Sync’s own version history.

Projects get a place that never closes

The second job is hosting the development sessions themselves. The structure is deliberately old-fashioned: tmux,6 with one long-lived session per project, each running a coding agent. On top of SSH sits mosh,7 which keeps the connection alive across network switches — walk out of Wi-Fi coverage mid-session and the terminal is still there when the phone picks up cellular.

The phone is the part that changes the experience. Blink Shell over the mesh gets me into any session from anywhere, and Claude Code’s Remote Control pairing8 makes the phone a first-class client: sessions push a notification when the agent finishes or needs a decision, and I can read the result and answer from wherever I am. There is no web IDE in this setup, and that is not an omission. An agent-driven workflow is what makes a phone a usable development client at all, because the work you do from a phone is reading, deciding, and directing, none of which needs an editor.

Nothing else moved to the server. Pushes to a project’s main branch still deploy through the same pipelines as before, and the server holds no deployment credentials.

What the plan didn’t survive

The design was written in one sitting, and execution corrected it in several places.

The location changed at the checkout page. The original plan chose a US datacenter for lower latency. Between planning and provisioning, Hetzner’s mid-2026 price adjustment left US locations several times the price of European ones, which inverted the decision. The European server adds real round-trip latency and it turns out not to matter: mosh’s local echo hides it while typing, and an agent-driven workflow is not latency-sensitive. You send intent and read results, and the milliseconds in between are lost inside the model’s thinking time anyway.

The fancy option lost to the boring one. Tailscale ships its own SSH, where the mesh itself authenticates you. It would have been one less thing to configure, but it breaks mosh, whose bootstrap needs a real SSH daemon on the other end. Plain OpenSSH over the mesh won. Relatedly, fail2ban — reflexive on any public server — was skipped, because with no public SSH there is nothing for it to protect.

The backup plan is that there is almost nothing to back up. Code re-clones from GitHub, the vault re-syncs from Obsidian Sync, and everything of value exists redundantly off the box, so a single manual snapshot replaced the provider’s paid automated backups. That covers losing the machine. It says nothing about someone else gaining it, and the box does hold things worth stealing: a mesh key, sync credentials, write access to the repository that holds my entire knowledge base, and — once the integrations landed — OAuth tokens for three more services. Near-stateless is a claim about recovery, not about confidentiality. Confidentiality is the job the closed front door does.

The first version of the auto-commit script had a quiet bug. It exited early when nothing had changed, which meant a failed push would strand its commits not until the next timer tick but until the next content change. The fix is a one-liner: push unconditionally, so the cheap redundant operation un-strands the failed expensive one.

The private-folder exclusion was tested by proving the positive first. The initial full sync ran unrestricted, confirming the private folder did land on the server — proof the pipeline could carry it. Only then was the exclusion enabled, the folder removed, and the negative verified from both directions: it never reappeared, and a fresh file created in it on the desktop never arrived, even transiently. A test that something never happens is only convincing after you have watched it happen.

The agents run without approval prompts. Each session runs with permission checks disabled — an explicit decision, not a default. On my notebook an agent asks before touching anything consequential; on the server, waiting for approval would defeat the purpose of sessions that make progress while I am away. What made that defensible was that the work they did there was recoverable work: the vault and the code are both under version control, so a bad agent action is a git revert rather than a loss. Autonomy came after the blast radius was made small, in that order.

The job I didn’t plan for

Once a machine is always on and already running an agent, you start asking it for things that have nothing to do with code. The sessions on the server now reach my task manager, my mail, and my calendar through MCP — the Model Context Protocol, an open standard for connecting an assistant to an external system9 — with one server each for Todoist, Gmail, and Google Calendar. Mail is deliberately scoped to reading and drafting; the agent cannot send on my behalf.

What that adds is not really automation; it is adjacency. Notes, tasks, mail, and calendar are the four places my week actually lives, and they were four apps I switched between, holding the connections between them in my head. An agent that reaches all four can hold them instead: find the mail thread that explains why a task exists, check what is due against what the calendar says the day can actually hold, draft the reply, file the follow-up, and write the result into the vault it already syncs.

In practice this is ad-hoc rather than scheduled. I ask it things in passing, from the phone: move this meeting and tell me what it collides with, find what someone said about this last month, turn that thread into a task with the right date on it. It works while I am doing something else, and the notification when it finishes arrives on the same channel as the coding sessions. There is no morning digest and nothing running on a cron — just something I can ask at the moment I would otherwise be making a mental note to deal with it later.

The same idea from the other end

I am not the only one who wanted this. OpenClaw — Peter Steinberger’s self-hosted personal assistant, and one of the most widely deployed pieces of personal AI infrastructure to appear in 2026 — starts from the same premise: your own always-on machine, your own data, an agent that is reachable when you are not at a desk.10 It arrives from the opposite direction, though. Its product is the bridge to the chat apps you already use: you run one gateway process and then message the assistant on WhatsApp or Telegram like a coworker. Mine exposes a terminal on a private network, and grew assistant duties only because it was already there running my code.

Most of that difference is ergonomics, and OpenClaw wins the part it optimizes for. Messaging an assistant in an app you already have open beats opening a terminal for “move my Thursday meeting,” and it isn’t close. What my version buys instead is a real shell in a real repository, which the coding half of the job needs and a chat window cannot provide.

One difference is not ergonomic at all, and it is why the boundary in the diagram matters. A chat-bridge design gives the assistant a public identity, an address the outside world can send messages to. Mine has none: nothing outside the mesh can start a conversation with the agent, because nothing outside the mesh can reach it at all. The verdict on that distinction arrived fast. Researchers catalogued tens of thousands of OpenClaw instances sitting exposed on the public internet,11 and showed that a single crafted email or web page could walk an exposed one into handing over SSH keys and API tokens, alongside a run of CVEs covering command injection and prompt-injection-driven code execution.12 None of that is an indictment of the idea. It is what happens when an agent with full system access acquires an inbound door.

Which brings back the decision to run my own agents without approval prompts. Two things carry it, and neither is the one I would have named first. The closed front door removes an entire category of attack: my agent cannot be found by scanning, addressed by a stranger, or reached by anyone not already on my mesh. And where an action would be genuinely irreversible, the limit is a capability rather than a prompt — the mail integration can read and draft but not send, so the worst case is a draft I delete rather than a message my contacts receive. A permission prompt I would have clicked through anyway is a weaker guarantee than a scope that makes the action impossible.

The same private-network boundary seen twice. An inbound connection from the internet stops at the boundary and is marked with a cross: nothing outside can scan, address, or connect to the agent. But the mail channel the agent itself opens crosses the boundary freely, and the text it carries back reaches the agent, which holds a shell and credentials.
The same boundary doing two different jobs. An inbound connection has nowhere to land — nothing outside can scan for the agent, address it, or reach it at all. But the channels the agent opens carry text back across, and a message written to hijack an assistant arrives as ordinary mail.

What none of that touches is the content. The moment the agent started reading my inbox, attacker-controlled text began arriving on the inside of the boundary: a message written to hijack an assistant does not need a port, it needs an assistant that reads messages. The mail scope lowers the ceiling on what a successful injection could achieve, but it does not stop one from being attempted, and the agent on the other side of it still has a shell. That is the unsolved part of this setup, and I would rather name it than let a dashed line in a diagram imply it is handled.

The notebook’s demotion

The unexpected result is what happened to the local machine. The notebook — WSL inside Windows — did all the bootstrapping, and the rule from the start was that it must never be needed again: the remote environment depends on GitHub, on Obsidian Sync, and on the mesh, but on no particular client device. It went from the center of my computing to one client among several, and the cheapest machine I own became the one everything else depends on being awake.

That may be one step from its final form. I am considering buying a physical server and running all of this on hardware I own, for reasons that accumulated rather than arrived at once. The €9 is only the machine, and once the assistant subscription is counted the monthly total is large enough that owning hardware changes the arithmetic. Concurrent agent sessions and an accumulating vault want more memory and disk than is economical to rent indefinitely. A box I own is a box where the vault and those OAuth tokens are not sitting on someone else’s computer. And with real hardware underneath, some of this could run on models I host rather than models I call, which would close the last dependency the setup has on anyone else’s uptime.

Meanwhile the rented box is doing the one thing a spec sheet cannot: telling me what I actually use. How much memory the sessions really need, how much disk the vault really accumulates, what sits idle. When that picture settles it becomes the configuration worth buying — and because the box is deliberately close to stateless, moving there is the same procedure as recovering from losing it: run the setup again, pointed at a server that is mine.

References

  1. Karpathy, A. LLM wiki spec. GitHub Gist. https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f

  2. Obsidian. Obsidian Sync. https://obsidian.md/sync

  3. Tailscale. How Tailscale works. https://tailscale.com/blog/how-tailscale-works

  4. Obsidian. obsidian-headless: official headless client for Obsidian Sync. GitHub. https://github.com/obsidianmd/obsidian-headless

  5. Anthropic. Introducing Agent Skills. https://claude.com/blog/skills

  6. tmux: a terminal multiplexer. GitHub. https://github.com/tmux/tmux/wiki

  7. Winstein, K. & Balakrishnan, H. Mosh: the mobile shell. https://mosh.org

  8. Anthropic. Continue local sessions from any device with Remote Control. Claude Code documentation. https://code.claude.com/docs/en/remote-control

  9. Anthropic. Introducing the Model Context Protocol. (2024). https://www.anthropic.com/news/model-context-protocol

  10. OpenClaw. Your own personal AI assistant. https://openclaw.ai

  11. Bitsight. OpenClaw Security: Risks of Exposed AI Agents Explained. (2026). https://www.bitsight.com/blog/openclaw-ai-security-risks-exposed-instances

  12. The Hacker News. OpenClaw AI Agent Flaws Could Enable Prompt Injection and Data Exfiltration. (2026). https://thehackernews.com/2026/03/openclaw-ai-agent-flaws-could-enable.html

← All articles