The monorepo's IOReport energy backends now decline unless the CPU energy rail keeps advancing: on macOS 27 an unprivileged reader sees the CPU rails frozen or republished only in rare lumps, so a meter that trusted a present counter reported CPU work as GPU-only energy, or as zero, while tagging it a reading. The owner's decision is that a vendor energy counter is a real reading (the trust gap is provenance, not accuracy), so a LIVE reading is graded as a hardware reading, and every spec that grades vendor counters now carries the same rule: A reading from a vendor energy counter (RAPL, NVML, Apple IOReport, ...) MAY be graded as a hardware reading only while the counter is demonstrably live for the domain the figure claims: the implementation MUST have observed the counter covering that domain advance under load (for Apple IOReport: the CPU energy rail itself advancing in at least 5 sample intervals, in at least 4 of every 5, over at least 300 ms while the probing thread burns CPU). A counter that is present but not live - frozen, or republished in lumps - MUST NOT produce a hardware-graded figure; the implementation falls back to its estimator or reports the work unmetered, and SHOULD record why. A figure MUST NOT claim coverage of a domain its counter does not read; where the format has a coverage field, such a figure is Partial. Joule Code - spec/receipt.md §2 (REQUIRED): HwShunt now reads "an external shunt, or a vendor energy counter (RAPL, NVML, Apple SMC/IOReport) while that counter is live"; the rule above is added verbatim, and in this receipt the hardware grade is a present measured_uj and the HwShunt tag, so a counter that is not live supplies neither. The §1 comment and §5 say "live". - SPEC.md §6: the provenance definition now names IOReport and NVML beside RAPL/SMC, measured_uj comes only from an interface live for the domain it claims, and a paragraph states the MAY/MUST NOT, pointing to receipt.md §2 for the test. The §9 readiness row says "live" and "not live". - ROADMAP.md v0.2 "Measured energy": a vendor counter feeds the HwShunt path only while live; where it is present but not live (IOReport's CPU rails to an unprivileged reader on macOS 27) the receipt stays on the estimator. - examples/l3-jouleclaw/README.md: the claim that the receipt is "a real local measurement ... (HwShunt on RAPL/NVML hosts; Estimator on Apple Silicon until IOReport is wired)" was wrong both ways: run.rs wires only Apple Silicon's counter, and other hosts fall to the token Estimator. It now says so, that the counter's own tag is carried, and that HwShunt needs a live counter. - joule-code-receipt: the Provenance::HwShunt doc comment says the same. - CHANGELOG.md [Unreleased] ### Changed: the rule; no wire or vector change. Sense - SPEC.md §7 (REQUIRED): measured_uj comes only from a live interface; the rule is added verbatim. The Sandbox PowerMeter was described as "(real RAPL/IOReport)"; it is now described as grading a reading HwShunt only while its counter is live and falling back to its estimator otherwise, which is what origin/sandbox-meter/cpu-rail-liveness implements. §10's Sandbox edge says the same in brief. - sense-schema: the HwShunt, Energy and Energy::measured doc comments say a vendor counter is a hardware reading only while live. - Sense keeps no CHANGELOG, so none is added. Other specs that grade vendor counters - map/spec/receipt.md §2: the HwShunt row read "RAPL/SMC/shunt"; it now names a counter "while it is live", and the rule is added verbatim, noting that Receipt::seal cannot check liveness (the meter's duty, upstream). map/SPEC.md §6 states the MUST NOT and points there. CHANGELOG.md gains an [Unreleased] ### Changed entry; no wire or vector change. - arl/ARL-S.md, Telemetry: physical telemetry is what gates tiers above 0, and it said energy is "measured directly via RAPL ... NVML". The rule is added in ARL-S's own terms and lower-case keywords (ARL uses no RFC 2119 capitals): a counter that is not live does not produce physical telemetry, the energy it would have covered is reported unmetered, and the Supervisor must have observed the counter advance. No version bump. - smart-byte treatise §8.6: "Where RAPL or equivalent hardware energy counters are available, the measurement is read from the hardware" now requires the counter to be demonstrably live, and a frozen or lump- republished counter yields the same honest zero as an absent one. Text and doc comments only: no code path, wire format, or conformance vector changes. joule-code-rs (joule-code-receipt, joule-code-conformance) and sense-rs (sense-schema, sense-conformance) build and test clean, their rustdoc builds under -D warnings, map-rs (map-receipt, map-conformance) tests pass, `joule-code-conformance verify ../conformance/v1` passes 24/0/0, the no-vanity-metrics check passes, and every relative link in the changed Markdown resolves. Co-Authored-By: Claude Opus 5.5 <[email protected]>
15 KiB
Joule Code v0.2 — Energy-Attributed Federated Coding Operations
Status: Draft Standard. Reference implementation: 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; 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 ofEdits. EachEditnames apath, ananchor(a byte range or a content-addressed hunk), and areplacement.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 Stages, 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; the agent schema that implements L1–L4 is 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 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 namel4can 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 honestEstimator; 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.pathMUST fall within it. An out-of-frame edit is an out-of-frame effect — caught at the boundary, and recorded as anundischargedframe 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_ujis present only when obtained from a hardware energy interface that is live for the domain the figure claims.estimated_ujis always present.provenance— one ofHwShunt(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 taggedHwShuntMUST correspond to a presentmeasured_uj; a reading taggedEstimatorMUST 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 §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/1profile 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 = -8only, over the canonical core. The endpoint identity is carried in the COSEkid(thesteward). A verifier MUST reject any otheralg, akidother 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.
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 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 CommunicationOS (MLS group state, FROST threshold signing, MoQT presence). This binding is specified at the interface level only in 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/ (the vector pack is per spec major version; v0.x share pack v1):
- C1 — content addressing. Reproduce the
op_idfor each vector incoding_op_vectors.jsonfrom 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.jsonagainst the steward + endpoint key, confirm its payload is the receipt's canonical signed core, and honor theProvenance/measured_ujcoupling 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.