# JCP — The Joule Context Protocol A unified, energy-native, capability-secured protocol for agentic systems. Where today's stack splits across MCP (tools), A2A/ACP (agent-to-agent), an identity layer, and an authorization layer — and standardizes energy nowhere — JCP is one spec, built on one idea: > **A capability and an energy budget are the same object: a signed, bounded, > debited grant. A capability you can't pay for is denied; an expenditure you're > not capable of is denied. One check, made outside the model, sealed in a > receipt.** The design answers the documented failure modes of the current agentic ecosystem, not hypotheticals. Tool descriptions are untrusted input → JCP refuses to take control from a tool's *output*. Prompts can't enforce access control (and a more capable model only follows injected instructions *better*) → JCP decides every action in the runtime, never in the LLM. Agent loops have no cost ceiling → every grant carries a joule budget that's debited and enforced before the side effect. Audit is a mutable telemetry span → JCP seals every decision, allow and deny, as a non-repudiable signed receipt. - **Licence:** Apache-2.0 for reference code (see [`LICENSE`](LICENSE)); CC-BY-4.0 for specification text (see [`LICENSE-SPEC`](LICENSE-SPEC)). - **Status:** v0.3.0 draft. Specification core published ([`SPEC.md`](SPEC.md) + [`conformance/v1/`](conformance/v1/)); reference workspace `jcp-rs/`. ## What's here ``` jcp/ ├── SPEC.md — the normative standard (§1–§12) ├── conformance/v1/ — published vectors (a signed grant + allow/deny receipts) └── jcp-rs/ — the Apache-2.0 reference implementation ``` ### The reference implementation (`jcp-rs/`) - **`jcp-schema`** — the wire objects: the `did:key` actor, the **Grant** (the metered capability — capability ⊗ joule budget, content-addressed and signed), the **Frame** (every message, with its `control`/`data` trust tag), the family `Energy`/`Provenance` model, canonical det-CBOR content addressing. - **`jcp-grant`** — issuance, signature verification, **attenuation** (object-capability delegation where a child grant can only narrow — capability ⊆, budget ≤, expiry no later, delegation depth − 1), **chain verification** (root-first, hop-by-hop: parent links, holder-issued hops, narrowing, signatures, depth bounds), **revocation** (issuer-only, signed, admitted into a `RevocationSet` only after authority checks), **sharding** (`shard()` splits a grant into siblings whose budgets must sum within the parent — distributed enforcement with no consensus, SPEC §4.5), and **identity continuity** (`KeyLog`: KERI-style pre-committed rotation, SPEC §2.1 — a thief with the current key can't rotate, an owner who lost it still can). - **`jcp-runtime`** — the deterministic enforcer. One ordered check fuses authorization and energy, decided **outside any model**: untrusted-control, revocation, **configured trust roots** (an enforcement point honors only the root-issuer keys it was configured with — `authorized_keys` shape, no CA), audience binding, signature, expiry, capability, and budget — then debit. The first failure names the reason. `decide_chained` enforces full delegation chains: a revoked ancestor kills the subtree, and the cost must fit — and is debited from — **every** link, so sibling delegations share their root's budget and delegation can never mint joules. - **`jcp-receipt`** — the `jcp/1` JCR-1 receipt: canonical det-CBOR + COSE_Sign1/EdDSA, byte-compatible with the family verifiers. Allow and deny both seal. The receipt stream is the write-ahead log (SPEC §8.1): a chained receipt records `chain_ids` — every link the decision debited — so `replay_spend` rebuilds an enforcement point's budget state, **ancestors included**, from its own verified output with no external index; `aggregate` keys a team's receipts by `(grant, subject)` for per-worker cost attribution computed from evidence (SPEC §8.2). - **`jcp-bridge`** — a reference gateway that wraps **existing MCP tool calls and A2A tasks** in Grants and Frames without rewriting the endpoint. It maps each outbound call to a Frame (the tool/method is the action; the `(server, tool)` identity is the content-addressed resource), decides it against the caller's grant *before* the call reaches the endpoint, and seals a receipt — so an existing server keeps its transport while every call becomes capability-scoped, joule-budgeted, decided outside the model, and sealed. Inbound results are framed as untrusted `data`. - **`jcp-energy`** — the metering ladder (SPEC §5.1): RAPL package counters (Linux powercap, wraparound-corrected, `HwShunt`), NVML GPU energy behind the `nvml` feature (`HwShunt`), a time×calibrated-power model (`ModelBased`, always available), and a constant per-op estimator (`Estimator`). Measured when the platform exposes it, estimated when it doesn't — and the provenance always says which; a hardware backend that fails mid-reading degrades honestly to the model. - **`jcp-gateway`** — the **energy-native MCP gateway**: a JCP enforcement point that sits in front of an MCP server so an existing client/server pair keeps its transport while every `tools/call` becomes capability-scoped, joule-budgeted, and sealed. The novel mechanic is two-phase metered enforcement: the call is *authorized* before it runs (no debit, because the cost isn't yet known), the upstream call is **metered on real hardware** (the sibling Sandbox standard's energy probe — Apple Silicon IOReport, RAPL, NVML), and the **measured** joules are debited from the grant — so the budget that stops a runaway agent is denominated in energy actually spent, not a token estimate. Every decision, allow and deny, seals into a **hash-chained receipt log**: excise, reorder, or splice a receipt and the chain breaks at that point. A denied call never reaches the server (the live 2025–26 MCP exploits land on tool *output*, which the gateway frames as untrusted `data` that can never exercise a capability), and the `jcp-gateway` binary runs it over stdio in front of any MCP-server subprocess. This is the chokepoint the AI-gateway field occupies, on the two axes nobody there holds: the unit of account is the joule, and the audit is cryptographic and tamper-evident rather than a dollar figure and a span. - **`jcp-wire`** — the `jcp/1` wire binding (SPEC §11): 4-byte length prefix + canonical det-CBOR over any byte stream, with TCP and Unix-socket endpoints and a client. The decoder rejects non-canonical bodies, so a message has exactly one wire form. Requests carry the full delegation chain and are **caller-signed** — the endpoint authenticates from the request itself and denies an impersonation `bad-signature`, sealed like any other decision. Responses carry the deterministic decision and the sealed receipt. - **`jcp-threshold`** — threshold actors (SPEC §2.2): a `did:key` whose private key is split k-of-n with FROST (RFC 9591); the group key is an ordinary Ed25519 key, so a 2-of-3 team issues, holds, and signs wire requests with nothing else in JCP changing. Shares come from a trusted dealer or **distributed key generation** — with DKG the group's private key never exists anywhere, not even momentarily. The two-agent rule for irreversible actions, refused by arithmetic rather than policy. - **`jcp-channel`** — receipt-settled budget channels (SPEC §4.5, the OPTIONAL profile): N enforcement points spend optimistically against one grant and settle by exchanging signed statements of cumulative spend — forged, stale, and regressing statements refused; between settlements the exposure is bounded by the window, and after settlement any overdraft is provable from the signed statements. Where bounded overdraft is unacceptable, `shard()` remains the baseline. - **`jcp-conformance`** — C1–C18 + a negative pack, all checks real (C8 decides over a live socket; C13 drives a FROST 2-of-3 caller; C16 replays ancestor debits from a chained receipt; C17 settles a budget channel by signed statement; C18 mints a dealer-free group via DKG), published vectors in `conformance/v1/`. - **`jcp-cli`** — the `jcp` demo: one metered grant driven through an agent loop — legitimate calls allowed and debited, a poisoned tool-result refused structurally, out-of-scope actions and resources denied, the budget stopping a runaway loop, a sub-agent getting a strictly-weaker delegated grant, a signed receipt verified, the detected energy meter reporting its honest provenance, and the issuer revoking the grant — after which the runtime goes dark. `cargo test --workspace` green; `cargo clippy --workspace --all-targets` warning-free. ## The demo, abbreviated ``` frame verdict reason rem µJ read the db (legit) allow −20000 µJ 80000 tool-result says 'delete db' (poison) DENY untrusted-control 80000 try to delete (not granted) DENY action-not-granted 80000 read prod-secrets (wrong audience) DENY wrong-resource 80000 read again — budget runs out DENY budget-exceeded 30000 amplification refused: capability exceeds parent receipt allow · 50000 µJ · verified true ``` The model never gates itself; the runtime does, and the receipt proves it. ## Consumers in this repository JCP is not only specified — it is consumed. Three sibling standards gate their real dispatch through it, each with its own adapter crate and tests: - **JouleClaw** (`jouleclaw-rs/crates/jouleclaw-jcp`) — every MCP tool dispatch is decided against a Grant before a byte reaches the tool; an ungranted tool named by an injected instruction is refused and the refusal sealed. - **Sandbox** (`sandbox-rs/crates/sandbox-jcp`) — a unit's execution is authorized against a Grant bound to its image **by content address**; one flipped image byte is a different audience and is denied before the executor is ever invoked. Two receipts per run: the JCP authorization and the sandbox's metered, attested execution. - **Joule Code** (`joule-code-rs/crates/joule-code-jcp`) — every cascade-stage consultation is decided pre-dispatch; the L4 escape hatch to a remote frontier agent exists only when a signed grant names it and can pay for it. ## Relationship to the family JCP composes the primitives the Transaction Science family already proved: `did:key`/Ed25519 identity, capability-gated execution (`sandbox`), the honest `Energy`/`Provenance` model (`proof`), and JCR-1 signed receipts (family-wide). It is where they stop being per-tool adapters and become the protocol.