Skip to content
GurtOS

Architecture

GurtOS is an operating system for a computer whose main users are AI agents. It runs on Ubuntu 24.04. Everything that makes it GurtOS is one service, the core, plus a handful of system parts around it: the box's own screen, first-boot setup, and whole-system updates.

This page names the parts and how they talk to each other. The pages after it explain each part in depth.

Architecture Your devices reach the box service's API. The box service runs as root and holds the API, the action log, the apps, the vault, a broker for each task and the network proxy. SpacetimeDB mirrors live state. Each task runs as its own Linux user and reaches the core only through its broker socket and the outside world only through the proxy. Portal in a browser The box's screen Phone HTTP API and live updates The box: one machine The core: the box service, runs as root API 127.0.0.1:7700 Action log append-only, fsynced Apps tools, triggers, routes Vault root only Broker one socket per task Proxy each task's allowed hosts mirrors live state SpacetimeDB tasks, approvals port 3000 Tasks: each its own Linux user Task A own copy of the files no keys Task B own copy of the files no keys Unix socket network Outside APIs tools call with vault keys Allowed hosts and the model service
Your devices talk to the core's API. Each task runs as its own user in its own copy of the files, and reaches the core only through its broker socket and the internet only through the proxy. On an installed GurtOS the API also answers private networks on port 7700, so phones on the same network can pair; from anywhere else it answers only through a relay.

The core is one Node.js process, box.service, running as root. It is the only part of the system that can read secrets, create users and mount file systems. It does six jobs:

  • The API. An HTTP server on port 7700 for the portal, the phone and other programs. It listens on 127.0.0.1 unless you set BOX_LISTEN. A machine installed from a GurtOS ISO, Server or Personal, listens on every address, and its firewall lets only private networks reach port 7700. A request from the box's own screen (the machine itself, with no proxy in between) is trusted. Any other request needs a paired device's token. See the HTTP API. While setup is open, the core also listens on port 7701 (BOX_SETUP_PORT), so you can set the computer up from another one. It forwards to the same API, and every request needs the setup token. It closes when setup finishes, when you stop it, or after two hours. It is plain HTTP, so the firewall opens it to private networks only, like 7700. Set a cloud computer up from its provider's console or over a private network such as Tailscale.
  • Tasks. It creates a Linux user for each task, mounts the task's own copy of its workspace, and starts the worker as a hardened systemd unit.
  • One broker per task. A Unix socket that only that task's user can open. It is the task's only way to reach the core: to log a step, call a tool, ask for an OK, or report cost.
  • The vault. A root-only file of secrets. Tools run inside the core and read the secrets they declare. Tasks never do.
  • The proxy. The only network path a task has. It lets each task reach only the hosts in its spec, and logs every refusal.
  • The action log. An append-only file of every event. At boot the core rebuilds every task and approval from it.

The core also loads apps. An app is a folder that plugs tools, triggers, log readers, model jobs, pages and routes into the core. An app's pages open in a sandbox with a token of their own. See apps and slots.

A task is one piece of agent work. The worker inside it is Factory's Droid with a Claude model, or a scripted fake worker used by the test suite. The worker runs:

  • as its own Linux user, box-<id>, with a uid from 30000 to 39999, no password, no shell and no sudo;
  • in its own overlayfs copy of a workspace, so its changes stay in its own layer until it finishes;
  • inside a systemd unit that hides other processes, gives it a private /tmp, blocks D-Bus and caps it at 2 GB of memory.

A worker holds no secrets. Droid needs a model key, either a Factory API key or your own Anthropic key, so the task gets a placeholder. The proxy swaps in the real key on the way out. See agents as their own users and the vault and the broker.

SpacetimeDB runs on the box on port 3000. Two public tables, task and approval, mirror the core's tasks and approvals, so the box's own screen sees updates the moment they happen. Smaller tables keep counters and per-minute activity. SpacetimeDB has no login, so it listens on 127.0.0.1 by default. A phone or a laptop follows the box's log stream over the authenticated API instead.

The mirror is a convenience, not the record. If SpacetimeDB is down, tasks keep running and the portal falls back to the log stream. When it comes back, the core refills it. See live updates.

  • The portal is a web app the core serves from the same address as the API.
  • The box's own screen on GurtOS Server is a full-screen browser that shows the portal's box screen, which the core serves at /screen. It has no desktop and no login prompt.
  • A phone or a laptop opens the portal at the box's address. Pairing gives it a device token, which every request from it carries, and the log records which device said yes. See approve from your phone.

Other programs can drive the box too, through the same API and the same approvals as the portal. Optional apps connect it to outside services such as Jira, Elastic and ASI:One. Each needs that service's account.

On a machine installed from a GurtOS ISO, the core is part of a fixed system:

  • On GurtOS Server there is no human account. Root's password is locked and there is no sudo binary. On GurtOS Personal the person who owns the computer has an account with sudo; task users never do.
  • box-firstboot makes the box's identity key and an empty vault on first start. The box's id is the first 6 hex digits of the SHA-256 of its public key, and the machine is named gurt-<id>, for example gurt-bf07fe, unless a name was already chosen (on Personal, the owner's). The core uses the machine's name as the box's id.
  • The disk has two system slots, A and B. An update writes the other slot, starts it once, and keeps it only if the box reports healthy. See system updates.

You can also install the core on an existing Ubuntu 24.04 machine. That gives you the same tasks, vault, log and API, without the A/B updates or the locked-down system. See install on Ubuntu.

Agents need real access to do real work: files, the network, paid APIs. The usual way to give that access is to hand an agent your account, your keys and your machine. GurtOS takes the opposite approach. It gives each task the least it needs and puts every privileged act behind the core:

  • Linux users and overlayfs keep one task's files apart from another's, so undo is exact.
  • The broker and the vault keep secrets out of tasks, so a hijacked agent has nothing to steal.
  • The proxy keeps each task to its own hosts, so a hijacked agent has nowhere to send data.
  • The log is written before anything else, so every act is on the record and survives a power cut.