Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mental model

What spt-core is, the five or six nouns everything else builds on, and how the pieces fit. Read this once and the rest of the docs are mostly reference.

The shape of the system

spt-core is per-machine infrastructure for agents. One binary (spt) installs on each machine. It carries everything: the CLI, the messaging substrate, the always-available daemon, and the networking layer. Agent harnesses — Claude Code, Codex, Pi (the pi coding agent), anything — plug in through a declarative adapter manifest and a small command surface (spt api …). spt-core never contains harness-specific logic; adapters declare what varies, spt-core does the work.

            machine A                                machine B
 ┌──────────────────────────────┐        ┌──────────────────────────────┐
 │  spt daemon (one per machine)│  QUIC  │  spt daemon                  │
 │  ┌────────┐    ┌───────────┐ │◄──────►│   (paired: same subnet)      │
 │  │ broker │    │   brain   │ │  P2P   │                              │
 │  │ PTYs · │    │ routing · │ │        │   ┌───────┐    ┌─────────┐   │
 │  │ sockets│    │ registry ·│ │        │   │ alice │    │ doorbell│   │
 │  └────────┘    │ lifecycle │ │        │   │(agent)│    │ (shell) │   │
 │                └───────────┘ │        │   └───────┘    └─────────┘   │
 │   ┌─────┐  ┌─────┐           │        └──────────────────────────────┘
 │   │ bob │  │ ling│  ← endpoints (perches live on disk; sessions come
 │   └─────┘  └─────┘     and go, identity persists)
 └──────────────────────────────┘

Endpoints and perches

An endpoint is anything addressable: an agent (bob), a worker, a shell (a driven non-agent surface — a notifier, a robot, a sensor). Every endpoint has a perch: its durable on-disk seat — identity, address, message spool, state. Sessions are ephemeral; perches persist. That split is why a message sent to an offline agent is queued, not lost, and why an agent can be revived days later as the same agent.

Endpoint IDs are adapter-agnostic: bob is bob whether his sessions run under one harness today and another tomorrow.

Messaging

The primitive everything else uses. spt send <id> delivers live when the target is listening, spools when it isn’t; spt ring <id> is the blocking ask (send + wait for the reply); __REPLY_TO__ routing makes answers cheap. Payloads carry typed operations and file blobs, not just text. Try it: the messaging quickstart.

The daemon: broker and brain

One spt daemon per machine owns all shared state: hosted session PTYs, the network identity and endpoint, the registry, every spool, all lifecycle loops. You never manage it — any spt invocation auto-starts it.

Internally it splits in two, and the split is what makes self-update seamless:

  • the broker holds only what must never die: PTY masters, spawned child processes, listening sockets. It almost never updates.
  • the brain holds all logic and restarts freely. An update swaps the brain while the broker keeps every session’s process and byte stream intact — running agents don’t notice.

Live agents and the mind

A live agent is an agent endpoint with a persistent working memory. Its context survives session resets and even machine moves through three file-drop mechanisms (no special APIs inside the agent’s session):

  • commune — the agent drops a context delta; spt-core ingests it into the endpoint’s tracked mind (two tiers: a live tier that follows the agent everywhere, and a project tier scoped to one project).
  • signoff — a graceful goodbye: final commune, then teardown.
  • echo-commune — when a session ends without a signoff, spt-core runs a bounded summarizer over the session’s history so the context delta is captured anyway.

The mind syncs between paired machines, so reviving bob elsewhere brings his memory with him.

Instances, dormancy, and rest

One endpoint can have instances on several nodes. Instances rest when unused — dormant (warm, zero idle cost, instantly wakeable) or suspended (cold) — and remain addressable while resting: messages for them are held and delivered on wake. spt wake bob re-activates the seat in place; nothing is respawned.

Subnets, pairing, and the network

Machines pair into subnets — private, named groups sharing a registry of endpoints. Pairing is a one-time ceremony seeded by a TOTP code (the same six digits an authenticator app shows); after that, connectivity is zero-config peer-to-peer QUIC with relay fallback, no central server. Every endpoint’s visibility and sync scope is controlled per subnet; nothing is shared by default with anyone you haven’t paired with.

The harness contract

The seam third parties build against — two halves:

  • the manifest: a TOML file declaring what varies per harness (how to spawn a session, which hooks fire, how to read history). Command templates are opaque strings; spt-core fills {key} placeholders and runs them. SPT is not a harness: models, flags, and tools are always the adapter’s business.
  • the spt api surface: the inbound commands a harness’s hooks fire to keep spt-core’s state in sync (session started, went idle, session ended, …).

A working adapter is a manifest plus whatever the harness already has. Build one in the adapter quickstart.

Self-update

Releases are signed (Ed25519, two-key trust anchor baked into every binary) and propagate peer-to-peer: one machine fetches a release, its peers verify and stage it from each other. Updates apply with the broker/brain split, so no endpoint process terminates or suspends during a self-update — the system’s standing invariant.

Where to go next

You want to…Go to
see two agents talkMessaging quickstart
integrate a harnessAdapter quickstartManifest reference
build a notifier/robot/sensorShells
pair two machinesNetworking & pairing
every command and flagCLI reference