wai.edge.derivation: the deriving edge — derive, publish under its own receipts, chain to the source, carry provenance #379
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/deriving-edge"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this is
D1, the deriving edge. The roadmap item reads: "An edge that evaluates derived tracks and rebuilds or re-packs content under its own receipt, chained to the source." Until now a conforming relay could only forward envelopes and receipts unaltered.
This PR adds that edge as the record
wai.edge.derivation(wai/extensions/deriving-edge.md):Derivations. An edge may do three things:
wai.derive.*operation (identity, crop, ROI selection, rotation, mirror, grid, overlay, scaling) over 8-bit RGB samples;wai.video.int_motionclip, written as awai.image.pngstill or awai.image.jpegpicture;WAI2component as its explodedWAI1envelope (wai-edge:explode).Publishing. Each output is a new object. The edge publishes it in a group of its own track, under its own key.
The record. It names:
object_id, frame and samples digest, and the record that derived it where another edge did;The record is JSON under jwp-receipts §2.4.3's encodings. It is signed over JCS (
wai:derivation\x01) and identified byBLAKE3("wai:derivation-link\x01" ‖ JCS).The check.
replicateapplies when every step is pinned:WIV1keyframe-0 decode;codecs::derivation::derived_sample_tier, the registry's own composition rule (every one but scaling);A verifier that holds the inputs re-executes the derivation and compares the output byte for byte.
attestapplies otherwise (a JPEG encode, a resampling). The inputs and every pinned step before the attested one are still checked.Verification. The verifier follows a derived object back to its source, one hop at a time. A sink policy can refuse attested hops (
attested: refuse), require re-execution (recompute: required), or require authority (authority: required).Authority. The authority is
edge/derive. It is registered in jwp-receipts §7.5, and it comes from the origin of the source each chain reaches: that origin's key log lists the edges it trusts with its content.Refusals. There are 31 reason codes, each with a corpus control. They include:
derivation_unknown;input_receipt_invalid,input_hash_mismatch);replicate_mismatch;edge_not_authorised;chain_skips_hop(a hop that passes an edge's output off as a source object),hop_not_heldandhop_mismatch;provenance_strippedandsynthesis_dropped.Provenance carried forward (added at the lead's request, from the regulation sweep)
I read California AB 853's chaptered text myself (Statutes of 2025, Chapter 674). §22757.3.1(b) says a large online platform "shall not, to the extent technically feasible, knowingly strip any system provenance data or digital signature…", operative 1 January 2027. §22757.1 (n), (o) and (p) define personal, provenance and system provenance data.
For C2PA I read version 2.2: §A.3.2 (a PNG carries its manifest store in a
caBXchunk) and §18.14 (actions).Provenance items. Each record lists, by digest, every provenance item of every input:
claim, by link hash);c2pa, by SHA-256). The still reader now admitscaBX.Each item is in a
systemor apersonalcompartment, read by §22757.1's split. An item the record leaves out is refused asprovenance_stripped. A sink therefore holds every item's digest from the subject's record alone.AI-origin label. Every input and output carries a label,
assist<generate, ornullwhen none is known. It may rise along a chain and never fall: a lowered label issynthesis_dropped. A step that synthesizes content labels its output. The terms are the top two step classes of the origin claimsyn-provenanceis building, so one vocabulary serves both; I told that session.Decisions, and why
claimclass. It follows the key log's precedent: JSON under §2.4.3's encodings, JCS, its own domains.claim_receipt.rs, the claims corpus andclaim_verify.pyare untouched, and every existing claim verifier is unaffected. The record still uses the JWP hash family, so it names inputs and outputs by content hash and group link hash.wai_edge derive|verify), not a mode ofjoule-moq-relay.wai-rsdependency, so a relay mode would add a local-publisher path and that dependency.tests/derive_edge.rsruns it twice over a publisher's clip to make a chain of two hops, checks that the chain verifies with recomputation required, and checks the refusals that follow when the bundle is tampered with.wai-packintowai-rs(png_still, a feature with no dependencies). The edge's replicate outputs are byte-reproducible pinned stills.wai-pack/src/png.rsre-exports the module and keeps its tests; nothing it calls changes.IHDR,IDAT,IENDandcaBX. A colour chunk would state a representation the samples do not carry, which breaks derived-tracks' same-representation condition.derived_fromnaming its input. A multi-input output carries none, becausederived_fromnames one motif and the record names all of the inputs.--energypasses a meter's figure, asjoule-moq-relaydoes. The corpus's figures are fixed test values.Checks
All cargo work ran on the build host through
rb.cargo test --locked --no-default-features --features derive_edge --lib -- derive_edge:: png_still::cargo test --locked --no-default-features --features derive_edge --test derive_edgecargo run --locked --no-default-features --features derive_edge --bin wai_edge_vectors -- verify ../edge-conformancepython3 -I edge-conformance/edge_verify.py edge-conformance(stdlib only)cargo test --locked --lib --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film,oer,receipt_claims,key_discovery,staged,video_int,audio_int,splat_int,stage_measure,telemetry,video_package,httpcargo run --no-default-features --bin wai -- registry export(pulled) then--checkcargo clippy --locked --no-default-features --features derive_edge --all-targetscargo clippy --locked --all-targets -- -D warnings;cargo test --release --locked;wai-pack conformance check ../pack-conformancecargo metadata --locked --offlinein every workspace whoseCargo.locknameswai(9)include/wai.hrb --pullover builds withderive_edgecbindgen:ignore)live-conformance/*_verify.py,claim_verify.py,jwp_verify.py,signer_verify.py,staged_verify.py,int_payload_verify.pycheck-tests-in-ci.py,check-workflow-concurrency.sh,check-spec-refs.py,check-wai-section-refs.py,check-no-vanity-metrics.sh,test-public-text-checks.sh,check-comparative-prose.sh,check-orphan-sources.pyFalsifications (each committed first, then broken, then restored)
verify.rs, and removed theprovenance_strippedrow from §9.tests/derive_edge.rsthen failed 3 of 4 tests (exit 101):provenance_strippedandreplicate_mismatchwere accepted;edge_verify.pyfails every one of its 23 mutated copies of the corpus. These include:Not done
parentOf, withc2pa.transcodedorc2pa.repackaged.syn-provenance's origin claim (wai-origin), and the edge signing the output's origin claim, are to come once both branches land.wai.derive.dissolveand nosrgb_fill. Rebuilds handle WIV1 keyframe 0 only. There is no video floor (AV1) rebuild.🤖 Generated with Claude Code