Skip to main content

The daemon

rt runs a small background daemon that keeps a few things warm so interactive commands feel instant instead of shelling out to GitHub, GitLab, and git on every keystroke.

What it does today

The daemon is a long-lived process (managed by launchd) that:

  • Caches MR/branch data. It keeps branch and merge-request caches warm for every registered repo, and commands like rt status read those caches instead of re-fetching from GitLab/Linear on every invocation. How warm depends on the repo's tracking level, set with rt daemon track: live repos hold a realtime events watcher and sync incrementally (with a daily deep reconcile), poll repos refresh on a timer, and off repos are left alone. Consumers can also demand freshness explicitly (a max-age on reads), so a stale cache is refreshed on the spot instead of served as-is.
  • Scans ports. It scans listening ports roughly every 30 seconds, so rt port can show you what's running across your repos with zero configuration.
  • Guards git hooks. For repos where rt manages hooks, it watches each repo's .git/config and re-applies rt's hooks shim path if something else (another tool running git config) clobbers it.
  • Answers status polls. CLI commands and the tray app both query the daemon over a local Unix socket (and a REST/WebSocket API) for cached data and health.
  • Runs the worktree lifecycle. rt worktree's provision/dispose/freshen verbs execute in the daemon, which owns the worktree registry, keeps the on-deck pool replenished, and reacts to merged MRs (auto-return plus guarded auto-dispose of the finished tree).
  • Kills a worktree's workload on dispose. When a worktree is disposed (its feature is done), the daemon finds the dev servers, watchers, and compilers rooted in that worktree, SIGTERMs them, and escalates any survivor to SIGKILL after about 5 seconds. It deliberately spares AI agent sessions (Claude, Codex, and the like) and everything they spawned, plus shells and .app bundle processes, since those aren't workload.
  • Scans for and notifies on runaway processes. Roughly every 10 seconds it scans system processes for anything rooted in a tracked repo, tracks a rolling CPU sample window per process, and notifies once a process has sustained high CPU for long enough (5 minutes above 80% by default, after a 2-minute grace period). AI agent sessions are excluded from this too.

The tray app (menu-bar icon) shows the daemon's health at a glance, polling its status so you can tell at a look whether it's up.

It does not run or supervise your dev servers for you the way the old managed-process feature did, and it does not provide tunnels: there's no "start this script and keep it alive" concept. The process-related behaviors above are reactive (dispose-time cleanup) and observational (runaway detection), not a general-purpose process supervisor.

Installing, starting, and stopping

rt daemon install # install and start the daemon (launchd or background process)
rt daemon uninstall # stop and remove the daemon
rt daemon start # start the daemon
rt daemon stop # stop the daemon
rt daemon restart # restart the daemon

rt verify (the command recommended after a fresh install) also completes daemon setup transparently on first run, so you rarely need to run rt daemon install yourself.

Checking health and logs

rt daemon status # pid, uptime, cached repos, cached ports
rt daemon logs # open the log viewer

rt daemon status reports basic liveness: pid, uptime, how many repos are watched, how many cache entries and ports are cached, and how stale the port cache is.

rt daemon logs opens a browser-based log viewer by default; pass --terminal (or -t) for a live tail in your terminal instead. All daemon (and other rt surface) logs live under ~/.mattstack/rt/logs/; see the logging guide for the file convention and how the viewer discovers them.

See the full command reference: rt daemon, rt daemon status, rt daemon logs, rt daemon track, rt daemon install, rt daemon start, rt daemon stop, rt daemon restart, and rt daemon uninstall.

Background server

The daemon owns a headless herdr server (session name bg) for agents that do not need a visible terminal. Any operation that creates a background pane starts the server automatically; you do not need to manage it yourself.

rt bg status # up/down, socket path, live claims
rt bg release <owner> # release one claim (picker when omitted)
rt bg stop # shut down (refuses while claims are live)

Background panes use a bg: prefix in pane addressing (e.g. bg:w1:p2). All standard pane verbs (rt pane list, rt pane peek, rt pane send, rt pane focus) work with that prefix.

Agents launched with rt agent start --bg run on the background server instead of the visible herdr instance.

Stale-claim sweep

The daemon periodically reconciles its worktree and background-server claims against live state. A claimed worktree whose owning agent has exited, or whose MR has merged, is swept and returned to the pool. The sweep honors a grace period and checks for recent activity, so a momentarily idle agent is not reclaimed prematurely.

Gates

Gates are daemon-persisted decisions that survive restarts. They are primarily agent-facing (the herd orchestrator opens them, workers wait on them), but the user-facing surface is how you answer a pending question or see what is waiting:

rt gate list --open # show pending decisions
rt gate answer <id> # answer one (first answer wins)

rt gate answer --override lets a human answer a gate that belongs to a herd, escalating past the automated owner. Gates whose owner has exited are escalated automatically after their TTL expires.

See the gates guide for the full lifecycle, rt gate ask, option descriptions, and delivery mechanics.

Herds

A herd is a group of workers (coding agents in herdr panes) coordinated by a shepherd. The daemon owns the herd registry, spawns workers, and routes their questions through gates.

rt herd brief

Assembles a worker's job brief from a shepherd skill's template plus a strategy body. The shepherd passes every path explicitly; this is agent-facing and not something you run by hand.

Spawn and folder trust

When a worker spawns, its pane may show Claude Code's folder-trust dialog. The spawn logic reads the dialog, computes the correct accept key, and verifies acceptance. If the dialog persists after a retry, the job is parked at stuck-at-modal, and rt herd status shows STUCK AT TRUST MODAL with remediation instructions.

Dead worker detection

A memory-pressure SIGKILL can remove the Claude process while leaving the pane's shell alive. The herd detects this by checking whether the pane still has a running agent session. When it doesn't, rt herd status reports SESSION DEAD with the respawn command.

Gate-fork hook

Herd spawns stamp the gate subject on the worker environment so each worker gets the gate-fork hook (a Claude Code hook that routes questions through the daemon's gate registry). A worker's own open run-gate is allowed through the hook so it doesn't block on its own question.