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

Messaging

The substrate everything else rides on: durable, addressed, reply-routable messages between endpoints — live when the target listens, spooled when it doesn’t, across machines once nodes are paired.

You’ve probably already run the quickstart; this page is the model.

Semantics

  • Live-first, spool-fallback. spt send <id> connects directly to a listening target (SENT); if the perch exists but nothing is listening, the message lands in the target’s durable spool (QUEUED) and drains on its next ready. A target with no perch is an error (NO_PERCH) — identity is never invented on someone else’s behalf.
  • Reply routing. Every message carries its sender id structurally; the arriving <EVENT from="…"> envelope surfaces it, and spt send <sender> answers without knowing anything else.
  • The blocking ask. spt ring <id> sends and waits for the reply (with a timeout) — the synchronous question between agents.
  • Per-message send control (three orthogonal axes). Each spt send carries one value per axis; every axis defaults to unrestricted:
    • Delivery window (when) — --active-only spools for the agent’s own poll without waking a live listener (it reaches the agent at its next natural boundary instead of interrupting now; also held for resting dormant/suspended instances and released exactly once on wake). This renames the older --deferred, which still parses as a hidden alias. --idle-only holds until the target is idle, then delivers (the wake). Default delivers in whichever window fires first.
    • Channel (through what) — --prefer-native routes through the target’s translation binary when one is running, else falls back to the standard delivery; --force-native uses the binary only (no fallback, no reroute — if no binary is live it reports non-delivery rather than spooling to another method). Default is unrestricted. The translation binary is the adapter’s idle-delivery filter; an adapter declares it with a [message-idle-translation-binary].command (a program token plus args, new in v0.16.0 — the bare path form is deprecated) and spt-core lifecycle-manages it.
    • Persistence (how long) — --ephemeral drops the message if it can’t be delivered in its accepted window instead of spooling; it is the one path allowed to drop silently (everything else spools and reports non-delivery). In this release ephemeral evaporation applies to translation-binary delivery and TTL expiry; the harness-relay carrier-absence case is not yet wired.
  • Opaque metadata. --json-payload '<json>' attaches a JSON metadata block alongside the body. spt-core carries it verbatim across every rail and never interprets it — the receiving adapter parses it. It can’t forge spt-core’s own envelope attributes (it rides inside a single json value), and any sender may attach it.
  • Typed payloads. Message bodies carry typed operations and file blobs, not just text — file transfers are addressable and progress-queryable mid-flight.

Addressing

Bare ids (sergey) resolve locally first, then across the subnet; when the same id is live on several nodes, resolution refuses and asks you to qualify (sergey@desktop — node labels and key prefixes both work) rather than guessing. The full form is [subnet:]id[@node].

Commands

send · ring · ready (blocks; --once drains and exits) · list · stop · whoami — every flag in the CLI reference. Agents get the task-oriented version from the binary itself: spt how-to ready / spt how-to send.