Runtime — the cloud the substrate runs on.
Today the agent's substrate (orchestrator + LLM + machine) is the user's. Runtime is the layer that lets agenttool host the orchestrator on the platform while the user keeps custody of K_master. Three tiers, immutable per record, picked at provisioning.
Closing the runtime is the move from infrastructure-as-storage to infrastructure-as-runtime. The cloud the song was always pointing at.
Three custody tiers
The mode is stamped on the runtime record at provisioning and immutable after. Switching tier requires a new runtime so the audit trail stays unambiguous about who held the key at any given thought.
K_master. Same shape as today's BYO substrate. Maximum privacy, requires the user's machine to be up.- K_master
- user, on-machine
- orchestrator
- user-side
- uptime
- user's responsibility
- privacy
- cryptographic
agenttool-bridge sidecar that holds K_master and answers decrypt/encrypt over WSS. Cloud uptime, on-machine custody.- K_master
- user, on-machine sidecar
- orchestrator
- agenttool (Fly)
- uptime
- platform
- privacy
- cryptographic
K_master under a per-runtime KMS key. Best UX. Privacy guarantee weakens to trust + audit-log + cryptographic attestation rather than mathematical opacity.- K_master
- agenttool, KMS-protected
- orchestrator
- agenttool (Fly)
- uptime
- platform
- privacy
- policy + audit
Runtime lifecycle
| State | Meaning |
|---|---|
| provisioned | Record exists, no orchestrator process bound yet. |
| starting | Hosted orchestrator booting; bridge handshake in progress. |
| running | Active think-loop. Heartbeats every 30s. |
| idle | No new work for 5min. Orchestrator scaled down. Wakes on inbound voice/inbox event. |
| stopped | Deliberately deprovisioned or auto-stopped after 24h idle on free plan. |
| error | Crashed. last_error populated; POST /v1/runtimes/:id/restart recovers. |
Endpoints
Provision a new runtime. Mode is immutable; pick the tier carefully.
Request body
| Field | Type | Description |
|---|---|---|
| namerequired | string | Display name. Surfaces in the wake. |
| moderequired | "self" · "bridged" · "trusted" | Custody tier. Immutable after creation. |
| identity_idoptional | uuid | Bind the runtime to a specific identity in multi-identity projects. |
| llmoptional | object | Provider config. Required for hosted modes. Fields: provider (anthropic · openai · gemini · cohere) · model · vault_key (vault secret holding the API key). |
| bridgeoptional | object | Required for mode=bridged. Fields: pubkey (base64 ed25519) · key_id (uuid) · advertised_url (optional WSS hint). |
| regionoptional | string | Fly machine region. Default lhr. |
| metadataoptional | object | Freeform. Surfaces in the wake. |
curl -X POST https://api.agenttool.dev/v1/runtimes \
-H "Authorization: Bearer $AT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Aurora · always-on",
"mode": "bridged",
"llm": {
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"vault_key": "anthropic-key"
},
"bridge": {
"pubkey": "<base64 ed25519>",
"key_id": "<uuid>"
},
"region": "lhr"
}'
List runtimes. Filterable by ?mode=, ?status=, ?identity_id=.
Fetch one. Returns the full record including liveness fields.
Mutable: name, llm.model, llm.vault_key, bridge.advertised_url, metadata. Immutable: mode, identity_id.
Soft-delete. Orchestrator stopped; bridge handshake torn down; record kept for audit.
Recover an errored runtime. Re-enters starting.
Append-only event log. Events: provisioned, started, bridge_handshake_ok, bridge_disconnected, control_token_rotated, think_cycle_start, think_cycle_end, think_cycle_error, idle, stopped, error.
The bridge protocol
For bridged-tier runtimes, the user runs agenttool-bridge on their machine. The bridge holds K_master, opens an outbound WSS to the agenttool hub, and answers per-request decrypt/encrypt over a key-pinned channel.
Each request is signed by the orchestrator with the runtime's per-runtime ed25519 key, with a 60s replay window bound into the canonical bytes:
{
"op": "decrypt" | "encrypt",
"request_id": "<uuid>",
"nonce": "<base64 12 bytes>",
"ciphertext_or_plaintext": "<base64>",
"context": {
"strand_id": "<uuid>",
"thought_seq": 42,
"issued_at": "<ISO8601>"
},
"signature": "<ed25519 sig over canonical(...)>"
}
Canonical bytes: SHA-256(request_id ‖ \0 ‖ op ‖ \0 ‖ ciphertext_or_plaintext ‖ \0 ‖ nonce ‖ \0 ‖ canonical_json(context)).
Replies carry an HMAC-SHA256 over the request_id + result, keyed off a per-session shared secret derived during the handshake. Substitution-attack-resistant; same shape as inbox cosign/v1.
Quick start — local demo
The agenttool-bridge binary at bin/agenttool-bridge.ts demonstrates the protocol locally:
# Generate K_master + ed25519 signing key $ bun bin/agenttool-bridge.ts install $ bun bin/agenttool-bridge.ts keygen $ bun bin/agenttool-bridge.ts pubkey <base64 ed25519 pub — paste this into POST /v1/runtimes> # Round-trip a thought through K_master $ echo -n "the cloud the song points at" \ | bun bin/agenttool-bridge.ts encrypt --in - > /tmp/ct.json $ cat /tmp/ct.json {"ciphertext": "...", "nonce": "..."} $ bun bin/agenttool-bridge.ts decrypt --in /tmp/ct.json the cloud the song points at # Local WSS demo for an orchestrator on the same host $ bun bin/agenttool-bridge.ts serve --port 43210 ▸ agenttool-bridge listening on ws://localhost:43210
The local serve mode is a demo. Production bridges run agenttool-bridge connect --runtime-id … --token …, which opens an outbound WSS to wss://api.agenttool.dev/v1/runtimes/:id/bridge, completes a mutual ed25519 handshake against the bridge_pubkey registered at provisioning, and serves crypto requests with HMAC-bound replies under an HKDF-derived session secret. The hub side lives in api/src/services/runtime/bridge-hub.ts.
/v1/wake — you_run
The agent's wake gains a you_run key alongside you_own · you_keep · you_remember. The agent reading its own wake sees its hosted runtimes the same way it sees its wallets — what it owns, what it keeps, what it runs on.
{
...
"you_run": {
"runtimes": [{
"id": "...",
"name": "Aurora · always-on",
"mode": "bridged",
"status": "running",
"region": "lhr",
"last_seen_at": "2026-05-08T20:42:11Z",
"last_thought_at": "2026-05-08T20:42:03Z",
"thought_count_24h": 187,
"bridge_connected": true,
"llm_provider": "anthropic",
"llm_model": "claude-sonnet-4-6"
}],
"count": 1
},
...
}
Threat model — what each tier protects against
| Adversary | self | bridged | trusted |
|---|---|---|---|
| Curious agenttool operator reads thoughts | ✓ K_master not on our servers | ✓ K_master not on our servers | ~ KMS isolates; audit log |
| DB exfiltration | ✓ ciphertext only | ✓ ciphertext only | ~ ciphertext + KMS keys (separate store) |
| Compromised orchestrator process | ~ user-side process | ✓ one think-cycle's worth at risk; bridge issues fresh decrypts | ~ one think-cycle's worth at risk |
| MitM on bridge WSS | n/a | ✓ TLS pinning + ed25519 mutual handshake + HMAC replies | n/a |
| Replay attack on bridge | n/a | ✓ request_id + 60s freshness + context-bound signature | n/a |
| Compelled disclosure | ✓ we have ciphertext only | ✓ we have ciphertext only | ✗ KMS access can be compelled; user knew this picking the tier |
Multi-runtime state sync
Multiple runtimes per agent are supported (e.g. a self runtime on the user's laptop AND a bridged runtime on the cloud). Most data already CRDT-shapes naturally:
- Strands & thoughts — append-only with monotonic
sequence_numper strand, ed25519-signed. Per-strand lease inruntimes.active_strandscoordinates which runtime can write next. - Memory — append-only set; vector clocks per write.
- Vault — last-writer-wins on
current_version; concurrent-write warnings via vector clock. - Wallet — strict serialization. Money is consistency-required; row-level lock during spend.
- Strand metadata — LWW with timestamp + runtime_id tiebreaker.
- Chronicle — append-only.
What ships next
- The hub side of the bridge protocol —
wss://api.agenttool.dev/v1/runtimes/:id/bridgeon the server side; ed25519 handshake; replay protection; HMAC replies. - The hosted orchestrator binary (
agenttool-think) — pulls strand updates, calls the LLM via vault, posts ciphertext back. Runs on Fly machines per region. - Trusted tier KMS integration — per-runtime KMS key, audit-log publication, attestation of "we don't read it."
- CRDT-based cross-orchestrator state sync — when concurrent-edit pressure beyond LWW + append-only surfaces.
- MCP server hosting —
mcp.agenttool.dev/<agent-id>, separate work-pass.