open-standards/joule-code/SPEC.md
Transaction Science b3afd4e766
Some checks failed
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 23s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 28s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 28s
wai-app and Create / wai-app · does this change touch it (push) Successful in 28s
wai-fleet service / does this change touch it (push) Successful in 28s
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (push) Successful in 40s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 48s
wai-fleet service / service · macos (push) Successful in 38s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 5m2s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 38s
joule-code conformance gate / Build + round-trip C1-C4 vectors (push) Successful in 2m55s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 17m6s
wai-fleet service / service · linux (push) Successful in 3m32s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (push) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has been cancelled
joule-code conformance gate / joule-moq-relay, every target (push) Has been cancelled
joule-code conformance gate / joule-moq-ingest, every target (push) Has been cancelled
The retired communicationOS name leaves the repository
communicationOS consolidated into WAI, and its site is retired. Where these texts
meant the transport they now say WAI or MoQT, and joule-moq's description, the
Joule Code docs and the Three Faces tables follow. The transport example names
joule-moq, which it uses, and its test drops the old name.

Changelog: none
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-07 02:39:44 -05:00

159 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Joule Code v0.2 — Energy-Attributed Federated Coding Operations
Status: **Draft Standard**. Reference implementation: [`joule-code-rs/`](joule-code-rs/) (Rust workspace, Apache-2.0). Specification text: CC-BY-4.0.
The keywords **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **MAY**, and **OPTIONAL** are to be interpreted as described in RFC 2119.
---
## 1. Scope and doctrine
Joule Code specifies how a **coding operation** — a unit of agentic change to a source tree — is identified, authorized, resolved through an energy-tiered cascade, and reported with its energy cost. It is the coding cargo class of the Transaction Science substrate.
The **doctrine** is one sentence: *capability per joule, not capability per token*. Two normative consequences follow.
### 1.1 The cascade (REQUIRED)
A conforming runtime **MUST** dispatch every coding request through an explicit energy-tiered cascade and **MUST** stop at the first tier that closes the request. The tiers are inherited from JouleClaw:
| Tier | Wire tag | Named tag | Joule class | What it is for a coding request |
|------|----------|-----------|----------------|------------------------------------------------------------------|
| L0 | `L0` | Cache | picojoules | content-addressed cache hit (identical request → identical op) |
| L1 | `L1` | Lawful | nanojoules | deterministic primitive (rename, format, mechanical refactor) |
| L2 | `L2` | Embed | sub-millijoules| embedding + hybrid retrieval (symbol/snippet lookup, recall) |
| L3 | `L3` | Model | joules | local model (SSM / ternary / open-weight, e.g. vLLM) |
| L4 | `L4` | Wire | tens of joules | remote frontier coding agent over ACP (escape hatch) |
A runtime **MUST NOT** invoke a higher tier when a lower tier closes the request. A runtime **MAY** omit any tier it does not implement, but **MUST** record in the receipt the tier that actually closed the request.
### 1.2 The receipt (REQUIRED)
Every coding operation **MUST** carry a receipt reporting its energy cost as a two-part record (`measured + estimated`, §6), and **MUST** tag every reading with a `Provenance` value. A runtime **MUST NOT** report a `measured` figure it did not obtain from a hardware energy interface. Where no hardware interface is available, the `measured` field **MUST** be absent and the `estimated` field **MUST** carry the figure with `Provenance: Estimator` or `Provenance: ModelBased`.
### 1.3 No capture (REQUIRED)
The protocol carries **no token**. A conforming endpoint **MUST** perform its core function (resolve a coding operation, emit a receipt) without contacting any single steward's servers as a condition of operation. Where a tier requires a remote frontier agent (L4), the credential to that agent **MUST** reside in the vendor's own client (e.g. a logged-in CLI driven over ACP) and **MUST NOT** be transported by the Joule Code protocol.
---
## 2. The coding operation (cargo)
A **coding operation** is a signed transition that transforms a source tree from a prior state to a successor state. Its normative type is in [`spec/cargo.md`](spec/cargo.md); this section fixes the wire-load-bearing fields.
A `CodingOp` **MUST** contain:
- `prior` — the content address (§3) of the tree state the operation builds on. Binds the operation to exactly one base.
- `edits` — an ordered, non-empty list of `Edit`s. Each `Edit` names a `path`, an `anchor` (a byte range or a content-addressed hunk), and a `replacement`.
- `author` — the Ed25519 verifying key (32 bytes) that authorizes the operation.
- `intent` — a UTF-8 string describing the request that produced the operation. Advisory; not load-bearing for identity beyond being part of the canonical form.
- `tier` — the cascade tier that closed the request (§1.1).
A `SignedOp` is a `CodingOp` plus a `signature`. The signature preimage **MUST** be `op_id ‖ prior` (§3, §4), so a signature is scoped to exactly one operation on exactly one base and cannot be replayed onto a different base. The schema **MUST** carry a one-byte algorithm identifier (`0x01` = Ed25519, RFC 8032) so a post-quantum successor can be introduced without a flag-day migration.
---
## 3. Identity and content addressing
Every load-bearing object (`CodingOp`, tree state, receipt) is identified by the **content address** of its canonical serialization (§4): `id = BLAKE3-256(canonical_bytes)`, rendered as unpadded base64url. Identity is independently computable by any party; no central authority assigns it.
The `op_id` of a `CodingOp` is the content address of its canonical form **excluding** the signature. The signature therefore binds the `op_id`, not the other way round.
---
## 4. Canonical serialization
The canonical form is **deterministic CBOR** (RFC 8949 §4.2 core deterministic encoding): map keys are sorted, shortest-form integers, no indefinite-length items. A conforming implementation **MUST** produce byte-identical canonical encodings for equal objects across platforms. Floats **MUST NOT** appear in any canonical form or decision path; energy figures are integer microjoules.
---
## 5. The cascade binding
A `Cascade` is an ordered list of `Stage`s, one per implemented tier. Each `Stage` exposes `try_resolve(request) -> Option<Resolution>`. The runtime calls stages in tier order and returns the first `Some`. A `Resolution` carries the produced `CodingOp` (or a non-mutating answer) and a `Receipt` (§6). The trait surface is normative in [`spec/cascade.md`](spec/cascade.md); the **agent schema** that implements L1–L4 is [JouleClaw](../jouleclaw/).
L4 stages bind to remote frontier coding agents over the **Agent Client Protocol (ACP)**. The Joule Code runtime is an ACP client; the frontier agent is an ACP server launched by the vendor's own CLI. The runtime **MUST** treat token usage reported by the ACP agent as input to the receipt's `estimated` energy (§6) when no measured figure is available.
### 5.1 Grant-gated consultation (OPTIONAL)
A deployment **MAY** gate the cascade behind a [JCP](../jcp/) delegation chain, turning "cheapest sufficient tier" into "cheapest sufficient **and authorized** tier". When it does, the binding is:
- **Tier as action.** Each tier is a JCP action verb (`l0`…`l4`). A stage is consulted only if the chain's leaf grant names its verb; in particular, a chain that does not name `l4` can never reach a remote frontier agent — structurally, not by policy prose.
- **Energy as budget.** Each consultation debits the tier's attempt cost from **every** link of the chain before the stage runs. The reference per-tier costs are the §1.1 class markers in µJ (`l0`=1, `l1`=10, `l2`=10³, `l3`=10⁶, `l4`=10⁷), tagged honest `Estimator`; a deployment with a meter substitutes measured figures.
- **Denial as fallthrough.** A denied tier behaves exactly as a tier that could not close: the cascade falls through. A request whose only closing tier is denied resolves to nothing rather than overspending.
- **Every consultation seals.** Allow and deny alike seal as chained JCR-1 receipts carrying the full grant-id chain and, on deny, the machine-readable reason (`action-not-granted`, `budget-exceeded`, …).
The reference binding is the `joule-code-jcp` crate (`JcpGate::wrap` over any `Stage`). Conformance class **C5** (§8) exercises this binding against the published vectors.
### 5.2 Contracted operations (OPTIONAL)
A deployment MAY run coding operations under a **JouleContract** (the sibling contract standard), turning the operation's implicit promises into a five-obligation contract with a signed receipt. When it does, the binding is field-for-field, not analogical:
- **The edit set is the frame.** The contract's declared mutable footprint is a path set; every `Edit.path` MUST fall within it. An out-of-frame edit is an out-of-frame effect — caught at the boundary, and recorded as an `undischarged` frame naming the offending path rather than suppressed (a breach recorded honestly beats a breach driven underground).
- **The tier cost is the ceiling.** The cascade's per-tier joule class prices the contract's EnPI ceiling; an overrun is a recorded deviation (negative residual), never a block — receipt-time enforcement, amend-or-fix resolution.
- **Provenance maps downward only.** `HwShunt` → `Metered` (with a meter binding), `ModelBased` → `ModelBased` (with a calibration anchor), `Estimator` → `Unaccounted`. The binding can never promote an energy category.
- **Receipts grade honestly.** The binding emits receipts that pass JouleContract's receipt-local validation (at most JR-2 under its two-stage rule); composing to JR-3+ with sealed evidence, a key log, and anchored intervals is the deployment's verifier-of-record work.
The reference binding is the `joule-code-joulecontract` crate (`contract_for_op` / `frame_check` / `Binder::receipt_for_op`).
---
## 6. The receipt (JCR-1)
A `Receipt` accounts for one coding operation and **MUST** carry:
- `op_id` — the operation it accounts for (§3).
- `tier` — the tier that closed the request (§1.1).
- `energy` — a record `{ measured_uj: Option<u64>, estimated_uj: u64, provenance: Provenance }`. `measured_uj` is present only when obtained from a hardware energy interface that is live for the domain the figure claims. `estimated_uj` is always present.
- `provenance` — one of `HwShunt` (read from a hardware energy interface: an external shunt, or a vendor energy counter — RAPL, NVML, Apple SMC/IOReport — while it is live), `ModelBased` (computed from a calibrated per-operation model), `Estimator` (a coarse constant estimator). A reading tagged `HwShunt` **MUST** correspond to a present `measured_uj`; a reading tagged `Estimator` **MUST NOT** carry one.
- `sequence`, `nonce` — monotonic sequence and per-receipt nonce.
A reading from a vendor energy counter (RAPL, NVML, Apple IOReport, ...) **MAY** be tagged `HwShunt` only while the counter is demonstrably live for the domain the figure claims — observed advancing under load, by the test in [`spec/receipt.md`](spec/receipt.md) §2. A counter that is present but not live — frozen, or republished in lumps — **MUST NOT** supply an `HwShunt` tag or a `measured_uj`; the reading falls back to the estimator, and a figure **MUST NOT** claim coverage of a domain its counter does not read.
### 6.1 Signed form (JCR-1)
The receipt's signed, on-the-wire form is a **JCR-1 envelope** — the signed-receipt format shared across the Transaction Science family. As of **v0.2** Joule Code adopts JCR-1 rather than a bespoke preimage, so a Joule Code receipt verifies under the family's existing JCR-1 tooling (and its cross-language Python/Go verifiers).
- **Canonical core.** The signed bytes are the canonical det-CBOR (RFC 8949 §4.2.1, **length-first** key order, shortest-form integers, no floats/bools/nulls) of the `joule-code/1` profile of the JCR-1 wire object: `{ jc_receipt: "joule-code/1", op_id, tier (the wire tag "L0".."L4"), estimated_uj, measured_uj (only when present), energy_provenance ("HwShunt"|"ModelBased"|"Estimator"), sequence, nonce (lowercase hex), steward }`. Null-valued fields are dropped from the core.
- **Envelope.** A **COSE_Sign1** envelope (RFC 9052), **EdDSA / Ed25519, `alg = -8`** only, over the canonical core. The endpoint identity is carried in the COSE `kid` (the `steward`). A verifier **MUST** reject any other `alg`, a `kid` other than the expected steward, and signature failure.
The estimator of last resort (when only token counts are available, e.g. from an L4 ACP agent) computes `estimated_uj` from per-token coefficients and **MUST** tag the reading `Estimator`. Reference coefficients are non-normative and live in [`spec/receipt.md`](spec/receipt.md).
---
## 7. Federated collaboration (Research)
Multiple endpoints **MAY** collaborate on a shared tree by replicating coding operations. When they do, an operation is structurally a [Smart Byte](../smart-byte/) envelope whose cargo is the `CodingOp`, replicated by lockstep deterministic simulation with BFT supermajority commit among a known, signed-membership cluster; session and transport bind to WAI (MLS group state, FROST threshold signing, MoQT presence). This binding is specified at the interface level only in [`spec/collab.md`](spec/collab.md) and is classified **Research** (§9). v0.1 conformance does **not** require it; a single-endpoint runtime is fully conformant.
---
## 8. Conformance
A Joule Code implementation is **conformant** if it round-trips the published wire vectors in [`conformance/v1/`](conformance/v1/) (the vector pack is per spec major version; v0.x share pack `v1`):
- **C1 — content addressing.** Reproduce the `op_id` for each vector in `coding_op_vectors.json` from its canonical CBOR.
- **C2 — signing.** Verify (and, given the seed, reproduce) each signature in `signature_vectors.json`; reject every negative vector (wrong base, tampered edits).
- **C3 — receipt.** Verify each receipt's JCR-1 COSE_Sign1 envelope in `receipt_vectors.json` against the steward + endpoint key, confirm its payload is the receipt's canonical signed core, and honor the `Provenance`/`measured_uj` coupling in §6; reject every negative vector.
- **C4 — cascade.** Given the scripted stage outcomes in `cascade_vectors.json`, select the same closing tier as each vector (stop-at-first-close).
- **C5 — gated cascade** *(only for implementations claiming §5.1)*. Given the grants, budgets, and scripted stage outcomes in `gated_cascade_vectors.json`, reproduce each vector's closing tiers, total debit, and the sealed receipt verdict sequence (deny reasons included). The fixture identities and per-tier costs are fixed in the vector pack so runs are deterministic end to end.
Reference implementations are conformant by construction. Third-party implementations certify themselves by running the public suite.
---
## 9. Readiness classification
Per the family discipline, each part is classified and the classification is respected when sequencing work:
| Part | Class | Note |
|---|---|---|
| §2 cargo, §3 identity, §4 canonical form | **Solid** | content addressing + deterministic CBOR are well-trodden |
| §6 receipt (`estimated`, `Estimator`) | **Solid** | the meter exists in the reference consumer today |
| §6 receipt (`measured`, `HwShunt`/`ModelBased`) | **Engineering** | requires a hardware energy interface that is live for the domain it claims; honest absence when unavailable or not live |
| §1.1/§5 cascade binding | **Engineering** | the agent schema (JouleClaw) exists; binding L0–L4 to coding requests is real integration work |
| §5.1 grant-gated consultation | **Solid** | the JCP runtime and chained receipts exist today; the binding is composition, exercised by C5 |
| §7 federated collaboration | **Research** | interface-level only in v0.1; not required for conformance |
---
## 10. Versioning
Joule Code versions independently of its sibling standards. Release tags follow `joule-code-vX.Y.Z` (current: `joule-code-v0.2.0`). A change here does not bump the others. Conformance vector packs are per-spec-major-version (`conformance/v1/`, ...); historical packs are never removed.