Daemon
install/uninstall/run/status/logs/doctor/drain/update. Multi-project and multi-org daemon.
rensei host is the command group for everything that belongs to this machine: the daemon process, the local capacity envelope, workarea pool, installed providers, and kits. This page covers daemon lifecycle - install, run, status, logs, health checks, graceful drain, and update - including multi-project and multi-org daemon configuration.
The legacy daemon command tree is retired. Use the rensei host commands on
this page for every lifecycle operation, including rensei host run for a
foreground daemon.
Architecture
The Rensei daemon (rensei host run) is a long-running process that:
- Registers this machine with the Rensei platform as a worker host using an org-scoped install token.
- Polls the platform for dispatched agent sessions and spawns them locally.
- Exposes a local HTTP control API on
127.0.0.1:7734used by all otherrensei hostcommands. - Manages the local workarea pool, credential socket, and capacity envelope.
Install
Register the daemon as a system service so it starts automatically at login and survives reboots. Installation owns only the operating-system service lifecycle; enable platform projects separately with rensei host project enable <slug>.
rensei host install
# With an explicit binary path
rensei host install --bin-path /usr/local/bin/rensei
# Enable projects after the service is installed
rensei host project enable my-project-slug
rensei host project enable alpha
rensei host project enable betaRegisters a launchd LaunchAgent under gui/<uid>/dev.rensei.daemon.
rensei host install --userRegisters a systemd user unit (dev.rensei.daemon.service). Starts automatically at user login.
sudo rensei host install --systemRegisters a system-scoped systemd unit. Requires sudo. Starts at boot for all users.
Flags
| Flag | Default | Description |
|---|---|---|
--bin-path | current executable | Path to the rensei binary the service will execute |
--user | (macOS: n/a; Linux: default) | Install as user-scoped systemd unit |
--system | - | Install as system-scoped systemd unit (requires sudo on Linux) |
--config | ~/.rensei/daemon.yaml | Path to daemon config file |
host install always wipes ~/.rensei/daemon.jwt so the daemon performs a clean registration on its first boot. This prevents the "Worker not found" 404 loop that occurs when a stale JWT outlives its worker registration.
Repeatable installs
rensei host install is repeatable and idempotent at the OS service level. Re-running it rewrites the plist/unit file and reloads the service atomically. Project admission is updated with rensei host project enable, without reinstalling the service.
Multi-project daemon
A single rensei daemon serves multiple projects at once. One daemon process handles session dispatch for all registered projects on the machine.
Adding a project
# Enable additional projects - daemon serves alpha AND beta
rensei host project enable alpha
rensei host project enable betaEach enable resolves the slug to its canonical platform ID and adds it to the daemon's registration claim set. Bind repositories separately with rensei project repo add; a project may be enabled before it has a repository.
# Add one more project without re-installing the service
rensei host project enable gammaUse rensei host project list to inspect the enabled set and rensei host project disable <slug> to remove admission for one project.
Context defaults vs explicit flags
--org and --project are root context flags. Prefix a host command with them when the invocation must target a specific organization or project. rensei setup, rensei auth activate, and rensei org activate set saved defaults without changing host admission.
# Per-command context override - does not change the active project
rensei --org acme --project gamma host statusViewing registered projects
rensei host status --json | jq .projectsAllowedThe projectsAllowed field counts the projects in the daemon's allowlist.
Multi-org daemon
One daemon process serves sessions for multiple Rensei orgs. Each org is configured as an independent satellite: its own daemon config file and JWT, but sharing the same OS service process.
Adding a satellite org
First, authenticate against the satellite org:
rensei auth add --org partner-co --user # browser login for partner-coThen enable its project through the satellite org context (no service re-registration):
rensei --org partner-co host project enable partner-projThis adds the project to the partner-co host admission set. Session credentials remain isolated by organization; credentials from main-org are never visible to partner-co sessions and vice versa.
# Restart the service to activate the new org config
rensei host restartRemoving a satellite org
rensei --org partner-co host project disable partner-proj
rensei host restartThis removes that project's admission without touching the shared service registration.
Uninstall
Remove the launchd/systemd service registration. Also wipes ~/.rensei/daemon.jwt.
rensei host uninstall # macOS, or Linux user scope
rensei host uninstall --user # Linux user scope
rensei host uninstall --system # Linux system scope (requires sudo)Deregister and Restore
New in v0.9.0. Unlike install/uninstall, which manage the local OS service, deregister and restore manage a host's record in the platform's capacity inventory - the row that makes the host appear in rensei capacity show and eligible for routed work. Both are admin/owner-gated, org-scoped (a host belonging to another org 404s exactly like an unknown one - existence is never leaked), and accept a host reference: the platform's exact host id, or the machine id / hostname printed by rensei host status or rensei capacity show. If more than one host matches, the command refuses rather than guessing - pass the exact host id to disambiguate.
rensei host deregister <host-id|machine-id|hostname>
rensei host deregister <host-id|machine-id|hostname> --force
rensei host deregister <host-id|machine-id|hostname> --yesSoft-deletes the host record. The platform refuses with 409 when the host is still live (a recent heartbeat) or has active sessions - pass --force to override either. A confirmation prompt is shown by default; --yes skips it, and is required whenever stdin is not a TTY (scripts must opt in explicitly).
rensei host restore <host-id|machine-id|hostname>Undoes a deregistration. The platform refuses with 409 when the host has no recent heartbeat - its daemon is gone, so restoring the record would just create a new phantom entry that the platform's stale-host reaper would delete again on its next pass. Restoring an already-live host is idempotent and reports success rather than erroring. There is deliberately no --force for restore: start the daemon, then restore.
Both refusals return a structured 409 body with a machine-readable reason field the CLI renders as plain English rather than a bare "conflict":
{
"error": "Host is offline (last heartbeat 2026-08-01T09:14:02Z). Restoring it would put a row back in the fleet that the stale-host reaper deletes again on its next pass. Start the daemon, then restore.",
"reason": "host_offline",
"health": "offline",
"lastHeartbeat": "2026-08-01T09:14:02Z"
}deregister's known reasons are host_live and host_has_active_sessions; restore's is host_offline. A reason this CLI version doesn't recognize falls back to the platform's own message text rather than a bare "conflict" error.
A host soft-deleted by the platform's own stale-host reaper (no heartbeat for the configured offline window) self-heals automatically the next time its daemon re-registers or sends a heartbeat - restore is rarely the normal recovery path for a reaped host. Reach for it to reverse an operator-run host deregister.
Foreground Run
Run the daemon interactively without registering a system service. Useful for debugging or CI environments.
rensei host run
rensei host run --config /path/to/daemon.yaml
rensei host run --port 7734 --skip-wizardFlags
| Flag | Default | Description |
|---|---|---|
--config | ~/.rensei/daemon.yaml | Daemon config file |
--jwt-path | ~/.rensei/daemon.jwt | Cached JWT path |
--host | 127.0.0.1 | HTTP bind host |
--port | 7734 | HTTP bind port |
--skip-wizard | false | Skip the interactive first-run setup |
SIGTERM and SIGINT trigger a graceful drain (60 s timeout).
Status
Check whether the daemon is running and healthy.
rensei host status
rensei host status --jsonSample output:
Daemon: ready
Machine: wkr_01hq...
Version: 0.11.2
PID: 12345
Uptime: 4h23m
Sessions: 2 / 8
Projects: 1 allowed
Ruleset snapshot: org_...@42 age=1m30s
Timestamp: 2026-06-02T14:00:00ZThe Ruleset snapshot: line only appears when this daemon has a
ruleset-snapshot source configured (a rulesetSnapshot: block in
daemon.yaml, or RENSEI_RULESET_SNAPSHOT_ENABLED) - it shows the
{orgId}@{revision} currently cached and its age, with (degraded)
appended once that age crosses the configured threshold. Its absence means
this daemon has no snapshot source configured, not that anything is wrong;
self-hosted, single-machine installs never print it. This is the same
staleness contract described in full on
Routing Durability & On-Prem Posture -
the line is this command's window onto it, not a separate mechanism.
With --json:
{
"status": "ready",
"machineId": "wkr_01hq...",
"version": "0.11.2",
"pid": 12345,
"uptimeSeconds": 15780,
"activeSessions": 2,
"maxSessions": 8,
"projectsAllowed": 1,
"timestamp": "2026-06-02T14:00:00Z"
}rensei host status shows the daemon's self-reported state. If the daemon is stuck in a JWT/worker-not-found loop, it may report "healthy" while every platform poll fails. Always confirm with ~/Library/Logs/rensei/daemon-error.log (macOS) when you suspect registration issues.
Logs
Stream or tail the daemon log file.
rensei host logs # last 50 lines, pretty-printed
rensei host logs --follow # stream new lines (like tail -f)
rensei host logs -n 200 # last 200 lines
rensei host logs --file /path/to/daemon.log
rensei host logs --raw # raw NDJSON without pretty-printingFlags
| Flag | Default | Description |
|---|---|---|
-f, --file | ~/.rensei/daemon.log | Log file path |
-F, --follow | false | Stream new lines as they arrive |
-n, --lines | 50 | Number of lines to show (0 = all) |
--raw | false | Print raw NDJSON without formatting |
NDJSON lines with time, level, and msg fields are formatted as 2026-06-02T14:00:00 [INFO] message. Other lines are printed as-is.
For daemon errors routed by launchd to stderr:
tail -f ~/Library/Logs/rensei/daemon-error.log # macOS
journalctl --user -u dev.rensei.daemon -f # LinuxDoctor
Run a health-check suite on the installed daemon setup. Exits 0 when healthy, non-zero when the service is not installed or misconfigured.
rensei host doctor
rensei host doctor --json
rensei host doctor --user # inspect user-scoped systemd unit (Linux)
rensei host doctor --system # inspect system-scoped unit (Linux)Sample output:
OS: darwin
Service path: ~/Library/LaunchAgents/dev.rensei.daemon.plist
Service installed: true
Service active: true
Host binary: /usr/local/bin/rensei
Binary present: trueStart and Restart
rensei host start and rensei host restart are available on the host surface (added in v0.7.17). They signal launchd/systemd to start or restart the registered service:
rensei host start # start the registered service (no-op if already running)
rensei host restart # stop and re-start the servicerensei host restart re-executes the binary currently baked into the launchd plist. After a brew upgrade rensei, always run rensei host install (not just restart) to rewrite the plist with the new Cellar path before restarting. See the Update section below.
Pause and Resume
Temporarily stop accepting new sessions without stopping the daemon process. In-flight sessions continue until they complete.
rensei host pause # stop accepting new sessions
rensei host resume # re-enable accepting sessionsDrain
Gracefully drain in-flight work before stopping. Sends a stop-accepting signal, waits for all running sessions to complete, then shuts down.
rensei host drain # use daemon's configured drain timeout
rensei host drain --timeout 120 # cap drain at 120 secondsUse drain before planned maintenance to avoid interrupting active agent sessions:
rensei host drain --timeout 300 && rensei host stopStop
Stop the daemon process immediately. In-flight sessions are interrupted.
rensei host stopUpdate
For Homebrew-managed installs (the standard install path), rensei host update detects Homebrew and prints the correct two-step upgrade flow rather than attempting a self-download:
brew upgrade rensei # 1. Install the new binary
rensei host install # 2. Rewrite the plist with the new binary path and reloadWhy two steps? The launchd plist stores the resolved Cellar path at install time (e.g. /opt/homebrew/Cellar/rensei/<version>/bin/rensei). After brew upgrade, that path is stale - the old binary is still running. rensei host install rewrites the plist to the new Cellar path and runs bootout+bootstrap+kickstart so the daemon immediately executes the upgraded binary. Running rensei host restart alone would re-exec the old binary from the unchanged plist.
# If you want to skip the brew detection and send the daemon's built-in update signal directly:
rensei host update --force--force bypasses the Homebrew check and sends the daemon's built-in self-update signal. Not recommended for Homebrew installs.
Setup Wizard
Run the interactive first-run configuration wizard. Persists configuration to ~/.rensei/daemon.yaml. Automatically skipped when stdin is not a TTY.
rensei host setupConfig Files
| Path | Purpose |
|---|---|
~/.rensei/daemon.yaml | Daemon config: capacity, allowlist, orchestrator.authToken |
~/.rensei/daemon.jwt | Cached worker JWT; wiped on host install/host uninstall |
~/.rensei/daemon.log | Daemon stdout log (tailed by host logs) |
~/Library/Logs/rensei/daemon-error.log | macOS launchd-routed stderr |
Daemon HTTP API
The daemon listens on 127.0.0.1:7734 (configurable with --port). All rensei host subcommands use this address. You can also query it directly:
curl http://127.0.0.1:7734/api/daemon/status
curl http://127.0.0.1:7734/api/daemon/stats
curl -X POST http://127.0.0.1:7734/api/daemon/pause
curl -X POST http://127.0.0.1:7734/api/daemon/drainOverride the address for all subcommands with --host and --port flags.
Related Pages
- Host Capacity - Per-host session limits, pool disk quota, eviction
- Credential Socket - How the daemon delivers credentials to agent processes
- Capacity - View every host in the org, configure project routing, pools, providers, cost explorer