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]>
68 lines
4.5 KiB
JSON
68 lines
4.5 KiB
JSON
[
|
|
{
|
|
"name": "rcpt-001-estimator-l4",
|
|
"description": "Positive (C3): an L4 receipt from token counts only, sealed as a JCR-1 COSE_Sign1 envelope (RFC 9052, EdDSA -8) over the canonical det-CBOR signed core. measured_uj MUST be absent; provenance MUST be Estimator. estimated_uj = input*200000 + output*2000000. Regenerated against joule-code-rs.",
|
|
"receipt": {
|
|
"op_id": "b3:6Ysltc7O3IupNKFXybnzyv2ot32SSLLvCQRB8AHKIdQ",
|
|
"tier": "L4",
|
|
"energy": { "measured_uj": null, "estimated_uj": 4400000000, "provenance": "Estimator" },
|
|
"sequence": 1,
|
|
"nonce": "0000000000000001"
|
|
},
|
|
"steward": "did:example:joule-code-endpoint",
|
|
"endpoint_seed": "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
|
|
"endpoint_verifying_key": "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
|
|
"expected_envelope": "d2845825a2012704581f6469643a6578616d706c653a6a6f756c652d636f64652d656e64706f696e74a058d3a86474696572624c34656e6f6e63657030303030303030303030303030303031656f705f6964782e62333a3659736c7463374f334975704e4b465879626e7a7976326f74333253534c4c76435152423841484b4964516773746577617264781f6469643a6578616d706c653a6a6f756c652d636f64652d656e64706f696e746873657175656e6365016a6a635f726563656970746c6a6f756c652d636f64652f316c657374696d617465645f756a1b000000010642ac0071656e657267795f70726f76656e616e636569457374696d61746f725840a9d221d11b8f8708dfeee070c626c47bd77ccfe2a64ef0b7c5c0f94e36702256b29a0f2037628eac0359c1c7249d985be25a8bdc01fd22fa596fd5fa2d659106",
|
|
"expected_verify": true,
|
|
"error": null
|
|
},
|
|
{
|
|
"name": "rcpt-002-hwshunt-measured",
|
|
"description": "Positive (C3): an L3 receipt with a hardware-measured figure, sealed as a JCR-1 COSE_Sign1 envelope. provenance HwShunt REQUIRES a present measured_uj, carried in the signed core.",
|
|
"receipt": {
|
|
"op_id": "b3:8kTnZfhR3BBgx2VP2_jOVImOXqkLUoSkNRSjw91j9uI",
|
|
"tier": "L3",
|
|
"energy": { "measured_uj": 1850000, "estimated_uj": 2000000, "provenance": "HwShunt" },
|
|
"sequence": 2,
|
|
"nonce": "0000000000000002"
|
|
},
|
|
"steward": "did:example:joule-code-endpoint",
|
|
"endpoint_seed": "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
|
|
"endpoint_verifying_key": "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
|
|
"expected_envelope": "d2845825a2012704581f6469643a6578616d706c653a6a6f756c652d636f64652d656e64706f696e74a058dea96474696572624c33656e6f6e63657030303030303030303030303030303032656f705f6964782e62333a386b546e5a6668523342426778325650325f6a4f56496d4f58716b4c556f536b4e52536a7739316a3975496773746577617264781f6469643a6578616d706c653a6a6f756c652d636f64652d656e64706f696e746873657175656e6365026a6a635f726563656970746c6a6f756c652d636f64652f316b6d656173757265645f756a1a001c3a906c657374696d617465645f756a1a001e848071656e657267795f70726f76656e616e63656748775368756e7458404a60a0a8fc89930af24c72f22f3c9cb4467a623d1fc2f9d9e332aa15dfcfa82af7ff19b7ed396862dd559f2e78eba748b0264b6cf86d25b3447da9790b7d8b0f",
|
|
"expected_verify": true,
|
|
"error": null
|
|
},
|
|
{
|
|
"name": "rcpt-003-hwshunt-without-measured-rejected",
|
|
"description": "Negative (C3): provenance HwShunt with measured_uj absent violates the provenance/measured coupling (SPEC §6) and MUST be rejected before sealing.",
|
|
"receipt": {
|
|
"op_id": "b3:8kTnZfhR3BBgx2VP2_jOVImOXqkLUoSkNRSjw91j9uI",
|
|
"tier": "L3",
|
|
"energy": { "measured_uj": null, "estimated_uj": 2000000, "provenance": "HwShunt" },
|
|
"sequence": 3,
|
|
"nonce": "0000000000000003"
|
|
},
|
|
"steward": "did:example:joule-code-endpoint",
|
|
"endpoint_verifying_key": "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
|
|
"expected_envelope": null,
|
|
"expected_verify": false,
|
|
"error": "hwshunt_requires_measured"
|
|
},
|
|
{
|
|
"name": "rcpt-004-estimator-with-measured-rejected",
|
|
"description": "Negative (C3): provenance Estimator with a present measured_uj is dishonest (a measured figure must not be tagged as an estimate) and MUST be rejected before sealing.",
|
|
"receipt": {
|
|
"op_id": "b3:6Ysltc7O3IupNKFXybnzyv2ot32SSLLvCQRB8AHKIdQ",
|
|
"tier": "L4",
|
|
"energy": { "measured_uj": 1000000, "estimated_uj": 4400000000, "provenance": "Estimator" },
|
|
"sequence": 4,
|
|
"nonce": "0000000000000004"
|
|
},
|
|
"steward": "did:example:joule-code-endpoint",
|
|
"endpoint_verifying_key": "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
|
|
"expected_envelope": null,
|
|
"expected_verify": false,
|
|
"error": "estimator_must_not_carry_measured"
|
|
}
|
|
]
|