Orbit Server & the Steward Architecture
One resident daemon per machine, one control plane for all of them. Core authors everything — agents, policies, reflexes, credentials. The edge enforces and executes, and keeps working from a signed local cache when core is unreachable.
1 · Principles
- Core authors, edge enforces and executes. Every artifact on the box — persona, tool policy, allowlists, reflex rules, credentials — is a synced projection of core state, never hand-managed. Drift is structurally impossible.
- Credentials are leases, not files. Short-lived, renewed through the sync channel, scoped per device. A lease that stops renewing expires; nothing rots half-alive.
- Defer, never self-approve. A gated action with core unreachable queues and pings on reconnect. Only deterministic reflexes act unattended.
- Orbits are peers. Each daemon pairs with its steward instance directly. Core load scales with humans and approvals, not machines × tool-calls.
- The watcher lives below the stack it watches. Sentinels and reflexes run in the daemon, beneath k8s, containers, and monitoring — they survive what those cannot.
2 · Topology
Cross-steward: no machine is stewarded by an instance it hosts. The 2026-07-31 gondor outage took down the responder with the platform; this makes that impossible.
flowchart LR
subgraph eda [machine · eda]
OE[orbit-server]
AE[(agenteda instance)]
end
subgraph gondor [machine · gondor]
OG[orbit-server]
end
subgraph rentamac [machine · rentamac]
OM[orbit-server · macOS headless]
end
NC[(neutroncore instance)]
OE -- pair + link --> NC
OG -- pair + link --> AE
OM -- pair + link --> AE
AE <-. constellation ask_peer .-> NC
D[Discord · web · voice] --- AE
D --- NC
Mac orbit-desktop and orbit-server share one crate: cargo features
orbit-desktop (UI, voice, wake) and orbit-server (headless: exec,
sentinels, reflexes). One pairing model, one link protocol, one release train —
and orbit-server runs on any OS, including headless Macs.
3 · The daemon
flowchart TB
subgraph daemon [orbit-server]
LINK[link · outbound WebSocket]
CACHE[signed artifact cache]
LOOP[steward loop · minimal Rust agent loop]
EXEC[exec · streaming, pty, async jobs]
SEN[sentinels · local probes → events up]
REF[reflexes · deterministic rules, no LLM]
WAL[audit WAL · spools, ships up]
end
CORE[(steward instance)]
CORE -- artifacts + leases --> CACHE
CACHE --> LOOP & REF & SEN
SEN -- events --> CORE
LOOP --> EXEC
REF --> EXEC
EXEC --> WAL --> CORE
LINK <--> CORE
The steward loop is a purpose-built minimal agent loop in Rust — not a port of the TS engine. It reads the cached persona and policy artifacts, calls the model through a leased credential, and drives local tools. Rich orchestration (teams, packs, controllers) stays core-side and reaches the machine through the same exec surface.
4 · Sync plane
| Direction | Artifact | Notes |
|---|---|---|
| core → edge | agent identity + persona | the steward's system prompt, versioned |
| core → edge | tool policy + command allowlists | same data core enforces; dual evaluators (TS + Rust) |
| core → edge | reflex + sentinel rules | authored and approved in core, pushed down |
| core → edge | credential leases | model API, git PAT — TTL-bound, auto-renewed |
| core → edge | device token rotation | the pairing credential itself renews in-band |
| edge → core | audit WAL | every exec + reflex firing; survives partition |
| edge → core | sentinel events | start agent turns via the existing headless-turn seam |
| edge → core | health heartbeat | silence itself is an alert on the core side |
Sync is push-on-change from core plus periodic pull from the edge; artifacts are signed so the daemon rejects anything not authored by its instance.
5 · Degraded-mode ladder
| Condition | Reasoning | Gated actions | Reflexes |
|---|---|---|---|
| core reachable | full steward | approval cards (Discord / web / voice) | run |
| core down · internet up | cached-policy loop | defer → queue, ping on reconnect | run |
| full partition | none (model API unreachable) | defer | run — the only thing that can |
The ladder is the whole argument for this architecture: the July 31 outage sat in row three
for thirty-five minutes with zero automated response. A reflex rule
(nspawn unit failed + start-limit → clear stale registration, restart) closes
that class in minute one.
6 · Governance
sequenceDiagram
participant L as steward loop
participant P as policy cache
participant C as core (approvals)
participant X as exec
L->>P: evaluate(command)
alt allowlisted
P-->>L: allow
L->>X: run
else gated
P-->>L: gate
L->>C: approval card
C-->>L: approve / deny / timeout=deny
L->>X: run (if approved)
end
X->>C: audit record (via WAL)
- Policy artifacts are data, not code — simple enough for identical evaluation in Rust (edge) and TS (core). Command prefix + argv-hash allowlists reuse the shape core's guardrails already have.
- Per-device dial:
drive_mode off / ask / autoalready exists for orbit devices — ask is the shipping default, auto is earned per-command via allowlists. Full power over the machine, throttled by governance, tuned over time. - New authz action
device.execscoped todevice:<id>, so instance policy can grant or deny whole machines per agent. - Approval timeout = deny. No approval channel = deny. Reflexes are the only unattended writes, and each firing is audited like an exec.
7 · What the steward does all day
- Responds — Alertmanager webhooks (new generic hook trigger in core) and sentinel events start turns; the agent investigates and remediates under the dial.
- Patrols — scheduled sweeps: disk/inode trends, cert and credential lease expiry, drift between IaC and live state, failed units, stale backups.
- Repairs — IaC-first through MRs and CI applies; imperative only for transient artifacts; everything audited.
- Reports — to Discord, with approval cards where the dial says so.
- Later: the doorway — the daemon's local socket doubles as a terminal
interface to the instance (
orbit ask "…") from any stewarded machine.
8 · Open questions
- Steward-loop scope: which tool surface ships in the minimal Rust loop (exec + file + journal is enough to start) and where is the cut line before things belong core-side?
- Policy artifact schema: one format serving guardrails (core) and the Rust evaluator — needs a spec before either side is built.
- Lease TTLs and the offline grace window: how long may a cached model lease outlive core contact before the loop stands down to reflex-only?
- Reflex rule language: how expressive before it stops being auditable? (Bias: trivially small — condition on unit/metric state, action from a fixed verb set.)
- Exec protocol details: pty, streaming backpressure, async job detach/reattach, output caps for the audit WAL.
- Does the WhatsApp-hardened guest-identity ladder apply to the pairing flow, or is device pairing already sufficient?
9 · Phasing — build order, no stopgaps
- Protocol + skeleton. orbit-server profile: pairing, link, signed
artifact cache, exec frames, audit WAL. Core:
device.execaction, artifact compiler, exec governance path. First stewarded machine: eda, paired to neutroncore. - Steward loop + leases. Minimal Rust loop, model-credential leasing, degraded-mode rows one and two live. Generic webhook trigger in core; gondor's Alertmanager gains the neutron receiver alongside hermes.
- Sentinels + reflexes. Probe rules, event-triggered turns, the reflex engine with core-authored rules. Row three of the ladder closes.
- IR team pack + incident controller. Triage / diagnose / remediate / review as a controller (sibling of the coding-team controller), packaged like the dev-team pack. Hermes retires to a chat surface or is decommissioned.
- The doorway. Local-socket CLI onto the instance from any stewarded machine.