wai: receipts, keys, grants and parameter sets over HTTP; key logs anchored over TLS (W3-3) #200
Merged
dcharlot
merged 23 commits from 2026-10-10 17:16:05 -04:00
wai/w3-3-http-receipts into main 2026-10-10
falsify: every mutation names the cases it must fail; receipt-surrogates reaches one
All checks were successful
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 35m41s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 36m22s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 4m31s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 4m56s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 4m42s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 4s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m17s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m6s
wai-pack / wai-pack · linux (pull_request) Successful in 1m5s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 1m47s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 16s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m20s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 36m54s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 52m0s
standards workspaces build + test / aac-rs (pull_request) Successful in 8m54s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 6m49s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 5m1s
standards workspaces build + test / map-rs (pull_request) Successful in 6m36s
standards workspaces build + test / mesh-rs (pull_request) Successful in 1m6s
standards workspaces build + test / openpay (pull_request) Successful in 1m31s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 9m7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m7s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m18s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 2m51s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m54s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m5s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 11m1s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m10s
wai-pack / wai-pack · macos (pull_request) Successful in 2m13s
A mutation used to pass when http_verify.py merely exited non-zero, so a crash counted as a catch: receipt-surrogates printed "ok … 0 failures" because the mutated verifier raised UnicodeEncodeError in lp() on the lone surrogate it had just admitted. - falsify/mutations.txt lists each of the 77 mutations with the cases it must fail, as each patch does; run.sh reads the mutations from it. A mutation passes only when http_verify.py exits non-zero and prints a FAIL line for every listed case; a traceback, or a non-zero exit with no named FAIL, is reported as a harness failure. The mutation count, and so the shard totals, are unchanged. - receipt-surrogates models a reader that admits an unpaired surrogate (RFC 8259 §8.2) and carries it on. Receipt text is now encoded with text_bytes(), which never raises (the unpaired surrogate goes as the bytes a lenient reader would hash), so the mutated verifier reaches a verdict: playlist_receipt_lone_surrogate and playlist_receipt_lone_low_surrogate give playlist_receipt_invalid where the corpus says playlist_receipt_malformed. The unmutated reader still refuses such text first, by name (playlist_receipt_malformed), as wai-rs does; no corpus case changes. Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09
CI: falsify the HTTP corpus in shards, each patch rebuilt incrementally
Some checks failed
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI HTTP delivery / WAI HTTP · does this change touch it (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
workflow hygiene / every workflow supersedes its own queue (pull_request) Has been cancelled
The single falsify job ran past the runner's 3 h limit: each patch built in a fresh worktree under the release profile (LTO, one codegen unit), about 72 s apiece, and the Python mutations ran one after another after them. - falsify/run.sh builds one worktree of the head once, then applies each patch, rebuilds incrementally, verifies, reverses the patch and requires a clean tree. The new `falsify` profile (wai-rs/Cargo.toml) keeps overflow checks and debug assertions on, as in the tests, so the oracle is unchanged; the unpatched tree must build and pass first. - `--patches I/N` and `--mutations I/N` run the ones whose index mod N is I; each shard prints what it ran and fails unless that is exactly what was assigned. `--check-shards` fails unless the declared shards' totals agree, their indices are 0..N-1 and their assignments cover every patch and mutation once. `--differential` runs the differential alone. - wai-http.yml: a matrix of three patch shards and three mutation shards; a `shards` job checks the matrix's own list with --check-shards; the corpus verify and the differential in their own job; a `relevant` job gates the work on the pull request's own diff (scripts/pr-touches-paths.py), as wai-pack.yml does. The concurrency block is kept. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (at
03ca161a) into wai/w3-3-http-receipts
Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 36m57s
standards workspaces build + test / aac-rs (pull_request) Successful in 9m0s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 6m48s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 3m16s
standards workspaces build + test / map-rs (pull_request) Successful in 7m28s
standards workspaces build + test / mesh-rs (pull_request) Successful in 5m43s
standards workspaces build + test / openpay (pull_request) Successful in 11m9s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 9m43s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 2m8s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m36s
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m11s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m11s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
WAI section references / cited sections exist (pull_request) Successful in 12s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m11s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 3m23s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 5m5s
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
Co-Authored-By: Claude Opus 5.5 <[email protected]>
http receipts round 4: falsify the bounded reads and the key-log cap
Patches bytes-read-whole and key-log-uncapped; bytes-unchecked, fetch-budget-unchecked and fetch-unmemoised regenerated against the new fetcher. Co-Authored-By: Claude Opus 5.5 <[email protected]>
http receipts round 4: a deadline TLS cannot stretch, a capped key log, a labelled test anchor, a byte budget never passed
The five items of the TLS verification of 0ef0063a, and the smaller sixth.
1. --deadline-ms on the TLS path. Every socket read and write goes through
DeadlineSocket, which waits at most what remains and is TimedOut once the
deadline passed, so rustls's handshake loop and a trickling peer cannot
extend it; the lookup runs on its own thread, joined within the deadline.
Plain HTTP uses the same socket.
2. A key log is read to 1 MiB and a longer one refused whole
(key_log_too_large): in anchor_retrieved and hold_cached_revisions
(http_binding::keys::MAX_KEY_LOG_BYTES), and on the test path. §8.4 states
the cap; corpus cases at and past it, anchored and cached, both ways.
3. The test path anchors with key_log::AnchorPath::TestPlaintext, labelled
test-plaintext in the report and in every confirmation, never fetched.
4. The exit-status test moves to O7, whose index passes whole: rc 0 with the
log pinned, rc 1 with the test anchor, the verdicts otherwise equal.
5. Each receipt fetch is asked for no more than what remains of the index's
64 MiB and of the file's cap plus one byte (the fetch closure now takes that
limit, and what it returns past it is unread); a file that reaches the end
of the budget is refused. The CLI reads no further than the limit. §8.2 says
so exactly.
6. Every address a host resolves to is tried in turn, within the deadline,
for TLS and plain HTTP alike.
Python mutations bytes-read-whole and key-log-uncapped. Corpus 1045 cases,
Rust and Python agree.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (at
17b7559a) into wai/w3-3-http-receipts
Some checks failed
standards workspaces build + test / jouleclaw-rs (pull_request) Has been cancelled
standards workspaces build + test / aac-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-code-rs (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Has been cancelled
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsification and differential (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
workflow hygiene / every workflow supersedes its own queue (pull_request) Has been cancelled
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08
Merge main (at
248846f1) into wai/w3-3-http-receipts
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (at
db5b8094, with W5-4 #187) into wai/w3-3-http-receipts
Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # wai/http-conformance/README.md # wai/http-conformance/falsify/run.sh # wai/http-conformance/http_verify.py
CI: the falsify job's comment names round 3's mutations
Co-Authored-By: Claude Opus 5.5 <[email protected]>
http receipts round 3: falsify the fixes
Patches (falsify/run.sh), each failing the corpus cases it names: bytes-unchecked, decision-unchecked, recovery-record-unchecked, operating-point-unchecked, session-accepted, declaration-unnamed, first-publisher, matchers-need-object and set-sha-faults; claim-through-any-receipt, fetch-unmemoised, fetch-budget-unchecked and file-cap-unchecked regenerated against the new receipts.rs. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai http receipts: anchor an origin over TLS only
Finding 1 of the review of 30cefd1b. `--key-origin` anchored an https origin over
plain HTTP, an origin with no port could not be anchored, and `--connect` let any
server stand in for the origin with the output unchanged.
- The CLI retrieves the key log over TLS itself (feature `cli_tls`, which only the
binary uses): rustls with the ring provider already in the graph, and
rustls-platform-verifier for the operating system's trust store. TLS to the
origin's host and port (443 by default), SNI and certificate validation for that
host, `Cache-Control: no-cache`, no redirect followed; the Retrieval built only
from that request and its response. A response's end must be authenticated
(close_notify) or framed (Content-Length, chunked).
- Without `cli_tls`, the CLI refuses to anchor (key_log_not_from_origin, "no TLS")
and connects to nothing.
- `--connect` is gone; `--test-plaintext-connect` is a test aid whose anchor is
labelled `test-plaintext` (relied_on false, "anchors nothing a verifier may rely
on"), never `fetched`, and the command exits 1.
- Tests: the binary's own TLS tests against servers under a test CA
(tests/fixtures/tls/, test keys): an anchor from a TLS retrieval with the SNI,
Host and no-cache seen by the server; another host's certificate, a plaintext
server (never sent a plaintext request), a redirect and an unauthenticated end
each anchor nothing; the origin parser. cli_http: the test anchor labelled as
such, and a plaintext server at the origin's address never asked in plaintext,
with and without cli_tls (CI runs both).
- §8.4: a retrieval is an https retrieval the verifier made itself.
- Licences: wai-rs gains deny.toml (wai-pack's allow-list, over the binary's
features on its host targets), checked in the wai-pack licences job; wai-pack's
lock is unchanged by this.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
http receipts round 3: publisher key, matchers, every step-6 class, declarations by name, a bytes budget
Findings 2-6 of the review of 30cefd1b, in the text, wai-rs, http_receipts.py and
the corpus together.
2. A soft binding's recovery uses, of the publisher keys held for the ancestor,
the one that signed the declaration, whichever delivery came first; the first
key only when none did, for the reason (recovery_signer_mismatch).
3. Recovery through a soft binding is gated on the object being held inside
check_claim (it now takes `held`); a recovery record's matchers are passed
whether or not the object is held (§2.6.3 step 5 needs a matcher, not the
object).
4. Corpus cases for lawful-basis decisions, binding-recovery records, operating
points and a session claim, accepted and refused, their bodies
claim-conformance's accepted vectors retargeted to the corpus's objects and
signed with its keys; O7 delivered under a second publisher's key, listed
before, after and alone.
5. A declaration fetched by link is read as §8.1 reads every file fetched by name
(receipt_name_mismatch and steps 1-2 first); step 6's reasons only for one that
names correctly and does not match. §8.2 states that this revision carries no
OER receipt over HTTP, so an energy claim naming one is context_not_held. Each
cap has its rationale; a 64 MiB read budget per index
(receipt_fetch_bytes_exhausted), counting at most a byte past each file's cap.
6. param_set with an uppercase digest is pin_malformed in wai-rs too (the corpus
tool no longer reads a grants file under a digest that does not read).
Python mutations bytes-unchecked, decision-unchecked, recovery-record-unchecked,
declaration-unnamed, first-publisher, matchers-need-object,
operating-point-unchecked and session-accepted; corpus 1030 cases, Rust and
Python agree.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (at
ae9a1ca6) into wai/w3-3-http-receipts
Co-Authored-By: Claude Opus 5.5 <[email protected]> # Conflicts: # wai/http-conformance/README.md # wai/wai-rs/src/jwp_delivery.rs
2026-10-07
http receipts: falsify the round-2 fixes
Patches (falsify/run.sh) for each fix, each failing the corpus cases it names: legacy-group-read, walk-unclamped, fetch-unmemoised, fetch-budget-unchecked, file-cap-unchecked, index-size-unchecked, index-items-uncapped, index-claims-uncapped, claim-through-any-receipt, ancestor-unrecovered, step6-skipped, figure-not-held-accepted, energy-context-assumed, gap-coordinates-unchecked; ancestor-as-object, claim-parent-unfetched, rcpt-name-unchecked, walk-skipped and walk-unbounded regenerated against the new receipts.rs. Python mutations groups-from-listed, budget-unchecked and caps-unchecked added, and the round's legacy-admitted, memo-off, walk-unclamped, step6-skipped and ancestor-any listed in run.sh in place of ancestor-as-object. The CLI's stream server now outlasts the deadline, so a client without the index cap reports the deadline instead; the wall-clock assertion is dropped (the deadline's own report is what the test reads). Co-Authored-By: Claude Opus 5.5 <[email protected]>
CI: wai-http paths cover what the receipt checks read; http_verify.py needs cryptography
wai-http.yml now runs on changes to jcs, signer_id, energy_class, energy_figure, energy_binding, energy_report, claim_text, oer, claim_receipt/ and oer2_verify.py, which the receipt, claim and key checks of §8.1-§8.5 read. wai-conformance.yml no longer says http_verify.py is standard library only. Co-Authored-By: Claude Opus 5.5 <[email protected]>
http receipts: step 6, items that passed, recovery, bounds, legacy groups, anchoring
Round-2 fixes to http-delivery §8.1-§8.4, in the text, wai-rs, http_receipts.py and the corpus together. 1. Claims run jwp-receipts §3.1 step 6 against what the passed delivery items deliver: energy against their object receipts (a named OER receipt is context_not_held); measurement/operating-point against the moq-jwp:object figure of an item delivered under the claimed group (energy_figure::HeldObject), else figure_not_held / context_not_held; delivery-gap against an item at its coordinates; decisions and recovery records against the declaration fetched by link; reconstruct-session context_not_held. Never acceptance without context. 2. A claim about a receipt attaches only through the group of an item whose delivery check passed. 3. A soft binding of another object is reported as attesting the ancestor only after §3.2 steps 2-5 pass (held object, a publisher key from a verified delivery, a matcher); otherwise receipt_not_about_object. 4. Bounds: receipt files 1 MiB (receipt_too_large), indexes 4 MiB with 256 items and 256 claims (receipt_index_too_large), each name fetched once per index (memo), 1024 fetches per index (receipt_fetch_budget_exhausted); the CLI fetches under a deadline (--deadline-ms) and these caps, never following a redirect. 5. A legacy (unlabelled) group file is refused (receipt_legacy_group): its name does not fix its parent. 6. The parent walk is clamped to 64 whatever bound is asked. 7. wai http receipts --key-origin retrieves the key log itself from --connect, sending anchoring_request_headers, following no redirect, and builds the Retrieval from the response. Corpus: measurement/energy/gap claims and O5's index, legacy group, a 66-deep chain, padded files and indexes, 256/257 items and claims, a fifty-fold item list; 1015 cases, Rust and Python agree. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (at
0e6c54dd) into wai/w3-3-http-receipts
Co-Authored-By: Claude Opus 5.5 <[email protected]>
http-conformance: falsify the receipt side — the receipt file's name, the parent walk and its bound, an object not received, a refused fetch, the ancestor rule, a claim's parent, the index's members, anchoring after a redirect, an older cached log, the grants file's module, a set held without the key log, and a non-string kind
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge main (PR #175 merged; main at
fda932fc) into wai/w3-3-http-receipts
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: http-delivery §8.1–§8.5 state what is built; README, CHANGELOG and CI for the receipt side
http-delivery §8.1–§8.5: the receipt file's form and reading, the parent walk and its bound, the index read item by item and each item's checks in order, claims by subject with the ancestor rule, where §8.3's content hash may come from and what an object not received gets, anchoring from the origin only, logs through caches, the grants file as a locator, the JCP grant carried only by reference, and sets held by their pins; four reasons in §13; §14 and §15. jwp-receipts §3 step 3 points to the HTTP recovery. CI: the corpus tool builds with key_discovery wherever it is built; the CLI test runs with it; the HTTP binding's receipts and keys build for wasm32; the falsify job installs the Ed25519 package its receipt-side mutations need, and its paths cover the receipt, claim, key-log and pin code and their Python verifiers. The key-log fuzz family anchors about half its cases. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai:
wai http receipts, the origin's index and status headers, and a non-string kind is wrong_kind
`wai http receipts` fetches an object by §7, then its receipt index and the receipt files it locates, through http_binding::receipts only, and prints what each item established, with signers confirmed under a pinned key log. The reference origin serves an index for revalidation and a key status for a quarter of the head's status_max_age_s at most (origin::receipt_index_headers, key_status_headers). The receipt-side differential found that jwp_delivery read a group or object receipt whose `kind` is not a string as `malformed`, where jwp-receipts §3 step 1 and jwp_verify.py say `wrong_kind`: fixed, with a unit test and a corpus case. The fuzz tallies now count refusals inside steps and checks. Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: receipts, keys, grants and parameter sets over HTTP
http_binding::receipts (receipt_claims): receipt files named by their link hash, the receipt index read item by item, each delivery item through jwp-receipts §3 against the client's chains with missing parents walked by their links up to a bound, step 4 against what the client holds of the object, and claims by subject and parent; a soft-binding claim about another object attests the ancestor. http_binding::keys (key_discovery): a key log anchored only from the origin's own location over HTTPS with a 200 and no redirect, logs through caches adding revisions without moving the anchor, grants files as locators, and parameter sets held only by their pins and §7.9. B's retrofit: jwp_hash::EstablishedHash, built only from bytes or by a fetch session whose head proof verified (FetchSession::established); ObjectReceipt::accept_hash and verify_against_hash, and WaiReceiptProperty::check_against_object_hash, which accept and check_against_object call; ReceiptChains::verify_admitted_object. Corpus: group receipts, claims, indexes, a key log, status, grants file and a set served by digest, with receipt_file, receipts, key_log, grants_file and param_set cases; http_receipts.py checks them for http_verify.py. Co-Authored-By: Claude Opus 5.5 <[email protected]>