wai: live provenance, C2PA 2.4 §19 for room tracks and takes, tied to the JWP receipts #381

Merged
dcharlot merged 11 commits from wai/c2pa-live into main 2026-10-21 07:14:09 -04:00
110 changed files with 11979 additions and 45 deletions

View file

@ -106,6 +106,10 @@ on:
# reports, live_ads_verify.py reads that table, and the registry's wire identifiers test
# reads its sections.
- 'wai/extensions/live-ads.md'
# tests/live_provenance.rs requires this extension's §12 to list the codes and the C2PA
# codes the reference reports, c2pa_live_verify.py reads that table, and the registry's
# wire identifiers test reads its sections.
- 'wai/extensions/live-provenance.md'
- 'wai/wai-web/**'
# The audio provenance check below reads the corpora above with this tool.
- 'wai/tools/wai_audio_provenance_check.py'
@ -776,7 +780,8 @@ jobs:
# live_metering_verify.py (the live-metering corpus), energy_steering_verify.py (the
# energy-steering corpus), and live_moderation_verify.py (the live-moderation corpus), and
# e2ee_verify.py (the end-to-end encrypted rooms corpus), live_watermark_verify.py (the
# forensic-watermark corpus) and live_ads_verify.py (the live-ads corpus).
# forensic-watermark corpus), live_ads_verify.py (the live-ads corpus) and
# c2pa_live_verify.py (the live-provenance corpus).
# Each exits non-zero on any failure or any difference, and the step fails with it.
# One platform: what they check is the reading of the text, not the architecture.
independent-verifiers:
@ -1091,6 +1096,27 @@ jobs:
(cd wai-rs && cargo test --no-default-features --features live_ads --lib wai_video_ssai::)
(cd wai-rs && cargo test --no-default-features --features live_ads --test live_ads)
python3 -I live-conformance/live_ads_verify.py live-conformance/ads
# wai.live.provenance (extensions/live-provenance.md): the reference module's unit tests
# (boxes, chunks, emsg and the BMFF hash; the JUMBF store; COSE_Sign1 and the OKP key;
# certificates written and read, their profile and chain; identifiers, track renderings,
# dates and the compositor's source type) and tests/live_provenance.rs (every file of the
# committed corpus regenerates byte for byte from its fixed seeds and the packaging
# corpus's AV1 floor, and no other file is there; wai-rs gives every vector its stated
# outcome; every reason of §12 refuses a vector; §12 lists exactly the reference's codes
# with the two C2PA codes it reports); then the corpus's second implementation,
# c2pa_live_verify.py, written from the extension's text and sharing no code with
# wai-rs, which reads CBOR, ISO BMFF, JUMBF, COSE and X.509 DER itself, verifies every
# signature with WAI's strict Ed25519 rule and every receipt with BLAKE3 from
# claim-conformance, reads the extension's reason table, and requires every mutated copy
# of a good vector to be refused; standard library only, run isolated (-I).
- name: live provenance · wai-rs and c2pa_live_verify.py
working-directory: wai
shell: bash
run: |
set -euo pipefail
(cd wai-rs && cargo test --no-default-features --features live_provenance --lib live_provenance::)
(cd wai-rs && cargo test --no-default-features --features live_provenance --test live_provenance)
python3 -I live-conformance/c2pa_live_verify.py live-conformance/c2pa-live
# wai.live.e2ee (extensions/confidentiality.md): the corpus's second implementation,
# e2ee_verify.py, written from the extension's text and the documents it reads and
# sharing no code with the reference (joule-moq's secure_objects and joule-moq-mls,

View file

@ -6,6 +6,72 @@ wire format may change and such changes are recorded here.
## v0.4.0 — current
### `wai.live.provenance`: C2PA 2.4 live video provenance for room tracks and takes, tied to the JWP receipts
- **The extension** ([live-provenance](extensions/live-provenance.md)) registers the record
`wai.live.provenance`: C2PA 2.4 §19's live video provenance, written exactly as §19 defines
it, for a room's CMAF tracks and a device's CMAF take. A room track packaged as CMAF travels
under `draft-ietf-moq-cmsf-01`, each MoQ group one segment and each object one CMAF chunk.
A segment is its C2PA boxes followed by its group's objects and nothing else, so the
segment's `c2pa.hash.bmff.v3` and the group's JWP receipt commit to the same chunks; the
segment's sequence number is its first `mfhd`'s, following from the receipts' leaf counts.
- **Both methods.** Per-segment C2PA Manifest Boxes: each manifest holds the hard binding, the
actions, `c2pa.livevideo.segment` (the stream identifier and the manifest before it) and a
group assertion naming its receipt by link hash and root. Verifiable Segment Info: an `emsg`
of version 0 per segment carrying a COSE_Sign1 by a session key over the segment-info map;
the session keys, OKP Ed25519 keys bound to the claim signer's certificate, are delivered in
the initialization manifest and rotated by a manifest in a segment, and the session key also
signs the group's receipts. A take uses both at once, its device's key the session key, and
its stream identifier its take id's, as capture-binding §11 had them.
- **The profile.** One manifest per store; EdDSA throughout, deterministic as C2PA §13.2.1
recommends for streaming; an X.509 chain of version 3 Ed25519 certificates with
`c2pa-kp-claimSigning`; four whole-box exclusions in every hash; every manifest identifier
derived from the stream, the manifest's role and the segment's sequence number. Two readings
of C2PA 2.4 are stated: the VSI box's exclusion offset is 12, where `scheme_id_uri` begins,
since the 0 §19.4.1 prints compares a box's size; and a `signerBinding` is detached with a
`nil` payload, as §13.2.3 requires, where §18.25's example prints `h''`.
- **AI disclosure.** Every manifest carries the IPTC digital source type and one
`c2pa.ai-disclosure` per model that the stream's label gives, as timed-text §10.3 gives them
for captions; a compositor's output is `compositeCapture`, `composite` or
`compositeSynthetic` from its inputs' labels and carries their models' disclosures. A stream
labelled machine-made without the marking is refused. This is the machine-readable marking
Regulation (EU) 2024/1689 Article 50(2) describes, stated as an engineering requirement.
- **Dynamic and redundant packaging.** C2PA 2.4 treats content packaged on request as live
(§19.2.1) and recommends deterministic signatures for it, naming ISO/IEC 23009-9 (§13.2.1).
With derived identifiers, deterministic CBOR and Ed25519, every byte of a segment is a
function of its group's objects, the stream and the claim signer's key: packagers that share
a key write the same segment, and packagers that do not chain across a failover, their
segments' objects under the publisher's one receipt. Checking two encoders' outputs by
re-encoding under a `replicate` capability is stated as not in this revision.
- **Repository receipts** (C2PA 2.4 §18.27). A registered initialization segment keeps its
manifest box as `original` and ends with an `update` box: an update manifest whose one
ingredient is the parent, with the parent's validation results, and whose
`c2pa.repository-receipt` carries, as the repository's proof, an RFC 9942 receipt of
inclusion of the parent's manifest hash in the repository's RFC 9162 log, verified against
the repository's key.
- **Carriage.** Over HTTP, the segment files. Over MoQ, each segment's C2PA boxes ride a
provenance track, `<layer>_c2pa` (`packaging` `wai-c2pa`, named in `wai_c2pa_track`), whose
group *g* is segment *g*'s C2PA boxes, so the media objects stay the chunks a CMSF player plays
and the receipts commit to; the initialization segment rides the catalog's inline data.
- **Thirty-three reasons**, from `segment_malformed` to `segment_missing`, each with the C2PA
2.4 §15 and §19.7 codes a C2PA validator reports for it, where C2PA checks it.
- **Reference and corpus.** `wai-rs` feature `live_provenance` (`src/live_provenance.rs` and
its `bmff`, `jumbf`, `cose`, `x509` and `corpus` modules), with no C2PA library and no new
dependency. `live-conformance/c2pa-live/`, written from fixed seeds by
`wai_live_provenance_vectors` over the packaging corpus's AV1 floor: a camera track under each
method (the session key rotated at its third segment), a track labelled machine-made, a
compositor's output, a take, a failover between two packagers and a registered stream; and
one negative per reason, among them a segment whose bytes
changed, a missing segment and a reordered one, a manifest bound to the wrong receipt, a
stream identifier that differs, an expired and a time-stamping end entity, and a machine-made
track without its disclosure. Checked by `tests/live_provenance.rs` and by
`live-conformance/c2pa_live_verify.py`, a second implementation that shares no code with
`wai-rs` and requires every mutated copy of a good vector to be refused. The corpus's
initialization segments, the registered one with its update manifest included, also validate
in the C2PA command-line tool; the tool opens no media segment (`c2pa-live/README.md`). The
registry lists the record and the catalog values `wai-c2pa` and `wai_c2pa_track`.
- **capture-binding §11** now points here for the C2PA side of a take, and is implemented.
### `wai-ops/1-i32` on GPUs, and the tier where a run showed it
- **`wai/wai-ops-gpu`**, an operator implementation of `wai-ops/1-i32` (integer-operators §9.1) in WGSL compute kernels through wgpu: Metal, Vulkan and DX12 natively, and a browser's WebGPU. WGSL has no 64-bit integer, so the kernels use 32-bit words only:

View file

@ -42,7 +42,8 @@ Every registered string has one kind.
`wai.video.manifest` and its siblings; the live records `wai.live.events`,
`wai.live.room`, `wai.capture.take`, `wai.live.compose`, `wai.live.recording`,
`wai.live.metering`, `wai.live.steering`, `wai.live.moderation`, `wai.live.e2ee`,
`wai.live.watermark` and `wai.live.ads`; timed text, `wai.text.timed`).
`wai.live.watermark`, `wai.live.ads` and `wai.live.provenance`; timed text,
`wai.text.timed`).
It names no payload format.
A derivation or record string is not a payload capability, so it is not
@ -202,6 +203,7 @@ and a role are fixed once registered.
| `wai.live.events` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.metering` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.moderation` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.provenance` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.recording` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.room` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.live.steering` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
@ -356,6 +358,7 @@ and a role are fixed once registered.
| `urn:wai:event:1` | scheme | defined | live-events §8.4 |
| `urn:wai:event:1` | catalog | defined | live-events §8.1 |
| `wai` | catalog | defined | moq-streaming-format §3 |
| `wai-c2pa` | catalog | defined | live-provenance §10.2 |
| `wai-key-status` | document-kind | defined | jwp-receipts §7.9 |
| `wai-module-grant` | document-kind | defined | jwp-receipts §7.9 |
| `wai-module-grants` | document-kind | defined | http-delivery §8.4 |
@ -366,6 +369,7 @@ and a role are fixed once registered.
| `wai2` | codecs-prefix | defined | http-delivery §4.1 |
| `wai2` | fourcc | provisional | http-delivery Appendix B |
| `waiC` | fourcc | provisional | http-delivery Appendix B |
| `wai_c2pa_track` | catalog | defined | live-provenance §10.2 |
| `wai_capabilities` | catalog | defined | moq-streaming-format §4 |
| `wai_delivery_timeout_ms` | catalog | defined | packaging §8 |
| `wai_determinism` | catalog | defined | moq-streaming-format §4 |

View file

@ -594,8 +594,8 @@ kind:
`wai.video.package` and `wai.video.channel`; and the live records `wai.live.events`,
`wai.live.room`, `wai.capture.take`, `wai.live.compose`, `wai.live.recording`,
`wai.live.metering`, `wai.live.steering`, `wai.live.moderation`, `wai.live.e2ee`,
`wai.live.watermark` and `wai.live.ads`, and timed text, `wai.text.timed`), which names no
payload format.
`wai.live.watermark`, `wai.live.ads` and `wai.live.provenance`, and timed text,
`wai.text.timed`), which names no payload format.
Only payload, companion and refinement capabilities have a media class, a
fidelity tier, a replicate class and a role. A derivation or record string is not a payload
@ -1071,6 +1071,28 @@ recomputes the fill and the asset list, refuses a second receipt of one session
and holds the spend of every receipt together to the decider grant's ceiling:
[`extensions/live-ads.md`](extensions/live-ads.md).
And for the **provenance** of a room's CMAF tracks and a device's CMAF take —
`wai.live.provenance`: the live video provenance of the C2PA Technical Specification, version
2.4, §19, written as it defines it. A room track packaged as CMAF travels under
`draft-ietf-moq-cmsf-01`, each MoQ group one segment and each object one chunk, and a segment
is its C2PA boxes followed by its group's objects and nothing else, so the segment's C2PA hard
binding and the group's JWP receipt commit to the same chunks. Under the per-segment C2PA
Manifest Box method each segment's manifest holds a `c2pa.hash.bmff.v3` over the segment, the
live video segment assertion naming the stream and the manifest before it, and the link hash
and root of its group's receipt; under the Verifiable Segment Info method each segment carries
an `emsg` with a segment-info map signed by a session key delivered in a manifest, rotated in a
segment's manifest, and the same key signs the group's receipts. The claim signer's X.509 chain
and its profile, the session keys' binding to it, and every object's receipt are checked
together. A stream labelled machine-made carries C2PA's digital source type and AI disclosure
for its model in every manifest, as timed text does for a caption model, and a compositor's
output names its inputs' labels. Manifest identifiers are derived from the stream and the
segment and every signature is deterministic, so packagers sharing a key write the same
segment and packagers that do not chain across a failover, as C2PA 2.4 has dynamically
packaged content; and a registered initialization manifest carries C2PA's repository receipt,
whose proof is an RFC 9942 receipt of inclusion in the repository's RFC 9162 log. The C2PA
boxes of each segment ride a provenance track beside the media track:
[`extensions/live-provenance.md`](extensions/live-provenance.md).
### Payloads of the WAI-native integer codecs
This revision pins a payload format to each WAI-native integer codec whose row named

View file

