jcp: dual ceilings — a money budget beside the joule budget (SPEC §4.8 + C22) #19

Merged
dcharlot merged 2 commits from jcp/dual-ceilings into main 2026-07-17 02:56:32 -04:00

2026-07-17

Transaction Science
jcp: C22 conformance — executable check + published dual-ceiling vectors
Completes SPEC §4.8. The prior commit left this as a noted follow-up; a
conformance class without an executable check and a published vector is not a
standard, just an assertion.

- jcp-conformance: `c22_dual_ceilings` registered in checks(), so it runs in the
  harness alongside C1-C21 (verified: "✓ C22 dual ceilings: money beside joules,
  no rate invented"). It asserts every property §4.8 requires — a joules-only
  grant's encoding omits the field entirely; adding a money ceiling changes the
  grant's identity; an allow debits both dimensions; money binding while joules
  have room denies funds-exceeded and debits neither; the mirror (joules bind,
  money has room) denies budget-exceeded; a foreign currency is refused
  currency-mismatch rather than converted; an absent ceiling means "joules alone
  bound", not zero; and attenuation refuses a raise, a drop, or a
  re-denomination while a plain attenuate inherits.

- conformance/v1/dual_ceilings.json: a NEW file (following standing.json's
  precedent of one file per feature) carrying the fixed-key dual-ceiling grant
  and the three receipts that define C22 — allow / funds-exceeded /
  currency-mismatch — plus spent_after {uj:10, minor:300} proving the denials
  debited nothing. A cross-language verifier can replay all three.

Verified the backward-compatibility guarantee rather than trusting it:
gen-vectors was run into a temp dir and vectors.json, standing.json, and
meta.json all diffed BYTE-IDENTICAL against the committed copies. Only the new
file is added.

Workspace green (40 suites), clippy clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-17 00:58:18 -04:00

2026-07-16

Transaction Science
jcp: dual ceilings — a money budget beside the joule budget (SPEC §4.8)
A real-world AP2 mandate authorizes agent spend in a currency (dollars), while
JCP meters work in joules. The two cannot be reconciled by an exchange rate —
there is no canonical joules-per-dollar, and inventing one fabricates authority.
Until now a currency-denominated mandate yielded no joule ceiling at all
(Ap2Mandate::joule_budget -> None) and simply could not be gated. This adds the
second dimension so the mandate is enforceable without any conversion.

Design: a Grant may carry an OPTIONAL budget_funds { currency, minor } beside
budget_uj. Both ceilings are enforced independently; the first to bind denies,
and the sealed receipt records which one. A receipt that reads "denied: joule
ceiling, while the money ceiling had room" is a statement no single-dimension
authorization can make -- that is the point.

- jcp-schema: Funds (integer minor units -- money is typed, and the canonical
  encoding forbids floats); Grant.budget_funds: Option<Funds> with
  skip_serializing_if, so a joules-only grant encodes BYTE-IDENTICALLY to one
  minted before this field existed -- content id, signature, and every published
  conformance vector unchanged (proven by test, and the vectors still verify).
  New deny reasons FundsExceeded / CurrencyMismatch.
- jcp-runtime: Price, decide_priced -- deny on whichever ceiling binds first,
  refuse a foreign currency (never convert), debit both on allow / neither on
  deny, and treat an absent money ceiling as "joules alone bound" (not zero).
- jcp-grant: attenuate INHERITS the parent's money ceiling (dropping it would
  amplify); attenuate_priced + funds_narrows narrow it independently and refuse
  a raise, a drop, or a currency change.
- jcp-bridge / jcp-a2a: the priced path end to end -- Ap2Mandate::funds_ceiling,
  A2aProfile::from_mandate_priced (money ceiling from the mandate, joule ceiling
  from the operator), serve_task_priced. Tested: a USD mandate now gates and
  denies on funds-exceeded, sealed in a verifiable receipt.
- SPEC.md: normative §4.8 + conformance class C22.

The other ~11 files are the compiler-forced budget_funds: None at each Grant
literal -- deliberately NOT defaulted, so a new construction site must decide
rather than silently inherit unbounded money authority.

Full workspace green (40 suites), clippy clean, existing a2a example unchanged.
Follow-up (not done): a published C22 conformance vector in conformance/v1/.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-16 23:16:51 -04:00