Runtime::charge debits before it computes the verdict, so a call that
breaches MaxCostUj or a joule window at the debit point is denied and stays
debited. replay_spend kept only verdict == "allow", so a replayed stream
restored less than was spent: reproduced at the base with three failing
tests (0 restored against 900, 400, and 900 on each link of a chain).
The verdict cannot say what was debited. The same reasons also refuse a call
before any work, and a refusal seals the cost it refused, so cost does not
separate them either. And a two-phase debit saturates at the ceiling, each
link of a chain at its own, so it can be less than cost_uj.
The signed core now says, where the verdict does not. debited_uj is a uint,
since the core holds no bool, and chain_debited_uj lists each link's figure
beside chain_ids where a cap left them differing. Only a capped debit and a
denial naming caveat-unsatisfied or window-exceeded carry a member, the
denial always, 0 on a refusal, so its absence there can only mean a receipt
sealed before the member. Every other receipt keeps its bytes and the tag
stays jcp/2: regenerating the pack changes no published file.
Those older receipts keep verifying. A denial of either reason without the
member reads as its cost_uj, the most it can have debited, since an unknown
debit is not a zero one: an old log restores at least what was debited, and
SPEC §8.1 says exactly what it can no longer prove.
Decision carries the debit, so it is no longer Copy: a chain's per-link
figures are a Vec. aggregate now matches the ledger too, charge no longer
underflows a grant an old log restored past its ceiling, and ReceiptLog gains
append_chained, without which a logged chained decision lost its ancestors.
conformance/v1/replay.json publishes a hash-chained log with chain_ids, seq,
prev and every form of the member, its spend taken from the runtime's ledger
and not from the receipts. conformance/verify_replay.py is a second reader
sharing no code with the reference implementation, run by the repository
checks with its own planted faults.
Changelog: none
Co-Authored-By: Claude Opus 5.5 <[email protected]>