@ -13,7 +13,8 @@
> its verdict: `single-take`, `aligned`, `complete` and `publishable` for each purpose.
> The reference case is a lesson or an audition, where the live call is low quality and
> the master is made on the performer's own device. No new transport: the commitments are
> events, and the mapping onto C2PA live video output is field semantics (§11). The
> events, and its C2PA live video output is a take stream of
> [live-provenance](live-provenance.md) (§11). The
> reference implementation is the `capture_take` module of `wai-rs` (feature
> `capture_take`); the corpus is [`live-conformance/takes/`](../live-conformance/takes/),
> and its second implementation is `live-conformance/capture_take_verify.py`.
@ -535,14 +536,14 @@ capture instant on the room clock maps that instant.
## 11. C2PA live video
This section maps a take, and a CMAF output of a room, onto the C2PA Technical
Specification's live video provenance (§19 there). It is field semantics, and this
revision implements none of it beyond the stream id: `wai-rs` has no CBOR or COSE
encoder, and the C2PA signer `c2pa_emit` uses writes whole-asset manifests and fragmented
BMFF manifests (one manifest in the initialization segment, a Merkle tree over the
fragments), with no live video segment assertion, no session keys assertion and no
Verifiable Segment Info. The take's commitments are the WAI side's witness; the C2PA
output is what a C2PA validator reads, and each is checked on its own.
This section maps a take onto the C2PA Technical Specification's live video provenance (§19
there). A take's CMAF master is a stream of kind `take` of [live-provenance](live-provenance.md)
(§3.1 there), which writes and verifies the C2PA structures; this section states what a take
puts in them. The reference implementation is `live-provenance`'s: the `live_provenance`
module of `wai-rs` writes a take's initialization segment and segments under both of §19's
methods and verifies them, and its corpus holds a take (`live-conformance/c2pa-live/take-both`).
The take's commitments are the WAI side's witness, which §9 verifies; the C2PA output is what
a C2PA validator reads, and each is checked on its own.
### 11.1 What maps to what
@ -550,29 +551,32 @@ output is what a C2PA validator reads, and each is checked on its own.
id's first 16 bytes as an RFC 9562 UUID of version 8: byte 6's high four bits set to
`1000`, byte 8's high two bits to `10`, written in the 8-4-4-4-12 lowercase form. The
corpus states it for each take.
- **The segments.** Where the master is CMAF, chunk *i* holds the segment whose movie
fragment the device numbers *i* + 1 in its `mfhd` `sequence_number`
(ISO/IEC 14496-12), and that is the segment's `sequenceNumber` in both methods. Chunk 0
holds the initialization segment too (§4.1), with the C2PA Manifest Box §19.2.3
requires.
- **The segments.** Where the master is CMAF, chunk *i* holds segment *i*, and chunk 0 holds
the initialization segment before it (§4.1), with the C2PA Manifest Box §19.2.3 requires.
The segment's `sequenceNumber`, in both methods, is the `mfhd` `sequence_number`
(ISO/IEC 14496-12) of its first movie fragment, the device numbering its movie fragments
from 1 across the take (live-provenance §3.3): *i* + 1 where each segment is one movie
fragment.
- **The hashes.** A chunk's `hash` covers every byte of the chunk, its C2PA boxes
included; the segment's `c2pa.hash.bmff.v3` excludes them by §19's exclusions. The two
are different digests of different spans.
### 11.2 Per-segment manifests (§19.3)
Each segment carries a C2PA Manifest Box in a `uuid` box, whose manifest holds a
`c2pa.hash.bmff.v3` over the segment and the assertion `c2pa.livevideo.segment` with
`sequenceNumber` as above, `streamId` the take's, `continuityMethod` `c2pa.manifestId`,
and `previousManifestId` the manifest identifier of chunk *i* − 1's segment. The
initialization segment's manifest carries `c2pa.actions.v2` whose first action is
`c2pa.created` with the IPTC digital source type `digitalCapture` (§18.15.2).
Each segment carries a C2PA Manifest Box whose manifest holds, as live-provenance §6 lists
them, a `c2pa.hash.bmff.v3` over the segment, `c2pa.actions.v2` (each segment's manifest is a
standard manifest, which §15.10.1.2 there requires to hold one) whose one action is
`c2pa.created` with the IPTC digital source type `digitalCapture` (§18.15.2), and the
assertion `c2pa.livevideo.segment` with `sequenceNumber` as above, `streamId` the take's,
`continuityMethod` `c2pa.manifestId`, and `previousManifestId` the manifest identifier of
the segment before it, or of the initialization segment's manifest for segment 0.
Each segment's manifest **MAY** also carry the assertion `science.transaction.wai.take`,
a map of `take` (the take id), `room` (the room id), `device` (the device's key) and
`commit` (the digest of the device's last `take_commit` before the segment was written,
absent before the first), each a byte string, so that a C2PA validator finds the room
events that witness the take.
Every manifest of the take holds the assertion `science.transaction.wai.take`
(live-provenance §5.3), a map of `take` (the take id), `room` (the room id) and `device` (the
device's key), each a byte string; a segment's also holds `commit`, the digest of the device's
last `take_commit` before the segment was written, and the initialization segment's `epoch`,
the room-clock instant of the master's media time 0 (§10), so that a C2PA validator finds the
room events that witness the take.
### 11.3 Verifiable Segment Info (§19.4)
@ -588,27 +592,25 @@ events that witness the take.
`timescale` and `event_duration` covering the segment, `id` the `sequenceNumber`, and
`message_data` a COSE_Sign1_Tagged by the session key whose payload holds
`sequenceNumber`, `bmffHash` (the segment's, excluding its C2PA `emsg` boxes, with no
`merkle` field) and `manifestId` (§19.4.1, §19.4.2).
`merkle` field) and `manifestId` (§19.4.1, §19.4.2), as live-provenance §7.2 writes it.
- A COSE Sig_structure begins with the context string `Signature1`, and every message
WAI signs begins with a `wai:` domain, so no signature of one is a signature of the
other.
### 11.4 A room's CMAF output
A CMAF rendition a packager makes of a room's live tracks maps the same way, as its own
live video session: its own `streamId`, its own session key, its own claim signer. That
is the packager's provenance of its output, not the device's of its take.
A CMAF rendition of a room's live tracks is a stream of kind `track` of live-provenance, as
its own live video session: its own `streamId`, its own session key, its own claim signer,
each segment tied to the JWP receipt of its group (§8 there). That is the publisher's or the
packager's provenance of its output, not the device's of its take.
### 11.5 AI disclosure and sustainability
- **AI disclosure** (§18.28, `c2pa.ai-disclosure`). A take's manifest has no field for a
trained model, and its C2PA output carries no `c2pa.ai-disclosure`: its source type is
a digital capture. A CMAF output that carries captions a model produced (live-events
§4.10, `origin` 2 or 3) discloses them: `modelIdentifier` is `sha256:` followed by the
caption's `model` digest in lowercase hexadecimal; `contentProfile`
`humanOversightLevel` is `fully_autonomous` for `origin` 2 and `human_validated` for 3;
`modelType` is required and an event does not carry it, so an emitter writes the
assertion only where it knows the model's type (§18.28's Table 12).
a digital capture. A room track or a compositor's output that is labelled machine-made
discloses its models as live-provenance §9 has it, and captions a model produced as
[timed-text](timed-text.md) §10.3 has it.
- **Sustainability** (§18.26, `c2pa.environmental-sustainability`). An emitter writes
`energy_kwh` only from a measured figure with its class, under
[energy-binding](energy-binding.md)'s rules, and never `carbon_kgco2e` or

View file

