STOKE Protocol — v1.0

STOKE Protocol — v1.0

STOKEStrong Traceable Observable Knowledge Executor.

STOKE is the event envelope that every R1-emitted reasoning event

carries when the NDJSON stream is enabled. It is additive on top of the

existing Claude-Code-compatible shape (type, uuid, session_id,

ts) and extends it with fields that let r1-server, CloudSwarm, and

any other consumer correlate a single event back to:

The protocol is intentionally tiny. The STOKE "glass box" thesis is

that R1 already produces a content-addressed Merkle-chained

reasoning ledger; this envelope just makes it addressable by external

consumers without parsing the event body.

Envelope

{
  "type":           "stoke.descent.tier",
  "ts":             "2026-04-20T21:05:32.123456Z",
  "uuid":           "8c36b0e2-df4d-4e08-b37f-f0a18c4bda2f",
  "session_id":     "c3b2e1a9-...",
  "stoke_version":  "1.0",
  "instance_id":    "r1-a3f7b2c4",
  "trace_parent":   "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01",
  "ledger_node_id": "node-sha256-...",
  "data":           { ... event body ... }
}
FieldSourceRequired?
typecall-site string, e.g. stoke.descent.tieryes
tsUTC RFC3339Nano, stamped by emitteryes
uuidfresh v4, stamped by emitteryes
session_idemitter's session ID (Claude-Code-compat)yes
stoke_versionstreamjson.StokeProtocolVersion constantwhen SetStokeMeta ran
instance_idr1-<8hex> from internal/session.NewInstanceIDwhen SetStokeMeta ran
trace_parentW3C Trace Context header stringwhen SetStokeMeta ran
ledgernodeidcontent-addressed hash of the emitting ledger nodewhen known by caller
remaindercall-site-provided body (kept under the event's top level)optional

Backward compatibility rule: envelope fields are additive. A

consumer that speaks only the Claude-Code-compatible subset (type,

uuid, session_id, ts) sees every STOKE event as a superset of

the old shape — never a breaking change. This is why empty envelope

values are *omitted*, not emitted as null.

Event types

Today's stoke.* namespace — grows as more R1 subsystems route

events through the envelope.

Event typeEmitted whenNotable body fields
stoke.plan.readySOW parsed + session DAG + cost estimatesowtitle, totalsessions, estimatedcost, sessionids
stoke.session.startsession goroutine beginssessionid, title, taskcount
stoke.session.endsession acceptance loop exitsoutcome, costusd, durations
stoke.task.starttask worker dispatchedtask_id, title
stoke.task.endtask worker returnsoutcome, durations, toolcalls
stoke.ac.resultacceptance criterion evaluatedac_id, passed, output (≤2KB)
stoke.descent.startverification-descent engine enteredacid, criteriondescription
stoke.descent.tiertier transition inside descentacid, fromtier, totier, reason
stoke.descent.resolvedescent exitsacid, outcome, tierreached, category, reason
stoke.costprovider cost updatesessionid, costusd, inputtokens, outputtokens
stoke.delegation.verifyhired-agent deliverable passes descentcontractid, acid, outcome, tierreached
stoke.delegation.settleTrustPlane settlement completescontract_id

Trace context

trace_parent follows the W3C Trace Context spec

(<https://www.w3.org/TR/trace-context-1/#traceparent-header>):

<version>-<trace-id>-<parent-id>-<trace-flags>
00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

the lifetime of one R1 process / session

R1 process; becomes the parent when cross-system propagation

lands

streamjson.NewTraceParent() generates one. R1 stamps it once at

startup via SetStokeMeta and keeps it immutable for the process

lifetime. A future release may extend this to propagate an incoming

traceparent from RelayGate / CloudSwarm headers — the envelope

field is already in place for that.

Ledger node IDs

ledgernodeid is a SHA-256-derived content-addressed identifier

allocated when R1 writes a node under <repo>/.stoke/ledger/nodes/.

The emit call site passes it in via the data map:

emitter.EmitStoke("stoke.descent.tier", map[string]any{
    "ledger_node_id": node.ID,
    "ac_id":          ac.ID,
    "from_tier":      "T3",
    "to_tier":        "T4",
})

r1-server uses this to join event rows against ledger_nodes without

pattern-matching on the event body.

Compatibility notes

EmitUser, EmitResult) keep their existing shapes verbatim. STOKE

does not retrofit them.

compact events catalog (hitl_required, error, complete,

mission.aborted). Those events will gain the STOKE envelope in a

follow-up if CloudSwarm wants early adoption; until then they stay

at their current shape.

without altering any pre-existing emit behavior.

Versioning

stoke_version is a semver-ish short string on the envelope. 1.0

covers the field set documented above. Breaking changes bump the

major (e.g. removing a field) and are announced in release notes;

additive changes bump the minor.

Consumers should gate on the version when reading newly-added fields:

if evt.StokeVersion == "" || semver.Compare("v"+evt.StokeVersion, "v1.0") < 0 {
    // old emitter; fall back to legacy parse
}

Pages in this directory