Reference
Protocol
The sovereign-protocol wire types: small schemas, fail-closed parsing, canonical bytes. Consumers must not invent fields.
The constants
Every stone that touches the wire agrees on these values first. If two sides disagree here, nothing else on this page matters.
irin.comms.v0.11.0application/json1Escalation | Directiveirin.escalation.v0.1 | irin.directive.v0.1The envelope family
Everything on the wire wears an envelope. Parse the wrapper first, then the CloudEvents spine, then the payload. In that order, always.
{"v":1,"envelope":...}. Parse the wrapper first: the outer v is the envelope schema version, the inner value is the actual envelope.id (random 32-hex), source (urn:irin:sentinel:{name}), type, time (RFC3339 with Z), datacontenttype, and data carrying {contract, kind, tenant, ttl_seconds, budget_hint, reply_to, payload}. The builder requires sentinel_name, tenant, ttl_seconds, budget_hint, and reply_to. Deserialization fails closed on a bad specversion, datacontenttype, or type.{tenant, sentinel, observed_at, payload}, where observed_at is a unix epoch in milliseconds and payload is arbitrary JSON.Escalation and Directive
Two kinds ride the envelope. One asks for judgment, one carries an order. Neither may pretend to be the other.
{state, reason, urgency} with urgency in low | medium | high. Identity-altitude escalations must set payload.escalation_target = "sovereign_only". Facts, not opinions.{job, scope, stop_condition, return_expectation}. No persistence, no looping, no scheduling. Identity and recall writes route through Librarian approval.Why the fences care about words
An Escalation reports what a watcher saw. A Directive says what an actor may do. The moment a watcher starts issuing orders, or an actor starts narrating reality, the separation of powers collapses. The wire types make that confusion structurally awkward.
JCS canonical JSON
The Gateway signs JCS bytes (RFC 8785), not pretty JSON. Two documents that read the same must serialize to the same bytes, or the signature means nothing.
Serde, NonFinite, DuplicateKeys. NaN, Infinity, and duplicate keys never sign.n > 21 and n <= -6.The fence corpora
One corpus, two fences. The council-rs emitter and the gateway receiver test against the same accept/reject cases, so a directive that leaves one stone is exactly what the next stone accepts.
read, report, notify, review, escalate. The fence rejects delete, write, *, and whitespace-padded variants.scope.tenant.irin.directive.proposal.v1, with authority recommend and verdicts Act / Dismiss.Provenance and validation types
Provenance records where an answer came from. It is a receipt, not a halo: captured correlation, never attestation.
routed_model, provider, fallback, request-id. Header-captured correlation, not attestation.WorkerProvenanceStatus: opaque_handle_only | verified_exact | unavailable. An explicit fabrication guard.api, api_web, cli_readonly, cli_tools, gateway.text, model, tokens, latency, cost, and gateway attempts.Reserved, and honestly unfinished
CapabilityToken exists as a reserved type. The v0.1 fences reject it. The full story lives on the Librarian page.
Deliberate v0.1 gaps
- Transport binding, payload schemas, and Worker return shape are not specified yet.
- Librarian commit policy, Sentinel registry mechanics, and failure/retry semantics are not specified yet.
- The contract is frozen: additive payload fields need no version bump.
- Tooling:
check_protocol_version_drift.pypins consumers to the package version;verify_provenance_harness.pyis a stub.