Skip to main content

The on-device agent

The Edge Agent reasons on-device, with a local model, or by relaying to a cell when connected, through the same governed tool interface either way. These commands drive that agent: interactive chat, autonomous missions, the approval queue for consequential actions, per-agent inboxes, the MCP tool surface, and peer-to-peer delegation. The runtime itself is described under the Agent Platform.

s9 chat​

Chat with the on-device operator agent, an interactive REPL, or a one-shot question when you pass [QUESTION].

FlagDescription
--model <MODEL>Local model id to reason with (default: the daemon's choice).
--effort <LEVEL>Reasoning effort low / medium / high, mapping to completion-token budgets.
--max-tokens <N>Output token ceiling per turn (overrides --effort).
--max-iters <N>Max reason→tool round-trips before the turn gives up (default 32).
--attach <PATH>Fold a file into the turn as untrusted, delimited data (repeatable).
--relayRelay reasoning to the fabric when connected; degrades to local if unreachable. Requires enrollment.
--workspace <ID> / --cleanroom <ID>Scope a relayed session to a workspace and/or clean room, so each turn is grounded there and audit rows are attributable to it.
--mcp <URL|stdio:CMD>MCP server(s) to wield as tools (repeatable); --mcp-token <T> sets the bearer token.
--auditRecord every reasoning step to a durable, hash-chained journal.
--session <NAME>Resume or start a named, durable conversation.
--bypass (--yes)Start in autonomy mode: pre-approve tool actions for the session. The security floor still applies.
--theme <NAME> / --no-colorConsole palette (aurora / solar / mono) and color control.
# One-shot question
s9 chat "which models are loaded on this device?"

# Interactive, audited, grounded in a workspace over relay
s9 chat --relay --workspace ws-acme --audit --session incident-42

s9 do​

Accomplish a goal autonomously, a single mission, run to completion. Aliased as s9 build. Missions record a durable reasoning trail by default.

Argument / flagDescription
<GOAL>The goal to accomplish.
--model <MODEL> / --max-tokens <N> / --max-iters <N>Model and budget controls (mission defaults: 2048 tokens, 12 iterations).
--relayRelay reasoning to the fabric when connected.
--mcp <URL> / --mcp-token <T>MCP tool servers to wield.
--workspace-id <ID> / --cleanroom <ID>Scope the mission's tool history to a workspace and/or clean room for attribution.
--hitlPause consequential tool calls for human approval instead of running them, recording each pause durably (see s9 hitl).
--no-auditDisable the durable reasoning trail (on by default).
--jsonEmit a machine-readable result.
s9 do "triage the failing sensor on this gateway and file a report" --hitl

s9 hitl​

List and resolve durable human-in-the-loop approvals. Because s9 do is headless, a mission run with --hitl writes each consequential call to a hash-chained, device-signed approval queue instead of running it; these commands resolve that queue, and decisions survive a restart.

SubcommandDescription
listList tool calls paused awaiting a human decision.
approve <ID>Approve a paused call; it may proceed on resume.
deny <ID>Deny a paused call; it is refused on resume.
historyReplay the full pause/resolve history.
s9 hitl list
s9 hitl approve 01J8...

s9 inbox​

The device's durable, per-agent inboxes, typed messages delivered to an entity's inbox on this device.

SubcommandDescriptionKey flags
sendPut a typed message in an entity's inbox.--to <ENTITY>, --content <TEXT>, --message-type <TYPE>, --thread, --in-reply-to, --correlation-id, --workspace, --clean-room
listShow the messages waiting, unread.--entity <ENTITY>
readHand over pending messages and record them read.--limit <N> (default 20)
historyReplay the full delivery / read / undeliverable log.
undeliverableShow what arrived and could not be accepted, and why.

Message types (--message-type) are task_delegation, task_result, status_update (default), negotiation, and escalation; a recipient's authority rules key on the type. --entity selects whose inbox to act on (default: this device's identity).

s9 inbox send --to entity:ops --content "gateway-07 online" --message-type status_update
s9 inbox read --limit 10

s9 mcp​

Inspect and expose the MCP tool surface, the fabric's governed tools and third-party servers.

SubcommandDescriptionKey flags
toolsList the tools exposed by the given MCP server(s).--mcp <URL> (repeatable), --mcp-token <T>
serveExpose this device's governed tool surface as an MCP server over HTTP. Opt-in (built with the mcp-serve feature); tools stay governed per call.--bind <ADDR>, --token <T> (mandatory for a non-loopback bind), --workspace <DIR>, --max-calls-per-sec, --max-call-burst, --allow-unauthenticated

A non-loopback serve bind requires a bearer token; --allow-unauthenticated is named for what it is because it is the only way to publish the surface without a credential.

s9 mcp tools --mcp https://node-a.system9.local:8443/mcp/rpc
s9 mcp serve --bind 127.0.0.1:8760

s9 a2a​

Interact with external A2A (Agent2Agent) peers, discover and verify a peer's Agent Card, delegate a task, publish this device's own card, or serve inbound tasks.