@ -0,0 +1,924 @@
# WAI Extension: Live Provenance
> Status: Draft. Registers the record `wai.live.provenance`: the live video provenance of
> C2PA 2.4 §19 for a room's CMAF tracks and for a device's CMAF take, written exactly as §19
> defines it and tied to WAI's own per-object commitments. A room track packaged as CMAF is
> carried over MoQ under `draft-ietf-moq-cmsf-01`: each MoQ group is one CMAF segment and each
> object one CMAF chunk. Its publisher signs a JWP group receipt for each group
> ([jwp-receipts](jwp-receipts.md)), and this extension makes the segment's C2PA hard binding
> and that receipt's Merkle root commit to the same bytes: the segment, less its C2PA boxes,
> **is** the group's objects in order. The per-segment C2PA Manifest Box method (§19.3 there)
> names the group's receipt inside the signed manifest; the Verifiable Segment Info method
> (§19.4 there) is signed by a session key that is also the key that signs the group's
> receipts. One verification then establishes the C2PA provenance of every segment and the
> receipt of every object. The C2PA boxes of each segment ride a **provenance track** beside
> the media track, as the receipts ride the receipts track. The machine-readable marking of
> machine-made content, the IPTC digital source type and the `c2pa.ai-disclosure` assertion,
> follows the stream's disclosure label, as [timed-text](timed-text.md) §10.3 has it for
> captions, and for a compositor's output, its inputs' labels. Every manifest identifier is
> derived from the stream and the segment, and every signature is Ed25519, so packagers that
> share a signing key write the same segment and packagers that do not still chain across a
> failover: the dynamically packaged content C2PA 2.4 §19.2.1 treats as live. The
> initialization manifest may carry C2PA's repository receipt (§18.27 there), whose proof is an
> RFC 9942 receipt of inclusion in a repository's RFC 9162 log. No new transport. The reference
> implementation is the `live_provenance` module of `wai-rs` (feature `live_provenance`); the
> corpus is [`live-conformance/c2pa-live/`](../live-conformance/c2pa-live/), and its second
> implementation is `live-conformance/c2pa_live_verify.py`.
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
>
> Texts read for this revision, each pinned to the version named: the C2PA Technical
> Specification, version 2.4 (April 2026), §5.3.1, §6.4, §8.1, §8.4.2, §10.2, §11.1, §11.2,
> §13.1, §13.2, §14.2, §14.4.1, §14.5, §15.5 to §15.12, §18.6, §18.15, §18.16, §18.25,
> §18.27, §18.28, §19 and Appendix A.5; RFC 9052 (COSE structures), RFC 9053 (EdDSA and OKP
> keys), RFC 9360 (`x5chain`), RFC 9942 (COSE Receipts) §2, §4 and §5, RFC 9162 §2.1,
> RFC 8949 §4.2.1, RFC 5280, RFC 8410, RFC 7093, RFC 9562 and RFC 4648 §5;
> `draft-ietf-moq-cmsf-01` §3; the Event Message box syntax of ISO/IEC 23009-1 §5.10.3.3.3 as
> AOM id3-emsg v1.0.0 §2.2.2 reproduces it; the IPTC Digital Source Type vocabulary as released
> on 2024-10-23; and Regulation (EU) 2024/1689, Article 50. ISO/IEC 14496-12, ISO/IEC 23000-19,
> ISO/IEC 19566-5:2023 (JUMBF) and ISO/IEC 23009-9:2025 (REaP) were not read for this
> revision: the box layouts below are the ones C2PA 2.4 and [packaging](packaging.md) §7
> (paragraph 7.6) state, REaP is named only as C2PA 2.4 §13.2.1 and §19.4.1 name it, and the
> corpus's README says what an independent C2PA validator reports for the corpus. A section
> number in this text is C2PA 2.4's unless it names another document.
## 1. Scope
In scope: what a stream is, how its segments correspond to a room track's groups or to a
take's chunks, its sequence numbers, its stream identifier and its presentation time (§3);
the C2PA structures this extension writes, which are a profile of C2PA 2.4: the manifest
store, the claim and its derived identifier, its signature and the signer's certificates, the
hard binding, the actions, and the repository receipt in an update manifest (§4); the WAI
assertions (§5); the per-segment C2PA Manifest Box method (§6); the Verifiable Segment Info
method, its session keys and their rotation (§7); the correspondence
with the group receipts and the object receipts (§8); the digital source type and AI
disclosure (§9); carriage over HTTP and over MoQ, and dynamic and redundant packaging (§10);
verification (§11); and the reasons (§12).
Out of scope: a transport; the media codecs; MPEG transport streams, which §19.1 excludes; a
track packaged as WAI envelopes (`packaging` `"wai"`, [moq-streaming-format](moq-streaming-format.md)
§3), which is not ISO BMFF and so has no §19 provenance; time-stamps (§10.3.2.5) and
revocation information (§14.5.2), which this revision neither writes nor reads; ingredients
other than an update manifest's parent, update manifests other than §4.7's, compressed
manifests, external manifests and the `manifestUri` of a segment-info map; the Merkle form of
the BMFF hash (Appendix A.5.4), which §19 does not use; consistency proofs between a
repository's tree heads (RFC 9942 §5.3); the segment indexing of ISO/IEC 23009-9 §6.2, which
§19.4.1 offers as an alternative to `mfhd` numbering; re-encoding a source to check that two
encoders' outputs agree (§10.3); and what a party does with a verdict.
Relationship to the core spec: `wai.live.provenance` is a **record** ([SPEC](../SPEC.md) §5):
a signed record a WAI tool emits and verifies. It names no payload format and is not
dispatchable.
Relationship to [capture-binding](capture-binding.md): §11 there maps a take onto C2PA live
video. A take is a stream of this extension of kind `take` (§3.1), and this extension is
where that mapping is written and verified.
## 2. Terms
- **Room**, **principal**, **track**, **Full Track Name**: as in [live-rooms](live-rooms.md)
§2 and §6.1. **Group receipt**, **object receipt**, **link hash**: as in
[jwp-receipts](jwp-receipts.md) §2.4 and §3 step 3.
- **Stream**: one C2PA live video session (§19): an initialization segment and media
segments, of one CMAF track.
- **Chunk**: one `moof` box and the `mdat` box after it.
- **Segment**: a media segment of the stream: its **C2PA boxes** (§3.2), then one or more
chunks.
- **C2PA Manifest Box**: the `uuid` box of Appendix A.5.1, with `box_purpose` `manifest`.
- **VSI box**: an `emsg` box carrying a verifiable-segment-info (§19.4.2).
- **Claim signer**: the holder of the X.509 end-entity certificate that signs a manifest's
claim. **Session key**: a key of §19.4.4, which signs segment-info maps.
- **Label**: the stream's disclosure label (§5.1): its `origin` (1 human, 2 machine, 3
machine-reviewed, as [timed-text](timed-text.md) §3.1 has them) and a model digest for 2
and 3, or, for a compositor's output, its inputs' labels.
- *T*: the instant a verification is made, in microseconds since 1970-01-01T00:00:00Z.
Integers in boxes are big-endian. A digest is SHA-256 (FIPS 180-4), 32 bytes, unless it is
named BLAKE3. CBOR is written in RFC 8949 §4.2.1's core deterministic encoding.
## 3. The stream
### 3.1 Kinds
A stream is of one of two kinds:
- **track**: a room track (live-rooms §6.1) of media kind `audio`, `video` or `screen`,
packaged as CMAF and published under `draft-ietf-moq-cmsf-01` (`packaging` `"cmaf"`). Each
MoQ group of the track is one segment and each object one chunk; `draft-ietf-moq-cmsf-01`
§3.3 lets an object hold more than one chunk, and this extension requires exactly one. The
publisher signs a group receipt for every group (jwp-receipts §2.4.1) and an object receipt
for every object (§2.4.2 there), and §8 ties them to the segments.
- **take**: the CMAF master of a take ([capture-binding](capture-binding.md) §3), whose chunk
*i* is the segment *i* of the stream, chunk 0 holding the initialization segment before it
(capture-binding §4.1, §11.1). The take's commitments in the room's events are its WAI
witness, and capture-binding §9 verifies them; this extension verifies the C2PA side and
the identity a take's manifests carry (§5.3).
### 3.2 Layout
The initialization segment is exactly three top-level boxes, in this order: `ftyp`, a C2PA
Manifest Box, and `moov`, holding one track (Appendix A.5.3; §19.2.3); or, once registered,
those three followed by the update box of §4.7. It holds no `mdat` (§19.7.1).
A segment is, in this order:
1. its C2PA boxes: a C2PA Manifest Box, a VSI box, or the first then the second;
2. one or more chunks.
It holds no other top-level box. A chunk's `moof` holds an `mfhd`, then one `traf` holding a
`tfhd` with default-base-is-moof and the track's `track_ID`, a `tfdt` of version 1 and a `trun`
of version 0 with a data offset and each sample's duration, size and flags, as packaging §7
(paragraph 7.6) writes a fragment; the data offset points at the `mdat`'s payload, and the
sizes fill it. The C2PA Manifest Box precedes the first `mdat` (Appendix A.5.3) and the VSI box
precedes the first `moof`, as an Event Message box precedes the `moof` of its chunk in CMAF.
**The bytes of a segment.** A segment is its C2PA boxes followed by its chunks, concatenated,
and nothing else. For a track, the chunks are the group's objects in object order, each
exactly as it travelled (§10.2), so a segment *is* `P ‖ O₀ ‖ … ‖ Oₙ₋₁`, *P* its C2PA boxes and
*O*ᵢ object *i*.
### 3.3 Sequence numbers
Every `moof` of the stream carries a `sequence_number` in its `mfhd`: 1 in the first chunk of
the stream's first segment, and one more in each chunk after it, across segments. A segment's
**sequence number** is the `sequence_number` of its first `moof`, and it is the
`sequenceNumber` of its live video segment assertion (§19.3.2) and of its segment-info map
(§19.4.1), each of which §19 requires to match `mfhd.sequence_number`. For a track, the
segment of group *g* therefore has the sequence number
*s*(*g*) = 1 + Σ *n*(*h*), over the groups *h* of the stream before *g*,
where *n*(*h*) is the `leaf_count` of group *h*'s receipt.
Where a segment holds more than one chunk, the sequence numbers of consecutive segments
differ by the number of chunks of the earlier one. §19.4.1's note reads them as one apart,
which is the case of one chunk per segment; its normative text, that the number matches
`mfhd.sequence_number` and never decreases or repeats, holds either way.
### 3.4 The stream identifier
A stream's `streamId` (§19.3.2) is an RFC 9562 UUID of version 8, written in the 8-4-4-4-12
lowercase form. Its 16 bytes are, before byte 6's high four bits are set to `1000` and byte
8's high two bits to `10`:
- for a track: the first 16 bytes of SHA-256(`"wai:live-provenance:stream\x01"` ‖ `room` ‖
u32(len(`track`)) ‖ `track` ‖ u64(`epoch`)), with the fields of the stream assertion
(§5.1);
- for a take: the take id's first 16 bytes (capture-binding §11.1).
### 3.5 Presentation time
The track's timescale is the `timescale` of its `mdhd`. A segment's presentation time is the
`baseMediaDecodeTime` of its first `tfdt`, in that timescale. For a track its instant is
`epoch` + ⌊`baseMediaDecodeTime` × 1 000 000 / `timescale`⌋ microseconds, with the `epoch` of
the stream assertion (§5.1) or, for a take, of the take assertion (§5.3).
## 4. The C2PA structures
Every C2PA structure this extension writes is the one C2PA 2.4 defines; this section fixes the
choices it leaves open, so that every conforming writer of a stream produces the same bytes
from the same inputs and keys.
### 4.1 The manifest store
A C2PA Manifest Box is a `uuid` box with extended type
`D8FEC3D6-1B0E-483C-9297-5828877EC481`, version 0 and flags 0, then `box_purpose` `manifest`
and a zero byte, then 8 zero bytes (the offset of the first merkle box, of which a stream has
none), then the manifest store (Appendix A.5.1 to A.5.3). It carries no padding.
The store is a JUMBF superbox (`jumb`, holding a description box `jumd` and then its content
boxes) of a single manifest, the active one. Each description box is the JUMBF type UUID (16
bytes), the toggles byte `0x03` (requestable, label present; §11.1.4.1.2), and the label in
UTF-8 followed by a zero byte. The boxes, with their type and label:
| box | JUMBF type UUID | label | content |
|---|---|---|---|
| the store | `63327061-0011-0010-8000-00AA00389B71` (c2pa) | `c2pa` | the manifest |
| the manifest | `63326D61-0011-0010-8000-00AA00389B71` (c2ma) | its identifier (§4.2) | the assertion store, the claim, the claim signature |
| the assertion store | `63326173-0011-0010-8000-00AA00389B71` (c2as) | `c2pa.assertions` | one superbox per assertion, in the claim's order |
| an assertion | `63626F72-0011-0010-8000-00AA00389B71` (cbor) | the assertion's label | one `cbor` box of its CBOR |
| the claim | `6332636C-0011-0010-8000-00AA00389B71` (c2cl) | `c2pa.claim.v2` | one `cbor` box of the claim |
| the claim signature | `63326373-0011-0010-8000-00AA00389B71` (c2cs) | `c2pa.signature` | one `cbor` box of the COSE structure |
Every box header is a 4-byte size, which includes the header, and a 4-byte type.
### 4.2 The manifest identifier and the claim
A manifest's identifier is `urn:c2pa:` followed by an RFC 9562 UUID of version 4 in the
8-4-4-4-12 lowercase form, with no claim generator identifier (§8.1). Its 16 bytes are, before
byte 6's high four bits are set to `0100` and byte 8's high two bits to `10`, the first 16
bytes of
SHA-256(`"wai:live-provenance:manifest\x01"` ‖ u32(len(`streamId`)) ‖ `streamId` ‖ u8(*role*) ‖ u64(*s*)),
`streamId` in its text form (§3.4), *role* 0 for the initialization segment's manifest, 1 for a
per-segment manifest (§6), 2 for a manifest that delivers session keys in a segment (§7.3) and
3 for the update manifest of §4.7, and *s* the segment's sequence number (§3.3), 0 for roles 0
and 3. The identifier is a function of the stream and the segment, not of the packager: every
packager of a stream writes the same identifier for the same manifest (§10.3). No two
manifests of a stream share one, and the 122 bits SHA-256 leaves are distributed as §8.1's
random ones are; the identifier is not a secret, and a signature, not the identifier, binds a
manifest.
The claim is a `claim-map-v2` (§10.2.1) with exactly these fields:
- `instanceID`: `xmp:iid:` followed by the manifest identifier's UUID;
- `claim_generator_info`: `{"name": "wai", "specVersion": "2.4.0"}`;
- `signature`: `self#jumbf=/c2pa/` ‖ the manifest identifier ‖ `/c2pa.signature`;
- `created_assertions`: one hashed URI (§8.4.2.1) per assertion, in the order of §6 and §7:
`url` `self#jumbf=/c2pa/` ‖ the manifest identifier ‖ `/c2pa.assertions/` ‖ the label, and
`hash` the SHA-256 of the assertion's superbox less its 8-byte header (§8.4.2.3);
- `alg`: `sha256`.
### 4.3 The claim signature
The claim signature is a `COSE_Sign1_Tagged` (CBOR tag 18; RFC 9052 §4.2) whose payload is
detached (`nil`) and whose Sig_structure payload is the claim's CBOR (§10.3.2.4, §13.2.2):
- protected header: the map `{1: -8, 33: [EE, CA]}`: the algorithm EdDSA, the Ed25519 instance
(§13.2.1; RFC 9053 §2.2), and `x5chain` under its integer label (§14.5; RFC 9360) holding the
claim signer's end-entity certificate and then every intermediate certificate, the trust
anchor left out;
- unprotected header: the empty map;
- Sig_structure: `["Signature1", protected, h'', payload]` (§13.2.3);
- signature: the 64-byte Ed25519 signature (RFC 8032) of the claim signer over the
Sig_structure's CBOR.
Ed25519 is deterministic, which §13.2.1 recommends for streaming so that equal segments
remain equal. Every signature this extension writes is Ed25519.
### 4.4 Certificates
The claim signer's chain meets §14.5.1.1 and RFC 5280: X.509 version 3; signature algorithm
`id-Ed25519` (RFC 8410 §3), no parameters; Ed25519 subject public keys; no unique
identifiers; a Basic Constraints extension, critical, asserting `cA` in a certificate
authority's certificate and absent `cA` in the end-entity's; a Key Usage extension, critical,
with `keyCertSign` (and `cRLSign`) in a certificate authority's and `digitalSignature` alone
in the end-entity's; a Subject Key Identifier in every certificate, the leftmost 160 bits of
the SHA-256 of the subject public key (RFC 7093 §2, method 1); an Authority Key Identifier,
its key identifier, in every certificate not self-signed; and, in the end-entity's, an
Extended Key Usage extension holding `c2pa-kp-claimSigning` (1.3.6.1.4.1.62558.2.1) and
`id-kp-documentSigning` (1.3.6.1.5.5.7.3.36), which §14.4.1 recommends for older validators.
Every name is an organization (`id-at-organizationName`) and a common name, each a
UTF8String. Validity is written as UTCTime through 2049 and GeneralizedTime from 2050 (RFC 5280
§4.1.2.5).
A verifier of this profile accepts a chain under §14.5.1 and §15.7 (§11.2).
### 4.5 The hard binding
Every manifest holds exactly one hard binding, a `c2pa.hash.bmff.v3` assertion (§18.6), the
map:
- `exclusions`: exactly these four, in this order:
1. `{"xpath": "/uuid", "data": [{"offset": 8, "value": h'D8FEC3D61B0E483C92975828877EC481'}]}`
(Appendix A.5.6);
2. `{"xpath": "/ftyp"}`;
3. `{"xpath": "/mfra"}`;
4. `{"xpath": "/emsg", "data": [{"offset": 12, "value": 'urn:c2pa:verifiable-segment-info' ‖ h'00'}]}`
(§19.4.1);
- `alg`: `sha256`;
- `hash`: the hash below;
- `sequenceNumber`: in a segment's manifest, the segment's sequence number (§3.3); absent in
the initialization segment's.
**The hash** (§18.6.2, Example 6) is SHA-256 over, for each top-level box of the segment that
no exclusion matches, in order, the box's offset from the segment's first byte as a u64
followed by every byte of the box. An exclusion matches a box when the box's type is the
xpath's and, at each `data` entry's offset from the box's first byte, the box holds the
entry's value. Every box the profile excludes is excluded whole, so no `subset` applies. In
the initialization segment the hash covers the `moov`, which §19.2.3 requires.
The fourth exclusion is the VSI box. §19.4.1 writes its `data` offset as 0, where every box
holds its size; offsets count from a box's first byte (§18.6.2, as the first exclusion's 8
shows), and the `scheme_id_uri` of an `emsg` of version 0 begins at 12. This extension writes
12, the entry that excludes the box. The same list is written in every manifest and every
segment-info map of a stream, whether or not the segment holds a VSI box, so a segment that
carries both methods has one hash under both.
### 4.6 The actions
Every manifest holds a `c2pa.actions.v2` assertion (§18.15.2) whose `actions` is one action:
`{"action": "c2pa.created", "digitalSourceType": DST}`, DST the IPTC term of §9 as a URI under
`http://cv.iptc.org/newscodes/digitalsourcetype/`. Each segment's manifest is a standard
manifest and so holds its own (§15.10.1.2).
### 4.7 The repository receipt
A publisher that registers the initialization segment's manifest with a C2PA Manifest
Repository records the repository's proof of ingestion in a `c2pa.repository-receipt`
assertion (§18.27), which C2PA allows only in an update manifest (§11.2.3):
- **The layout.** The initialization segment keeps its three boxes, its C2PA Manifest Box's
`box_purpose` becoming `original`, and a fourth, a C2PA `uuid` box of `box_purpose` `update`,
ends the file (Appendix A.5.3). Both purposes are eight bytes, so no offset moves and the
hard binding is unchanged; both boxes are C2PA `uuid` boxes, which the hash excludes.
- **The update store** holds one update manifest (JUMBF type `6332756D-0011-0010-8000-00AA00389B71`,
c2um), of role 3 (§4.2), whose claim (§4.2) and signature (§4.3) are as a standard
manifest's, and which holds, in this order and nothing else:
1. `c2pa.ingredient.v3` (§18.16), the map `{"relationship": "parentOf", "validationResults":
V, "activeManifest": {"url": "self#jumbf=/c2pa/" ‖ P, "hash": H}, "claimSignature": {"url":
"self#jumbf=/c2pa/" ‖ P ‖ "/c2pa.signature", "hash": G}}`, `P` the parent's identifier, `H`
and `G` the hashes of its manifest superbox and its claim signature superbox (§8.4.2.3),
as §11.2.3 requires of an update manifest's one ingredient. `V` is the result of validating
the parent, which §18.16.12.4.3 requires with an `activeManifest`: `{"activeManifest":
{"success": S, "informational": [], "failure": []}, "ingredientDeltas": [], "specVersion":
"2.4.0"}`, `S` the status maps `{"code": C, "url": U}` of `claimSignature.validated`,
`signingCredential.trusted` and `claimSignature.insideValidity` with `U` the parent's
signature URI, then `assertion.hashedURI.match` for each of the parent's assertions in its
claim's order with `U` that assertion's URI (`self#jumbf=/c2pa/` ‖ P ‖
`/c2pa.assertions/` ‖ its label), then `assertion.bmffHash.match` with the hard binding's
URI. A parent that does not verify is not registered, so `S` is the one list a valid
parent gives, and a verifier recomputes it;
2. `c2pa.repository-receipt`, a JSON content superbox (JUMBF type
`6A736F6E-0011-0010-8000-00AA00389B71`, one `json` box), the object of §18.27.2:
`{"@context": {"c2pa": "https://c2pa.org/ns/", "receipt": "https://c2pa.org/ns/repository-receipt#"},
"@type": "org.c2pa.repository-receipt", "repository": {"uri": R, "manifestId": P},
"anchor": {"uri": A, "proof": {"profile": "urn:ietf:rfc:9942", "entry": E, "receipt": C}}}`,
written compactly in this member order. `R` is the repository's base URI and `A` where the
proof may be retrieved.
- **The proof.** §18.27 leaves the `proof` object to the repository; this extension's is a
receipt of inclusion. The repository keeps an RFC 9162 §2.1 log over SHA-256 whose entries
are manifests by `H`; `E` is `H` in lowercase hexadecimal, and `C` is, in base64url without
padding (RFC 4648 §5), an RFC 9942 §5.2.1 receipt of inclusion: a `COSE_Sign1_Tagged` with
protected header `{1: -8, 395: 1}` (EdDSA, `vds` `RFC9162_SHA256`), unprotected header
`{396: {-1: [I]}}` with one inclusion proof `I`, the CBOR of `[tree_size, leaf_index,
inclusion_path]` in a byte string, and a detached payload. Its signature is the repository's
Ed25519 key's over the Sig_structure whose payload is the tree's root.
A verifier holds the repositories it accepts, each its base URI and key. The receipt then
establishes that the repository's log held the manifest at that tree size: the leaf is
SHA-256(0x00 ‖ `H`), the inclusion path leads from it to a root (RFC 9162 §2.1.3.2), and the
repository signed that root. It does not establish the manifest's content or its signer,
which §11.2 checks, and it is a witness of registration, not a trust anchor
([transparency](transparency.md) §6).
## 5. The WAI assertions
The assertions in this section are CBOR maps under C2PA's entity-specific namespace (§6.2.1).
### 5.1 The stream assertion
A track's initialization manifest, and every manifest of a segment that holds no live video
segment assertion (§7.3), holds `science.transaction.wai.stream`:
| key | value |
|---|---|
| `room` | the room id, 32 bytes |
| `track` | the track's Full Track Name in MOQT §8.8's rendering, as live-rooms §6.1 writes it: `<room>-<owner>-<kind>--<layer>` |
| `trackAlias` | the `wai_receipt_alias` the track's receipts sign ([moq-streaming-format](moq-streaming-format.md) §4) |
| `epoch` | the instant of media time 0, in microseconds since 1970-01-01T00:00:00Z |
| `firstGroup` | the group id of the stream's first segment |
| `label` | `{"origin": O}` with `O` 1; `{"origin": O, "model": M}` with `O` 2 or 3 and `M` the model's 32-byte digest; or, for a compositor's output, `{"inputs": [I, …]}`, each `I` `{"streamId": S, "track": N, "origin": O}` or the same with `"model": M` |
The `track`'s first field is `room` in lowercase hexadecimal, and its kind is `audio`, `video`
or `screen`. A stream assertion in a later manifest equals the initialization manifest's.
### 5.2 The group assertion
A track's per-segment manifest (§6) holds `science.transaction.wai.group`:
| key | value |
|---|---|
| `groupId` | the group id of the segment's group |
| `receipt` | the link hash of the group's receipt (jwp-receipts §3 step 3), 32 bytes |
| `root` | the group receipt's `root_hash`, 32 bytes |
| `objects` | the group receipt's `leaf_count` |
### 5.3 The take assertion
Every manifest of a take holds `science.transaction.wai.take`, as capture-binding §11.2 has
it: `take` (the take id), `room` (the room id) and `device` (the device's key), each 32 bytes,
and `commit` (32 bytes), the digest of the device's last `take_commit` before the segment was
written, absent in the initialization manifest. The initialization manifest's also holds
`epoch`: the instant of the master's media time 0 on the room clock, in microseconds since
1970-01-01T00:00:00Z (capture-binding §10), which no later manifest holds. `take`, `room` and
`device` are the same in every manifest of the take.
## 6. The per-segment C2PA Manifest Box method
Under §19.3, every segment holds a C2PA Manifest Box whose manifest holds, in this order:
1. `c2pa.hash.bmff.v3` over the segment (§4.5);
2. `c2pa.actions.v2` (§4.6);
3. `c2pa.livevideo.segment` (§19.3.2): `{"sequenceNumber": s, "streamId": S, "continuityMethod":
"c2pa.manifestId", "previousManifestId": P}`, `s` the segment's sequence number (§3.3), `S`
the stream's identifier (§3.4), and `P` the identifier of the manifest of the segment
before it, which for the first segment is the initialization segment's;
4. the AI disclosure assertions of §9, if any;
5. `science.transaction.wai.group` (§5.2) for a track, or `science.transaction.wai.take`
(§5.3) for a take.
The initialization segment's manifest holds `c2pa.hash.bmff.v3` over it, `c2pa.actions.v2`,
`c2pa.session-keys` where §7 applies, the AI disclosure assertions, and the stream assertion
(§5.1) for a track or the take assertion for a take.
The continuity chain makes each segment's manifest name the one before it. A segment that is
lost, inserted or moved breaks it at the next segment (§19.7.2).
## 7. The Verifiable Segment Info method
### 7.1 Session keys
Under §19.4, the initialization manifest holds `c2pa.session-keys` (§18.25): `{"keys": [K, …]}`,
each `K`:
- `key`: an OKP COSE_Key (RFC 9053 §7.2): `{1: 1, 2: kid, -1: 6, -2: x}`, the key type OKP,
its `kid`, the curve Ed25519 and the 32-byte public key `x`. `kid` is `x` itself, so a key
names itself;
- `minSequenceNumber`: the first sequence number it signs;
- `createdAt`: CBOR tag 0 over an RFC 3339 date-time in UTC with no fraction,
`YYYY-MM-DDTHH:MM:SSZ`;
- `validityPeriod`: seconds from `createdAt`;
- `signerBinding`: a `COSE_Sign1_Tagged` with protected header `{1: -8}`, an empty
unprotected header and a detached payload (`nil`), whose Sig_structure payload is the claim
signer's end-entity certificate, the first certificate of the manifest's `x5chain`. §18.25's
example shows the payload as `h''`; §13.2.3 reserves `nil` for detached content, and the
text calls the signature detached, so this extension writes `nil`.
A key is valid from `createdAt` to `createdAt` + `validityPeriod` (excluded). For a track, the
session key that signs a segment's segment-info map is also the `signer_pubkey` of that
segment's group receipt (§8.3). For a take, the session key is the device's key
(capture-binding §11.3).
### 7.2 The VSI box
Every segment holds a VSI box (§19.4.2): an `emsg` of version 0 and flags 0 (ISO/IEC 23009-1
§5.10.3.3.3) with:
| field | value |
|---|---|
| `scheme_id_uri` | `urn:c2pa:verifiable-segment-info`, then a zero byte |
| `value` | `fseg`, then a zero byte |
| `timescale` | the track's timescale (§3.5) |
| `presentation_time_delta` | 0 |
| `event_duration` | the sum of the segment's sample durations, in the timescale |
| `id` | the segment's sequence number |
| `message_data` | the verifiable-segment-info |
The verifiable-segment-info is a `COSE_Sign1_Tagged` with protected header `{1: -8}`,
unprotected header `{4: kid}`, the session key's `kid`, and the payload present: the CBOR of
the segment-info map `{"sequenceNumber": s, "bmffHash": H, "manifestId": M}`. `s` is the
segment's sequence number; `H` is the segment's hash as §4.5 writes it, with its
`sequenceNumber` and no `merkle`; `M` is the identifier of the active manifest: the manifest
of the segment's own C2PA Manifest Box where it has one, and otherwise the last manifest the
stream carried before it. The signature is the session key's over the Sig_structure
`["Signature1", protected, h'', payload]`.
### 7.3 Rotation
A new session key is delivered in a manifest carried in a segment's C2PA Manifest Box
(§19.4.3, §18.25), whose minimum sequence number is that segment's. Appendix A.5.3 requires
every initialization segment of a stream to carry the same manifest store, so this extension
rotates keys in a segment, not in a repeated initialization segment. That manifest holds, in
this order, the hard binding over its segment, the actions, `c2pa.session-keys` with the new
keys, the AI disclosure assertions, and the stream or take assertion; it holds no live video
segment assertion unless the stream also uses §6, and it becomes the active manifest. Its
segment's segment-info map names it and is signed by the new key.
A segment is signed by the **current key** for its sequence number *s*: among the keys the
verifier holds, the one with the greatest `minSequenceNumber` not above *s*. A key's
`minSequenceNumber` is at least the sequence number of the segment that delivers it.
## 8. The correspondence with WAI's receipts
### 8.1 The same bytes
For a track, the segment of group *g* and the group's receipts commit to the same objects:
- the segment's chunks are the group's objects, one chunk an object, in object order (§3.2);
- object *i*'s `content_hash` is BLAKE3(`"moq-jwp:object\x01"` ‖ *O*ᵢ) (jwp-receipts §2.1),
over the chunk's bytes, its `moof` and its `mdat`, as the object travelled;
- the group receipt's `root_hash` is the Merkle root of jwp-receipts §2.2 over the objects'
leaves, and its `leaf_count` is the number of chunks;
- the segment's hard binding covers the same chunks at their offsets in the segment (§4.5).
So no byte of an object can change without changing both the root the publisher signed and the
hash the claim signer or the session key signed, and each covers exactly the objects: the
C2PA boxes are what C2PA adds, and the group's objects are everything else. The objects carry
no energy label in this profile, so each leaf takes jwp-receipts §2.2's first form.
### 8.2 The per-segment method
A per-segment manifest names its group's receipt in its group assertion (§5.2): `groupId` is
the receipt's `group_id`, `receipt` its link hash, `root` its `root_hash` and `objects` its
`leaf_count`. The claim signer thereby signs which receipt the segment is, and the receipt's
signer signs which objects it holds.
### 8.3 The Verifiable Segment Info method
The session key that signs a segment's segment-info map is the `signer_pubkey` of the group's
receipt: one key signs both, over different structures. A Sig_structure's CBOR begins with
the byte `0x84` and a group signing payload with `moq-jwp:` (jwp-receipts §2.3), so no message
of one is a message of the other. A rotation (§7.3) changes the receipt key at the same group,
and the receipts of the new key start a chain of their own, whose first `parent_receipt_hash`
is `null` (jwp-receipts §2.4.1).
### 8.4 Receipts
The group receipt of every group of the stream, from `firstGroup` on, verifies under
jwp-receipts §3 steps 1 and 2, has the stream's `trackAlias`, and links to the receipt before
it under the same key (§3 step 3 there). Every object receipt of the group is accepted under
jwp-receipts §3 steps 1 to 5 against the group receipt and its chunk's bytes. The sequence
numbers of §3.3 follow from the receipts' `leaf_count`s.
## 9. Digital source type and AI disclosure
### 9.1 A stream's own label
| label | digital source type | AI disclosure |
|---|---|---|
| `origin` 1, kind `audio` or `video` | `digitalCapture` | none |
| `origin` 1, kind `screen` | `screenCapture` | none |
| `origin` 2, model *M* | `trainedAlgorithmicMedia` | one, *M*, `fully_autonomous` |
| `origin` 3, model *M* | `compositeWithTrainedAlgorithmicMedia` | one, *M*, `human_validated` |
| a take | `digitalCapture` | none |
An AI disclosure is a `c2pa.ai-disclosure` assertion (§18.28): `{"modelType":
"c2pa.types.model", "modelIdentifier": "tag:transaction.science,2026:wai/model/" ‖ M,
"contentProfile": {"humanOversightLevel": H}}`, `M` the model's digest in lowercase
hexadecimal, exactly as [timed-text](timed-text.md) §10.3 writes it for a caption model.
`c2pa.types.model` is Table 12's generic model type: an event names its model by digest and not
by type. Several are labelled `c2pa.ai-disclosure`, `c2pa.ai-disclosure__1`, … (§6.4).
### 9.2 A compositor's output
The output of a server compositor ([live-compose](live-compose.md)) is a stream whose label
lists its inputs. Its digital source type is `compositeCapture` when every input is of
`origin` 1 and kind `audio` or `video`; `compositeSynthetic` when any input is of `origin` 2
or 3; and `composite` otherwise. It carries one AI disclosure per model of its inputs, in the
order models first appear among them, `fully_autonomous` when any input of that model is of
`origin` 2 and `human_validated` otherwise. This is timed-text §10.3's rule for a set of cues
of more than one origin, applied to inputs.
### 9.3 What is checked
Every manifest of a stream holds the digital source type and exactly the AI disclosures its
label gives, in that order; a verifier refuses a manifest whose `c2pa.created` action names
another source type (`source_type_mismatch`) or that lacks, adds or changes a disclosure
(`ai_disclosure_missing`). The check is against the label the stream states. Whether content
is machine-made is not decidable from its bytes: the label is the publisher's statement,
signed with the stream's other assertions, as a caption's `origin` is its producer's
(timed-text §14). What the check establishes is that a stream labelled machine-made carries
C2PA's machine-readable marking of it, in every manifest, and a stream labelled human carries
none.
Regulation (EU) 2024/1689, Article 50(2), requires the outputs of AI systems that generate
synthetic audio, image, video or text to be marked in a machine-readable format and detectable
as artificially generated or manipulated; Article 50(4) requires a deployer to disclose a deep
fake. The digital source type and the AI disclosure assertion are such a marking, carried in
every segment's provenance. Writing them is an engineering requirement of this extension, and
meeting it is not a statement about the Regulation.
## 10. Carriage
### 10.1 HTTP
Over HTTP the initialization segment and each segment are files as §3.2 lays them out, and a
playlist lists them as for any CMAF track ([live-recording](live-recording.md) §7).
### 10.2 MoQ: the provenance track
Over MoQ the track's objects are its chunks, exactly as `draft-ietf-moq-cmsf-01` §3.3 has
them, and the initialization segment, its C2PA Manifest Box included, is the catalog's inline
initialization data (§3.1 there). Each segment's C2PA boxes ride a **provenance track**:
- it is in the media track's namespace and its Track Name is the media track's followed by
`_c2pa`, as `0_c2pa` (live-rooms §6.1's characters);
- its group *g* holds one object, the C2PA boxes of the media track's group *g*, exactly as
they lead the segment;
- the media track's catalog entry names it in `wai_c2pa_track`, and its own catalog entry has
`packaging` `"wai-c2pa"`;
- a relay forwards it as it forwards any track, unaltered.
A subscriber that verifies reassembles the segment of group *g* as the provenance object of
group *g* followed by the media objects of group *g* in object order.
**Why a track, not an object property.** A MOQT object property (MOQT §8.4, as
[moq-streaming-format](moq-streaming-format.md) §5 uses one) rides the header of every copy
of the object it is on, and a property of the first object would make every forwarded copy of
that object kilobytes larger, since a manifest holds a certificate chain. A track keeps the
media objects exactly the CMAF chunks a CMSF player plays and the receipts commit to (§8.1),
lets a subscriber that does not verify leave it out, lets one that does fetch a past group's
provenance by its group number (live-recording §8), and has the receipts track's form
(live-rooms §6.1), with which it shares group numbers.
### 10.3 Dynamic and redundant packaging
C2PA 2.4 treats dynamically packaged content, packaged just in time on request, as live video
(§19.2.1), and recommends deterministic signature algorithms for streaming so that segments
packaged apart remain equal and cacheable, naming ISO/IEC 23009-9 (REaP) among the workflows
that need it (§13.2.1). In this profile every byte of a segment is a function of the group's
objects, the stream, the segment's sequence number and the claim signer's key:
- the chunks are the objects as they travelled (§3.2), and the layout and every box are fixed
(§4);
- the manifest identifiers are derived (§4.2), not drawn;
- CBOR is deterministic (§2), and Ed25519 signatures are deterministic (RFC 8032), as are the
session keys' and the receipts'.
So two packagers that hold one claim signer's key and package the same group write the same
segment, byte for byte: a segment from either is interchangeable with the other's and caches
as one. Two packagers with different keys write segments whose manifests differ in their
signatures and certificates but share their identifiers, so the continuity chain of §6 holds
across a failover from one to the other, and both segments' chunks are the objects one group
receipt commits to (§8.1). Under the Verifiable Segment Info method a session key also signs
the receipts (§8.3), so a packager that is not the publisher uses the per-segment method.
A packager that changes what a segment holds, by re-segmenting a stream or writing its objects
into another layout or codec, makes a new stream, derived from the first: its manifests are its
own, under its own stream identifier, and where it holds the source segments' manifests, its
output's manifest names each as a `parentOf` ingredient, with `c2pa.repackaged` for a
repackaging and `c2pa.transcoded` for a re-encoding, as deriving-edge §6.1 has a deriving edge
name its inputs' manifest stores. Packaging a group's objects into this profile's segment, which
this section is about, changes no object: there is no derivation, and the objects stay under
the publisher's receipt.
What a verifier checks of a repackaged segment is its own: the identifiers (§11.4 step 3), the
manifest under its own signer, and the objects under the publisher's receipt, so it needs to
trust neither packager for the objects. Checking that two **encoders** produced the same
objects, by re-encoding the source under a WAI capability whose decode is `replicate`
([determinism-tiers](determinism-tiers.md)), is not in this revision: it needs the source and
an encoder that is itself a pure function of it.
## 11. Verification
### 11.1 Inputs
A verifier holds: the trust anchors it accepts for `c2pa-kp-claimSigning` (§14.4.1); the
manifest repositories it accepts, each its base URI and Ed25519 key (§4.7); the instant *T*;
the stream's kind; its initialization segment; its segments in the order it received them,
each with its group id for a track (the MoQ group it came in, or the playlist's); and, for a
track, the group receipts and object receipts of the stream's groups. It verifies in the order
below and stops at the first refusal, which it reports with the reason, where it was raised
(`init`, `segment` *k* for the *k*-th segment received counting from 0, or `group` *g*), and
the two C2PA codes §12 gives it. A stream every step accepts is accepted.
### 11.2 A manifest
A C2PA Manifest Box of a segment (or of the initialization segment) is verified against that
segment's bytes, in C2PA's order (§15.6 to §15.12):
1. The store, the manifest and its three parts read as §4.1 lays them out, the manifest
identifier as §4.2 has it, the claim as well-formed deterministic CBOR with the fields of
§4.2, and the claim signature as a `COSE_Sign1_Tagged` with an EdDSA algorithm, a detached
payload and exactly one `x5chain`, in the protected header (§14.2): otherwise
`manifest_malformed`.
2. The end-entity certificate and the intermediates meet §4.4's profile and §14.5.1.1, and the
end-entity's Extended Key Usage holds `c2pa-kp-claimSigning` and neither `id-kp-timeStamping`
nor `id-kp-OCSPSigning`: otherwise `credential_invalid` (`signingCredential.invalid`).
3. A chain is built from the end-entity through the intermediates to a trust anchor, each
certificate's issuer name equal to the next's subject, its Authority Key Identifier to the
next's Subject Key Identifier, and its signature verifying under the next's key: otherwise
`credential_untrusted` (`signingCredential.untrusted`).
4. The signature verifies under the end-entity's key over the claim (§4.3), with the strict
Ed25519 rule of jwp-receipts §3.1 step 3: otherwise `claim_signature_mismatch`
(`claimSignature.mismatch`).
5. *T* is within the validity of every certificate of the chain, the anchor's included; with
no time-stamp, §15.8 checks the current time: otherwise `credential_expired`
(`claimSignature.outsideValidity`).
6. Every hashed URI of `created_assertions` resolves to an assertion of the store whose hash it
holds: otherwise `assertion_hash_mismatch` (`assertion.hashedURI.mismatch`), or, for a URI
that resolves to nothing, `manifest_malformed`.
7. The assertions are the ones §6 or §7 lists for the manifest, in that order and no others,
the AI disclosures in any number at their place (§9.3 checks them), each readable with the
fields it defines: exactly one hard binding (§15.10.1.2), with §4.5's exclusions and `alg`;
the actions of §4.6, one `c2pa.created` action with a source type of the IPTC vocabulary;
and the rest as their sections give them: otherwise `manifest_malformed`. Which list
applies follows from where the manifest is and what it holds: the initialization segment's
(§6), a segment's with a live video segment assertion (§6), or a segment's without one
(§7.3).
8. The hard binding's `hash` is the segment's hash (§4.5): otherwise `hard_binding_mismatch`
(`assertion.bmffHash.mismatch`).
A refusal at steps 1 to 8 in any segment, the initialization segment included, carries §19.7's
`livevideo.manifest.invalid`.
### 11.3 The initialization segment
1. Its boxes read: otherwise `segment_malformed`. It holds an `mdat`, or is not `ftyp`, a C2PA
`uuid` box and `moov` with one track whose `tkhd`, `mdhd` and `trex` read, then optionally
a second C2PA `uuid` box: otherwise `init_invalid`.
2. Its manifest verifies (§11.2): the store of the first C2PA box, of purpose `manifest`, or
`original` where a second box follows.
3. For a track, the stream assertion reads as §5.1 has it; for a take, the take assertion as
§5.3 has it: otherwise `stream_assertion_invalid`. The stream identifier follows from it
(§3.4), and the manifest's identifier is §4.2's of role 0: otherwise `manifest_id_mismatch`.
4. The digital source type and the AI disclosures are the label's (§9.3).
5. Every session key reads as §7.1 has it, its `kid` is its `x`, and its `signerBinding`
verifies under it over the claim signer's end-entity certificate, and no two keys share an
`x`: otherwise `session_key_invalid`. For a take, a session key is the take assertion's
`device`.
6. Where a second C2PA box follows, of purpose `update` (§4.7): its store reads as one update
manifest, whose claim and signature verify as §11.2 steps 1 to 6 have them, a failure of
form being `update_manifest_invalid`; its identifier is §4.2's of role 3
(`manifest_id_mismatch`); it holds exactly the ingredient and the repository receipt of
§4.7, the ingredient naming the initialization manifest and its claim signature by their
hashes, and the receipt's JSON reading as §4.7 writes it, naming that manifest and its hash
(`update_manifest_invalid`); the repository is one the verifier accepts, and the receipt of
inclusion verifies under its key for the entry `H` (`repository_receipt_invalid`).
### 11.4 Each segment
For the segment *k* received, of group *g* for a track:
1. Its boxes read, and after a leading C2PA Manifest Box and then a VSI box, each where present,
they are one or more chunks as §3.2 lays them out: otherwise `segment_malformed`. It holds
neither C2PA box: `provenance_missing`. Its `moof`s carry consecutive `sequence_number`s and
the track's `track_ID`: otherwise `segment_malformed`.
2. Its sequence number exceeds the previous segment's, and, for a track, *g* exceeds the
previous segment's group: otherwise `sequence_not_increasing`.
3. Where it holds a C2PA Manifest Box, the manifest verifies (§11.2), its identifier is §4.2's,
of role 1 where it holds a live video segment assertion and 2 where it does not, for the
segment's sequence number (`manifest_id_mismatch`), its hard binding's `sequenceNumber` is
the segment's sequence number (`sequence_mismatch`), and then:
- with a live video segment assertion (§6): its `sequenceNumber` is the segment's sequence
number (`sequence_mismatch`); its `streamId` is the stream's (`stream_id_mismatch`);
`continuityMethod` is `c2pa.manifestId` and `previousManifestId` is present
(`continuity_invalid`); and `previousManifestId` is the identifier of the previous
segment's manifest, or the initialization segment's for the first (`continuity_broken`).
For a track the group assertion reads (§11.2 step 7) and is checked at step 6; for a take
the take assertion's `take`, `room` and `device` are the initialization manifest's
(`stream_assertion_invalid`);
- without one (§7.3): the segment holds a VSI box, as the method that delivers keys signs
its segments (`provenance_missing`); the manifest holds the stream or take assertion,
equal to the initialization manifest's (`stream_assertion_invalid`), and new session
keys, each read as §11.3 step 5 reads one, none with the `x` of a key already held, and
each with a `minSequenceNumber` not below the segment's sequence number
(`session_key_invalid`); the keys are added to those held, and the manifest becomes the
active one;
- its digital source type and AI disclosures are the label's (§9.3).
4. Where it holds a VSI box:
- the box has §7.2's fields, the verifiable-segment-info reads as a `COSE_Sign1_Tagged`
with an EdDSA algorithm, a `kid` and a payload present, and the payload as a segment-info
map with §4.5's exclusions and `alg`: otherwise `segment_info_invalid`;
- the verifier holds a session key of that `kid`: otherwise `session_key_unknown`;
- the signature verifies under it, by the strict rule: otherwise
`segment_info_signature_failed`;
- the key is the current key for the segment (§7.3), its `minSequenceNumber` is not above
the segment's sequence number, and the segment's presentation instant (§3.5) is within
its validity: otherwise `session_key_out_of_range`;
- the map's `sequenceNumber`, and its `bmffHash`'s, is the segment's sequence number:
otherwise `sequence_mismatch`;
- its `manifestId` is the active manifest's (§7.2): otherwise `segment_info_invalid`;
- its `bmffHash.hash` is the segment's hash (§4.5): otherwise `segment_hash_mismatch`.
5. For a track: the group receipt of every group from `firstGroup` to *g* is held
(`receipt_missing`), and only one of group *g* (`receipt_invalid`), and the sequence number
is *s*(*g*) (§3.3). For a take: the sequence
number is one more than the last `sequence_number` of the previous segment, or 1 for the
first. Otherwise `sequence_mismatch`.
6. For a track, of group *g*'s receipt (§8): it is of the legacy form (jwp-receipts §2.3; its
total carries no class of its own, §8.1), it verifies, has the stream's `trackAlias` and
`group_id` *g*, and links to the held receipt of the group before it under the same key, or
has a `null` parent where that receipt is under another key or *g* is `firstGroup`
(`receipt_invalid`); its `leaf_count` is the number of chunks and its `root_hash` the root
over the chunks' leaves, and, for a per-segment manifest, the group assertion names it
(`receipt_mismatch`); for a segment with a VSI box, its `signer_pubkey` is the session key
that signed the segment-info map (`receipt_signer_mismatch`); and the group's object
receipts are one per chunk, each accepted against its chunk (`object_receipt_invalid`).
### 11.5 The end of the stream
For a track, every group from `firstGroup` to the last of which the verifier holds a receipt
has a segment: otherwise `segment_missing`, at the first group without one.
### 11.6 What an accepted stream states
The stream identifier; its digital source type; the initialization manifest's registration,
where it carries one: the repository's base URI, the tree size and the leaf index; and, for
each segment in order, its sequence
number, its group (a track) or chunk index (a take), the methods it carries (`manifest`,
`vsi` or both), the identifier of its active manifest, its number of chunks, and the root of
its group (a track) or the SHA-256 of its take chunk (a take: chunk 0 is the initialization
segment followed by segment 0).
## 12. Reasons
| reason | raised at | C2PA 2.4 §15 code | §19.7 code |
|---|---|---|---|
| `segment_malformed` | §11.3 step 1, §11.4 step 1 | — | `livevideo.segment.invalid` |
| `init_invalid` | §11.3 step 1 | — | `livevideo.init.invalid` |
| `provenance_missing` | §11.4 steps 1, 3 | — | `livevideo.segment.invalid` |
| `manifest_malformed` | §11.2 steps 1, 6, 7; §11.4 step 3 | `claim.malformed` | `livevideo.manifest.invalid` |
| `credential_invalid` | §11.2 step 2 | `signingCredential.invalid` | `livevideo.manifest.invalid` |
| `credential_untrusted` | §11.2 step 3 | `signingCredential.untrusted` | `livevideo.manifest.invalid` |
| `claim_signature_mismatch` | §11.2 step 4 | `claimSignature.mismatch` | `livevideo.manifest.invalid` |
| `credential_expired` | §11.2 step 5 | `claimSignature.outsideValidity` | `livevideo.manifest.invalid` |
| `assertion_hash_mismatch` | §11.2 step 6 | `assertion.hashedURI.mismatch` | `livevideo.manifest.invalid` |
| `hard_binding_mismatch` | §11.2 step 8 | `assertion.bmffHash.mismatch` | `livevideo.manifest.invalid` |
| `manifest_id_mismatch` | §4.2, §11.3 steps 3, 6, §11.4 step 3 | — | — |
| `stream_assertion_invalid` | §11.3 step 3, §11.4 step 3 | — | — |
| `source_type_mismatch` | §9.3, §11.3 step 4, §11.4 step 3 | — | — |
| `ai_disclosure_missing` | §9.3, §11.3 step 4, §11.4 step 3 | — | — |
| `update_manifest_invalid` | §4.7, §11.3 step 6 | `manifest.update.invalid` | `livevideo.manifest.invalid` |
| `repository_receipt_invalid` | §4.7, §11.3 step 6 | — | — |
| `session_key_invalid` | §11.3 step 5, §11.4 step 3 | — | `livevideo.sessionkey.invalid` |
| `sequence_not_increasing` | §11.4 step 2 | — | `livevideo.assertion.invalid` |
| `sequence_mismatch` | §11.4 steps 3, 4, 5 | — | — |
| `stream_id_mismatch` | §11.4 step 3 | — | `livevideo.assertion.invalid` |
| `continuity_invalid` | §11.4 step 3 | — | `livevideo.continuityMethod.invalid` |
| `continuity_broken` | §11.4 step 3 | — | `livevideo.segment.invalid` |
| `segment_info_invalid` | §11.4 step 4 | — | `livevideo.segment.invalid` |
| `session_key_unknown` | §11.4 step 4 | — | `livevideo.segment.invalid` |
| `segment_info_signature_failed` | §11.4 step 4 | — | `livevideo.segment.invalid` |
| `session_key_out_of_range` | §11.4 step 4 | — | `livevideo.segment.invalid` |
| `segment_hash_mismatch` | §11.4 step 4 | `assertion.bmffHash.mismatch` | `livevideo.segment.invalid` |
| `receipt_missing` | §11.4 step 5 | — | — |
| `receipt_invalid` | §11.4 step 6 | — | — |
| `receipt_mismatch` | §11.4 step 6 | — | — |
| `receipt_signer_mismatch` | §11.4 step 6 | — | — |
| `object_receipt_invalid` | §11.4 step 6 | — | — |
| `segment_missing` | §11.5 | — | — |
The two code columns are what a C2PA validator reports for the same defect where C2PA checks
it: §15's failure code for a check of a manifest, and §19.7's for a check of live video, which
for a manifest's own failure in a segment is `livevideo.manifest.invalid` (§19.7.1). A refusal
reports both. `—` marks a check C2PA does not make: the rules of this extension; the sequence
numbers' match with `mfhd.sequence_number`, which §19.4.1 requires of a writer and §19.7 does
not check; the identifiers' derivation; and the repository's proof, whose form §18.27 leaves
to the repository. `update_manifest_invalid` stands for every failure of the update manifest's
form, which §15.10.1.3 reports as `manifest.update.invalid` or `manifest.update.wrongParents`;
it reports the first. `manifest_malformed` stands for every failure of a manifest's form, whose
§15 codes are many (`claim.malformed`, `claim.cbor.invalid`, `claimSignature.missing`,
`algorithm.unsupported`, `assertion.missing`, `claim.hardBindings.missing`,
`assertion.bmffHash.malformed`, …); it reports `claim.malformed`. Over the Verifiable Segment
Info method alone, §19.7.3 states no order check, and `sequence_not_increasing` there is this
extension's rule, reported with §19.7.2's code.
## 13. Conformance
[`live-conformance/c2pa-live/`](../live-conformance/c2pa-live/) holds the corpus, written from
fixed seeds by `wai_live_provenance_vectors gen`: `vectors.json`, the trust anchor, and for
each vector its initialization segment, its segments and, for a track, its receipts, each a
file of its own. Every key and certificate is derived from the seeds, and none is a key anyone
holds; every manifest identifier is its stream's (§4.2). The media are the AV1 floor of the
packaging corpus's `video-base-01` (packaging §7, paragraph 7.6), its samples cut into chunks
of at most 15 frames, each group one of its pieces, so every segment begins at a key frame.
- **Good streams**: a camera track under the per-segment method; the same track under the
Verifiable Segment Info method, with the session key rotated at its third segment by a
manifest in that segment, the receipts' chain restarting under the new key; a track
labelled machine-made, with its AI disclosure; a compositor's output of a camera and that
track; a take under both methods at once, the device's key as its session key; the camera
track with a second packager, under its own claim signer, taking over at the third segment
(§10.3); and the camera track with its initialization manifest registered, its update
manifest and repository receipt after it (§4.7).
- **Negatives**, each a control of one defect: a segment whose bytes changed under each
method; a missing segment under each; a reordered segment; a manifest bound to the wrong
receipt; a stream identifier that differs; an end-entity certificate that has expired, one
whose Extended Key Usage is time-stamping, and one under an anchor the verifier does not
hold; a machine-made track without its AI disclosure, and a compositor's output that names
a source type of captures; a manifest whose identifier is not derived; a repository receipt
signed by a key that is not the repository's, and an update manifest whose ingredient names
another parent; and every other reason of §12.
A conforming verifier gives every vector the outcome, the reason, the place, the two C2PA
codes and, for an accepted stream, what §11.6 states, as the corpus states them.
`wai_live_provenance_vectors verify` and the test `tests/live_provenance.rs` check that every
file regenerates byte for byte, that no other file is there, that `wai-rs` gives every vector
its outcome, that every reason of §12 refuses a vector, and that §12 lists exactly the
reference's codes. `live-conformance/c2pa_live_verify.py` is the second implementation,
written from this text: it shares no code with `wai-rs`; it reads CBOR, COSE, JUMBF, ISO BMFF
and X.509 DER itself, verifies signatures with WAI's strict rule written from RFC 8032
(`claim-conformance/_ed25519.py`) and hashes with BLAKE3 from `claim-conformance/_blake3.py`;
gives every vector the same outcome; and mutates copies of the good vectors, one defect each,
and requires every copy to be refused. The README of the corpus records what an independent C2PA validator reports for the
corpus's files.
## 14. Security and privacy considerations
- **What is bound to what.** The claim signer's certificate names who stands behind a
manifest; a session key is bound to it by the `signerBinding` and, for a track, signs the
group receipts too, so the C2PA signer, the session key and the receipts' signer are one
chain of statements. Which principal of the room the receipts' key belongs to is the room's
(jwp-receipts §7, live-rooms §4) and is not checked here.
- **Signed is not trusted.** A chain to an anchor the verifier holds is a check of the chain,
not of the anchor: the corpus's anchor is a test anchor, and §14.4's trust lists are the
relying party's choice.
- **Order and loss.** Sequence numbers, the continuity chain and the receipts' chain each
detect a segment lost, repeated or moved; under the Verifiable Segment Info method alone a
segment-info map does not name the one before it, so a lost segment is found by the
receipts (§11.5), which a relay forwards for objects it did not forward (jwp-receipts §4.4).
- **Session keys.** A session key signs every segment of its range. Its validity bounds how
long a stolen key signs; rotation (§7.3) shortens it. §19.7.3 recommends that a verifier
of a very long session check the claim signer's certificate again; this revision checks it
once, at *T*.
- **Registration is a witness.** A repository receipt (§4.7) shows that the repository's log
held the manifest at a tree size under the repository's key; it says nothing of the
manifest's truth, and a verifier that accepts a repository chooses whom it believes about
registration, as it chooses anchors. Consistency between two tree heads, which would show
the log did not fork, is not checked in this revision.
- **Derived identifiers.** Anyone can compute the identifier of a future segment's manifest
(§4.2). That forges nothing: a manifest is bound by its signature and its hard binding, and
a verifier checks both before it reads the identifier. What derivation buys is that a
packager cannot choose an identifier, so two packagers agree on it.
- **No time-stamps.** Without a time-stamp a manifest is valid only while the signer's
certificate is (§15.8): a recording verified after the certificate expires is refused
`credential_expired`. A publisher that keeps recordings SHOULD time-stamp them, which a later
revision adds.
- **The label is a statement.** §9.3 checks that a stream labelled machine-made is marked as
C2PA marks it; it cannot detect a machine-made stream labelled human. The label is signed
with the stream, so a false one is attributable to its signer.
- **Privacy.** A manifest carries the claim signer's certificate and, for a take, the
device's key and the room's id; the stream assertion carries the room id and the publisher's
key in the track name. A stream is public provenance of its publisher; a take's manifests
link the device to the room, as capture-binding §14 says of a take.

View file

@ -17,6 +17,7 @@ and the independent verifier of each, beside it.
| [`ads/`](ads/) | [live-ads](../extensions/live-ads.md) (`wai.live.ads`) | `live_ads_verify.py` |
| [`e2ee/`](e2ee/) | [confidentiality](../extensions/confidentiality.md) (`wai.live.e2ee`) | `e2ee_verify.py` |
| [`watermark/`](watermark/) | [forensic-watermark](../extensions/forensic-watermark.md) (`wai.live.watermark`) | `live_watermark_verify.py` |
| [`c2pa-live/`](c2pa-live/) | [live-provenance](../extensions/live-provenance.md) (`wai.live.provenance`) | `c2pa_live_verify.py` |
**Provenance.** Generated here: `wai_live_events_vectors gen` writes `events/`,
`wai_live_room_vectors gen` writes `rooms/`, `wai_capture_take_vectors gen` writes
@ -24,11 +25,13 @@ and the independent verifier of each, beside it.
writes `recordings/`, `wai_timed_text_vectors gen` writes `captions/` and
`wai_live_metering_vectors gen` writes `metering/`, `wai_energy_steering_vectors gen` writes
`steering/`, `wai_live_moderation_vectors gen` writes `moderation/`,
`wai_live_watermark_vectors gen` writes `watermark/` and `wai_live_ads_vectors gen` writes
`ads/`, each from records authored in code, from fixed seeds (`events/README.md`,
`wai_live_watermark_vectors gen` writes `watermark/`, `wai_live_ads_vectors gen` writes
`ads/` and `wai_live_provenance_vectors gen` writes `c2pa-live/`, each from records authored
in code, from fixed seeds (`events/README.md`,
`rooms/README.md`, `takes/README.md`, `compose/README.md`, `recordings/README.md`,
`captions/README.md`, `metering/README.md`, `steering/README.md`, `moderation/README.md`,
`watermark/README.md`, `ads/README.md`). `joule_moq_e2ee_vectors gen` (in
`watermark/README.md`, `ads/README.md`, `c2pa-live/README.md`); `c2pa-live/` cuts its media
from the packaging corpus's AV1 floor. `joule_moq_e2ee_vectors gen` (in
`joule-code/joule-code-rs/crates/joule-moq-mls`) writes `e2ee/vectors.json` from fixed seeds,
and `e2ee/` also holds the test vectors RFC 9605 and `draft-ietf-moq-secure-objects-01`
publish, as printed (`e2ee/README.md`). One recorded record: `metering/relay-record.wmh` and
@ -51,4 +54,5 @@ python3 live_moderation_verify.py moderation
python3 live_ads_verify.py ads
python3 e2ee_verify.py e2ee
python3 live_watermark_verify.py watermark
python3 c2pa_live_verify.py c2pa-live
```

View file

@ -0,0 +1,83 @@
# live-conformance/c2pa-live — live provenance
The corpus of [`extensions/live-provenance.md`](../../extensions/live-provenance.md) §13: C2PA
2.4 §19 live video streams, each an initialization segment and its segments in the order a
verifier receives them, with, for a room track, the JWP group and object receipts of its
groups; the trust anchor every vector is verified under; and what a verifier states of each.
**Files.** `vectors.json` lists the vectors, each its `name`, `kind` (`track` or `take`),
`init`, `segments` (each a `file` and, for a track, the `group` it came in), `receipts` (a JSON
file of `groups` and `objects` in jwp-receipts §2.4's forms, or `null` for a take) and
`expect`. A file whose bytes another vector already wrote is named by that vector's path, so a
negative that changes one segment holds one file of its own. `anchor.der` is the trust anchor
for `c2pa-kp-claimSigning`, and `time` the instant *T* (§11.1).
**Equivalence.** A conforming verifier given a vector's files, the anchor and *T* reaches the
outcome `expect` states (§11):
- `refuse`: the `reason` of §12, `at` (`init`, `segment k` counting received segments from 0,
or `group g`), and the two C2PA codes §12 gives the reason, `c2pa` (§15's) and `livevideo`
(§19.7's), each `null` where §12 gives none;
- `accept`: the `streamId`, the `sourceType`, the `registration` (the `repository`, the
`treeSize` and the `leafIndex` of the receipt of inclusion) or `null`, and for each segment
(§11.6) its
`sequenceNumber`, its `group` (a track) or `chunk` (a take), its `methods` (`manifest`,
`vsi` or `manifest+vsi`), the active `manifestId`, its number of `chunks`, and its group's
`root` or its take chunk's `chunkHash`, in lowercase hexadecimal.
**The vectors.**
- Good: `camera-manifests` (the per-segment method), `camera-vsi` (the Verifiable Segment
Info method from group 10, the session key rotated at the third segment by a manifest in
it, the receipts' chain restarting under the new key), `avatar-manifests` (a track labelled
machine-made, with its AI disclosure), `composite-manifests` (a compositor's output of the
camera and the avatar: `compositeSynthetic` and the avatar's disclosure), `take-both` (a
take under both methods at once, the device's key as its session key), `camera-failover`
(the camera track, a second packager under its own claim signer taking over at the third
segment, the continuity chain holding across it because the identifiers are derived) and
`camera-registered` (the camera track's initialization segment with its update manifest
and repository receipt; `repositories` in `vectors.json` names the repository and its key).
- One negative for each reason of §12, and for some reasons more than one; each name says its
defect.
**Provenance.** `wai_live_provenance_vectors gen` writes every file but this one from fixed
seeds: every key is SHA-256 of a label and no key is one anyone holds; the certificates are
issued under the corpus's own test anchor; the media are the AV1 floor of
`pack-conformance/packs/video-base-01`, its samples cut into chunks of at most 15 frames, each
group one of the floor's pieces, renumbered and retimed across the stream.
**Checked by.** `wai_live_provenance_vectors verify` and `tests/live_provenance.rs` in
`wai-rs` (every file regenerates byte for byte and no other is here; every vector gets its
outcome; every reason refuses one; §12 lists the reference's codes), and
`../c2pa_live_verify.py`, the second implementation, written from the extension's text, which
also requires every mutated copy of a good vector to be refused.
**An independent C2PA validator.** The corpus's files were also read with the C2PA
command-line tool, version 0.27.22, given `anchor.der` as its trust anchor, on 2026-10-21:
- every good vector's initialization segment validates: state `Trusted`, with
`assertion.bmffHash.match`, `assertion.hashedURI.match`, `claimSignature.validated`,
`claimSignature.insideValidity` and `signingCredential.trusted`. The manifest store, the
claim, its signature, the certificate chain and the BMFF hash over the `moov` are therefore
read the same way by an implementation that shares nothing with this one;
- `camera-registered/init.mp4` validates too, state `Trusted`, its active manifest the update
manifest: the tool reads the ingredient (`ingredient.manifest.validated`) and its validation
results. Before the ingredient carried them it reported `assertion.ingredient.malformed`,
which C2PA 2.4 §18.16.12.4.3 requires; `update-ingredient/init.mp4` is reported
`ingredient.manifest.mismatch`, where this corpus states `update_manifest_invalid`;
`repository-receipt-forged/init.mp4` is reported `Trusted`: the receipt's proof is the
repository's form (§18.27), which the tool does not check;
- `cert-untrusted/init.mp4` is reported `signingCredential.untrusted`, as here;
- `cert-expired/init.mp4` is reported `signingCredential.expired`, a code C2PA 2.4 does not
list; §15.8 names this failure `claimSignature.outsideValidity`, which this corpus states;
- `cert-wrong-eku/init.mp4`, whose end entity is valid for `id-kp-timeStamping` alone, is
reported `Trusted`: the tool's default list of accepted extended key usages includes
time-stamping and OCSP signing. C2PA 2.4 §14.5.1.1 makes a certificate valid for either of
those purposes valid for no other, and §14.5.1.2 requires a claim signer's to hold an EKU of
the validator's configuration, so this corpus refuses it `credential_invalid`;
- the tool reads no media segment: a file that does not begin with `ftyp` is not one it
opens, so it does not verify §19 per-segment manifests, segment-info maps or session keys.
The segments are checked by the two implementations above alone.
The tool reports a claim signature as failed when the end-entity certificate's subject holds
no organization name, which C2PA does not require; the corpus's names all hold one (§4.4).

Binary file not shown.

View file

@ -0,0 +1,163 @@
{
"groups": [
{
"kind": "group",
"track_alias": 2,
"group_id": 0,
"root_hash": "99c1ee93a49d44a71d04407c59b1f688f1ccd160c388ea2a94a4ebfe0ee162e0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:01.000000Z",
"signer_pubkey": "cb1e7aca7605dd3f10a7e215063c7bca869b83ba11c259cb6bc3a815836f67f5",
"signer_id": "corpus publisher",
"sig": "57f56e2e571f43062b6be26642e369d80633de7f813502420868a2ce2d750e085dfde6501fb064c1c34387558fea8e793f96ab1fb0f17410281a31ef7533970f",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 2,
"group_id": 1,
"root_hash": "3e5165b1371e3693e542dca31f1aeba5c362bff06c7c64b39237913101faedb9",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:01.000000Z",
"group_end": "2026-10-20T11:00:02.000000Z",
"signer_pubkey": "cb1e7aca7605dd3f10a7e215063c7bca869b83ba11c259cb6bc3a815836f67f5",
"signer_id": "corpus publisher",
"sig": "abd8b03222d2c7c9f0f0068d6d48f258f12d8d1d2f0cc8bab92d9bfe5c721a435671217e4cdc1b9b6eabb219c548affd069e4277f13ba819e884d850611a3c09",
"parent_receipt_hash": "2d8f6b9fb2434236acce8ad994a84cd4160971e82c60e239fb25e5c7cb03dcae"
},
{
"kind": "group",
"track_alias": 2,
"group_id": 2,
"root_hash": "c605d0c6ba8546635e3783f9a130355667c68085e44f043ae18df8ba974ce6b3",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.000000Z",
"group_end": "2026-10-20T11:00:03.600000Z",
"signer_pubkey": "cb1e7aca7605dd3f10a7e215063c7bca869b83ba11c259cb6bc3a815836f67f5",
"signer_id": "corpus publisher",
"sig": "432ee5edc46ea0eef4d35b8b0751dfb13668691919eac0b59bbeaa09c7c418dd3586df1cd698d818d8eed5ec469fb354325bf1d6630ad0773c8a0afe08c5eb02",
"parent_receipt_hash": "16fe87519f983c0484d60e031f0e6227854697ed783c90ee10a5845b478b95e2"
}
],
"objects": [
{
"kind": "object",
"track_alias": 2,
"group_id": 0,
"object_id": 0,
"content_hash": "5a942f3a7fd658d2c4ee8b4db9dd11c605a56c6dc3718f869b049faa8850ec7d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b2659df6816d8da90543f3169c36eccd5b78a0a4294232f38e5811c4b13a34ac"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 0,
"object_id": 1,
"content_hash": "99ec5ab9416df8a59ef5750c22e0e4f18b4eda8fda7172fa248831592b35aa00",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"38d035a1e790abbca8af2f04899b88f8dad09fdc08e9c52b83348a2be4e85f39"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 1,
"object_id": 0,
"content_hash": "463b72614a6be56062a09fe4b7d32eac97fbbdc236adf689c9cabfa8c7c89863",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"68bf7ad2e58084a8cab1a2ea0796e6ed8d3d269efc010991998f73be81b1c517"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 1,
"object_id": 1,
"content_hash": "2cb216ed938cdccf0951b31101fb568ca2e239bb104a48e9814eb9d029ea75a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"961a306577f65e0f6acc69587c643b14eded1b0a8f4ee0956b0a6a6fad548871"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 2,
"object_id": 0,
"content_hash": "a5997aaab20bc8bcc8cdac4fc3c786b92352433b0b8b22e2214fbe628efab6d8",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2e78c4feba0e79ef8596f688bc7826dfbb3868b21af78bb679b44ff4583e83b2",
"7e95960d0d4d629b92965a7ca6f5260167330632c6f0ac3ebe6e21712766b982"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 2,
"object_id": 1,
"content_hash": "3ffb00ddeae6286fb93e015f05a0f13ef8491ec1fe36c7238ba0842296ebf58d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"9bb3706bca48afff149104cd93664ee02c35cc7b1ef79bf6d9ded3e1af11fe2d",
"7e95960d0d4d629b92965a7ca6f5260167330632c6f0ac3ebe6e21712766b982"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 2,
"group_id": 2,
"object_id": 2,
"content_hash": "d1bc55a8c7ebfa6bab73ecdf2c8abed915c9b4f033be93acf2664bd7be2b7738",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"3edb959cd3da90f4a7bdb2238b1a3a938caf77445245b23a73918b48d9068d26",
"9e9a526eb74468568b1c429128744208f640c7e06b2879b5209ca3478b999579"
],
"direction_bits": 2,
"leaf_index": 2
}
}
]
}

View file

@ -0,0 +1,262 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 0,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "b5b033e2c5d98007d13e75aeefe0abd2d89c0e186a1484f3dae6d6e43ca312f0",
"signer_id": "corpus publisher",
"sig": "02644ca827c8ea3daa2e72a421bb949bb67b263b6feec2c02bd59427e42abec4648cdd9b8706b57982982d32cdb48f4dd8225847d6e7ee6a14e24d3ae7c30b0b",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 1,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "b5b033e2c5d98007d13e75aeefe0abd2d89c0e186a1484f3dae6d6e43ca312f0",
"signer_id": "corpus publisher",
"sig": "0f906851a29aacaab43f606e74f0983047a329b36e8999ea91638e7f30691a9c9e566cf12071a169ce352675a69505b3460df9abdf86f7335a1ec703cadae70c",
"parent_receipt_hash": "77806cf33682f4544f7fea3101005e9bfdd290ecebe78dd7b0e24b570f52d521"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 2,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "b5b033e2c5d98007d13e75aeefe0abd2d89c0e186a1484f3dae6d6e43ca312f0",
"signer_id": "corpus publisher",
"sig": "421706dcece46963a6283d15f0269b711e2125ffee005507d18981f8858d7102d4898efed0778ae997fadf06da29d31e583662b69ad0eb70c654ddaa538dca01",
"parent_receipt_hash": "7e45ba5b32c2baeef1b55d2473a0b8096b6d0e156f478f051e859403337c4dbb"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 3,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "b5b033e2c5d98007d13e75aeefe0abd2d89c0e186a1484f3dae6d6e43ca312f0",
"signer_id": "corpus publisher",
"sig": "876f172a3c59e83575552bd9082e2252c01441100d75bbd65d8ea0f5cf3cfbb04a6f61c00f8898e2e6bfba2e947ab1efdf9122520faba0a6e4437d74d9293d0f",
"parent_receipt_hash": "e47d3c48a3688255bd2f89fa71a5af8d044742eae7742d18f2c862654d9b2968"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
}
]
}

View file

@ -0,0 +1,262 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 0,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "f6e30f65fceac9b6ada8dcac2cc2570dc0f995a47510f1f8a9b059df4c8078cd22f9dcadcfe9b6fe63e09cfb66456ee52ec95d888eb9ee97da9d7d9401ffd502",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 1,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "726b6d73a220c9145b0dc85ef8b8f165d1dda249b61dac2f4e4182da953c5d7da1d05fccfbacdf4f16831898a019386175216a80f0bb61f65e1f66f8799bc80a",
"parent_receipt_hash": "351b15632022ea1de17b0625f29e1b5da5fd1f8062f08e2ac71592a3a06ed278"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 2,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "efb642334c4f1bd9e314cfa40b7ebad09b0a1bcf2755f9f53aff673d05c9e6b29447da8fd211ef0f7688f5fd66dc124b4a46f9ca6b41c92d04577c7239066004",
"parent_receipt_hash": "34fc9a08f1f5be49823e319385542696b4d388088d0117b8823a58ed6aed811f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 3,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "0652205c00a64d57cf0e33d358c22319c3bb39e37d3d3a6186241bd9a35a46e040024ec8c5c7c17fa4c0ee3135bb229e7a46708651cf4b225266ded20b21bb09",
"parent_receipt_hash": "6bea20c763d58218a72402e7d6d75ef9db460b3c62258b26e1a49762800c9516"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
}
]
}

Binary file not shown.

View file

@ -0,0 +1,327 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 10,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "84df449899ed40a12e7d03c9ec84a37d3e9102d53ddeed19ebf8d9eecad4edb89427f7eb4a34cffda0417a2ffabef2617dd626be82eb3a02fa92623bda3e240d",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 11,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "30769cdf9cc26ae3054323d0ba4d16ad9c381c86f05f458c084a707a060bdde8849883f4f8ebcf7c34a1314da2f86e6711e791f1d9fc2c3d8fb9c4598abbba0b",
"parent_receipt_hash": "8c02df8dba110bfcf3a8e9e8849fc74c4afcd5fa033b9002efc460964225c11e"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 12,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "02b221bcdcefb2977d2c5d6db6acf971aa1137524976d84f6674af4d2a8ff044cf2eb905d0d730a0422d5a0c53db6af8aa556567e1ebdb022ed22620112fcd0c",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 13,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "dc2f2c66935d91c8b4dc1f3922670cd0966fec281852bc1d31161b1365bff8a714f9785e17cff3db17e51652b125a95685eff0777052cd924ea9faf64c3d9501",
"parent_receipt_hash": "3899aa43e23adcafb061e18f011c724107eb054da674322abf859f51cbcf9e8f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 14,
"root_hash": "54a6deeba8e5e8e4a3b6e5d53f6156408652c1f9fbdb822ab22fe0b8ecb959c0",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:06.400000Z",
"group_end": "2026-10-20T11:00:08.000000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "e39cb9411567ec6d234350a11db255c55ed9b177032cd9b1538dec5290df58e206bcc43137cc9b33532aeed7fbc45d416f8a5f569ef2c5610c6a95552d3a6301",
"parent_receipt_hash": "b331689118cb8ea170eb38a414fa9fee995adc47e50fce629a809d264a0c1c54"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 0,
"content_hash": "9513817d3f50ea722639343dcc52b1919677ebbf90a269b4202af216e63a2d80",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"4b215fc705ff8f7283d9d8a278bdcb14465d952c871e22748edfa35ace8f7993",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 1,
"content_hash": "dd2ff276ca81c40d2152c7bd76e03c28e9d356f20157f1f1af28248aeab6e261",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6a3fdf96c6c86ba1e7c5b97ec0b966b1b221dcf2f4569589b1c0d927955b3f26",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 2,
"content_hash": "287cf5dc07c0ddbbca276149a450e84da9b01d4f26daad93c9061ffbaf93e61d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2f713e57cb5e7d69741ceeb374bebd00450d9f233b95f00e3c7ad935e15478a2",
"389e3783984727b17412c2965c5e97ef01b9225dbee3b3200922e2ae9e83ff56"
],
"direction_bits": 2,
"leaf_index": 2
}
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,235 @@
{
"groups": [
{
"kind": "group",
"track_alias": 3,
"group_id": 0,
"root_hash": "e1a83ba6bfd481ac0f831d04edbccf3d2ff94b2e447ba3add4ab9b481220d8e1",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:01.600000Z",
"signer_pubkey": "c6d973538beef5386cc061f48a81c581312b56ee754bd1ca5345938052e7c1b0",
"signer_id": "corpus publisher",
"sig": "87331eda06f11cc3e6117722508a22b3ecaee3e718089f8ef78156b76ecd9e6c5f677a6395ff66b5269e5b09ac5955ee6251b9ebbf6fe1312b62c3fdb767b408",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 3,
"group_id": 1,
"root_hash": "db7bfcbeb3cc6749cac67629bcf4b80ea89576de4ab35e26c01cf9cec5e89a2b",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:01.600000Z",
"group_end": "2026-10-20T11:00:04.000000Z",
"signer_pubkey": "c6d973538beef5386cc061f48a81c581312b56ee754bd1ca5345938052e7c1b0",
"signer_id": "corpus publisher",
"sig": "29b4dab9052d0ba13f6af8fb1297c5ed01a3e1a763602344e032d8fd388cb47cb1c0c1b0c7c1e440234d7a1433fb7ef1d3c5bbcab9228927b6bb92440af1950f",
"parent_receipt_hash": "c075cc5af1e63d18079a5da68c927639cd98d760747cb94bbb42a8e5181b1e85"
},
{
"kind": "group",
"track_alias": 3,
"group_id": 2,
"root_hash": "197d569450354354a4c0334579bbcf74930804b3231ac5eeb14c396dfbbd8e47",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:04.000000Z",
"group_end": "2026-10-20T11:00:06.000000Z",
"signer_pubkey": "c6d973538beef5386cc061f48a81c581312b56ee754bd1ca5345938052e7c1b0",
"signer_id": "corpus publisher",
"sig": "4f2b2ffeeadc6e4bcb1c0869b8461a40157c8ee36107783b13b0d95def100f6d42b686f031a07975748d95c35c4913cc6bc21c593623ab4018d219c1e24aa305",
"parent_receipt_hash": "c86f619afaddf1c01831563ee04cf587daa845b933e178264b3e640466a9b659"
}
],
"objects": [
{
"kind": "object",
"track_alias": 3,
"group_id": 0,
"object_id": 0,
"content_hash": "cccf0f7cf804fde5d752a6b594f7d2bb436d82cf8185dafcdbe08c10bb3dfd0a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8b5f9ae72ca1383edc1797ec81312e393d80e2487713b36376e9d9ea2f48f591",
"c6923246eb07c837ec211840187a1e0a03e02c53bc0d4cf63064f0ebae8ad695"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 0,
"object_id": 1,
"content_hash": "48048f298f38270ff99c343912a55c15714d1d95a747438d33361e70ac0b6e41",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8b2955c8060f6760cdbdd3d0faa690994e3485fec0591bb1f23254ef9ef0f6f4",
"c6923246eb07c837ec211840187a1e0a03e02c53bc0d4cf63064f0ebae8ad695"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 0,
"object_id": 2,
"content_hash": "782a9615578ad1b6dfce2688dff7fe112da7c8de2f8d44128a8adbcbcc096919",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"ddcf3f22cbb5dac9540a3e38ecfc70cc037062142faaaccbfc12f0dc7cb33db3",
"d6837f1b58faee67f8fadbb83949888c8695b7ba458e09855ba042184469d4ca"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 1,
"object_id": 0,
"content_hash": "96e5ab63f8b0786fe8134df7dbbf766f874b00327111a68200bd96ce0da2ab7a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b89d6e096ba98f5bf3b9e06bf9a9bfe4d0910f0a48c39de1fa7238e23a798504",
"cde9b502fb70313628c3e90426d3eba0b02b954f4278aee205881387360a90ce"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 1,
"object_id": 1,
"content_hash": "b6138e08ce5070082dbf3cfd65640cc3715fd688088902f22446c53256c53c91",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"05997be1dfdbed39dfb9751c086dcb6eddceab89c4839a4803d7dd763cc96057",
"cde9b502fb70313628c3e90426d3eba0b02b954f4278aee205881387360a90ce"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 1,
"object_id": 2,
"content_hash": "b235d04615e6f10f8484dc24b53d399de4182e3db66e9dd51fc13160b9faf84c",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6152066b69fa966442153bf4f8820a862a071e0daba93cd1dbbac949751fe55d",
"131f4882b5990ca31505c5a5402009a499628914d215bebc93f8af5827d9bdcd"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 1,
"object_id": 3,
"content_hash": "ae978bdaa19dd90c35546ee87cd5871e93948cb977674c72d53538ec5ec92fea",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"e11ca7d076239e6293344e7eee2c2c4b1d10354c1f794e67c0fe58140f257ba4",
"131f4882b5990ca31505c5a5402009a499628914d215bebc93f8af5827d9bdcd"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 2,
"object_id": 0,
"content_hash": "c69a9e0afd679fcf5d9743807b38a55d951b59a7f1b1920059e1c272af1638d2",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5396302ece948169569bb6671300709fa00c3c479f014177a23997f855956cfa",
"e288602bf44a8efc15f36e6dabdd165eea2e71c993f9ca8273694290a9ec83d1"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 2,
"object_id": 1,
"content_hash": "3da88edb3c6793f3bf206b74db210618d716c28a075d9d2e9b3142f4aeb46013",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d5094da95008c6d0bf238d854873a0b7696dfd80082cb8481890bbd699b15398",
"e288602bf44a8efc15f36e6dabdd165eea2e71c993f9ca8273694290a9ec83d1"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 2,
"object_id": 2,
"content_hash": "f32df7ab37e364edc2d22b3fab7a7cefaccb3357a1e51396200460e77b02d305",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"a76d58e41afb10f34613eb62755419bd56c3f96685385fdfbce8d1d5f95e23ca",
"c63fb69cd61d929eb5360c97c168490c0bc57bb2318f8ded79e67edffe168d1a"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 3,
"group_id": 2,
"object_id": 3,
"content_hash": "a132892d5bb477f409493bea4699e8d335027d30aa66c82d69aaa89cc15f1a9c",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6be22c59f2b8aeeacae5713c9d74e612d1943412c3932c71ac6f280d238649c8",
"c63fb69cd61d929eb5360c97c168490c0bc57bb2318f8ded79e67edffe168d1a"
],
"direction_bits": 3,
"leaf_index": 3
}
}
]
}

Binary file not shown.

View file

@ -0,0 +1,262 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 0,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "f6e30f65fceac9b6ada8dcac2cc2570dc0f995a47510f1f8a9b059df4c8078cd22f9dcadcfe9b6fe63e09cfb66456ee52ec95d888eb9ee97da9d7d9401ffd502",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 1,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "726b6d73a220c9145b0dc85ef8b8f165d1dda249b61dac2f4e4182da953c5d7da1d05fccfbacdf4f16831898a019386175216a80f0bb61f65e1f66f8799bc80a",
"parent_receipt_hash": "351b15632022ea1de17b0625f29e1b5da5fd1f8062f08e2ac71592a3a06ed278"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 2,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "efb642334c4f1bd9e314cfa40b7ebad09b0a1bcf2755f9f53aff673d05c9e6b29447da8fd211ef0f7688f5fd66dc124b4a46f9ca6b41c92d04577c7239066004",
"parent_receipt_hash": "34fc9a08f1f5be49823e319385542696b4d388088d0117b8823a58ed6aed811f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 3,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "0652205c00a64d57cf0e33d358c22319c3bb39e37d3d3a6186241bd9a35a46e040024ec8c5c7c17fa4c0ee3135bb229e7a46708651cf4b225266ded20b21bb09",
"parent_receipt_hash": "6bea20c763d58218a72402e7d6d75ef9db460b3c62258b26e1a49762800c9516"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0bae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
}
]
}

View file

@ -0,0 +1,262 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 0,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "f6e30f65fceac9b6ada8dcac2cc2570dc0f995a47510f1f8a9b059df4c8078cd22f9dcadcfe9b6fe63e09cfb66456ee52ec95d888eb9ee97da9d7d9401ffd502",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 1,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "736b6d73a220c9145b0dc85ef8b8f165d1dda249b61dac2f4e4182da953c5d7da1d05fccfbacdf4f16831898a019386175216a80f0bb61f65e1f66f8799bc80a",
"parent_receipt_hash": "351b15632022ea1de17b0625f29e1b5da5fd1f8062f08e2ac71592a3a06ed278"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 2,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "efb642334c4f1bd9e314cfa40b7ebad09b0a1bcf2755f9f53aff673d05c9e6b29447da8fd211ef0f7688f5fd66dc124b4a46f9ca6b41c92d04577c7239066004",
"parent_receipt_hash": "34fc9a08f1f5be49823e319385542696b4d388088d0117b8823a58ed6aed811f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 3,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "0652205c00a64d57cf0e33d358c22319c3bb39e37d3d3a6186241bd9a35a46e040024ec8c5c7c17fa4c0ee3135bb229e7a46708651cf4b225266ded20b21bb09",
"parent_receipt_hash": "6bea20c763d58218a72402e7d6d75ef9db460b3c62258b26e1a49762800c9516"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
}
]
}

View file

@ -0,0 +1,248 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 0,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "f6e30f65fceac9b6ada8dcac2cc2570dc0f995a47510f1f8a9b059df4c8078cd22f9dcadcfe9b6fe63e09cfb66456ee52ec95d888eb9ee97da9d7d9401ffd502",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 2,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "efb642334c4f1bd9e314cfa40b7ebad09b0a1bcf2755f9f53aff673d05c9e6b29447da8fd211ef0f7688f5fd66dc124b4a46f9ca6b41c92d04577c7239066004",
"parent_receipt_hash": "34fc9a08f1f5be49823e319385542696b4d388088d0117b8823a58ed6aed811f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 3,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "7772ae8959f2a940a9f4e895d8ba7cf958632cb3ad7f98625c25b5a86fb21d6b",
"signer_id": "corpus publisher",
"sig": "0652205c00a64d57cf0e33d358c22319c3bb39e37d3d3a6186241bd9a35a46e040024ec8c5c7c17fa4c0ee3135bb229e7a46708651cf4b225266ded20b21bb09",
"parent_receipt_hash": "6bea20c763d58218a72402e7d6d75ef9db460b3c62258b26e1a49762800c9516"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 0,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 1,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 2,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 3,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
}
]
}

View file

@ -0,0 +1,327 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 10,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "84df449899ed40a12e7d03c9ec84a37d3e9102d53ddeed19ebf8d9eecad4edb89427f7eb4a34cffda0417a2ffabef2617dd626be82eb3a02fa92623bda3e240d",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 11,
"root_hash": "9c8cbf9446de2268f89df7d65f94e8ee8429fbe8506435355878cd8a29024b8a",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "39b23a7bb5c1ef3db475be398dcb34b433dbb344c1478c8dfddd2a7a19fdf8f279ea1f67bbfcce1a6fa0863a813b4bc28fb7754f86a6735b2462c79fb758360f",
"parent_receipt_hash": "8c02df8dba110bfcf3a8e9e8849fc74c4afcd5fa033b9002efc460964225c11e"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 12,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "02b221bcdcefb2977d2c5d6db6acf971aa1137524976d84f6674af4d2a8ff044cf2eb905d0d730a0422d5a0c53db6af8aa556567e1ebdb022ed22620112fcd0c",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 13,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "dc2f2c66935d91c8b4dc1f3922670cd0966fec281852bc1d31161b1365bff8a714f9785e17cff3db17e51652b125a95685eff0777052cd924ea9faf64c3d9501",
"parent_receipt_hash": "3899aa43e23adcafb061e18f011c724107eb054da674322abf859f51cbcf9e8f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 14,
"root_hash": "54a6deeba8e5e8e4a3b6e5d53f6156408652c1f9fbdb822ab22fe0b8ecb959c0",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:06.400000Z",
"group_end": "2026-10-20T11:00:08.000000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "e39cb9411567ec6d234350a11db255c55ed9b177032cd9b1538dec5290df58e206bcc43137cc9b33532aeed7fbc45d416f8a5f569ef2c5610c6a95552d3a6301",
"parent_receipt_hash": "b331689118cb8ea170eb38a414fa9fee995adc47e50fce629a809d264a0c1c54"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 0,
"content_hash": "9cf4550fd7e78c9a34fb59234db253b7d254d4d29e6aab037d072f6f3965dd69",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8a86dca33eb5ed4e7c9db15a2d55c6f788bc73a0dae2cd42f50500115bdb2b89"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 0,
"content_hash": "9513817d3f50ea722639343dcc52b1919677ebbf90a269b4202af216e63a2d80",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"4b215fc705ff8f7283d9d8a278bdcb14465d952c871e22748edfa35ace8f7993",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 1,
"content_hash": "dd2ff276ca81c40d2152c7bd76e03c28e9d356f20157f1f1af28248aeab6e261",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6a3fdf96c6c86ba1e7c5b97ec0b966b1b221dcf2f4569589b1c0d927955b3f26",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 2,
"content_hash": "287cf5dc07c0ddbbca276149a450e84da9b01d4f26daad93c9061ffbaf93e61d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2f713e57cb5e7d69741ceeb374bebd00450d9f233b95f00e3c7ad935e15478a2",
"389e3783984727b17412c2965c5e97ef01b9225dbee3b3200922e2ae9e83ff56"
],
"direction_bits": 2,
"leaf_index": 2
}
}
]
}

View file

@ -0,0 +1,327 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 10,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "84df449899ed40a12e7d03c9ec84a37d3e9102d53ddeed19ebf8d9eecad4edb89427f7eb4a34cffda0417a2ffabef2617dd626be82eb3a02fa92623bda3e240d",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 11,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "a8c27d61a29c34ff447794561bbbd5eb9ff4c6cd7f75989b12e9e97e34645520",
"signer_id": "corpus publisher",
"sig": "e5ee49fee1fd989c5e1c65ff294dbe0711cccbba89e381bd4af7066f4779385e32fd235f63199c9f31dcd994bdd8bfdba4f7c80cc248f95904a5823091adea01",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 12,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "02b221bcdcefb2977d2c5d6db6acf971aa1137524976d84f6674af4d2a8ff044cf2eb905d0d730a0422d5a0c53db6af8aa556567e1ebdb022ed22620112fcd0c",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 13,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "dc2f2c66935d91c8b4dc1f3922670cd0966fec281852bc1d31161b1365bff8a714f9785e17cff3db17e51652b125a95685eff0777052cd924ea9faf64c3d9501",
"parent_receipt_hash": "3899aa43e23adcafb061e18f011c724107eb054da674322abf859f51cbcf9e8f"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 14,
"root_hash": "54a6deeba8e5e8e4a3b6e5d53f6156408652c1f9fbdb822ab22fe0b8ecb959c0",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:06.400000Z",
"group_end": "2026-10-20T11:00:08.000000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "e39cb9411567ec6d234350a11db255c55ed9b177032cd9b1538dec5290df58e206bcc43137cc9b33532aeed7fbc45d416f8a5f569ef2c5610c6a95552d3a6301",
"parent_receipt_hash": "b331689118cb8ea170eb38a414fa9fee995adc47e50fce629a809d264a0c1c54"
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 0,
"content_hash": "9513817d3f50ea722639343dcc52b1919677ebbf90a269b4202af216e63a2d80",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"4b215fc705ff8f7283d9d8a278bdcb14465d952c871e22748edfa35ace8f7993",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 1,
"content_hash": "dd2ff276ca81c40d2152c7bd76e03c28e9d356f20157f1f1af28248aeab6e261",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6a3fdf96c6c86ba1e7c5b97ec0b966b1b221dcf2f4569589b1c0d927955b3f26",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 2,
"content_hash": "287cf5dc07c0ddbbca276149a450e84da9b01d4f26daad93c9061ffbaf93e61d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2f713e57cb5e7d69741ceeb374bebd00450d9f233b95f00e3c7ad935e15478a2",
"389e3783984727b17412c2965c5e97ef01b9225dbee3b3200922e2ae9e83ff56"
],
"direction_bits": 2,
"leaf_index": 2
}
}
]
}

View file

@ -0,0 +1,327 @@
{
"groups": [
{
"kind": "group",
"track_alias": 1,
"group_id": 10,
"root_hash": "d7c41cd63b26b976cc556f9f5a5ecb1151421210aa5979e124958e951e7ed309",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:00.000000Z",
"group_end": "2026-10-20T11:00:02.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "84df449899ed40a12e7d03c9ec84a37d3e9102d53ddeed19ebf8d9eecad4edb89427f7eb4a34cffda0417a2ffabef2617dd626be82eb3a02fa92623bda3e240d",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 11,
"root_hash": "73ff462e0454b7c6d37af29e979c3a7dcad4d128e15c15035f601c3819d12c71",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:02.400000Z",
"group_end": "2026-10-20T11:00:03.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "30769cdf9cc26ae3054323d0ba4d16ad9c381c86f05f458c084a707a060bdde8849883f4f8ebcf7c34a1314da2f86e6711e791f1d9fc2c3d8fb9c4598abbba0b",
"parent_receipt_hash": "8c02df8dba110bfcf3a8e9e8849fc74c4afcd5fa033b9002efc460964225c11e"
},
{
"kind": "group",
"track_alias": 1,
"group_id": 12,
"root_hash": "7db0b6d4458309c8be8df8080ce08452bdccc79aed00d85cec614ce5adc83009",
"leaf_count": 4,
"joules_total": 0,
"group_start": "2026-10-20T11:00:03.400000Z",
"group_end": "2026-10-20T11:00:05.400000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "02b221bcdcefb2977d2c5d6db6acf971aa1137524976d84f6674af4d2a8ff044cf2eb905d0d730a0422d5a0c53db6af8aa556567e1ebdb022ed22620112fcd0c",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 13,
"root_hash": "293931ddebcd8e3cca482475e3b1a93cc2f225427538a3e5da476bf5eae3b4d0",
"leaf_count": 2,
"joules_total": 0,
"group_start": "2026-10-20T11:00:05.400000Z",
"group_end": "2026-10-20T11:00:06.400000Z",
"signer_pubkey": "4ae5f950c862c6f33f7bb93849fcfb198d87421660fa5ab5e71c0548abf7983e",
"signer_id": "corpus publisher",
"sig": "99ad73ac72a6b82438857655e4919171449152d2857246f4a413ff79d521c2e3ab79ae713a66b5fcfb64872fd401cb9882b46928a9bff5727824ca12c5ef0b00",
"parent_receipt_hash": null
},
{
"kind": "group",
"track_alias": 1,
"group_id": 14,
"root_hash": "54a6deeba8e5e8e4a3b6e5d53f6156408652c1f9fbdb822ab22fe0b8ecb959c0",
"leaf_count": 3,
"joules_total": 0,
"group_start": "2026-10-20T11:00:06.400000Z",
"group_end": "2026-10-20T11:00:08.000000Z",
"signer_pubkey": "9e5e5a3320bc06913b2cd5b938c59fe79ad4d89015467b16638a41a464719557",
"signer_id": "corpus publisher",
"sig": "e39cb9411567ec6d234350a11db255c55ed9b177032cd9b1538dec5290df58e206bcc43137cc9b33532aeed7fbc45d416f8a5f569ef2c5610c6a95552d3a6301",
"parent_receipt_hash": null
}
],
"objects": [
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 0,
"content_hash": "ed3e285f8b0590025be3a310fd384642973f7ab4cc2531ffb3767dc65decbc87",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"84bd9285e1a79ab4d31fc47abcc3d4d7385c4ee38be89090f67b3d0da066fe03",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 1,
"content_hash": "c3c0621e9c77910ba45e7c7d6060ca3baa48454877a3c2947c1327f0b5042960",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"476483f91e3ae73abe1fa7137178680a3350d30a86d619ccde04ce7b9d4672f1",
"a3f56e2717b3cae3def088678e67d4b8266e38cecd14b6a29f03653ef1d01996"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 2,
"content_hash": "313e889ebc1aaa08f347a248bae963fdb3ce7cb1ebffd13a0ea862d4833184de",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2212db8269bac3d91fd34abfda366d918d848c5d0b1f5b900b1421d22cbe0225",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 10,
"object_id": 3,
"content_hash": "c9b87a65ceabd21a394a62f0b27677207fa40002294635bc4c19235dfdae2b35",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"b760b6cef18489c4db7a83675f09424498848a4e93f112700ac075dbb1ff05df",
"a954156f25c6e4a22d745879b4e028f3a1039875a5c784423c876399b4e4e2fb"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 0,
"content_hash": "d26598db3232eabc5dd6f8e733f3c684a4ec2b7974b185d88ac3bcd3c020e167",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"0aae05deca890dcf94db748d801465bb0b62247cf070cd34016ed810b7b5e3b8"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 11,
"object_id": 1,
"content_hash": "56421ee48deb82f5692315209c0be565c75fde7531c924e68ee0159515de135b",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"d22a0c40cbd68fa52e6afb9ecb920e80fabb689963214e037059b2c45ecfe151"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 0,
"content_hash": "7032e9f88dc8b7f736553b7a9c7236669833b4e633ca24d28ed5c839b692b716",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"5e4b0d6ce028d04f28ab23761ce1f3b0f3f5e4d014f4b4f9b2fdfbd9a6994a00",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 1,
"content_hash": "07508165a8199e0362b74c498999eea3b023cb67f89b663250ab0677dcb47966",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"df44809333587e5f04510b40dd099829f3214d783044dd56a5683f56a4a5dafd",
"e4e9b40d3ba168108dc827586994c75940b4168078970493d41828b60c816605"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 2,
"content_hash": "b20995ab22a57bc11cfdc93867ba34e004a038fa39b8517e7b09354f9097e1cc",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"afcffc4feb8366e461d33125a05a371ffeeb6d52e8a66f823cd7682788ccd6fc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 2,
"leaf_index": 2
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 12,
"object_id": 3,
"content_hash": "c4156696922509b57ff04f290a8f880b2c7f9c567d72ac7ef8aa1dd4a3f9702d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"f0be86f54fbf3a67c5ba7b56d3efb346e7efc1dcd75eec634be99ae33afd52bc",
"4f8188470c70525b9004625ecb9e384b61df9fb5c4c7cad082e408ea3754ccec"
],
"direction_bits": 3,
"leaf_index": 3
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 0,
"content_hash": "14400b38229ea3c7ba3a9df42a9ad39cc3a9d9a26cf086d1474237e3aaa4f0a3",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"1dd9e51b1130f7abaaa90a130e278f4a85e62f423e0ae95cb122a6b77cccd9f3"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 13,
"object_id": 1,
"content_hash": "70dee7a8e6962e9ea7e80b4b8591bf565799fa0b835ad5e4933fc6ffcf83a81a",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"8fe3347c01ade8ed1f58502398c60ab6b8cc6b68017b2632bde4fd3631edb286"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 0,
"content_hash": "9513817d3f50ea722639343dcc52b1919677ebbf90a269b4202af216e63a2d80",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"4b215fc705ff8f7283d9d8a278bdcb14465d952c871e22748edfa35ace8f7993",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 0,
"leaf_index": 0
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 1,
"content_hash": "dd2ff276ca81c40d2152c7bd76e03c28e9d356f20157f1f1af28248aeab6e261",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"6a3fdf96c6c86ba1e7c5b97ec0b966b1b221dcf2f4569589b1c0d927955b3f26",
"2ec5cd1f3d701bd4dd6ddb31e8cb3a27dd0ff54ec3a66b91d2e9bb996b6ca883"
],
"direction_bits": 1,
"leaf_index": 1
}
},
{
"kind": "object",
"track_alias": 1,
"group_id": 14,
"object_id": 2,
"content_hash": "287cf5dc07c0ddbbca276149a450e84da9b01d4f26daad93c9061ffbaf93e61d",
"joules_micro": 0,
"origin": "corpus",
"merkle_proof": {
"siblings": [
"2f713e57cb5e7d69741ceeb374bebd00450d9f233b95f00e3c7ad935e15478a2",
"389e3783984727b17412c2965c5e97ef01b9225dbee3b3200922e2ae9e83ff56"
],
"direction_bits": 2,
"leaf_index": 2
}
}
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -686,6 +686,20 @@
"edition": null,
"registered": "2026-10-19"
},
{
"capability": "wai.live.provenance",
"kind": "record",
"status": "registered",
"media": null,
"role": null,
"tier": null,
"licence": null,
"replicate": null,
"sets": [],
"spec_section": "§5 Interactive, temporal & computed content",
"edition": null,
"registered": "2026-10-21"
},
{
"capability": "wai.live.recording",
"kind": "record",
@ -2277,6 +2291,13 @@
"section": "§3",
"status": "defined"
},
{
"name": "wai-c2pa",
"kind": "catalog",
"document": "extensions/live-provenance.md",
"section": "§10.2",
"status": "defined"
},
{
"name": "wai-key-status",
"kind": "document-kind",
@ -2347,6 +2368,13 @@
"section": "Appendix B",
"status": "provisional"
},
{
"name": "wai_c2pa_track",
"kind": "catalog",
"document": "extensions/live-provenance.md",
"section": "§10.2",
"status": "defined"
},
{
"name": "wai_capabilities",
"kind": "catalog",

View file

@ -576,6 +576,13 @@ wai:wai.live.moderation a wai:Capability ;
wai:specSection "§5 Interactive, temporal & computed content" ;
wai:registeredOn "2026-10-19"^^xsd:date .
wai:wai.live.provenance a wai:Capability ;
rdfs:label "wai.live.provenance" ;
wai:kind wai:kind-record ;
wai:status wai:status-registered ;
wai:specSection "§5 Interactive, temporal & computed content" ;
wai:registeredOn "2026-10-21"^^xsd:date .
wai:wai.live.recording a wai:Capability ;
rdfs:label "wai.live.recording" ;
wai:kind wai:kind-record ;

View file

@ -264,6 +264,16 @@ live_watermark = ["live_room"]
# wai.video.ssai's receipt: the decision recomputed, the asset list bound, the spend held to the
# decider grant's ceiling. SHA-256, BLAKE3, Ed25519 and the key log only; no new dependency.
live_ads = ["live_room", "video_ssai"]
# Live provenance (extensions/live-provenance): `wai.live.provenance` — the live video provenance
# of C2PA 2.4 §19 for a room's CMAF tracks and a device's CMAF take, written and verified with no
# C2PA library: ISO BMFF segments and the BMFF hash over whole-box exclusions, the JUMBF manifest
# store, COSE_Sign1 with EdDSA and the OKP key, the claim signer's X.509 chain (DER written and
# read here), per-segment manifests chained by manifest identifier, Verifiable Segment Info under
# rotating session keys, and each segment tied to the JWP group receipt and object receipts of the
# same chunks. CBOR through live_watermark's deterministic reader; the disclosure label and its
# IPTC and AI-disclosure mapping through timed_text. SHA-256, BLAKE3 and Ed25519 only; no new
# dependency.
live_provenance = ["live_watermark", "timed_text"]
# Timed text and live captions (extensions/timed-text): `wai.text.timed` — the cue model,
# live caption revisions (`caption` events of wai.live.events with the WTX1 annotation),
# and their exact mappings onto WebVTT documents and segments, the IMSC1 Text Profile,
@ -728,6 +738,11 @@ name = "wai_live_ads_vectors"
path = "src/bin/wai_live_ads_vectors.rs"
required-features = ["live_ads"]
[[bin]]
name = "wai_live_provenance_vectors"
path = "src/bin/wai_live_provenance_vectors.rs"
required-features = ["live_provenance"]
[[bin]]
name = "wai_timed_text_vectors"
path = "src/bin/wai_timed_text_vectors.rs"
@ -1428,6 +1443,11 @@ name = "live_ads"
path = "tests/live_ads.rs"
required-features = ["live_ads"]
[[test]]
name = "live_provenance"
path = "tests/live_provenance.rs"
required-features = ["live_provenance"]
[[test]]
name = "timed_text"
path = "tests/timed_text.rs"

View file

@ -0,0 +1,93 @@
//! Conformance corpus for live provenance (`live-conformance/c2pa-live/`,
//! extensions/live-provenance.md §13).
//!
//! wai_live_provenance_vectors gen <corpus-dir> write vectors.json, the trust anchor and
//! every vector's segments and receipts,
//! from fixed seeds
//! wai_live_provenance_vectors verify <corpus-dir> every file regenerates byte for byte, no
//! other file but README.md is there, and
//! every vector gets the outcome it states
//!
//! The media are the AV1 floor of the packaging corpus (`pack-conformance/packs/video-base-01`),
//! read from the `wai` directory two levels above the corpus directory. The generator and this
//! verifier are one implementation; the corpus's second implementation is
//! `live-conformance/c2pa_live_verify.py`, written from the extension's text and sharing no
//! code with this binary.
use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use wai::live_provenance::corpus::{self, Media};
fn media(dir: &Path) -> Media {
// The corpus directory need not exist yet, so its parents are taken from the path.
let wai = dir.parent().and_then(Path::parent).map_or_else(|| dir.join("../.."), Path::to_path_buf);
match Media::load(&wai) {
Some(m) => m,
None => {
eprintln!("the floor under {} does not read", wai.join(corpus::FLOOR_DIR).display());
std::process::exit(1);
}
}
}
fn main() {
let a: Vec<String> = std::env::args().collect();
match (a.get(1).map(String::as_str), a.get(2)) {
(Some("gen"), Some(d)) => {
let dir = PathBuf::from(d);
let m = media(&dir);
for (name, body) in corpus::generate(&m) {
let p = dir.join(&name);
if let Some(parent) = p.parent()
&& let Err(e) = std::fs::create_dir_all(parent)
{
eprintln!("create {}: {e}", parent.display());
std::process::exit(1);
}
if let Err(e) = std::fs::write(&p, body) {
eprintln!("write {}: {e}", p.display());
std::process::exit(1);
}
}
println!("wrote {d}");
}
(Some("verify"), Some(d)) => std::process::exit(verify(Path::new(d))),
_ => {
eprintln!("usage: wai_live_provenance_vectors gen|verify <corpus-dir>");
std::process::exit(2);
}
}
}
fn read_tree(root: &Path, dir: &Path, out: &mut BTreeMap<String, Vec<u8>>) -> std::io::Result<()> {
for e in std::fs::read_dir(dir)? {
let e = e?;
let p = e.path();
if p.is_dir() {
read_tree(root, &p, out)?;
} else {
let rel = p.strip_prefix(root).expect("under the root").to_string_lossy().replace('\\', "/");
if rel != "README.md" {
out.insert(rel, std::fs::read(&p)?);
}
}
}
Ok(())
}
fn verify(dir: &Path) -> i32 {
let mut files = BTreeMap::new();
if let Err(e) = read_tree(dir, dir, &mut files) {
eprintln!("read {}: {e}", dir.display());
return 1;
}
let generated: BTreeMap<String, Vec<u8>> = corpus::generate(&media(dir)).into_iter().collect();
let same = files == generated;
println!("{} every file regenerates byte for byte from its seeds, and no other file is there", if same { "PASS" } else { "FAIL" });
let fails = corpus::verify_files(&files);
for f in &fails {
println!("FAIL {f}");
}
println!("{} every vector gets the outcome the corpus states", if fails.is_empty() { "PASS" } else { "FAIL" });
(!same || !fails.is_empty()) as i32
}

Some files were not shown because too many files have changed in this diff Show more