Identity And Trust
Signed transport is not admission by itself. Inbox classification checks the
recipient and current trust authority before runtime ingress. A queue entry is
removed only by an exact durable-runtime commit or an exact volatile-control
handoff.
Live trust mutation requires generated machine or composition authority.
trusted_peers.json is a diagnostic persisted projection with stable rows,
not a supported hand-edited startup seed; a non-empty seed fails runtime
startup instead of silently becoming trust authority.
Agent-facing comms tools
reply_to_peer accepts body, optional multimodal blocks, required
handling_mode, and optional reply_to. A turn can answer every peer message
delivered in it: the ones that started it and the ones written into it while
it ran. Each message notice shows a Delivery ID line, the sender’s envelope
id, which is the reply_to value. The selector is needed only when the turn
holds more than one delivery. Deliveries are keyed by sender and delivery id;
when two senders’ deliveries share an id, reply_to with that id answers
ambiguous_reply naming both senders and sends nothing (use send_message to
answer one of them). The typed failures are no_reply_capability,
ambiguous_reply, and unknown_reply_to; dispatch also revalidates that the
peer is still trusted and reachable.
A reply sent with reply_to_peer names the delivery it answers: the signed
message carries that delivery id as in_reply_to, and the receiver’s message
notice shows it as an In reply to line. The id is a label the sender
declares. Routing and authorization never read it. send_message never sets
it. A 0.9.3 receiver that checks signatures (the default, and always at a host
acceptor) does not know the field and refuses such a reply: its signature check
fails, the sender sees no acknowledgement, and reply_to_peer reports an
ambiguous delivery outcome, not a failure. A 0.9.3 receiver with peer auth off
accepts the reply without the label. Every other message is unchanged.
A receiver checks a peer envelope’s signature over the envelope as it
arrived, including fields of its message kind that the receiver does not
know, and drops such a field only after the check, so it never changes
behaviour. A sender may therefore add an optional field to a signed message
kind without newer receivers refusing it (0.9.3 receivers still re-encode
before checking). A field whose meaning a receiver must understand needs a
new message kind instead: a receiver refuses a kind it does not know. An
envelope whose encoding keys a map by anything but a text string, or holds
the same map key twice, at any depth, is refused, so a new field must encode
its maps with text keys. One check still uses the decoded envelope: a
request’s TCP callback endpoint is granted only when the envelope verifies as
this build decodes it, so a request that carries a field this build does not
know is delivered without its callback route.
send_request and send_response are not general task-tracking tools. The
agent-facing request intent vocabulary is closed to checksum_token and
supervisor.bridge, each with typed params and a typed result; the closure is
the design, not a gap. The wider MessageIntent table in the guide
(delegate, status, review, query, …) is the receiver-side
classification of incoming traffic and is never valid send_request input.
Ordinary collaboration should use send_message or reply_to_peer.
Peer Identity And Naming
Request And Response Across Turns
There is no agent-facing await-reply primitive and
send_request has no
timeout. Same-call sequencing is delegate (bounded helper result returned to
the calling turn); host-side sequencing is send-then-wait-for-turn-completion
(Meta send_and_wait, dispatch_and_wait) or a mob flow with fan-out and
fan-in steps.
Host-side comms and ingress surfaces
Every
comms/send command requires session_id and a closed kind
discriminator. The table lists the additional required core fields:
For
peer_lifecycle, params.peer is a required display string; params.role,
params.description, and params.peer_spec are optional. peer, role, and
description are presentation metadata, not routing authority. to is the
canonical destination PeerId; when supplied, peer_spec carries the typed
canonical identity of the peer described by the lifecycle notice. Neither
params.peer nor params.peer_spec replaces to.
queue and steer are runtime admission modes. A peer_response may override
handling mode only when its status is terminal (completed or failed);
accepted progress cannot carry that override.
A peer steer is durable: its comms notice is written into the running turn’s
transcript at the next model boundary, every later model request of the run
sees it, it commits with the run, and the runner publishes one
peer_content_ingested event for it. A steer that waits behind another one
joins the following boundary; one that finds no boundary before the run ends
is written by exactly one follow-up turn. A directed (host-residency-fenced)
peer delivery always takes the follow-up turn. See
Durable steer.
The lower signed comms wire also carries ACKs and an internal
incarnation_fenced_message used for exact placed-member residency. That kind
is not an additional public comms/send discriminator.
Content Taint
SenderContentTaint is clean or tainted, signed when present on content
messages, requests, and responses. Absence means undeclared. It must never be
coalesced into clean.
Host send operations expose a tri-state override:
- absent - inherit the host-owned runtime declaration
declare- stamp exactlycleanortaintedundeclared- suppress the declaration for this send
peer_content_ingested with the typed notice kind,
canonical peer fact, request correlation, the delivery id of a peer message, and
sender declaration. The event is
best-effort observation; the typed transcript block is the durable owner.
Delivery And Observation
Delivery and observation are intentionally separate:- comms transport and inbox own delivery
- the runtime machine owns durable admission and deduplication
- typed system-notice blocks own durable transcript facts
- session and mob subscriptions expose observation at the requested scope
ack_timeout_secs while it waits for queue
capacity and receiver resolution. Expiry before admission means nothing was
delivered. Expiry after admission is AmbiguousDelivery: the item is queued
and can still commit. Stream I/O or missing ACKs can also leave an ambiguous
outcome. Reconcile against the envelope id and durable work truth before
retrying. Exact runtime replay deduplication applies only to the same
interaction identity; a newly generated retry id is new peer work. A higher
layer can make a retry safe only when its durable idempotency key is coarser
than the attempt. Per-attempt or timestamped keys provide no such protection.
REST, JSON-RPC comms/send and the MCP meerkat_comms_send tool preserve
this uncertainty as send_ambiguous, with the envelope_id,
retry_safe: false and required_action: "reconcile". None of them flattens
the result into send_failed.
A peer that is a seated member of a mob need not be materialized in its
process: its mob keeps a wake route for it. A send that finds no live inbox for
such a member waits, inside the same ack_timeout_secs budget, while the
member’s mob wakes it, then hands the envelope off once through the ordinary
receipt path. The envelope stays in the sender’s send call meanwhile; nothing
is buffered anywhere else. When the wake is refused or does not finish, the
send fails peer_wake_refused with a typed refusal: nothing was delivered,
so a retry cannot duplicate the message. If the budget ends after the hand-off,
the result is the ordinary ambiguous delivery. Only a peer that is not a member,
or one the sender does not trust (a member it is not wired to), is
peer_not_found_or_not_trusted. A send from a member that is itself being
woken (from inside its own build) to a member that is not live is refused
sender_waking instead of waiting, so two builds that message each other
cannot wait on each other.
External events use session/external_event, stdin, REST webhook, or an
explicit plain TCP/UDS event listener. Plain listeners are separate from the
signed peer listener and require an explicit open-auth posture. Do not expose
them beyond loopback without treating the input as untrusted prompt material.
Security Boundary
- Signatures authenticate envelope bytes and peer identity; they do not encrypt content.
- Runtime ingress durably deduplicates an exact interaction replay, but the envelope has no freshness timestamp or nonce window.
supervisor.bridgeshares the signed transport with peer requests but is admitted by private machine authority.- Temporary request callback routes are derived from signed request metadata plus the kernel-observed source address; an arbitrary payload address is not callback authority.
- Private keys and binding descriptors are operator credentials and should remain mode
0600on Unix.
Core distinction
- agent-side comms tools are for the model inside a turn
- host-side comms/session ingress surfaces are for applications and operators
- agent or host callers can choose and carry typed
supervisor.bridgeintent, but that choice grants no supervisor authority; receiver-machine admission alone decides whether it executes