SubcommandDescriptionKey flags
fetch-card <URL>Fetch and verify a peer Agent Card and print it with its pin.--pin <PIN>
delegate <URL> <MESSAGE>Delegate a task to a peer (send, then poll).--pin <PIN>, --max-polls <N>
cardPrint this device's signed Agent Card (or its JWKS with --jwks): including for a device whose card no peer can fetch over a network.--url <URL>, --name <NAME>, --jwks
serveServe inbound A2A tasks over HTTP, routing each to the coding skill. Opt-in (a2a-serve feature) and fail-closed: an inbound task runs only if it carries a signature from a trusted peer.--bind <ADDR>, --trusted-jwks <PATH>, --advertise-url, --workspace, --name
# Publish this device's card onto removable media for an offline peer
s9 a2a card --jwks > /media/usb/gateway-07.jwks

# Delegate a task to a peer, enforcing an expected pin
s9 a2a delegate https://peer.local/ '{"role":"user","parts":[{"text":"scan"}]}' --pin abc123

s9 presence​

Device-root subagent spawn authority, the presence delegation. Without one, subagent tools are never advertised to the model. Minting runs on an operator workstation that holds the keys; a device can never mint its own, so this is a three-step courier flow.

SubcommandDescriptionWhere it runs
statusShow the spawn delegation this device is operating under.Device
requestGenerate the device's presence keypair and emit the request an operator carries to the minter. --rotate replaces an existing keypair.Device
mintMint a signed presence delegation bundle from a device request.Operator workstation
applyVerify and apply a signed presence bundle from removable media. --dry-run verifies without writing.Device

mint binds the delegation to the agent, entity, device entity, and cell, and can attach a classification --clearance (a ladder name, PUBLIC, INTERNAL, CONFIDENTIAL, SECRET, TOP_SECRET), --compartment labels, and --dispatch-scope entries (an exact cell id, or a *-terminated scope honoured only over an authenticated connection. This is what makes elastic scale-out reachable without re-couriering every device). It supports hybrid post-quantum release-signing keys via --mldsa-key.

# 1. On the device
s9 presence request --out /media/usb/dev-1.presence-request.json

# 2. On the operator workstation
s9 presence mint --request /media/usb/dev-1.presence-request.json \
--agent-id agent:7f3a --agent-key ./agent.key \
--entity-id entity:acme --device-entity-id entity:dev-1 \
--cell-id cell:alpha --key ./fleet-release.key \
--key-id fleet-release-2026Q3 --ttl-days 30 \
--out /media/usb/dev-1.pdbundle

# 3. Back on the device
s9 presence apply --bundle-path /media/usb/dev-1.pdbundle

s9 scheduled-jobs​

Consume leased work addressed to this device over the signed job-envelope path. A unit of work arrives as a request envelope sealed by a pinned issuer; the device leases it, runs it on-device, and seals a result the cell can verify. The spool is the delivery-agnostic arrival path, a networked cell drops envelopes into the inbox, and a sovereign / air-gapped box lands the same files off removable media.

SubcommandDescriptionKey flags
consumeOne pass (or a bounded loop) over the inbox: verify the seal, check addressing, de-duplicate on the request id, admit through the on-device resource governor, execute, then seal a result.--issuer-key <HEX|PATH> (required), --inbox <DIR>, --outbound <DIR>, --offline, --peer-job-type <TYPE> (repeatable), --cap <N>, --max-passes <N>, --json
statusRead-only: inbox depth, outbound-spool depth, durable-outbox depth, and posture.--inbox <DIR>, --outbound <DIR>, --json

The pinned issuer key is mandatory, an unpinned consumer would run whatever it was handed, so a request sealed by any other key is refused. Online, sealed results are written to the outbound spool for the transport to carry; with --offline the device treats itself as air-gapped: results buffer to a durable outbox with a persisted request sidecar (so a result buffered before a restart can still be sealed against its request when a path returns), and any job that needs a peer is refused, never faked (--peer-job-type, default federate). A device that cannot serve a job (no local model, for instance) fails the job rather than fabricating a completed result.

# One pass, online, pinning the cell that is allowed to task this device
s9 scheduled-jobs consume --issuer-key ./cell-alpha.pub

# Air-gapped: buffer sealed results to the durable outbox, refuse peer jobs
s9 scheduled-jobs consume --issuer-key ./cell-alpha.pub --offline --max-passes 20

# What is waiting, what is buffered
s9 scheduled-jobs status
Deployment matrix: one device, three properties

An Edge Agent is one device, so no cross-cell dispatch is owed. The consumer delivers the three single-device properties instead: it holds a governor-admitted lease, survives a blackout (the durable outbox plus the persisted request sidecar), and seals an envelope the cell verifies with the device key. The refuse-not-fabricate rule holds at both edges, a peer-requiring job is refused when air-gapped, and an on-device runner that cannot serve fails the job. The job envelope is byte-identical to the core's, pinned by a cross-runtime parity fixture that is re-derived from the live core encoder so the projection cannot go quiet when the source diverges.