Reconciles the Joule Code receipt with JCR-1, the signed-receipt format shared across the Transaction Science family, so a Joule Code receipt verifies under the family's existing JCR-1 tooling (and its cross-language Python/Go verifiers) instead of a bespoke preimage. v0.1 -> v0.2 wire change. - SPEC 6.1: the receipt's signed form is now a JCR-1 envelope — canonical det-CBOR (RFC 8949 4.2.1, length-first key order) of the "joule-code/1" profile, inside a COSE_Sign1 envelope (RFC 9052, EdDSA alg -8); steward in kid. - joule-code-receipt: new jcr1 module (canonical CBOR + COSE_Sign1, vendored from the JCR-1 reference algorithm — no JouleClaw dependency, keeping the lean lib self-contained) + Receipt::to_jcr1_wire / seal / verify_envelope. Removed the bespoke sign/verify. A test pins the canonical encoder byte-for-byte against a published JCR-1 conformance vector. - Conformance C3 vectors regenerated as JCR-1 COSE_Sign1 envelopes; the harness verifies the envelope and that its payload is the receipt's canonical core. - spec/receipt.md, CHANGELOG (0.2.0), READMEs, workspace version -> 0.2.0. Verified: the conformance harness passes the whole pack with no skips; cargo test --workspace green; vanity scanner clean. Co-Authored-By: Claude Opus 4.8 <[email protected]>
4.1 KiB
Joule Code — The Receipt
Normative sub-specification of ../SPEC.md §6. CC-BY-4.0.
Every coding operation carries a receipt: a signed, two-part energy record carried in a Joule Wire Protocol (JWP) frame. The receipt is the falsifiable cost basis of the operation — not its market price, but its honest energy cost.
1. Structure
Receipt {
op_id: ContentId,
tier: Tier,
energy: Energy,
sequence: u64,
nonce: [u8; 8],
sig: [u8; 64], // Ed25519 over the energy preimage (§3)
}
Energy {
measured_uj: Option<u64>, // present ONLY when from a hardware interface
estimated_uj: u64, // always present
provenance: Provenance,
}
Provenance = HwShunt | ModelBased | Estimator
2. The provenance contract (REQUIRED)
The Provenance tag states how honest the figure is, and the spec never claims more than the platform delivers:
HwShunt— read from a hardware energy interface (RAPL, Apple SMC/IOReport, an external shunt). A reading taggedHwShuntMUST havemeasured_uj = Some.ModelBased— computed from a calibrated per-operation energy model.measured_ujMAY be absent.Estimator— a coarse constant estimator (e.g. per-token coefficients applied to L4 token counts).measured_ujMUST be absent.
A runtime MUST NOT populate measured_uj from anything but a hardware interface, and MUST NOT tag a reading HwShunt without a present measured_uj. Absence is the honest answer when the platform cannot measure.
3. Signed form — JCR-1 (v0.2)
As of v0.2 the receipt's signed form is a JCR-1 envelope (SPEC §6.1), the signed-receipt format shared across the Transaction Science family — not a bespoke preimage. A Joule Code receipt therefore verifies under the family's existing JCR-1 tooling and its cross-language (Python/Go) reference verifiers.
core = canonical-det-CBOR( # RFC 8949 §4.2.1, length-first keys
{ jc_receipt: "joule-code/1", op_id, tier, estimated_uj,
measured_uj?, energy_provenance, sequence, nonce, steward } )
envelope = COSE_Sign1( # RFC 9052, EdDSA -8
protected = { 1: -8, 4: bstr(steward) },
payload = core,
signature = Ed25519_sign(endpoint_secret, Sig_structure) )
Sig_structure is ["Signature1", protected, external_aad(empty), core] (RFC 9052 §4.4). Verification parses the tagged COSE_Sign1 (CBOR tag 18), rejects any alg but -8, rejects a kid other than the expected steward, checks the Ed25519 signature, and confirms the payload equals the receipt's canonical core. Sealing the receipt this way makes the cost basis non-repudiable by the endpoint that produced it and interoperable with every other family pillar.
v0.1 used a bespoke
estimated_uj ‖ sequence ‖ nonce [‖ measured_uj]preimage; v0.2 replaces it with JCR-1. This is the v0.1→v0.2 wire change.
4. The estimator of last resort (non-normative coefficients)
When only token counts are available — the common L4 case, where a remote ACP agent reports input_tokens / output_tokens but no energy — the estimator computes:
estimated_uj = input_tokens * J_IN_uj
+ output_tokens * J_OUT_uj
and tags the reading Estimator. The coefficients are non-normative and tunable; the reference consumer ships datacenter-scale defaults where output dominates prefill. Reference values (illustrative, not part of conformance): J_IN_uj = 200_000, J_OUT_uj = 2_000_000 (i.e. 0.2 J / 2.0 J per token). The point of the standard is not the constant — it is that the figure is reported, signed, and honestly tagged as an estimate.
5. From estimated to measured
Promoting a tier's receipts from Estimator to HwShunt/ModelBased is the work item that turns the meter "real" (ROADMAP v0.2). The receipt schema does not change; only the provenance tag and the presence of measured_uj improve as the platform gains a hardware interface. A consumer's UI SHOULD surface the provenance so a reader can tell a measured joule from an estimated one.