===== 001 BEGIN review brief | 2209 bytes | SHA256 30e0ec95a9600622234db11dcca0651cbe8017250c671d6a02e899037f3a17da =====
Fresh PLAN review only: bounded whole-buffer Poseidon2 BAO proof verifier.
Author: Codex. Different-vendor reviewer requested by the parent; no implementation exists.
Review this proposed API/state/error/work/output contract and its literal test plan.
Return APPROVE or REQUEST CHANGES, with concrete blockers separated from finite advice.
Canon pass: preserve licenses/vocabulary, same-byte particle/root authority boundary,
canonical fixed-4096 profile and declared Radio→soft3 / prospective Kadek→Cyb reach.

Actual Radio implementation parent b933829cbe273d2f31fe75ca83125f3ddd8917a2 includes
reviewed/merged RangeTraversal. Research measurements remain at a96d86e; exact bridge
confirms 38/39 unchanged source/lock/consumer inputs and one lib module-wiring delta.
GroupHasher and concrete Hemera kernels are reused. Kadek BaoAnchor is committed at
4d9ca9ab3498238b9c1e03f6d6f160e1ec729912; no Kadek production change is proposed here.

Full owning Radio types/geometry/reducer/backend/carrier sources and actual traversal
tests are included, plus exact kernel/authority/registry excerpts, proposed tasks,
manual probe source, primary raw stdout and all command-result summaries. Excerpts
are labeled with exact ranges and full-source hashes. No new verifier pass, allocation
guarantee, first-partial authentication or row-4 closure is claimed.

Explicit omissions: complete historical audit archives, compiled targets, full Cargo
metadata stdout, bulk lock bodies, unrelated workspace runtime/network sources, the
rest of Hemera sponge/permutation/tree source, and historical broad gate raw bodies.
Their relevant hashes/revisions remain indexed in support manifests; do not claim you
reviewed those omitted inputs. No global dependency inventory is newly fetched. The
retained registry at cached origin 18fd identifies Radio as part_of soft3; the earlier
registry inventory is a historical reference, not proof of current entire-graph build.
The new API migrates no legacy consumer. Required native/CI/rung gates are planned,
not green by inheritance. Source reviewers must distinguish synthetic encoding aliases
from actual complete-file proof commitments. The original legacy APIs stay unchanged.

===== 001 END =====

===== 002 BEGIN task/plan.md | 14878 bytes | SHA256 6a104b42977d594a0ac1e05cd999ec750c896f4d4e24865a0eb1718cfba34350 =====
# Bounded complete-buffer BAO proof verification

Proposed PLAN; no production implementation or approval. Serves Kadek foundation
row 4 through Radio, declared part of soft3; the future Kadek adapter reaches Cyb.
Radio implementation parent is b933829cbe273d2f31fe75ca83125f3ddd8917a2 (PR39);
research probes remain attributed to a96d86e28d384cdf656aadc4282c78c0c170c102.
Hemera is d5f0a09539360934fb32db9b2e15a91995607db6. The prerequisite RangeTraversal
is merged; an ordinary fast-forward and exact source/lock/consumer bridge preserve
the research identities. Its source equals the previously frozen candidate. Kadek's
sealed BaoAnchor is now committed at 4d9ca9ab3498238b9c1e03f6d6f160e1ec729912.

## Result and boundary

Add one concrete no_std Poseidon2 proof reader borrowing an immutable complete
proof buffer. It verifies one nonempty half-open byte request, or the empty file,
against an externally trusted complete-root/length pair. It returns a private-field
borrowed view only after every selected group, every required parent and exact
encoded EOF have passed. The view can replay one geometry item per output action
without allocating spans or copying payload. Legacy std readers/producers remain
unchanged. This is an additive minor API, with ring 1 reach, not a patch/ring-0-only
claim. The canonical-wire requirement is an intentional new-profile tightening.

Radio does not derive particle authority. The future Kadek adapter must use the
committed BaoAnchor's root, length and HemeraFixed4096V1 profile, retain that sealed
association, charge persistent work, own bounded proof/output storage and publish
only after full verification. A caller-created root or Radio view cannot create a
Kadek VerifiedRange. No Kadek adapter, network fetch, incremental byte feeding,
serialized anchor, first-partial authentication, multi-range set or legacy-reader
migration belongs to this unit.

## Carrier and admission

The borrowed carrier is exactly: eight-byte LE complete u64 length, followed by
the selected preorder parent pairs and whole selected group payloads. Both 32-byte
children are present for every visited parent, even when only one child is selected.
Request and BlockSize are separate trusted operation inputs, not wire fields.
The supplied length must equal the header. A file-backed slice's in-memory length
does not substitute for this complete file length. No suffix or concatenated proof
is permitted. A final short group consumes exactly its remaining file bytes.

ROOT, absolute 4096-byte counters, complete-left shape and concrete kernels follow
Hemera d5's tree/capacity/encoding contracts and parameters, already used by Radio
a96's GroupHasher. Grouping changes the carrier, never the canonical complete root.
Historical grouped internal CVs without ROOT are not accepted as canonical roots.
This does not equate the tree root with the separately pinned plain particle hash.

Constructor order is deterministic: RangeTraversal geometry admission (BlockSize
before range), reject an empty request when length > 0, then check the four expected
root words in ascending order. The constructor reads no proof bytes and hashes none.
Each hash word is one LE u64 and must be strictly below exported `hemera::field::P`;
check all four words in the supplied root and both children of every wire pair.
Use public Hemera constants for widths. `Hash::from_bytes` itself is a raw wrapper;
the proof reader must perform the canonical check before parent arithmetic.

Block log admits exactly the RangeTraversal range: 0..=51 on 64-bit, 0..=19 on
32-bit. This is integer geometry, not an allocation/Layout promise. Range requires
start <= end <= length. Empty file only admits 0..0: header must be zero, one empty
ROOT leaf is hashed, and EOF must be byte 8. It yields a verified empty view with
no output items. A nonempty file's empty request is rejected, including at EOF;
there is no successful mode with an unchecked root.

## Small public surface and lifetime

Names below are proposed, to be frozen by review:

```rust
ProofVerifier::new(proof: &[u8], root: [u8; 32], size: u64,
                   block: BlockSize, request: Range<u64>) -> Result<Self, ProofError>
ProofVerifier::is_finished(&self) -> bool
ProofVerifier::step(&mut self) -> Result<Option<VerifiedProof<'a>>, ProofError>
VerifiedProof::{root, size, block_size, request} // exact admitted operation inputs
VerifiedProof::items(&self) -> ProofItems<'a>
ProofItems::is_complete(&self) -> bool
impl Iterator<Item = ProofItem<'a>> + FusedIterator for ProofItems<'a>
enum ProofItem<'a> {
    Parent,
    Leaf { file_offset: u64, proof_offset: usize, bytes: &'a [u8] },
}

The implementation supplies explicit named lifetimes; this sketch abbreviates them. VerifiedProof has private fields and no public constructor, conversion from raw bytes, Deserialize, attestation or mutable-byte escape. Its accessors return the root/size/block by value, and a cloned range. It borrows only the original immutable proof, not the verifier. It can outlive a dropped verifier but not the proof bytes. No allocation owner/clone is acquired. Debug prints coordinates/state, not payload. Public ProofItem values carry slices/coordinates, not independent sealed authority; consumers obtain trusted items through a successfully completed view and its root.

Pending successful steps return None with is_finished=false. Exact EOF completion returns Some(view) once and sets is_finished=true. Later successful polls return None without work. Any processing error becomes sticky and sets is_finished=true; later polls return that same Copy error without work. Dropping cancels a pending job. No push/flush/reset/request reuse or hidden quota renewal exists.

Bounded machine and work

Use one RangeTraversal, one fixed 53-slot expected-hash stack, and at most one GroupHasher borrowing the current proof group and a static Poseidon2Backend. The expected stack follows the same frontier bound as traversal: at most 52 deferred siblings plus one current value. Parent processing pops exactly one expectation, hashes the pair using that node's ROOT bit, compares it, then pushes only selected right/left expectations in that order. It does not traverse or authenticate the unselected sibling payload. Never clone an arbitrary generic backend hash.

After constructor setup, each pending call admits exactly one of these actions:

Action Exact bounded work and transition
Header Read at most 8 bytes, compare declared/trusted size, seed expected root.
Parent Obtain one traversal item, consume exactly 64 bytes, validate left words then right words, one parent kernel, compare, push at most two expectations.
Group setup Obtain one leaf item, take exactly its checked payload slice, pop its expectation, initialize the fixed reducer; no kernel.
Group kernel Exactly one GroupHasher step: one <=4096-byte leaf or one two-child parent. On completing hash, compare the pending expected hash in this same action.
Commit Geometry and expected stack must be empty and no group pending; check cursor == proof.len, emit the view.

The empty file substitutes one synthetic zero-length ROOT group setup for geometry, then one kernel. No generic reducer, traversal scan, proof-sized buffer initialization or payload copy may be hidden in any action or constructor. Fixed 53-slot setup and small scalar checks are bounded setup. GroupHasher admission cannot fail after checked traversal: real group bytes fit usize/u64 and final absolute chunk counters are <=2^52-1; use an internal invariant assertion rather than inventing a reachable new external failure class. Stack/geometry invariants likewise follow private state.

For a valid nonempty proof let P be visited parents, L selected groups, and C the number of 4096-byte chunks across those groups. Total actions are 2 + P + L + sum(2*N_group-1) = 2 + P + 2*C. Empty-file total is 4. This is an exact oracle, not an uncharged constructor traversal. Across a u64-sized file with N=ceil(size/4096), P <= groups-1 <= N-1, so total <=3*N+1 <2^54. Counts cannot overflow u64. Error attempts cost their one admitted action; terminal polls cost 0. Radio owns no budget type. The caller checks is_finished, admits one persistent unit, then steps; it may abort on total exhaustion with no published result. A future Kadek adapter must not reset totals on yields, completed groups or the transition from verification to output/copy. No exact-total preflight is promised by this Radio API; a separate charged planning walk would be an adapter choice.

Read extents use needed <= proof.len()-cursor before slicing/advancing. Leaf coordinates come from the checked traversal; multiply its absolute chunk start by 4096 only under that bound. Keep proof usize offsets distinct from file u64 offsets. No unchecked BaoTree byte helpers are used for large geometry.

Errors and output actions

ProofError derives Debug, Clone, Copy, PartialEq and Eq, and implements Display and core::error::Error. Its exact variants and precedence are:

Location Error and coordinate
Constructor Geometry(RangeTraversalError), then EmptyRequest, then NonCanonicalRoot { word: u8 }.
Header Truncated { offset: 0, needed: 8 }, then SizeMismatch { expected, declared }.
Parent Truncated { offset: cursor, needed: 64 }, then NonCanonicalHash { offset: offending LE word's absolute proof offset } scanning left then right, then ParentMismatch { node: TreeNode }.
Group setup Truncated { offset: cursor, needed: exact group size }.
Completing group LeafMismatch { start_chunk: u64 }; zero for empty file.
Commit TrailingBytes { offset: consumed proof length }.

No EOF publication on a matching last group alone. An invalid suffix makes the whole proof fail. No partially verified view is accessible on any failure. Freeze exact Display messages and variant/coordinate assertions with tests before implementation; do not make diagnostic strings the only oracle.

items() creates a fresh checked geometry cursor in bounded fixed setup and starts its proof cursor at 8; construction scans/hashes/copies no proof. Each pending next obtains exactly one geometry item. Parent advances 64 bytes and returns Parent; leaf advances its exact size and returns that immutable slice plus file/proof coordinates. It must not loop across parents to find a leaf. Verified immutable input permits infallible replay; assert private invariants rather than rehash. P+L output actions, zero for empty file. The cursor is immediately complete after the final item and all later polls return None without work. Caller charges each pending output action separately, then charges any byte copying separately; no free collect/copy helper. Whole groups may extend outside the request. Copy only their intersection with the view's exact requested range for a requested-range packet; do not confuse wire offsets with authenticated file offsets.

Steps, files, and gates

  1. Preserve research probes and fixtures and the completed actual traversal bridge. → verify: exact Git identities, retained a96d measurements, identical prerequisite candidate/merged source, unchanged lock and owning consumers except module wiring.
  2. Freeze manual fixtures and tests from finite-cases.md, then demonstrate API absence on the exact parent. → verify: expected missing-module compiler class, separated from the measured legacy behavior; no false new runtime baseline.
  3. Add only concrete proof module, output view and re-export/module wiring. → verify: all literal cases, exact costs/coordinates, step pauses/failures, no early result.
  4. Exercise lifetime/field seals, allocation and feature/build contracts. → verify: positive control compiler case, expected compile-error classes, host allocation observer, debug/release, actual no-default count, no_std cross check; no final-link allocator-free claim based only on a library compile.
  5. Freeze gate receipts, source delta and bounded fresh CODE context. → verify: independent exact-parent/raw/source replay, different-vendor CODE approval before root's commit/merge. No production CODE review is claimed by this PLAN.

Expected production paths: cyber-bao/src/lib.rs, new cyber-bao/src/proof.rs and cyber-bao/src/proof/output.rs. Tests: new cyber-bao/tests/proof.rs, proof_failures.rs, proof_allocation.rs and support/proof.rs (split by contract if needed; every file <500 lines). Rustdoc is the API/carrier/work contract; README gets at most a module link. No dependency/feature/wire-producer/kernel changes. Task and audit paths are owned here; other source paths require a justified scope amendment. No Kadek source or shared fixture ledger changes in this unit.

Required owner gates: strict warning-free cyber-bao debug/release tests for default, no-default and all-features; doctests; Clippy and formatting; exact library no_std cross check and measured MSRV. Semver against v0.1.0 plus actual-parent comparison if needed; additive API requires minor acceptance regardless of no breaking findings. Radio CI argv/config are frozen as support: workspace all/default/none test, Clippy, docs, MSRV, formatting, deny and applicable native consumer gates are retained as required gate rows, not silently replaced by the small owner suite. External/rung closure and unavailable platform/toolchain rows must be explicit. Current parent failure comparisons use exact failing cases/commands and identical env/profile, never stale ancestor reds or an unnecessary second whole matrix. Local --locked, offline, jobs=2, incremental=0 and bounded-time configuration are labeled local strengthening, with raw command/timeout receipts. CI profile termination must be read from actual config, not inferred. Research runs no broad CI matrix.

Five likely failures

  1. A trusted size/root becomes an arbitrary authority escape: keep Radio result conditional on supplied root, borrow original bytes, publish only at strict EOF; Kadek integration is separately sealed and outside this change.
  2. ROOT or absolute counters change with grouping/selection: explicit three-leaf, sole-group, right-only and final-short manual carriers and historical-CV rejection.
  3. Unbounded work hides in a traversal/leaf/output call: exact action schedules, largest-depth finite prefixes, one-item output events and source invariant review.
  4. Canonical validation normalizes/reduces instead of rejecting: four independent word positions, both child sides and root, p-1/p/MAX boundaries before hashing.
  5. Completion, failure or borrowed retention leaks partial authority: late suffix and last-leaf failures, sticky terminal polls, interleaved jobs, output exact ranges, successful/failed/cancelled drop and compile-time lifetime/field seals.

===== 002 END =====

===== 003 BEGIN task/finite-cases.md | 8731 bytes | SHA256 93056283cc10f6fe9310aa8493c533557b5f96876b357dc8039a7b87b879a24c =====

Finite proof-verifier acceptance table

Proposed tests, frozen before the new API exists. Research fixtures are under audit/2026-10-12-bao-proof-research/fixtures. Rust primary-probe builds the wire manually, uses explicit chunk/parent expressions, then checks legacy producer and reader agreement as supplemental evidence. It does not implement the proposed reader. Its printed expected_actions are PLAN literals, not measured new-reader work.

For D[n], byte i = (31*i + floor(i/4096)) mod 256. Let Li be the non-ROOT hash of the actual chunk at absolute counter i; P01=parent(L0,L1,false). Three-chunk ROOT is parent(P01,L2,true). No recursive test helper infers these small tree shapes. Future five/seven-group cases spell their parent expressions independently: R5=P(P(P(L0,L1),P(L2,L3)),L4,ROOT); R7=P(P(P(L0,L1),P(L2,L3)),P(P(L4,L5),L6),ROOT), inner P never ROOT.

Literal successful carriers

Offsets below refer to payload in the encoded proof; file coordinates are separate. H=header, P=one parent, S=group setup, K=one reducer kernel, E=EOF commit. Every proper prefix of each action sequence must return no completed view. Output Parent events consume one action each; output leaves borrow exactly the listed proof bytes.

Fixture File/request/log Payload (proof offset; file offset; bytes) Verification Output
empty 0 / 0..0 / 0 none H S K E = 4 0
hello 5 / 1..4 / 0 8; 0; 5 H S K E = 4 Leaf
three-right 12288 / 8192..8193 / 0 72; 8192; 4096 H P S K E = 5 Parent, Leaf
three-interior 12288 / 4097..4100 / 0 136; 4096; 4096 H P P S K E = 6 Parent, Parent, Leaf
three-boundary 12288 / 4095..4097 / 0 136; 0; 4096 and 4232; 4096; 4096 H P P S K S K E = 8 Parent, Parent, Leaf, Leaf
grouped-left 12288 / 4095..4097 / 1 72; 0; 8192 H P S K K K E = 7 Parent, Leaf
final-short 8193 / 8192..8193 / 1 72; 8192; 1 H P S K E = 5 Parent, Leaf
sole-group 8192 / 1..8191 / 1 8; 0; 8192 H S K K K E = 6 Leaf

Root literals: empty ea57b2e6b1ec7d2de11b15cb6d7060dd61d247fe0fbf5f7d3fb97a7be9328552; hello 626fa46e4e7bd5c87d630eef8333931a0b9198587400a0191eae7821692880d7; D8192 2abf65dd26465a7352707d79d18ff3aab9ee5d97614a774619c79ed527e20190; D12288 373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992; D8193 40c6bd68b6e89443753bce2dd95fd159da63a7399340fa6070a762d102d9e3ae. D8192 historical internal CV is 11890a7e7cf1e4de463a04bf53bfdf269d627983a221daaf9029a3ff43297389. It must fail sole-group LeafMismatch { start_chunk: 0 }, not normalize to ROOT.

Complete the pre-implementation fixture set with explicit full-three, right/interior five/seven, all groupings 0/1/2/4 where their wire differs, one-byte final group and nonaligned requests. Freeze expected pair order/ranges before coding; roundtrip is never their sole oracle. Freeze source files before failure-first API-absence run.

Admission, malformed proof, and precedence

Case Required result
Exhaust all 256 logs, including short/empty file Geometry InvalidBlockSize outside host range; compile-only 32-bit evidence labeled separately.
Reversed range, EOF+1, both invalid log/range Geometry InvalidRange; bad log takes precedence.
Nonempty file 0..0, interior empty, EOF empty EmptyRequest before root/proof parsing.
Empty file valid 0..0 / invalid 0..1 Four-step root verification / InvalidRange.
Expected root has p or MAX in each word independently NonCanonicalRoot { word: 0/1/2/3 }; ascending first error, before header.
Root word 0 or p-1 Canonical admission, then ordinary proof mismatch if not the matching root; no false validity claim.
Hello header declared 0, 4, 6, 4096, MAX, trusted length 5 Header SizeMismatch with exact expected/declared. LE 5 succeeds.
Every header prefix 0..7 bytes Truncated { offset:0, needed:8 }.
Every truncated prefix of three-interior, grouped-left Stage-specific Truncated cursor/needed; complete bytes required before examining a pair or starting a group.
Pair word p/MAX, left and right, all four positions NonCanonicalHash at 8+word8 or 40+word8 for first pair, before parent hashing; second parent starts at 72.
Noncanonical left followed by incomplete right pair Pair Truncated takes precedence over canonical validation.
Canonical pair order swap, canonical wrong root, modified canonical sibling ParentMismatch at literal node3 or1, before group output.
Three-boundary first/last payload mutation LeafMismatch counter 0/1; completed earlier group never yields a view.
Same selected data computed at wrong absolute counter LeafMismatch of selected start counter.
Single/multiple group suffix 1 byte / concatenated valid proof TrailingBytes at exact original carrier length after hashing, no view.
Empty-file correct root + suffix / canonical wrong root TrailingBytes offset 8 / LeafMismatch counter 0.
Nonempty file header-only, nonempty request First parent or leaf setup Truncated, never success with an unchecked root.
u64MAX file, log 51 on 64-bit, first-byte query, short carrier Bounded Parent processing then leaf Truncated with exact large needed; no allocation or overflowing end.

The synthetic-canonical and four synthetic-alias fixtures bind a supplied parent commitment with an arbitrary zero unselected sibling. Each alias changes only one right child's LE word from 0 to p. Legacy accepts all under the same supplied root; the new profile must reject each at offsets 40, 48, 56, 64. No actual complete file with this synthetic root has been witnessed; these fixtures prove encoding behavior, not a particle bypass or a complete-file collision.

Work, state, retention, and bounds

  • Exact valid action sequences above under per-call schedules 1,2,total,total+1; an external test budget with total exact and exact+1 completes at identical paid count; total one below prevents final commit and yields no authority. Radio has no WorkBudget constructor, so the harness must not pretend to test Kadek's adapter.
  • Interleave two jobs and pause after every stage. No kernel repeats on resumption. Every error becomes sticky; repeat 10 failed polls returns identical variant/offset, no additional state work. Repeat 10 completed polls returns None. Drop at every pending stage performs no additional hashing or output.
  • Rewalk each completed view twice, interleave its output cursors, assert exact event counts, slices, pointer offsets, file offsets and request intersections. Retain a borrowed view/leaf after verifier/cursor drop while proof stays alive. Empty view has 0 events and immediately complete. Final next makes complete true.
  • Field/constructor seal compiler probes: a valid public API control succeeds; raw VerifiedProof struct literal fails E0451; no From/raw constructor/Deserialize escape exists; destroying or mutating borrowed proof storage before use fails the expected borrow-check class. Capture actual compiler diagnostics, not only generic compile_fail. No test claims aliases imply extra allocation charges.
  • A host counting allocator test has an allocating positive control and observes constructor, each verifier stage, completed output replay, errors/terminal polls and cancellation/drop separately. Build and retain fixture storage outside observation; exclude its later deallocation. Concrete Poseidon2 scope only; a library cross compile does not prove allocator-free linking.
  • Largest-depth fixed prefix uses u64MAX geometry, 52 explicit parent levels and one 4096-byte first leaf. Compute only those explicit synthetic commitments with zero deferred sibling CVs; a full-range request builds the 53-entry expected frontier then runs out of supplied proof. Observe Truncated and no result; do not enumerate the file or call this a real complete-file proof. This is separate from the already reviewed traversal boundary witness. Exact large coordinate/multiplication checks are asserted. Proof input retains no proof-sized output vector.

Canonical errors proposed Display strings (freeze with variants before coding): geometry delegates to RangeTraversal; EmptyRequest = "empty request for nonempty file"; NonCanonicalRoot = "noncanonical expected root word {word}"; Truncated = "truncated proof at {offset}: need {needed} bytes"; SizeMismatch = "proof size {declared} differs from expected {expected}"; NonCanonicalHash = "noncanonical proof hash word at {offset}"; ParentMismatch = "proof parent mismatch at node {node_index}"; LeafMismatch = "proof leaf mismatch at chunk {start_chunk}"; TrailingBytes = "trailing proof bytes at {offset}".

===== 003 END =====

===== 004 BEGIN task/research.md | 9092 bytes | SHA256 956ea7addb3dba2a6f16771958dd1746fd737679ca9d3de527f3a074d29ed8e7 =====

Bounded BAO proof research

Serves Kadek foundation row 4 through Radio (declared part of soft3) and a future Kadek adapter in Cyb. Stage: research complete; PLAN proposed, not approved. Owned branch research/bao-bounded-proof; no production changes, commit, push or vendor dispatch. Original preliminary note is retained in audit/2026-10-12-bao-proof-research/notes/initial-research.md.

Source identities: Radio a96d86e28d384cdf656aadc4282c78c0c170c102; Hemera d5f0a09539360934fb32db9b2e15a91995607db6; committed Kadek anchor 4d9ca9ab3498238b9c1e03f6d6f160e1ec729912. RangeTraversal merged as Radio PR39, b933829cbe273d2f31fe75ca83125f3ddd8917a2. Ordinary fetch/fast-forward and an exact source bridge confirm candidate identity and unchanged kernels/carrier/lock/consumers, except module wiring. New implementation will use b933; all research measurements remain attributed to a96d. No broad Radio matrix was run for research. This research does not close Kadek row 4 or prove an allocator-free final no_std application link.

Existing carrier and measured boundary

cyber-bao/src/io/slice.rs writes eight LE complete-length bytes, selected preorder parent pairs and complete selected groups. Multi-group verification allocates traversal, expected-hash and output vectors, hashes an entire group in one call, and does not require encoded EOF. The single-group shortcut hashes all remaining bytes without checking their length against the header. Single-group extraction includes the body even for an empty request; multi-group empty extraction is only its header. These are existing API semantics, left unchanged by the proposed unit.

The immutable legacy probe manually supplies LE5 + hello, mutates only the header, appends a six-byte suffix to a two-chunk carrier, and checks empty requests. At Radio a96d and Rust 1.95, debug and release both accept declared lengths 0,4,5,6,4096 for five actual bytes; accept the suffix after an 8264-byte proof; and return an empty result for an empty multi-group query with a wrong root. Both captured outputs are identical 321-byte files. These are size/EOF/empty-selection admission witnesses, not forged hashes, a particle/root substitution, or new-reader test failures.

Commands are captured verbatim in records/initial-debug.json and legacy-release.json: cargo run [--release] --locked --offline --manifest-path .../probe/Cargo.toml, Rust 1.95, jobs 2, incremental 0, RUSTFLAGS=-Dwarnings, a private target directory. The legacy three-file freeze remains unchanged. Root's first inline source-freeze helper used a wrong Ruby text/binary comparison and was corrected before handoff; that helper mistake is not a production discrepancy.

Independent carrier and encoding evidence

The separate 269-line primary-probe manually writes eight real-file carriers using explicit small chunk/parent expressions. They cover empty/hello, three-chunk right and interior selection, a cross-chunk request, grouped-left selection, a final one-byte group and a sole two-chunk group. Its root/offset/action table is in finite-cases.md. It compares with existing producer/reader only after construction; roundtrip is supplemental, not the wire-shape oracle. Existing empty, hello, D8192 ROOT and historical non-ROOT literals are asserted independently. New D12288 and D8193 roots are pinned kernel-expression results, not independent cryptographic implementations. Printed action counts are proposed-machine literals, not measured new-API work. Debug and release outputs and every generated fixture agree exactly.

At pinned Hemera, public hemera::field::P is 0xffff_ffff_0000_0001 and Hash stores four LE words. Hash::from_bytes preserves any 32 bytes with bytewise equality. bytes_to_cv calls Goldilocks::new, which stores raw u64; it does not itself reduce. Field arithmetic and canonical hash output identify residue-equivalent values. This corrects the preliminary shorthand that the constructor performs reduction. The normative output encoding is canonical [0,p); parent input parsing currently has no representation guard. The new profile must check all four words of root and both children before hashing; it must not normalize an invalid encoding.

A synthetic parent commitment, with actual selected-left chunk CV and an arbitrary zero unselected-right CV, demonstrates each word independently. Replacing any one zero right word by p preserves parent output and legacy acceptance; the raw Hash still differs. Five fixtures retain the canonical and four alias carriers. There is no witnessed complete file for this synthetic commitment. This measures encoding behavior, not a complete-file collision or a Kadek authority bypass. Separate 0,p-1,p,MAX raw-word controls retain their exact bytes. The proposed canonical rule accepts the first two representations and rejects the latter two, regardless of any later root mismatch. All checks pass in debug/release with strict warnings.

Smallest composition

GroupHasher is already merged: one <=4096-byte leaf or one parent kernel per call, fixed 53 frontier, absolute counters and only final ROOT. Merged RangeTraversal supplies checked u64/usize geometry with a fixed 53-frame frontier and one selected node per call. Parent child flags specify which paths to visit; both child hashes remain necessary. Neither primitive parses the carrier or binds a particle.

Proposed composition is concrete Poseidon2: a borrowed whole-buffer verifier, fixed expected-hash stack and at most one borrowed GroupHasher. Generic HashBackend permits arbitrary allocation/cost through its associated Hash and methods, so it cannot justify unconditional resource guarantees. No new hash arithmetic, generic transform, allocation, byte owner or budget abstraction is needed. The verifier checks trusted header length, all parents/groups, canonical words and exact EOF, then seals a borrowed result. Its output cursor emits one parent event or whole leaf slice per call; it never scans for a leaf, hashes again, or allocates a span vector. Kadek will separately match its BaoAnchor and own quota/pool/copy/publication.

For a valid nonempty proof, exact action count is header 1 + parents P + group setups L

  • sum(2N_group-1) + EOF 1 =2+P+2C; empty file costs 4 and has no output items. No exact total is computed by an uncharged traversal. Caller-supplied persistent budgets can stop before any next action without publication. One atomic kernel remains a bounded unit, not constant wall time. Immutable proof borrowing prevents mutation after verification; completed views depend on proof lifetime, not verifier lifetime. Private fields prevent fabricating a completed view through safe API.

Chosen empty policy is strict: reject any empty request to a nonempty file, including EOF, instead of adding a successful no-authentication mode. Empty file 0..0 still hashes canonical empty ROOT and requires an exact eight-byte header. This API is a new strict profile; unchanged legacy single-group empty extraction does not define its admission. A profile-preserving grouping change uses repaired canonical roots; old grouped internal CVs are not grandfathered.

Consumers, scope and remaining verification

Within exact Radio a96d, four manifests directly depend on cyber-bao: iroh-blobs, particle, radio-cli, tests/integration. iroh-docs depends on local iroh-blobs. Current particle/radio-cli use std encode/decode/outboard; the iroh-blobs slice decoder call is in the cfg(test) export_pairs module. Other current slice callers are cyber-bao unit/integration tests. The new additive module migrates none of those APIs. Radio exporter writes the same size/pair carrier; its actual literal exporter tests are relevant regression coverage. Sync/fsm transport variants can omit a size header; they are not silently admitted as this complete-buffer profile.

Kadek now pins cyber-bao a96d with default-features=false for BaoAnchor, using the same merged GroupHasher and Git Hemera d5; its plain particle remains registry Hemera 0.3.1. Same immutable-body association is the authority invariant, not alleged identity of the two source packages. A Radio result verified under an arbitrary root cannot mint VerifiedRange. The future adapter remains a separate reviewed unit.

The prior exact-revision graph inventory is retained by hash/reference, with its cached-default and retained-Nu distinctions; it is not a fresh network inventory. The registry declares Radio part_of soft3 and Kadek part_of Cyb. New public API reaches ring 1 even when existing direct calls remain unchanged. Required closure/gates and unavailable platforms must be reported explicitly. No inherited-red assumption is attached to this new candidate: eventual negatives need current exact-parent comparisons.

Next: freeze the bounded fresh vendor PLAN input after root's draft read and the completed traversal merge bridge. Only approval authorizes tests-first production. Implementation will supply exact diagnostics, allocation and lifetime witnesses, current owner/workspace/consumer gates and a separate fresh CODE review.

===== 004 END =====

===== 005 BEGIN README.md | 3476 bytes | SHA256 46d04dd9718b8f1c5efb7bf8af78527e9fe0a8c26aa316f8dc85af186c2cd961 =====

Bounded proof research evidence

Research and proposed PLAN only. No bounded-proof production API, implementation review or whole Kadek foundation-row closure is claimed.

Radio measurements use a96d86e28d384cdf656aadc4282c78c0c170c102 and Git Hemera d5f0a09539360934fb32db9b2e15a91995607db6. Ordinary fetch/fast-forward integrated traversal PR39, b933829cbe273d2f31fe75ca83125f3ddd8917a2, for the future proof implementation. merged-bridge.json compares 39 owning source/lock/consumer inputs: 38 unchanged; lib.rs adds traversal module wiring. The merged traversal source equals the retained unmerged candidate. Its accepted CODE review is copied from the actual committed audit, with invocation/completion; its gates are not relabeled as bounded-proof gates and hosted CI was not claimed green.

Seven research command receipts retain raw output, argv, environment, exit status and timings: initial lock/metadata/debug, legacy release, primary lock/debug/release. Two further receipts retain fetch and fast-forward. The initial standalone std probe characterizes old reader semantics. The separate primary-probe writes manual carriers from explicit small kernel expressions. Both Rust 1.95 debug/release pairs have identical stdout; generated fixtures agree byte-for-byte across profiles. The fixture manifest has 13 files / 54,126 bytes: eight real-file carriers and five explicitly synthetic parent-encoding carriers. The latter do not witness a complete file or particle authority. Work counts in the primary output are PLAN expectations, not executed new-API measurements. No timing, allocation or MSRV claim is inferred.

The initial 55 Git input records and both probe freezes are unchanged. Additional support records pin contracts/callers, committed Kadek anchor and retained soft3 registry. Thirteen exact primary excerpts are replayed from their committed source. Radio is declared part_of soft3; Kadek part_of Cyb. historical-inventory-reference.json names the earlier cached 52-repository inventory and its original archive/member hashes, including the later retained-Nu clarification. This archive does not embed or replay that entire historical capsule and does not claim a fresh network inventory.

Replay from a checkout holding the exact Radio a96d/b933, Hemera d5, Kadek4d9 and soft3 18fd Git objects, with sibling repositories available:

nu audit/2026-10-12-bao-proof-research/verify.nu \
  --repo /path/to/radio-proof-worktree --siblings /path/to/cyber --live

Without --live, current working tree/HEAD need not equal the research task; committed objects remain required. The verifier checks all local file hashes, committed blob identities, exact excerpts, the bridge, raw receipt hashes, fixture hashes and frozen task copies. It does not rerun Cargo or cryptographically recompute the fixtures. To rerun probes, use the captured argv from the Radio worktree and a writable new fixture output directory. Cargo requires the exact lock dependencies in its cache or an explicitly recorded acquisition. These are repository/Git-object replay requirements, not an archive-only or cache-free reproducibility claim.

freeze-research.rb records the original assembly procedure, with original private paths. verify.nu is the portable replay entry point. Initial source-freeze helper text/binary mismatch was corrected before these records; no production discrepancy is attributed to that helper failure. No Python tooling dependency is introduced.

===== 005 END =====

===== 006 BEGIN measurements.json | 517 bytes | SHA256 2e4bf703dc2a42de12f63f9887b5405b47373b51fcbecb25bfe1fa8edc6a7195 ===== { "created": "2026-10-12T23:38:30Z", "radio": "a96d86e28d384cdf656aadc4282c78c0c170c102", "initial_git_inputs": 55, "support_git_inputs": 35, "records": 7, "all_record_exit_codes": [ 0, 0, 0, 0, 0, 0, 0 ], "legacy_outputs_equal": true, "primary_outputs_equal": true, "fixtures": 13, "fixture_bytes": 54126, "debug_release_fixtures_equal": true, "new_verifier_implemented": false, "new_api_work_measured": false, "whole_file_synthetic_root_witnessed": false }

===== 006 END =====

===== 007 BEGIN merged-bridge.json | 25353 bytes | SHA256 b91114934b55522a56180cb4a62804b63f2f84bd22315aabeb083ead9a5b7852 ===== { "created": "2026-10-12T23:40:34Z", "parent": "a96d86e28d384cdf656aadc4282c78c0c170c102", "current": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "source": "24b189ea809d214994a32b78aa65d338c0c2b2b3", "merge": "https://github.com/cyberia-to/radio/pull/39", "production_claim": "Mechanical dependency integration only; earlier measurements remain at a96d. No bounded-proof implementation.", "comparison": [ { "path": "Cargo.toml", "parent_sha256": "3f8d71aa50c829445d66c981166e22f9b64fbd1f91bdddf4ecb422cf4ebd39f2", "sha256": "3f8d71aa50c829445d66c981166e22f9b64fbd1f91bdddf4ecb422cf4ebd39f2", "bytes": 2085, "unchanged": true }, { "path": "cyber-bao/Cargo.toml", "parent_sha256": "95e58b3d1e130d6a579b361111e848b9aa907f66eee0e2acb7ab5449c9f9e365", "sha256": "95e58b3d1e130d6a579b361111e848b9aa907f66eee0e2acb7ab5449c9f9e365", "bytes": 1078, "unchanged": true }, { "path": "cyber-bao/src/group.rs", "parent_sha256": "948307e945b1f7f3808b5828dacb04547a89c701c8f00ba1534fa396d0b66cdf", "sha256": "948307e945b1f7f3808b5828dacb04547a89c701c8f00ba1534fa396d0b66cdf", "bytes": 6349, "unchanged": true }, { "path": "cyber-bao/src/group/tests.rs", "parent_sha256": "6d8d75cd586684c6d13c7a9ed2c563bec418a8687910110bdce8dbbb5473053d", "sha256": "6d8d75cd586684c6d13c7a9ed2c563bec418a8687910110bdce8dbbb5473053d", "bytes": 745, "unchanged": true }, { "path": "cyber-bao/src/hash.rs", "parent_sha256": "1e705848543784c326be3ecd347878eae8dc5ab0207392d64ba5d9efb695bf1f", "sha256": "1e705848543784c326be3ecd347878eae8dc5ab0207392d64ba5d9efb695bf1f", "bytes": 3960, "unchanged": true }, { "path": "cyber-bao/src/io/content.rs", "parent_sha256": "582fa031c6ee9f38e9f38cf875a5e8e76827fc6c07c0c88027857f92147e7ecd", "sha256": "582fa031c6ee9f38e9f38cf875a5e8e76827fc6c07c0c88027857f92147e7ecd", "bytes": 1342, "unchanged": true }, { "path": "cyber-bao/src/io/decode.rs", "parent_sha256": "334bfbe8e731a7b2b863c36b6a8f95562206c14ed2b944492897b5920837589d", "sha256": "334bfbe8e731a7b2b863c36b6a8f95562206c14ed2b944492897b5920837589d", "bytes": 9782, "unchanged": true }, { "path": "cyber-bao/src/io/encode.rs", "parent_sha256": "c30d550675db2cf288ab3e438270d2c862416fc4c9972e6ce799e9a2f80dcbf0", "sha256": "c30d550675db2cf288ab3e438270d2c862416fc4c9972e6ce799e9a2f80dcbf0", "bytes": 5619, "unchanged": true }, { "path": "cyber-bao/src/io/error.rs", "parent_sha256": "ef64b616b421e8ced59a76cae247ba5ea6a2180e03e27bd4e1438d2246aa2c29", "sha256": "ef64b616b421e8ced59a76cae247ba5ea6a2180e03e27bd4e1438d2246aa2c29", "bytes": 4193, "unchanged": true }, { "path": "cyber-bao/src/io/fsm.rs", "parent_sha256": "ddebb307e02e97b1dfed9f961102a115578f1079d633ece6f5f0006b01c91b0f", "sha256": "ddebb307e02e97b1dfed9f961102a115578f1079d633ece6f5f0006b01c91b0f", "bytes": 10938, "unchanged": true }, { "path": "cyber-bao/src/io/mixed.rs", "parent_sha256": "6301d689a80d341f778462a0615720a495e81f94ae722926c5cbef26f6db17b2", "sha256": "6301d689a80d341f778462a0615720a495e81f94ae722926c5cbef26f6db17b2", "bytes": 5019, "unchanged": true }, { "path": "cyber-bao/src/io/mod.rs", "parent_sha256": "252d9f85216e4534d15116ba005d86e4e8e47a99d62331759540a526a283c55a", "sha256": "252d9f85216e4534d15116ba005d86e4e8e47a99d62331759540a526a283c55a", "bytes": 8630, "unchanged": true }, { "path": "cyber-bao/src/io/outboard.rs", "parent_sha256": "da155075c63eded19b8a17dcbb6e9716eae50690117bf3ce3802b6982f8f1a06", "sha256": "da155075c63eded19b8a17dcbb6e9716eae50690117bf3ce3802b6982f8f1a06", "bytes": 6220, "unchanged": true }, { "path": "cyber-bao/src/io/pre_order.rs", "parent_sha256": "225d2bcaaa3ba36780a7f6c599cc2dfe27cf6cf8cce4a7f9ac900e235a7bde65", "sha256": "225d2bcaaa3ba36780a7f6c599cc2dfe27cf6cf8cce4a7f9ac900e235a7bde65", "bytes": 14509, "unchanged": true }, { "path": "cyber-bao/src/io/slice.rs", "parent_sha256": "0f29291599f56c3c8dda4930e660d41a3e04cf1a3ee9cdfb8c36e3fc1de832d7", "sha256": "0f29291599f56c3c8dda4930e660d41a3e04cf1a3ee9cdfb8c36e3fc1de832d7", "bytes": 13041, "unchanged": true }, { "path": "cyber-bao/src/io/sync.rs", "parent_sha256": "da90915445d295c63ee051bd569015a6f78be226da933e89d11053f1293da63a", "sha256": "da90915445d295c63ee051bd569015a6f78be226da933e89d11053f1293da63a", "bytes": 13540, "unchanged": true }, { "path": "cyber-bao/src/io/traits.rs", "parent_sha256": "e212344d3a42d4ce967dbf0530a99a3d3f3e4bb27f1dc04c975c88202538f326", "sha256": "e212344d3a42d4ce967dbf0530a99a3d3f3e4bb27f1dc04c975c88202538f326", "bytes": 8211, "unchanged": true }, { "path": "cyber-bao/src/lib.rs", "parent_sha256": "8b504071c619a79dfe5e1b7fa8825d507afe907bd8817a92d9951b37345bd602", "sha256": "2e054f65e05d5a47555e684cb339903972672e2f1077a2ee19ddd6648f88ac40", "bytes": 1330, "unchanged": false }, { "path": "cyber-bao/src/tree.rs", "parent_sha256": "458f26235aee22c42376dde8929a55831c1f8a58dd59a5dac270cd9bb8bd667a", "sha256": "458f26235aee22c42376dde8929a55831c1f8a58dd59a5dac270cd9bb8bd667a", "bytes": 12320, "unchanged": true }, { "path": "cyber-bao/src/tree/tests.rs", "parent_sha256": "2c9cd904ac8595341f1946e31c79be1a01c97574c86a51068cba343238601e1d", "sha256": "2c9cd904ac8595341f1946e31c79be1a01c97574c86a51068cba343238601e1d", "bytes": 4810, "unchanged": true }, { "path": "cyber-bao/src/tree/traversal.rs", "parent_sha256": "d0f2a97b0bbe3b90a8009aeb96ba7f47ff119c0f69b1b015fc643a1e863ae26e", "sha256": "d0f2a97b0bbe3b90a8009aeb96ba7f47ff119c0f69b1b015fc643a1e863ae26e", "bytes": 12053, "unchanged": true }, { "path": "cyber-bao/tests/group.rs", "parent_sha256": "cfaffe11dd1abdd6ebac7678223d6bb821cf768f1345124bee1d358265196884", "sha256": "cfaffe11dd1abdd6ebac7678223d6bb821cf768f1345124bee1d358265196884", "bytes": 10376, "unchanged": true }, { "path": "cyber-bao/tests/group_allocation.rs", "parent_sha256": "fbad19824bed68c777fa32eda14aee86af8cb0812b4a7fb1632de93eb2c0cbd5", "sha256": "fbad19824bed68c777fa32eda14aee86af8cb0812b4a7fb1632de93eb2c0cbd5", "bytes": 2476, "unchanged": true }, { "path": "cyber-bao/tests/root_policy.rs", "parent_sha256": "42737b5a4f3c3e6f9d19f91a5d14279e3f43a8e3eaaf8d4caf251b744944f94b", "sha256": "42737b5a4f3c3e6f9d19f91a5d14279e3f43a8e3eaaf8d4caf251b744944f94b", "bytes": 8717, "unchanged": true }, { "path": "cyber-bao/tests/slice_traversal.rs", "parent_sha256": "b85161fc1a8105a46f6239ff243f7d414ed28882669c93bea55fc4274a047180", "sha256": "b85161fc1a8105a46f6239ff243f7d414ed28882669c93bea55fc4274a047180", "bytes": 9055, "unchanged": true }, { "path": "Cargo.lock", "parent_sha256": "90d5aa88f4fb507434036ad5ec0ca7a3897741fe810fdf16a080bff006130d65", "sha256": "90d5aa88f4fb507434036ad5ec0ca7a3897741fe810fdf16a080bff006130d65", "bytes": 186712, "unchanged": true }, { "path": "Makefile.toml", "parent_sha256": "0f1e457aa4bb7c6e4674d2dfbd847b58344319a1242625c2f055241ebd048d8d", "sha256": "0f1e457aa4bb7c6e4674d2dfbd847b58344319a1242625c2f055241ebd048d8d", "bytes": 662, "unchanged": true }, { "path": ".config/nextest.toml", "parent_sha256": "ef588b7e34ddd981c24a523ba359ec76a616a45b40f3f3f525692ae809aea590", "sha256": "ef588b7e34ddd981c24a523ba359ec76a616a45b40f3f3f525692ae809aea590", "bytes": 594, "unchanged": true }, { "path": ".github/workflows/ci.yml", "parent_sha256": "ded5a95996283b54293810ab4938dadc1d589fab73be85397ad9c3435b203208", "sha256": "ded5a95996283b54293810ab4938dadc1d589fab73be85397ad9c3435b203208", "bytes": 11846, "unchanged": true }, { "path": ".github/workflows/tests.yaml", "parent_sha256": "749952dae052754d58ca44b060dac25431a507f5ddf9e854e2c54a91084b5a6b", "sha256": "749952dae052754d58ca44b060dac25431a507f5ddf9e854e2c54a91084b5a6b", "bytes": 10418, "unchanged": true }, { "path": "iroh-blobs/Cargo.toml", "parent_sha256": "cbf2f94e32cb76f6976b9f271231077da1eadeb9a8fea69636180bec5441c011", "sha256": "cbf2f94e32cb76f6976b9f271231077da1eadeb9a8fea69636180bec5441c011", "bytes": 3156, "unchanged": true }, { "path": "particle/Cargo.toml", "parent_sha256": "a80402ad3fce896380f81f4a510e7ef081c1a881043970a81c7b24e203996969", "sha256": "a80402ad3fce896380f81f4a510e7ef081c1a881043970a81c7b24e203996969", "bytes": 367, "unchanged": true }, { "path": "radio-cli/Cargo.toml", "parent_sha256": "5d2e24decf543ba918766c57dd5bd3f3224b871933c3f4fc51d2420461cfccc0", "sha256": "5d2e24decf543ba918766c57dd5bd3f3224b871933c3f4fc51d2420461cfccc0", "bytes": 666, "unchanged": true }, { "path": "tests/integration/Cargo.toml", "parent_sha256": "ac74983dbeee09aed2222c0c6108e81f97a176e59a7b3db444b3d4e1e429b4a0", "sha256": "ac74983dbeee09aed2222c0c6108e81f97a176e59a7b3db444b3d4e1e429b4a0", "bytes": 673, "unchanged": true }, { "path": "iroh-docs/Cargo.toml", "parent_sha256": "fc5de9598d40d5265bbc36c4bc6bd7f38f55ba206bf0f717bfdf9b8e0e8b07c6", "sha256": "fc5de9598d40d5265bbc36c4bc6bd7f38f55ba206bf0f717bfdf9b8e0e8b07c6", "bytes": 2490, "unchanged": true }, { "path": "iroh-blobs/src/api/blobs.rs", "parent_sha256": "4750b32042433b27a9f1740327e2925a8da94217b0ff87dbd0626c756c9ad286", "sha256": "4750b32042433b27a9f1740327e2925a8da94217b0ff87dbd0626c756c9ad286", "bytes": 40466, "unchanged": true }, { "path": "iroh-blobs/src/api/blobs/export_pairs.rs", "parent_sha256": "96914dc66c602b6e0bc9cf29a5287a84214b514be367ca96eef0b637079eb9c2", "sha256": "96914dc66c602b6e0bc9cf29a5287a84214b514be367ca96eef0b637079eb9c2", "bytes": 13409, "unchanged": true }, { "path": "particle/src/main.rs", "parent_sha256": "14602af31ea2950f3d7af6ad831150e469d745ef4d237bdbf86d56087f843e75", "sha256": "14602af31ea2950f3d7af6ad831150e469d745ef4d237bdbf86d56087f843e75", "bytes": 5460, "unchanged": true }, { "path": "radio-cli/src/main.rs", "parent_sha256": "e80c1d700e19d4a32a7427853664d3ba49ead62b339c9584d59581f6e886e61a", "sha256": "e80c1d700e19d4a32a7427853664d3ba49ead62b339c9584d59581f6e886e61a", "bytes": 18693, "unchanged": true } ], "merged_inputs": [ { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "cyber-bao/src/traversal.rs", "local": "merged-prerequisite/traversal.rs", "bytes": 6067, "sha256": "87f646ef36a1e7ba1be3dd4576acf4bf6637d1ec6705953aef0bf8c6ac42eb5a" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "cyber-bao/src/lib.rs", "local": "merged-prerequisite/lib.rs", "bytes": 1330, "sha256": "2e054f65e05d5a47555e684cb339903972672e2f1077a2ee19ddd6648f88ac40" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "cyber-bao/tests/range_traversal.rs", "local": "merged-prerequisite/range_traversal.rs", "bytes": 12350, "sha256": "e07530aa7035ccad8c75da53c50355efc03c503f2480189c32ac133ead883d25" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "cyber-bao/tests/range_traversal_allocation.rs", "local": "merged-prerequisite/range_traversal_allocation.rs", "bytes": 3083, "sha256": "cc7b2cc32b710ee835be001d77887c5176e42e6719b3fc8c97d31ddec4fe6c59" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": ".claude/tasks/bao-bounded-traversal/code-review.md", "local": "merged-prerequisite/code-review.md", "bytes": 1774, "sha256": "094d6c46d2da82a937499cd3015dc2289d54a4abf02f8d3fe3d6d502ea28b94a" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "audit/2026-10-11-bao-bounded-traversal/code/review/result.md", "local": "merged-prerequisite/result.md", "bytes": 10113, "sha256": "42a737b1963d82f27bd13349bdd049cc535848890531a9af64cb91b11deb98d0" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "audit/2026-10-11-bao-bounded-traversal/code/review/invocation.json", "local": "merged-prerequisite/invocation.json", "bytes": 1218, "sha256": "719f82d3af1f4bbcfb4e4dd8c73ff1409db72ac90effc1a18197be3bd6b08968" }, { "repository": "radio", "revision": "b933829cbe273d2f31fe75ca83125f3ddd8917a2", "path": "audit/2026-10-11-bao-bounded-traversal/code/review/completion.json", "local": "merged-prerequisite/completion.json", "bytes": 240, "sha256": "7a8fbbc20da54b3ddc82921a245e4eb10bb844384d7e5e94a7c823588ab9bd35" } ], "diff_name_status": [ "A\t.claude/tasks/bao-bounded-traversal/code-review.md", "A\t.claude/tasks/bao-bounded-traversal/execution.md", "A\t.claude/tasks/bao-bounded-traversal/implementation.md", "A\t.claude/tasks/bao-bounded-traversal/literal-cases.md", "A\t.claude/tasks/bao-bounded-traversal/plan.md", "A\t.claude/tasks/bao-bounded-traversal/research.md", "A\t.claude/tasks/bao-bounded-traversal/review-status.md", "A\taudit/2026-10-11-bao-bounded-traversal/README.md", "A\taudit/2026-10-11-bao-bounded-traversal/SHA256SUMS", "A\taudit/2026-10-11-bao-bounded-traversal/capsule.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/README.md", "A\taudit/2026-10-11-bao-bounded-traversal/code/SHA256SUMS", "A\taudit/2026-10-11-bao-bounded-traversal/code/capsule.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/evidence-index.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/evidence.tar.gz", "A\taudit/2026-10-11-bao-bounded-traversal/code/replay/command.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/replay/local-doc-check.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/replay/stderr", "A\taudit/2026-10-11-bao-bounded-traversal/code/replay/stdout", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/completion.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/invocation.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/launcher.rb", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/result.md", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/stderr.txt", "A\taudit/2026-10-11-bao-bounded-traversal/code/review/stdout.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/code-execution-v4.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/code-v4.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/code-v4.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/code-v4.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/code-verification-v4.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/docs-check.rb.txt", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/docs-v1.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/docs-v1.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/docs-v1.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/portable-v1.json", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/portable-v1.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/code/root-replay/portable-v1.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/code/verify.nu", "A\taudit/2026-10-11-bao-bounded-traversal/evidence-index.json", "A\taudit/2026-10-11-bao-bounded-traversal/evidence.tar.gz", "A\taudit/2026-10-11-bao-bounded-traversal/package.rb.txt", "A\taudit/2026-10-11-bao-bounded-traversal/plan-review/completion.json", "A\taudit/2026-10-11-bao-bounded-traversal/plan-review/invocation.json", "A\taudit/2026-10-11-bao-bounded-traversal/plan-review/stdout.txt", "A\taudit/2026-10-11-bao-bounded-traversal/plan/README.md", "A\taudit/2026-10-11-bao-bounded-traversal/plan/SHA256SUMS", "A\taudit/2026-10-11-bao-bounded-traversal/plan/capsule.json", "A\taudit/2026-10-11-bao-bounded-traversal/plan/evidence-index.json", "A\taudit/2026-10-11-bao-bounded-traversal/plan/evidence.tar.gz", "A\taudit/2026-10-11-bao-bounded-traversal/plan/verify.nu", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt1.json", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt1.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt1.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt2.json", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt2.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt2.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt3.json", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt3.stderr", "A\taudit/2026-10-11-bao-bounded-traversal/portable/attempt3.stdout", "A\taudit/2026-10-11-bao-bounded-traversal/verify-attempt1.nu.txt", "A\taudit/2026-10-11-bao-bounded-traversal/verify.nu", "M\tcyber-bao/src/lib.rs", "A\tcyber-bao/src/traversal.rs", "A\tcyber-bao/tests/range_traversal.rs", "A\tcyber-bao/tests/range_traversal_allocation.rs" ], "source_diff": "diff --git a/cyber-bao/src/lib.rs b/cyber-bao/src/lib.rs\nindex 30525582..073146bc 100644\n--- a/cyber-bao/src/lib.rs\n+++ b/cyber-bao/src/lib.rs\n@@ -17,6 +17,7 @@ pub mod group;\n pub mod hash;\n #[cfg(feature = "std")]\n pub mod io;\n+pub mod traversal;\n pub mod tree;\n \n pub use hash::{HashBackend, Poseidon2Backend};\ndiff --git a/cyber-bao/src/traversal.rs b/cyber-bao/src/traversal.rs\nnew file mode 100644\nindex 00000000..c1acc11b\n--- /dev/null\n+++ b/cyber-bao/src/traversal.rs\n@@ -0,0 +1,172 @@\n+//! Checked, allocation-free preorder geometry for one byte range.\n+//!\n+//! This cursor emits geometry only. It does not parse a proof or authenticate\n+//! a particle, root, payload or empty request.\n+\n+use core::{fmt, iter::FusedIterator, ops::Range};\n+\n+use crate::{BaoChunk, BlockSize, CHUNK_SIZE, TreeNode};\n+\n+/// Invalid geometry supplied to [RangeTraversal::new].\n+#[derive(Debug, Clone, Copy, PartialEq, Eq)]\n+pub enum RangeTraversalError {\n+ /// The group width cannot be represented by both u64 and usize.\n+ InvalidBlockSize,\n+ /// The byte range is reversed or extends beyond the file.\n+ InvalidRange,\n+}\n+\n+impl fmt::Display for RangeTraversalError {\n+ fn fmt(&self, f: &mut fmt::Formatter<'>) -> fmt::Result {\n+ f.write_str(match self {\n+ Self::InvalidBlockSize => "invalid traversal block size",\n+ Self::InvalidRange => "invalid traversal byte range",\n+ })\n+ }\n+}\n+\n+impl core::error::Error for RangeTraversalError {}\n+\n+#[derive(Debug, Clone, Copy)]\n+struct Frame {\n+ first: u64,\n+ count: u64,\n+ is_root: bool,\n+}\n+\n+/// Preorder cursor over whole groups intersecting a half-open byte range.\n+///\n+/// Construction uses fixed storage for 53 frames. Each pending [Iterator::next]\n+/// pops one frame, pushes at most two children and returns one item, without\n+/// allocation, recursion, scanning or hashing. Pausing requires no extra state:\n+/// simply retain the cursor without calling next.\n+///\n+/// ROOT belongs to the complete file tree, even when the request selects only\n+/// one leaf. Parent flags identify children visited by this request; a parent\n+/// still describes a pair of hashes. An empty request is immediately complete\n+/// and emits no item; it makes no authentication claim.\n+pub struct RangeTraversal {\n+ size: u64,\n+ group_bytes: u64,\n+ selected: Range,\n+ frames: [Frame; 53],\n+ pending: usize,\n+}\n+\n+impl fmt::Debug for RangeTraversal {\n+ fn fmt(&self, f: &mut fmt::Formatter<'>) -> fmt::Result {\n+ f.debug_struct("RangeTraversal")\n+ .field("size", &self.size)\n+ .field("group_bytes", &self.group_bytes)\n+ .field("selected", &self.selected)\n+ .field("pending", &self.pending)\n+ .finish()\n+ }\n+}\n+\n+impl RangeTraversal {\n+ /// Admit a file size, group width and half-open requested byte interval.\n+ ///\n+ /// Block geometry is validated before the request: the block log must be at\n+ /// most 51, and its byte width must fit usize. This admits logs 0..=51 on\n+ /// 64-bit targets and 0..=19 on 32-bit targets, even for a short or empty file.\n+ /// Width admission concerns integer geometry, not allocation layout validity.\n+ /// The request must satisfy start <= end <= size; an empty interval at EOF\n+ /// is valid. Only the final file group is clipped to its actual byte length.\n+ pub fn new(\n+ size: u64,\n+ block_size: BlockSize,\n+ request: Range,\n+ ) -> Result<Self, RangeTraversalError> {\n+ if block_size.0 > 51 {\n+ return Err(RangeTraversalError::InvalidBlockSize);\n+ }\n+ let group_bytes = (CHUNK_SIZE as u64) << block_size.0;\n+ usize::try_from(group_bytes).map_err(|_| RangeTraversalError::InvalidBlockSize)?;\n+ if request.start > request.end || request.end > size {\n+ return Err(RangeTraversalError::InvalidRange);\n+ }\n+ let mut result = Self {\n+ size,\n+ group_bytes,\n+ selected: 0..0,\n+ frames: [Frame {\n+ first: 0,\n+ count: 0,\n+ is_root: false,\n+ }; 53],\n+ pending: 0,\n+ };\n+ if request.start < request.end {\n+ result.selected = request.start / group_bytes..(request.end - 1) / group_bytes + 1;\n+ result.push(Frame {\n+ first: 0,\n+ count: size.div_ceil(group_bytes),\n+ is_root: true,\n+ });\n+ }\n+ Ok(result)\n+ }\n+\n+ /// Whether no item remains, including immediately after the last emission.\n+ pub fn is_complete(&self) -> bool {\n+ self.pending == 0\n+ }\n+\n+ fn push(&mut self, frame: Frame) {\n+ // N <= 2^52: at depth d <= 52, at most d deferred siblings plus\n+ // one current frame exist. Pop before pushing children preserves 53.\n+ self.frames[self.pending] = frame;\n+ self.pending += 1;\n+ }\n+}\n+\n+impl Iterator for RangeTraversal {\n+ type Item = BaoChunk;\n+\n+ fn next(&mut self) -> OptionSelf::Item {\n+ if self.is_complete() {\n+ return None;\n+ }\n+ self.pending -= 1;\n+ let frame = self.frames[self.pending];\n+ if frame.count == 1 {\n+ // first < N implies first * group_bytes <= size - 1. Subtract\n+ // before clipping: the next group's byte end need not fit u64.\n+ let start = frame.first * self.group_bytes;\n+ return Some(BaoChunk::Leaf {\n+ start_chunk: start / CHUNK_SIZE as u64,\n+ size: self.group_bytes.min(self.size - start) as usize,\n+ is_root: frame.is_root,\n+ });\n+ }\n+ let left_count = 1u64 << (frame.count - 1).ilog2();\n+ let middle = frame.first + left_count;\n+ let end = frame.first + frame.count;\n+ let left = self.selected.start < middle && frame.first < self.selected.end;\n+ let right = self.selected.start < end && middle < self.selected.end;\n+ if right {\n+ self.push(Frame {\n+ first: middle,\n+ count: frame.count - left_count,\n+ is_root: false,\n+ });\n+ }\n+ if left {\n+ self.push(Frame {\n+ first: frame.first,\n+ count: left_count,\n+ is_root: false,\n+ });\n+ }\n+ // middle < N <= 2^52, so this group-based index is below 2^53.\n+ Some(BaoChunk::Parent {\n+ node: TreeNode::new(2 * middle - 1),\n+ is_root: frame.is_root,\n+ left,\n+ right,\n+ })\n+ }\n+}\n+\n+impl FusedIterator for RangeTraversal {}\n", "candidate_traversal_identical": true }

===== 007 END =====

===== 008 BEGIN fixtures.json | 2661 bytes | SHA256 9bbf3e8081aba15edd426cd810096fe219b40e99596bfcd216bb4342c918dddc ===== [ { "path": "fixtures/empty.bin", "bytes": 8, "sha256": "af5570f5a1810b7af78caf4bc70a660f0df51e42baf91d4de5b2328de0e83dfc", "kind": "manual complete-file carrier" }, { "path": "fixtures/final-short.bin", "bytes": 73, "sha256": "77a2744c2afa90a5d1e8c1d2d96412d9780ffae5cd0e63ff114c03224e7cbaa5", "kind": "manual complete-file carrier" }, { "path": "fixtures/grouped-left.bin", "bytes": 8264, "sha256": "7c512483a57fb4d7e82c69ff44859d68433dec8cd1d61a96463e0f16444deef5", "kind": "manual complete-file carrier" }, { "path": "fixtures/hello.bin", "bytes": 13, "sha256": "fe745503750fdbf3e6ef676d16d85ee0d63626c594222f7e991908bdffef7ac9", "kind": "manual complete-file carrier" }, { "path": "fixtures/sole-group.bin", "bytes": 8200, "sha256": "ad31d4c9d0040256379a6ebf3437beed5eaa6117e14b208f53ceacaa13bbd57a", "kind": "manual complete-file carrier" }, { "path": "fixtures/synthetic-alias-0.bin", "bytes": 4168, "sha256": "8f7c882a3f95fa6e5ac9a9e03cbc496be87a57045926ba72f6932d2cd4038f10", "kind": "synthetic parent encoding, not a complete-file witness" }, { "path": "fixtures/synthetic-alias-1.bin", "bytes": 4168, "sha256": "d37df99e36ad1e7dbbfa274f2d080b26e24dfff8ce92b08aa51da4076ed9fa02", "kind": "synthetic parent encoding, not a complete-file witness" }, { "path": "fixtures/synthetic-alias-2.bin", "bytes": 4168, "sha256": "a57093440c5849056fa27f012891703ed9f4854c29e00fa2cdc04fd9f0bb8970", "kind": "synthetic parent encoding, not a complete-file witness" }, { "path": "fixtures/synthetic-alias-3.bin", "bytes": 4168, "sha256": "2de4d22e2e54f125f60c5daa9cd5cfe0d04e64b5f3a49ba151d8b2291f752375", "kind": "synthetic parent encoding, not a complete-file witness" }, { "path": "fixtures/synthetic-canonical.bin", "bytes": 4168, "sha256": "d6f0a7ef1554d256e020798f27ed2db632a3e949ddfc795e5f0683916e4f9014", "kind": "synthetic parent encoding, not a complete-file witness" }, { "path": "fixtures/three-boundary.bin", "bytes": 8328, "sha256": "f58ca31c3f1eb4c9a28d216a8dcd745e4019d94e16a71142b16919a87b11471d", "kind": "manual complete-file carrier" }, { "path": "fixtures/three-interior.bin", "bytes": 4232, "sha256": "5bace76142c12c4cffebcf8d287ab109a7453ed2875191625a6f1a18b536019f", "kind": "manual complete-file carrier" }, { "path": "fixtures/three-right.bin", "bytes": 4168, "sha256": "708ab4a235f6b8f0a796304e6155f57107b2b293f9b3d693309b0d15e658fd35", "kind": "manual complete-file carrier" } ]

===== 008 END =====

===== 009 BEGIN inputs.json | 14411 bytes | SHA256 4995cc059ec39e366af5086da72b6a2f30881414b177972e969c5c018829ffe6 ===== { "created": "2026-10-12T23:18:23Z", "radio": "a96d86e28d384cdf656aadc4282c78c0c170c102", "git_inputs": [ { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "Cargo.toml", "bytes": 2085, "sha256": "3f8d71aa50c829445d66c981166e22f9b64fbd1f91bdddf4ecb422cf4ebd39f2" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/Cargo.toml", "bytes": 1078, "sha256": "95e58b3d1e130d6a579b361111e848b9aa907f66eee0e2acb7ab5449c9f9e365" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/group.rs", "bytes": 6349, "sha256": "948307e945b1f7f3808b5828dacb04547a89c701c8f00ba1534fa396d0b66cdf" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/group/tests.rs", "bytes": 745, "sha256": "6d8d75cd586684c6d13c7a9ed2c563bec418a8687910110bdce8dbbb5473053d" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/hash.rs", "bytes": 3960, "sha256": "1e705848543784c326be3ecd347878eae8dc5ab0207392d64ba5d9efb695bf1f" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/content.rs", "bytes": 1342, "sha256": "582fa031c6ee9f38e9f38cf875a5e8e76827fc6c07c0c88027857f92147e7ecd" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/decode.rs", "bytes": 9782, "sha256": "334bfbe8e731a7b2b863c36b6a8f95562206c14ed2b944492897b5920837589d" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/encode.rs", "bytes": 5619, "sha256": "c30d550675db2cf288ab3e438270d2c862416fc4c9972e6ce799e9a2f80dcbf0" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/error.rs", "bytes": 4193, "sha256": "ef64b616b421e8ced59a76cae247ba5ea6a2180e03e27bd4e1438d2246aa2c29" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/fsm.rs", "bytes": 10938, "sha256": "ddebb307e02e97b1dfed9f961102a115578f1079d633ece6f5f0006b01c91b0f" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/mixed.rs", "bytes": 5019, "sha256": "6301d689a80d341f778462a0615720a495e81f94ae722926c5cbef26f6db17b2" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/mod.rs", "bytes": 8630, "sha256": "252d9f85216e4534d15116ba005d86e4e8e47a99d62331759540a526a283c55a" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/outboard.rs", "bytes": 6220, "sha256": "da155075c63eded19b8a17dcbb6e9716eae50690117bf3ce3802b6982f8f1a06" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/pre_order.rs", "bytes": 14509, "sha256": "225d2bcaaa3ba36780a7f6c599cc2dfe27cf6cf8cce4a7f9ac900e235a7bde65" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/slice.rs", "bytes": 13041, "sha256": "0f29291599f56c3c8dda4930e660d41a3e04cf1a3ee9cdfb8c36e3fc1de832d7" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/sync.rs", "bytes": 13540, "sha256": "da90915445d295c63ee051bd569015a6f78be226da933e89d11053f1293da63a" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/io/traits.rs", "bytes": 8211, "sha256": "e212344d3a42d4ce967dbf0530a99a3d3f3e4bb27f1dc04c975c88202538f326" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/lib.rs", "bytes": 1311, "sha256": "8b504071c619a79dfe5e1b7fa8825d507afe907bd8817a92d9951b37345bd602" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/tree.rs", "bytes": 12320, "sha256": "458f26235aee22c42376dde8929a55831c1f8a58dd59a5dac270cd9bb8bd667a" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/tree/tests.rs", "bytes": 4810, "sha256": "2c9cd904ac8595341f1946e31c79be1a01c97574c86a51068cba343238601e1d" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/src/tree/traversal.rs", "bytes": 12053, "sha256": "d0f2a97b0bbe3b90a8009aeb96ba7f47ff119c0f69b1b015fc643a1e863ae26e" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/tests/group.rs", "bytes": 10376, "sha256": "cfaffe11dd1abdd6ebac7678223d6bb821cf768f1345124bee1d358265196884" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/tests/group_allocation.rs", "bytes": 2476, "sha256": "fbad19824bed68c777fa32eda14aee86af8cb0812b4a7fb1632de93eb2c0cbd5" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/tests/root_policy.rs", "bytes": 8717, "sha256": "42737b5a4f3c3e6f9d19f91a5d14279e3f43a8e3eaaf8d4caf251b744944f94b" }, { "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "path": "cyber-bao/tests/slice_traversal.rs", "bytes": 9055, "sha256": "b85161fc1a8105a46f6239ff243f7d414ed28882669c93bea55fc4274a047180" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/Cargo.toml", "bytes": 970, "sha256": "351913fa05ec28a0fce1078fd03c0fe84b957435b970c9dd122f140983fcdd75" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/examples/bench.rs", "bytes": 8232, "sha256": "dff24684ad117b4302303c101f5d0994eb10cbab5bd79f162e36dbff7d766221" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/examples/neon_mul.rs", "bytes": 6607, "sha256": "5a86e7009d4c1a539531369f6ab71cef2aa4198eb08fba70d83a4e2b719f098b" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/examples/split.rs", "bytes": 3293, "sha256": "507fdeb2d27a7cc92e61577ac1033c1e1751478ddbd89a084200b7570debd0c0" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/arith.rs", "bytes": 12016, "sha256": "42c41ce43ab3f00e8ac32c812830044583e686581cd44762d61977f9a3c33ebf" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/async_io.rs", "bytes": 4033, "sha256": "a898313b5f2237015050375c5cf982be61e3982cfeb834543adace3df01c74a8" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/backend.rs", "bytes": 6726, "sha256": "7c42ab817693b484f327cbb745b7fac3ae76bf4a5c762990cea62ef01b913d53" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/batch.rs", "bytes": 13057, "sha256": "614607f86923b31212a908c868f5a6b41982f32b3f3ad34a8e84571e22e3918a" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/bootstrap.rs", "bytes": 5694, "sha256": "fa865dbb6fcee2b047000d8235d259d66a924c17cbee5c2be451e4926e71b6f7" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/cdc.rs", "bytes": 18537, "sha256": "3320d137fcb381a2a512ffb545720deba24c46eedd8d6026a073ba6f01778fc7" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/constants.rs", "bytes": 5509, "sha256": "dbf8bf10ec173fd2aa6518281677ee4de3882b29b2f3912f712dcc361b20382a" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/encoding.rs", "bytes": 7759, "sha256": "4da69b468a5276a6ed32092e0ed6149b67bf16ded2e6aba2c405af805291701e" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/field.rs", "bytes": 12041, "sha256": "7a9da58f2daa65d946574753d819e4c0d39d80d61fd519ad42e38d038aebd09a" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/kernel.rs", "bytes": 7430, "sha256": "cc05e4c745ead3bdc60bfa1b8285686957c63917ea13e788005b51c4120f08b2" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/lib.rs", "bytes": 10109, "sha256": "597a5690eb43fde59265d0055152c185cee2e719ff2059719e148ce2fc3c077d" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/merkle.rs", "bytes": 6777, "sha256": "baacc02a9f798d73a596d644c538330b9d10fadbb72cc22ff1e41b0607d233d5" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/params.rs", "bytes": 6597, "sha256": "bf5b2cb5a80697d272546425bddcdf2cb2bfe7e08367ae7c793a0922088f2a91" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/permutation.rs", "bytes": 11403, "sha256": "7238b9789a19c0aa10ec6e828e75fcaf87ce437103137cfe4556729b4037d76c" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/profile.rs", "bytes": 3344, "sha256": "bd666bffb1e797330ae93eb7cc4fe38e5bbb4e02b5dc532e756ac056d8f37d49" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/reference.rs", "bytes": 4962, "sha256": "a91a3a2f7f0a01e3003cd8b5856e684a22391ee8050cce7523e71737ed49f516" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/sparse.rs", "bytes": 16841, "sha256": "2eff551631f7c1d155b794ec95a1de652c4b54c4700fd8c4c521bd73365d9d2c" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/sponge.rs", "bytes": 29369, "sha256": "e4152c73ca942140fc82575a3d68c6538d323a6355842210b4b40302d7b8daa9" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/step_sponge.rs", "bytes": 5892, "sha256": "64ec167940782c5f83b684965ee06bcb88f001f2baccdc3be189aa57b6fc5922" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/stream.rs", "bytes": 16940, "sha256": "8516cbe65d0f704035e146fc58ead96ac66115966213ab5377e6b1c4b64c40e3" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/stream_async.rs", "bytes": 14822, "sha256": "207f9c0d34663d583d4dbc38170d745f15e56ed3880eb518c39399ce4e99b8f6" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/trace.rs", "bytes": 1979, "sha256": "823d30b41ac817749fe5352e919dafa73522df9ef3c575807995ef50b3e0665d" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/src/tree.rs", "bytes": 53162, "sha256": "2226bc0526238cf05b79c3188ad8a3bcdcc482916a45c6b49cf33c30799440c6" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/tests/constant_time.rs", "bytes": 6189, "sha256": "fc6e9e767773a7715b306179ee16cefd6da52ae74ed14e5c6c1e7091dc36adbf" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/tests/differential.rs", "bytes": 12890, "sha256": "737ba241712a25c71f94270504bd1eb210194adc082260095bee09a0ab203080" }, { "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "path": "rs/tests/vectors.rs", "bytes": 1310, "sha256": "9724feea2af43654e0670e813faae61e23072f345f0d73669e1a38a23aa9f620" } ], "probe_inputs": [ { "path": "probe/Cargo.lock", "bytes": 8633, "sha256": "28d29a81c11ab806a32fd7a63d10624614ab0d7ca5fbf25051b0fd04de2da4e8" }, { "path": "probe/Cargo.toml", "bytes": 217, "sha256": "26df88edd220a39b6d5c7964a5dc8767acd2712349ed27b28904cf0e2bc0c038" }, { "path": "probe/src/main.rs", "bytes": 2322, "sha256": "5a6f0b73072d4d40075dbe57c26408a52a3634e898036eb452da0fe54436f526" } ], "boundary": "Frozen after initial debug characterization; next run uses this identity. Registry resolution is pinned by standalone lock. No proof-verifier production changes." }

===== 009 END =====

===== 010 BEGIN primary-inputs.json | 694 bytes | SHA256 902b084cb6ec74fe81964d0921f65653e0672d739cb60f3033c4eb512d964de2 ===== { "created": "2026-10-12T23:27:52Z", "radio": "a96d86e28d384cdf656aadc4282c78c0c170c102", "files": [ { "path": "primary-probe/Cargo.lock", "bytes": 8650, "sha256": "bb8b429d65035bef93e2182c9c27021157266d275a9ee50e02d5b04485eda18b" }, { "path": "primary-probe/Cargo.toml", "bytes": 377, "sha256": "eb9de62bfb997f05ffd0c06ef0069e1708d6ff24d5ca277fc25f3c6beef894fd" }, { "path": "primary-probe/src/main.rs", "bytes": 7858, "sha256": "6c274529c97ebc1e98ffd0bcb37e2e47abf02f5e1db7ca07480ff20ea432971f" } ], "boundary": "Frozen primary expressions/manual carriers before execution; no verifier implementation" }

===== 010 END =====

===== 011 BEGIN support-inputs.json | 8166 bytes | SHA256 66d0649ab0ef7c60f3149e224d1957495e4fcba30d0303950943972553ddcb98 ===== [ { "path": "Cargo.lock", "bytes": 186712, "sha256": "90d5aa88f4fb507434036ad5ec0ca7a3897741fe810fdf16a080bff006130d65", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "Makefile.toml", "bytes": 662, "sha256": "0f1e457aa4bb7c6e4674d2dfbd847b58344319a1242625c2f055241ebd048d8d", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": ".config/nextest.toml", "bytes": 594, "sha256": "ef588b7e34ddd981c24a523ba359ec76a616a45b40f3f3f525692ae809aea590", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": ".github/workflows/ci.yml", "bytes": 11846, "sha256": "ded5a95996283b54293810ab4938dadc1d589fab73be85397ad9c3435b203208", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": ".github/workflows/tests.yaml", "bytes": 10418, "sha256": "749952dae052754d58ca44b060dac25431a507f5ddf9e854e2c54a91084b5a6b", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "cyber-bao/src/lib.rs", "bytes": 1311, "sha256": "8b504071c619a79dfe5e1b7fa8825d507afe907bd8817a92d9951b37345bd602", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "cyber-bao/src/tree.rs", "bytes": 12320, "sha256": "458f26235aee22c42376dde8929a55831c1f8a58dd59a5dac270cd9bb8bd667a", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "cyber-bao/src/io/slice.rs", "bytes": 13041, "sha256": "0f29291599f56c3c8dda4930e660d41a3e04cf1a3ee9cdfb8c36e3fc1de832d7", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "cyber-bao/tests/root_policy.rs", "bytes": 8717, "sha256": "42737b5a4f3c3e6f9d19f91a5d14279e3f43a8e3eaaf8d4caf251b744944f94b", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "cyber-bao/tests/slice_traversal.rs", "bytes": 9055, "sha256": "b85161fc1a8105a46f6239ff243f7d414ed28882669c93bea55fc4274a047180", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "iroh-blobs/Cargo.toml", "bytes": 3156, "sha256": "cbf2f94e32cb76f6976b9f271231077da1eadeb9a8fea69636180bec5441c011", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "particle/Cargo.toml", "bytes": 367, "sha256": "a80402ad3fce896380f81f4a510e7ef081c1a881043970a81c7b24e203996969", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "radio-cli/Cargo.toml", "bytes": 666, "sha256": "5d2e24decf543ba918766c57dd5bd3f3224b871933c3f4fc51d2420461cfccc0", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "tests/integration/Cargo.toml", "bytes": 673, "sha256": "ac74983dbeee09aed2222c0c6108e81f97a176e59a7b3db444b3d4e1e429b4a0", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "iroh-docs/Cargo.toml", "bytes": 2490, "sha256": "fc5de9598d40d5265bbc36c4bc6bd7f38f55ba206bf0f717bfdf9b8e0e8b07c6", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "iroh-blobs/src/api/blobs.rs", "bytes": 40466, "sha256": "4750b32042433b27a9f1740327e2925a8da94217b0ff87dbd0626c756c9ad286", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "iroh-blobs/src/api/blobs/export_pairs.rs", "bytes": 13409, "sha256": "96914dc66c602b6e0bc9cf29a5287a84214b514be367ca96eef0b637079eb9c2", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "particle/src/main.rs", "bytes": 5460, "sha256": "14602af31ea2950f3d7af6ad831150e469d745ef4d237bdbf86d56087f843e75", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "radio-cli/src/main.rs", "bytes": 18693, "sha256": "e80c1d700e19d4a32a7427853664d3ba49ead62b339c9584d59581f6e886e61a", "repository": "radio", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102" }, { "path": "specs/tree.md", "bytes": 24383, "sha256": "28d2336a9d040f28f635df706850a02750652d3e8231bdedfd0038ce3761fe5e", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "specs/capacity.md", "bytes": 4941, "sha256": "5f6d008183b9a570515c4ef465693ce6f2ff6bdb4c9f0499cf519791523b84cb", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "specs/encoding.md", "bytes": 3119, "sha256": "5486943c44cc427382c09520581766d4b7d153cb2cf171b342bc91af53b43849", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/params.rs", "bytes": 6597, "sha256": "bf5b2cb5a80697d272546425bddcdf2cb2bfe7e08367ae7c793a0922088f2a91", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/lib.rs", "bytes": 10109, "sha256": "597a5690eb43fde59265d0055152c185cee2e719ff2059719e148ce2fc3c077d", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/field.rs", "bytes": 12041, "sha256": "7a9da58f2daa65d946574753d819e4c0d39d80d61fd519ad42e38d038aebd09a", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/encoding.rs", "bytes": 7759, "sha256": "4da69b468a5276a6ed32092e0ed6149b67bf16ded2e6aba2c405af805291701e", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/sponge.rs", "bytes": 29369, "sha256": "e4152c73ca942140fc82575a3d68c6538d323a6355842210b4b40302d7b8daa9", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "rs/src/tree.rs", "bytes": 53162, "sha256": "2226bc0526238cf05b79c3188ad8a3bcdcc482916a45c6b49cf33c30799440c6", "repository": "hemera", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6" }, { "path": "Cargo.toml", "bytes": 649, "sha256": "4b566e235442b954358c013931da64b9c5bdd20d5e3d1a5e098c3628e153e44f", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "Cargo.lock", "bytes": 32453, "sha256": "6ad5172616dd0bafd554ea965de50afd2c7bcc2daeba730491e14a9d874d67f7", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "kadek-ifac/Cargo.toml", "bytes": 429, "sha256": "8ee668643ce9154222b83817ad1a332db824c846842ac828e87fea3394a51ea6", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "kadek-ifac/src/provenance.rs", "bytes": 13254, "sha256": "3083e381fa7965065b4baa8e61af2a8032317aced1bb94b81ae3493fcd6834cf", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "kadek-ifac/src/provenance/anchor.rs", "bytes": 6443, "sha256": "93ef654721a60df46d6bd716dfca483f30ac4c3e696d4c061d346bfab1b4188d", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "specs/runtime.md", "bytes": 18047, "sha256": "025d6dd6cd9e6adccdc80872923f4535f500a717f938e30771bea07d9b774841", "repository": "kadek", "revision": "4d9ca9ab3498238b9c1e03f6d6f160e1ec729912" }, { "path": "release/components.toml", "bytes": 16783, "sha256": "02aae8e6f2def3e23c124c76be6cc52b01cc54e86ab514c0a519dcbaf7c21e8e", "repository": "soft3", "revision": "18fd6b22ec45725aa776e37d377c5a75aeeaf553" } ]

===== 011 END =====

===== 012 BEGIN historical-inventory-reference.json | 8725 bytes | SHA256 3be511c656596a18910a77a292b5166fddd23500d346114691205d48e51f7158 ===== { "source_archive": "/Users/master/cyber/kadek-bao-anchor/audit/2026-10-12-bao-anchor-research/evidence.tar.gz", "archive_sha256": "b37063a53da33f19c411a58f62b854425efdc1da30c3cd168b327634931483c8", "member": "./external-inventory.json", "member_sha256": "19546c3da15fbdda1c291dde046f0d6dc1d0ac667d79e1d89cb25e0412794ed3", "registry_revision": "18fd6b22ec45725aa776e37d377c5a75aeeaf553", "registry_sha256": "02aae8e6f2def3e23c124c76be6cc52b01cc54e86ab514c0a519dcbaf7c21e8e", "boundary": "Historical exact cached revisions, no fresh network inventory. Full original archive is referenced, not embedded or replayed by this capsule. Nu was subsequently recovered at retained 1e58416ef0501675ef503dd86f80dc1236dfc2a4; Kern absent. Radio a96 and Kadek4d9 support refreshed directly here.", "repositories": [ { "repo": "bbg", "status": "cached-origin", "revision": "441e3c9ddf85c4bee36b40ed7ae8805b1481bc27", "manifests": 2 }, { "repo": "bostrom", "status": "cached-origin", "revision": "bc01d7dc9c22cb1c48caa0edaef6575ce5c38d14", "manifests": 0 }, { "repo": "cve", "status": "cached-origin", "revision": "727eec0074394bdde806dc9273aa889e38d6d26f", "manifests": 0 }, { "repo": "cy", "status": "cached-origin", "revision": "94fc97ae9ee0213a46a3cc2ae3be1f4930ffe67c", "manifests": 0 }, { "repo": "cyb", "status": "cached-origin", "revision": "4e4711f1ba4de640e60e29304b6180c94f20c9d7", "manifests": 7 }, { "repo": "cyber-valley", "status": "cached-origin", "revision": "ed59bf3fce22ec3cdf5a545fdd45f2aed5182fe6", "manifests": 0 }, { "repo": "cybergraph", "status": "cached-origin", "revision": "42fc2512389c7411d8cc3461501d859c1545980e", "manifests": 2 }, { "repo": "cyberia", "status": "cached-origin", "revision": "acbad2e899d5632ebcc24494d206d822bf8499b9", "manifests": 0 }, { "repo": "cyberia-blog", "status": "cached-origin", "revision": "961c956bdc021fa56a14e24980af4a447b7d95c7", "manifests": 0 }, { "repo": "cyberia-my", "status": "cached-origin", "revision": "d1d036728957295d6ba782ba65a1ced88191f225", "manifests": 1 }, { "repo": "cybernode", "status": "cached-origin", "revision": "475e91161cd3c3069a998b01299f0ae735cf8d31", "manifests": 0 }, { "repo": "cyberstates", "status": "cached-origin", "revision": "ce254a1c690416994f0278e547756644c2669cc8", "manifests": 1 }, { "repo": "eidos", "status": "cached-origin", "revision": "e9baa2ef849c34bbfab57c59de20ec7d083fee2f", "manifests": 3 }, { "repo": "evy", "status": "cached-origin", "revision": "a194311ae557bd6dac3ef0c2f12141cb9fc1e01f", "manifests": 27 }, { "repo": "file", "status": "cached-origin", "revision": "e29b4c74804f1fecf123ad4bab14c3cf5b7f3551", "manifests": 1 }, { "repo": "foculus", "status": "cached-origin", "revision": "8a935e1695dfeed2b0241256bc2cd762729bb324", "manifests": 1 }, { "repo": "fs", "status": "cached-origin", "revision": "f1ab2516b636c517a80a8d80782780d83a00679f", "manifests": 0 }, { "repo": "glia", "status": "cached-origin", "revision": "477d91c0a75f8985f4af5f873401a867327bd014", "manifests": 3 }, { "repo": "hemera", "status": "cached-origin", "revision": "d5f0a09539360934fb32db9b2e15a91995607db6", "manifests": 5 }, { "repo": "honeycrisp", "status": "cached-origin", "revision": "9cbd48070a136e24711896c930670fcff8a147fc", "manifests": 14 }, { "repo": "inf", "status": "cached-origin", "revision": "5054c939adbc875c32f1d89cce839d87bbd428bb", "manifests": 11 }, { "repo": "joy", "status": "cached-origin", "revision": "10844a890e2939d529a1003474298a09be30b75c", "manifests": 3 }, { "repo": "kadek", "status": "cached-origin", "revision": "fe61aba6f3eb485abb328b269a3921f6b476d72d", "manifests": 32 }, { "repo": "kern", "status": "unavailable", "revision": null, "manifests": 0 }, { "repo": "lens", "status": "cached-origin", "revision": "8b26cef6587bee6a686f2cf163f6a8496931ee6a", "manifests": 9 }, { "repo": "lytics", "status": "cached-origin", "revision": "02c98495deda66c5f3c69ba3d5be650ce658e313", "manifests": 5 }, { "repo": "mir", "status": "cached-origin", "revision": "b9c832d5011d5a719bec6021afef123be35490ab", "manifests": 1 }, { "repo": "mudra", "status": "cached-origin", "revision": "186c0f22871e72ac5d27396d893998865fc604d4", "manifests": 3 }, { "repo": "neural", "status": "cached-origin", "revision": "47b086c2e3255c784f17ab9303a987bb1dff534c", "manifests": 4 }, { "repo": "neuron", "status": "cached-origin", "revision": "c87541120caae4fb5d5bb401653d1cbcbeffeb7d", "manifests": 7 }, { "repo": "nox", "status": "cached-origin", "revision": "0b1407a4b855e4961ede07e1b7ea199cb8018c30", "manifests": 3 }, { "repo": "nu", "status": "retained-revision", "revision": "1e58416ef0501675ef503dd86f80dc1236dfc2a4", "manifests": 42 }, { "repo": "optica", "status": "cached-origin", "revision": "9f0c352cfea30e1ac8ce0feb0d735ffb9fa47ace", "manifests": 1 }, { "repo": "prysm", "status": "cached-origin", "revision": "f66cbd82cada5f5e6315b674818bce705b962eb6", "manifests": 1 }, { "repo": "radio", "status": "cached-origin", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "manifests": 33 }, { "repo": "rs", "status": "cached-origin", "revision": "01d82825d93129401df064ff3e0c3adae04d852a", "manifests": 11 }, { "repo": "rune", "status": "cached-origin", "revision": "67281db727070c1160c12be341c6fd85e39e5380", "manifests": 12 }, { "repo": "seer", "status": "cached-origin", "revision": "40924ac6c9e2d7564d90962e6c10356c58308877", "manifests": 0 }, { "repo": "sigma", "status": "cached-origin", "revision": "93ae6e201a0b23842349829639480fc7d094119b", "manifests": 0 }, { "repo": "soft3", "status": "cached-origin", "revision": "18fd6b22ec45725aa776e37d377c5a75aeeaf553", "manifests": 2 }, { "repo": "soma", "status": "cached-origin", "revision": "7cfa6f8a602367ceedf45e0bd7e120884c9a6ae3", "manifests": 0 }, { "repo": "space-pussy", "status": "cached-origin", "revision": "3c6e32a43fcfe2338d66780194fd2959308a4f24", "manifests": 0 }, { "repo": "spark", "status": "cached-origin", "revision": "5399d36e99637a9d36018ecf88f3d4d6a80cc9a9", "manifests": 1 }, { "repo": "strata", "status": "cached-origin", "revision": "494df7a0973ae10a6cc1c2022e644d70449a29d6", "manifests": 22 }, { "repo": "tade", "status": "cached-origin", "revision": "c7d404aa8aa4c1e960f7a7268cbef47f2d6ba4d4", "manifests": 1 }, { "repo": "tok", "status": "cached-origin", "revision": "e27da0dff72b948418a5e40a5ed6290c0fd167f3", "manifests": 1 }, { "repo": "trident", "status": "cached-origin", "revision": "ec986d8edb926da51a70c23c97782d65a239c144", "manifests": 3 }, { "repo": "tru", "status": "cached-origin", "revision": "2f3a2556afc943ae949530a626ba4f2a83ace06b", "manifests": 3 }, { "repo": "true-cyber", "status": "cached-origin", "revision": "b58589f130f4f80dd8b2752f98704842372aa2d9", "manifests": 1 }, { "repo": "vault", "status": "cached-origin", "revision": "c980557471184a78d43366e1c52fc978a3e82444", "manifests": 1 }, { "repo": "wysm", "status": "cached-origin", "revision": "bde62d57e4ed2a89fae475ea9e216aeffbd6deb8", "manifests": 13 }, { "repo": "zheng", "status": "cached-origin", "revision": "5733dfdcc15cbc22fce9f5877b37515d005b8c44", "manifests": 3 } ] }

===== 012 END =====

===== 013 BEGIN probe/src/main.rs | 2322 bytes | SHA256 5a6f0b73072d4d40075dbe57c26408a52a3634e898036eb452da0fe54436f526 ===== //! Characterize the committed legacy carrier, without proposing a new decoder. use cyber_bao::{ BlockSize, CHUNK_SIZE, ChunkNum, ChunkRanges, HashBackend, Poseidon2Backend, io::slice::{decode_slice, extract_slice}, };

fn main() { let backend = Poseidon2Backend; let hello = b"hello"; let (root, proof) = extract_slice(&backend, hello, 0..5, BlockSize::ZERO); assert_eq!(proof, [5_u64.to_le_bytes().as_slice(), hello].concat()); let one = ChunkRanges::from(ChunkNum(0)..ChunkNum(1)); for declared in [0_u64, 4, 5, 6, 4096] { let mut changed = proof.clone(); changed[..8].copy_from_slice(&declared.to_le_bytes()); let decoded = decode_slice(&backend, &changed, &root, &one, BlockSize::ZERO) .expect("legacy single-group decoder accepts changed header"); assert_eq!(decoded, vec![(0, hello.to_vec())]); println!("single declared={declared} payload=5 accepted=true"); }

let body = vec![0x42; 2 * CHUNK_SIZE];
let all = ChunkRanges::from(ChunkNum(0)..ChunkNum(2));
let (root, mut proof) = extract_slice(&backend, &body, 0..8192, BlockSize::ZERO);
let original_len = proof.len();
proof.extend_from_slice(b"suffix");
let decoded = decode_slice(&backend, &proof, &root, &all, BlockSize::ZERO)
    .expect("legacy multi-group decoder accepts suffix");
assert_eq!(
    decoded,
    vec![(0, body[..4096].to_vec()), (4096, body[4096..].to_vec())]
);
println!("multi original={original_len} suffix=6 accepted=true");

let (_, single_empty) = extract_slice(&backend, hello, 2..2, BlockSize::ZERO);
assert_eq!(
    single_empty,
    [5_u64.to_le_bytes().as_slice(), hello].concat()
);
let (_, multi_empty) = extract_slice(&backend, &body, 2..2, BlockSize::ZERO);
assert_eq!(multi_empty, 8192_u64.to_le_bytes());
let empty = ChunkRanges::from(ChunkNum(0)..ChunkNum(0));
let wrong = backend.chunk_hash(b"wrong", 0, true);
let decoded = decode_slice(&backend, &multi_empty, &wrong, &empty, BlockSize::ZERO)
    .expect("legacy empty traversal performs no root check");
assert!(decoded.is_empty());
println!(
    "empty single_wire={} multi_wire={} multi_wrong_root_accepted=true",
    single_empty.len(),
    multi_empty.len()
);

}

===== 013 END =====

===== 014 BEGIN primary-probe/src/main.rs | 7858 bytes | SHA256 6c274529c97ebc1e98ffd0bcb37e2e47abf02f5e1db7ca07480ff20ea432971f ===== //! Primary expressions and manual carriers, not a proposed verifier prototype. use cyber_bao::{ BlockSize, ChunkNum, ChunkRanges, HashBackend, Poseidon2Backend, group::GroupHasher, io::slice::{decode_slice, extract_slice}, }; use hemera::{Hash, field::P}; use std::{ops::Range, path::Path};

fn data(n: usize) -> Vec { (0..n).map(|i| ((31 * i + i / 4096) % 256) as u8).collect() } fn leaf(data: &[u8], index: u64) -> Hash { Poseidon2Backend.chunk_hash(data, index, false) } fn parent(left: Hash, right: Hash, root: bool) -> Hash { Poseidon2Backend.parent_hash(&left, &right, root) } fn pair(wire: &mut Vec, left: Hash, right: Hash) { wire.extend_from_slice(left.as_bytes()); wire.extend_from_slice(right.as_bytes()); } fn save(dir: &Path, name: &str, wire: &[u8]) { std::fs::write(dir.join(format!("{name}.bin")), wire).unwrap(); } fn ranges(range: Range) -> ChunkRanges { ChunkRanges::from(ChunkNum(range.start / 4096)..ChunkNum(range.end.div_ceil(4096))) } #[allow(clippy::too_many_arguments)] fn witness( dir: &Path, name: &str, body: &[u8], root: Hash, wire: &[u8], request: Range, log: u8, expected: &[(u64, Vec)], actions: u64, ) { assert_eq!( u64::from_le_bytes(wire[..8].try_into().unwrap()), u64::try_from(body.len()).unwrap() ); assert_eq!( decode_slice( &Poseidon2Backend, wire, &root, &ranges(request.clone()), BlockSize(log) ) .unwrap(), expected ); // Producer agreement is supplemental. The wire above was built by literal expressions. assert_eq!( extract_slice(&Poseidon2Backend, body, request.clone(), BlockSize(log)), (root, wire.to_vec()) ); save(dir, name, wire); println!( "fixture={name} size={} log={log} request={}..{} wire={} root={root} expected_actions={actions}", body.len(), request.start, request.end, wire.len() ); } fn main() { let dir = std::env::args_os().nth(1).expect("fixture directory"); let dir = Path::new(&dir); assert_eq!(P, 0xffff_ffff_0000_0001); let empty = Poseidon2Backend.chunk_hash(&[], 0, true); let hello = Poseidon2Backend.chunk_hash(b"hello", 0, true); assert_eq!( empty.to_string(), "ea57b2e6b1ec7d2de11b15cb6d7060dd61d247fe0fbf5f7d3fb97a7be9328552" ); assert_eq!( hello.to_string(), "626fa46e4e7bd5c87d630eef8333931a0b9198587400a0191eae7821692880d7" ); save(dir, "empty", &0u64.to_le_bytes()); let mut wire = 5u64.to_le_bytes().to_vec(); wire.extend_from_slice(b"hello"); witness( dir, "hello", b"hello", hello, &wire, 1..4, 0, &[(0, b"hello".to_vec())], 4, ); println!("fixture=empty size=0 log=0 request=0..0 wire=8 root={empty} expected_actions=4");

let body = data(12288);
let l0 = leaf(&body[..4096], 0);
let l1 = leaf(&body[4096..8192], 1);
let l2 = leaf(&body[8192..], 2);
let p01 = parent(l0, l1, false);
let root = parent(p01, l2, true);
let mut wire = 12288u64.to_le_bytes().to_vec();
pair(&mut wire, p01, l2);
wire.extend_from_slice(&body[8192..]);
witness(
    dir,
    "three-right",
    &body,
    root,
    &wire,
    8192..8193,
    0,
    &[(8192, body[8192..].to_vec())],
    5,
);
let mut wire = 12288u64.to_le_bytes().to_vec();
pair(&mut wire, p01, l2);
pair(&mut wire, l0, l1);
wire.extend_from_slice(&body[4096..8192]);
witness(
    dir,
    "three-interior",
    &body,
    root,
    &wire,
    4097..4100,
    0,
    &[(4096, body[4096..8192].to_vec())],
    6,
);
let mut wire = 12288u64.to_le_bytes().to_vec();
pair(&mut wire, p01, l2);
pair(&mut wire, l0, l1);
wire.extend_from_slice(&body[..8192]);
witness(
    dir,
    "three-boundary",
    &body,
    root,
    &wire,
    4095..4097,
    0,
    &[
        (0, body[..4096].to_vec()),
        (4096, body[4096..8192].to_vec()),
    ],
    8,
);
let mut wire = 12288u64.to_le_bytes().to_vec();
pair(&mut wire, p01, l2);
wire.extend_from_slice(&body[..8192]);
witness(
    dir,
    "grouped-left",
    &body,
    root,
    &wire,
    4095..4097,
    1,
    &[(0, body[..8192].to_vec())],
    7,
);

let body = data(8193);
let l2 = leaf(&body[8192..], 2);
let root = parent(p01, l2, true);
let mut wire = 8193u64.to_le_bytes().to_vec();
pair(&mut wire, p01, l2);
wire.extend_from_slice(&body[8192..]);
witness(
    dir,
    "final-short",
    &body,
    root,
    &wire,
    8192..8193,
    1,
    &[(8192, body[8192..].to_vec())],
    5,
);

let body = data(8192);
let root = parent(l0, l1, true);
assert_eq!(
    root.to_string(),
    "2abf65dd26465a7352707d79d18ff3aab9ee5d97614a774619c79ed527e20190"
);
assert_eq!(
    p01.to_string(),
    "11890a7e7cf1e4de463a04bf53bfdf269d627983a221daaf9029a3ff43297389"
);
assert_ne!(root, p01);
let mut wire = 8192u64.to_le_bytes().to_vec();
wire.extend_from_slice(&body);
witness(
    dir,
    "sole-group",
    &body,
    root,
    &wire,
    1..8191,
    1,
    &[(0, body.clone())],
    6,
);
let mut reducer = GroupHasher::new(&Poseidon2Backend, &body, 0, true).unwrap();
assert_eq!(reducer.step(), None);
assert_eq!(reducer.step(), None);
assert_eq!(reducer.step(), Some(root));
assert!(reducer.is_complete());
assert_eq!(reducer.step(), None);

// Synthetic parent commitment, NOT the root of a witnessed complete file.
// Its unselected sibling is an arbitrary zero CV. This probes representation.
let zero = Hash::from_bytes([0; 32]);
let synthetic_root = parent(l0, zero, true);
let mut canonical = 8192u64.to_le_bytes().to_vec();
pair(&mut canonical, l0, zero);
canonical.extend_from_slice(&body[..4096]);
let query = ranges(0..1);
let baseline = decode_slice(
    &Poseidon2Backend,
    &canonical,
    &synthetic_root,
    &query,
    BlockSize(0),
)
.unwrap();
assert_eq!(baseline, [(0, body[..4096].to_vec())]);
save(dir, "synthetic-canonical", &canonical);
for word in 0..4 {
    let mut noncanonical = [0; 32];
    noncanonical[word * 8..word * 8 + 8].copy_from_slice(&P.to_le_bytes());
    let raw = Hash::from_bytes(noncanonical);
    assert_ne!(raw, zero);
    assert_eq!(raw.as_bytes(), &noncanonical);
    assert_eq!(parent(l0, raw, true), synthetic_root);
    let mut alias = canonical.clone();
    alias[40 + word * 8..48 + word * 8].copy_from_slice(&P.to_le_bytes());
    assert_eq!(
        decode_slice(
            &Poseidon2Backend,
            &alias,
            &synthetic_root,
            &query,
            BlockSize(0)
        )
        .unwrap(),
        baseline
    );
    save(dir, &format!("synthetic-alias-{word}"), &alias);
    println!(
        "alias_word={word} raw_equal=false parent_equal=true legacy_accept=true root={synthetic_root}"
    );
}
for value in [0, P - 1, P, u64::MAX] {
    let mut raw = [0; 32];
    raw[..8].copy_from_slice(&value.to_le_bytes());
    assert_eq!(Hash::from_bytes(raw).as_bytes(), &raw);
    println!("word={value} proposed_canonical={}", value < P);
}
println!(
    "No new verifier API, allocation guarantee, or whole-file synthetic-root authority is tested here."
);

}

===== 014 END =====

===== 015 BEGIN probe/Cargo.toml | 217 bytes | SHA256 26df88edd220a39b6d5c7964a5dc8767acd2712349ed27b28904cf0e2bc0c038 ===== [package] name = "bao-proof-carrier-probe" version = "0.0.0" edition = "2024" publish = false

[workspace]

[dependencies] cyber-bao = { path = "../../../cyber-bao" }

[profile.dev.package.cyber-hemera] opt-level = 3

===== 015 END =====

===== 016 BEGIN primary-probe/Cargo.toml | 377 bytes | SHA256 eb9de62bfb997f05ffd0c06ef0069e1708d6ff24d5ca277fc25f3c6beef894fd ===== [package] name = "bao-proof-primary-probe" version = "0.0.0" edition = "2024" publish = false

[workspace]

[dependencies] cyber-bao = { path = "../../../cyber-bao" } hemera = { package = "cyber-hemera", git = "https://github.com/cyberia-to/hemera", rev = "d5f0a09539360934fb32db9b2e15a91995607db6", default-features = false }

[profile.dev.package.cyber-hemera] opt-level = 3

===== 016 END =====

===== 017 BEGIN records/initial-debug.json | 1124 bytes | SHA256 8e9fbb3eeca3a7d3a763da790b6e7ee80ed2d2a1ba4b3512804111c9c729ce04 ===== { "started": "2026-10-12T23:15:22.035158Z", "finished": "2026-10-12T23:15:31.749678Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "env", "CARGO_BUILD_JOBS=2", "CARGO_INCREMENTAL=0", "CARGO_TARGET_DIR=/tmp/radio-bao-proof-research-target", "RUSTC=/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/rustc", "RUSTFLAGS=-Dwarnings", "/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/cargo", "run", "--locked", "--offline", "--manifest-path", "audit/2026-10-12-bao-proof-research/probe/Cargo.toml" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-legacy-debug-v1.stdout", "bytes": 321, "sha256": "f8d6893e760591b3ee6ce82d39b620cb6847309ae831276fe27fcbb99f82fb2c" }, "stderr": { "path": "/tmp/radio-bao-proof-legacy-debug-v1.stderr", "bytes": 1592, "sha256": "c131545b9bde8e42c1144a5657559568248727dd279618ec3cd633700c0f3b84" } }

===== 017 END =====

===== 018 BEGIN records/initial-debug.stdout | 321 bytes | SHA256 f8d6893e760591b3ee6ce82d39b620cb6847309ae831276fe27fcbb99f82fb2c ===== single declared=0 payload=5 accepted=true single declared=4 payload=5 accepted=true single declared=5 payload=5 accepted=true single declared=6 payload=5 accepted=true single declared=4096 payload=5 accepted=true multi original=8264 suffix=6 accepted=true empty single_wire=13 multi_wire=8 multi_wrong_root_accepted=true

===== 018 END =====

===== 019 BEGIN records/initial-debug.stderr | 1592 bytes | SHA256 c131545b9bde8e42c1144a5657559568248727dd279618ec3cd633700c0f3b84 ===== Compiling proc-macro2 v1.0.107 Compiling unicode-ident v1.0.26 Compiling quote v1.0.47 Compiling version_check v0.9.5 Compiling syn v1.0.109 Compiling proc-macro-error-attr v0.4.12 Compiling proc-macro-error v0.4.12 Compiling serde_core v1.0.229 Compiling proc-macro-hack v0.5.20+deprecated Compiling syn-mid v0.5.4 Compiling syn v2.0.119 Compiling syn v3.0.8 Compiling serde v1.0.229 Compiling smallvec v1.16.3 Compiling pin-project-lite v0.2.17 Compiling ref-cast v1.0.27 Compiling futures-core v0.3.34 Compiling pin-project-internal v1.1.13 Compiling ref-cast-impl v1.0.27 Compiling parking v2.2.1 Compiling futures-io v0.3.34 Compiling fastrand v2.5.0 Compiling bytes v1.12.1 Compiling futures-lite v2.6.1 Compiling tokio v1.53.2 Compiling genawaiter-proc-macro v0.99.1 Compiling pin-project v1.1.13 Compiling inplace-vec-builder v0.1.1 Compiling genawaiter-macro v0.99.1 Compiling binary-merge v0.1.2 Compiling range-collections v0.4.6 Compiling genawaiter v0.99.1 Compiling iroh-io v0.6.2 Compiling cyber-hemera v0.3.1 (https://github.com/cyberia-to/hemera?rev=d5f0a09539360934fb32db9b2e15a91995607db6#d5f0a095) Compiling cyber-bao v0.1.0 (/Users/master/cyber/radio-bao-bounded-proof/cyber-bao) Compiling bao-proof-carrier-probe v0.0.0 (/Users/master/cyber/radio-bao-bounded-proof/audit/2026-10-12-bao-proof-research/probe) Finished dev profile [unoptimized + debuginfo] target(s) in 9.34s Running /tmp/radio-bao-proof-research-target/debug/bao-proof-carrier-probe

===== 019 END =====

===== 020 BEGIN records/legacy-release.json | 1145 bytes | SHA256 99239687d886f2f236b93c6cd68b0b3402e6c2be74497316b0c4640771c72979 ===== { "started": "2026-10-12T23:18:23.305971Z", "finished": "2026-10-12T23:18:34.336388Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "env", "CARGO_BUILD_JOBS=2", "CARGO_INCREMENTAL=0", "CARGO_TARGET_DIR=/tmp/radio-bao-proof-research-target", "RUSTC=/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/rustc", "RUSTFLAGS=-Dwarnings", "/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/cargo", "run", "--release", "--locked", "--offline", "--manifest-path", "audit/2026-10-12-bao-proof-research/probe/Cargo.toml" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-legacy-release-v1.stdout", "bytes": 321, "sha256": "f8d6893e760591b3ee6ce82d39b620cb6847309ae831276fe27fcbb99f82fb2c" }, "stderr": { "path": "/tmp/radio-bao-proof-legacy-release-v1.stderr", "bytes": 1585, "sha256": "e2cb8d0a2da7eb7b765f1f81440473bf0526a952f9dfa2a3f2c9595fddb4442a" } }

===== 020 END =====

===== 021 BEGIN records/legacy-release.stdout | 321 bytes | SHA256 f8d6893e760591b3ee6ce82d39b620cb6847309ae831276fe27fcbb99f82fb2c ===== single declared=0 payload=5 accepted=true single declared=4 payload=5 accepted=true single declared=5 payload=5 accepted=true single declared=6 payload=5 accepted=true single declared=4096 payload=5 accepted=true multi original=8264 suffix=6 accepted=true empty single_wire=13 multi_wire=8 multi_wrong_root_accepted=true

===== 021 END =====

===== 022 BEGIN records/legacy-release.stderr | 1585 bytes | SHA256 e2cb8d0a2da7eb7b765f1f81440473bf0526a952f9dfa2a3f2c9595fddb4442a ===== Compiling proc-macro2 v1.0.107 Compiling quote v1.0.47 Compiling unicode-ident v1.0.26 Compiling version_check v0.9.5 Compiling syn v1.0.109 Compiling proc-macro-error-attr v0.4.12 Compiling proc-macro-error v0.4.12 Compiling proc-macro-hack v0.5.20+deprecated Compiling serde_core v1.0.229 Compiling syn-mid v0.5.4 Compiling syn v2.0.119 Compiling syn v3.0.8 Compiling futures-core v0.3.34 Compiling smallvec v1.16.3 Compiling ref-cast v1.0.27 Compiling serde v1.0.229 Compiling pin-project-lite v0.2.17 Compiling pin-project-internal v1.1.13 Compiling ref-cast-impl v1.0.27 Compiling parking v2.2.1 Compiling futures-io v0.3.34 Compiling bytes v1.12.1 Compiling fastrand v2.5.0 Compiling futures-lite v2.6.1 Compiling tokio v1.53.2 Compiling genawaiter-proc-macro v0.99.1 Compiling pin-project v1.1.13 Compiling inplace-vec-builder v0.1.1 Compiling genawaiter-macro v0.99.1 Compiling binary-merge v0.1.2 Compiling range-collections v0.4.6 Compiling genawaiter v0.99.1 Compiling iroh-io v0.6.2 Compiling cyber-hemera v0.3.1 (https://github.com/cyberia-to/hemera?rev=d5f0a09539360934fb32db9b2e15a91995607db6#d5f0a095) Compiling cyber-bao v0.1.0 (/Users/master/cyber/radio-bao-bounded-proof/cyber-bao) Compiling bao-proof-carrier-probe v0.0.0 (/Users/master/cyber/radio-bao-bounded-proof/audit/2026-10-12-bao-proof-research/probe) Finished release profile [optimized] target(s) in 10.73s Running /tmp/radio-bao-proof-research-target/release/bao-proof-carrier-probe

===== 022 END =====

===== 023 BEGIN records/primary-debug.json | 1196 bytes | SHA256 bb50494b19380ee7ffef7df470701d2289f9317d0e5769bcc8211d871b0c935b ===== { "started": "2026-10-12T23:27:52.108496Z", "finished": "2026-10-12T23:27:52.789415Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "env", "CARGO_BUILD_JOBS=2", "CARGO_INCREMENTAL=0", "CARGO_TARGET_DIR=/tmp/radio-bao-proof-research-target", "RUSTC=/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/rustc", "RUSTFLAGS=-Dwarnings", "/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/cargo", "run", "--locked", "--offline", "--manifest-path", "audit/2026-10-12-bao-proof-research/primary-probe/Cargo.toml", "--", "audit/2026-10-12-bao-proof-research/fixtures" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-primary-debug-v1.stdout", "bytes": 2027, "sha256": "f9a0230bf0df0f91e29b223d34a72ac2d3321349c4c1553a51874b4b1d6204a0" }, "stderr": { "path": "/tmp/radio-bao-proof-primary-debug-v1.stderr", "bytes": 339, "sha256": "d6fed383ca7cd2b0c5c7088425c2e4942823cfe3498b965ddac79e53ce4063aa" } }

===== 023 END =====

===== 024 BEGIN records/primary-debug.stdout | 2027 bytes | SHA256 f9a0230bf0df0f91e29b223d34a72ac2d3321349c4c1553a51874b4b1d6204a0 ===== fixture=hello size=5 log=0 request=1..4 wire=13 root=626fa46e4e7bd5c87d630eef8333931a0b9198587400a0191eae7821692880d7 expected_actions=4 fixture=empty size=0 log=0 request=0..0 wire=8 root=ea57b2e6b1ec7d2de11b15cb6d7060dd61d247fe0fbf5f7d3fb97a7be9328552 expected_actions=4 fixture=three-right size=12288 log=0 request=8192..8193 wire=4168 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=5 fixture=three-interior size=12288 log=0 request=4097..4100 wire=4232 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=6 fixture=three-boundary size=12288 log=0 request=4095..4097 wire=8328 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=8 fixture=grouped-left size=12288 log=1 request=4095..4097 wire=8264 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=7 fixture=final-short size=8193 log=1 request=8192..8193 wire=73 root=40c6bd68b6e89443753bce2dd95fd159da63a7399340fa6070a762d102d9e3ae expected_actions=5 fixture=sole-group size=8192 log=1 request=1..8191 wire=8200 root=2abf65dd26465a7352707d79d18ff3aab9ee5d97614a774619c79ed527e20190 expected_actions=6 alias_word=0 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=1 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=2 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=3 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 word=0 proposed_canonical=true word=18446744069414584320 proposed_canonical=true word=18446744069414584321 proposed_canonical=false word=18446744073709551615 proposed_canonical=false No new verifier API, allocation guarantee, or whole-file synthetic-root authority is tested here.

===== 024 END =====

===== 025 BEGIN records/primary-debug.stderr | 339 bytes | SHA256 d6fed383ca7cd2b0c5c7088425c2e4942823cfe3498b965ddac79e53ce4063aa ===== Compiling bao-proof-primary-probe v0.0.0 (/Users/master/cyber/radio-bao-bounded-proof/audit/2026-10-12-bao-proof-research/primary-probe) Finished dev profile [unoptimized + debuginfo] target(s) in 0.19s Running /tmp/radio-bao-proof-research-target/debug/bao-proof-primary-probe audit/2026-10-12-bao-proof-research/fixtures

===== 025 END =====

===== 026 BEGIN records/primary-release.json | 1218 bytes | SHA256 b9d17ac3d8630f31a35e64e59ebb6a7be2d53dcabcfec2916ca78f5c1ea8c6a2 ===== { "started": "2026-10-12T23:28:02.679214Z", "finished": "2026-10-12T23:28:03.318341Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "env", "CARGO_BUILD_JOBS=2", "CARGO_INCREMENTAL=0", "CARGO_TARGET_DIR=/tmp/radio-bao-proof-research-target", "RUSTC=/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/rustc", "RUSTFLAGS=-Dwarnings", "/Users/master/.rustup/toolchains/1.95.0-aarch64-apple-darwin/bin/cargo", "run", "--release", "--locked", "--offline", "--manifest-path", "audit/2026-10-12-bao-proof-research/primary-probe/Cargo.toml", "--", "/tmp/radio-bao-proof-primary-release-fixtures" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-primary-release-v1.stdout", "bytes": 2027, "sha256": "f9a0230bf0df0f91e29b223d34a72ac2d3321349c4c1553a51874b4b1d6204a0" }, "stderr": { "path": "/tmp/radio-bao-proof-primary-release-v1.stderr", "bytes": 332, "sha256": "8e540185254d93b8c3d3cbcfdb02e35368db3646159abbea9e90d99eb150f09f" } }

===== 026 END =====

===== 027 BEGIN records/primary-release.stdout | 2027 bytes | SHA256 f9a0230bf0df0f91e29b223d34a72ac2d3321349c4c1553a51874b4b1d6204a0 ===== fixture=hello size=5 log=0 request=1..4 wire=13 root=626fa46e4e7bd5c87d630eef8333931a0b9198587400a0191eae7821692880d7 expected_actions=4 fixture=empty size=0 log=0 request=0..0 wire=8 root=ea57b2e6b1ec7d2de11b15cb6d7060dd61d247fe0fbf5f7d3fb97a7be9328552 expected_actions=4 fixture=three-right size=12288 log=0 request=8192..8193 wire=4168 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=5 fixture=three-interior size=12288 log=0 request=4097..4100 wire=4232 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=6 fixture=three-boundary size=12288 log=0 request=4095..4097 wire=8328 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=8 fixture=grouped-left size=12288 log=1 request=4095..4097 wire=8264 root=373d0ded6b2bd351ba575cdc690ca79bbc04af1a49844f67140ce7a10e672992 expected_actions=7 fixture=final-short size=8193 log=1 request=8192..8193 wire=73 root=40c6bd68b6e89443753bce2dd95fd159da63a7399340fa6070a762d102d9e3ae expected_actions=5 fixture=sole-group size=8192 log=1 request=1..8191 wire=8200 root=2abf65dd26465a7352707d79d18ff3aab9ee5d97614a774619c79ed527e20190 expected_actions=6 alias_word=0 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=1 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=2 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 alias_word=3 raw_equal=false parent_equal=true legacy_accept=true root=9fa00cab5db073eea8280861b4c3b2eb5fd5f13334fb2d481c3b16a3b4244879 word=0 proposed_canonical=true word=18446744069414584320 proposed_canonical=true word=18446744069414584321 proposed_canonical=false word=18446744073709551615 proposed_canonical=false No new verifier API, allocation guarantee, or whole-file synthetic-root authority is tested here.

===== 027 END =====

===== 028 BEGIN records/primary-release.stderr | 332 bytes | SHA256 8e540185254d93b8c3d3cbcfdb02e35368db3646159abbea9e90d99eb150f09f ===== Compiling bao-proof-primary-probe v0.0.0 (/Users/master/cyber/radio-bao-bounded-proof/audit/2026-10-12-bao-proof-research/primary-probe) Finished release profile [optimized] target(s) in 0.30s Running /tmp/radio-bao-proof-research-target/release/bao-proof-primary-probe /tmp/radio-bao-proof-primary-release-fixtures

===== 028 END =====

===== 029 BEGIN records/fetch-traversal.json | 721 bytes | SHA256 159350cba22014a985fd07095b33544de8ea3d1cbc5aa76ca80db1e7442a3a4f ===== { "started": "2026-10-12T23:39:32.524015Z", "finished": "2026-10-12T23:39:33.259147Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "git", "fetch", "origin" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-fetch-traversal-v1.stdout", "bytes": 0, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, "stderr": { "path": "/tmp/radio-bao-proof-fetch-traversal-v1.stderr", "bytes": 0, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" } }

===== 029 END =====

===== 030 BEGIN records/integrate-traversal.json | 783 bytes | SHA256 80b00239f601b7ae149a8205c7acb6a9fc698184f79ddc855e251dec89929791 ===== { "started": "2026-10-12T23:39:37.683898Z", "finished": "2026-10-12T23:39:37.719759Z", "cwd": "/Users/master/cyber/radio-bao-bounded-proof", "revision": "a96d86e28d384cdf656aadc4282c78c0c170c102", "argv": [ "git", "merge", "--ff-only", "b933829cbe273d2f31fe75ca83125f3ddd8917a2" ], "runner_sha256": "10fc0f8210a06cd42e2cc85d0f2b328da05a5e09e01c8feb75651b31fdb0d5d6", "exit_code": 0, "stdout": { "path": "/tmp/radio-bao-proof-integrate-traversal-v1.stdout", "bytes": 9300, "sha256": "25086d4aa53574486ed550b0f242d68091b2e50373f31c0e14f55bba09385062" }, "stderr": { "path": "/tmp/radio-bao-proof-integrate-traversal-v1.stderr", "bytes": 0, "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" } }

===== 030 END =====

===== 031 BEGIN Radio Cargo.toml | 2085 bytes | SHA256 3f8d71aa50c829445d66c981166e22f9b64fbd1f91bdddf4ecb422cf4ebd39f2 ===== [workspace] members = [ "iroh-base", "iroh-dns-server", "iroh", "iroh/bench", "iroh-relay",

"cyber-bao", "particle", "iroh-blobs", "iroh-gossip", "iroh-docs", "iroh-car", "iroh-willow", "tests/integration", "radio-cli", ] resolver = "2" exclude = ["quinn", "nettools"]

[workspace.dependencies] hemera = { package = "cyber-hemera", git = "https://github.com/cyberia-to/hemera", rev = "d5f0a09539360934fb32db9b2e15a91995607db6", default-features = false }

[profile.release] debug = true

Hemera is the hash under every blob, BAO tree and ticket. Unoptimized it makes the

two-node tests (8 MB blobs) take minutes and starve their QUIC paths into idle

timeouts; optimizing just the hash keeps debug builds debuggable everywhere else.

[profile.dev.package.cyber-hemera] opt-level = 3

[profile.dev-ci] inherits = 'dev' opt-level = 1

[profile.optimized-release] inherits = 'release' debug = false lto = true debug-assertions = false opt-level = 3 panic = 'abort' incremental = false

[workspace.lints.rust] missing_debug_implementations = "warn"

We use this --cfg for documenting the cargo features on which an API

is available. To preview this locally use: RUSTDOCFLAGS="--cfg

iroh_docsrs" cargo +nightly doc --all-features. We use our own

iroh_docsrs instead of the common docsrs to avoid also enabling this

feature in any dependencies, because some indirect dependencies

require a feature enabled when using --cfg docsrs which we can not

do. To enable for a crate set `#![cfg_attr(iroh_docsrs,

feature(doc_cfg))]` in the crate.

We also have our own iroh_loom cfg to enable tokio-rs/loom testing.

unexpected_cfgs = { level = "warn", check-cfg = ["cfg(iroh_docsrs)", "cfg(iroh_loom)"] }

[workspace.lints.clippy] unused-async = "warn"

[patch.crates-io] willow-data-model = { git = "https://github.com/n0-computer/willow-rs.git", branch = "main" } willow-encoding = { git = "https://github.com/n0-computer/willow-rs.git", branch = "main" } meadowcap = { git = "https://github.com/n0-computer/willow-rs.git", branch = "main" }

===== 031 END =====

===== 032 BEGIN Radio cyber-bao/Cargo.toml | 1078 bytes | SHA256 95e58b3d1e130d6a579b361111e848b9aa907f66eee0e2acb7ab5449c9f9e365 ===== [package] name = "cyber-bao" version = "0.1.0" edition = "2024" description = "Poseidon2-BAO: verified streaming with Poseidon2 hash over Goldilocks" license = "MIT OR Apache-2.0" rust-version = "1.89"

[lints] workspace = true

[dependencies] hemera = { workspace = true } bytes = { version = "1", optional = true } smallvec = { version = "1", features = ["const_new"], optional = true } range-collections = { version = "0.4", features = ["serde", "new_unchecked"], optional = true } iroh-io = { version = "0.6.1", optional = true } genawaiter = { version = "0.99.1", features = ["futures03"], optional = true } tokio = { version = "1", features = ["io-util"], optional = true } serde = { version = "1", features = ["derive"], optional = true }

[dev-dependencies] proptest = "1" tokio = { version = "1", features = ["macros", "rt", "io-util"] }

[features] default = ["std"] std = ["hemera/std", "dep:bytes", "dep:smallvec", "dep:range-collections", "dep:iroh-io", "dep:genawaiter"] tokio_fsm = ["std", "dep:tokio"] serde = ["std", "dep:serde", "hemera/serde", "bytes/serde"]

===== 032 END =====

===== 033 BEGIN Radio cyber-bao/src/lib.rs | 1330 bytes | SHA256 2e054f65e05d5a47555e684cb339903972672e2f1077a2ee19ddd6648f88ac40 ===== //! Poseidon2-BAO: verified streaming with Poseidon2 hash over Goldilocks. //! //! This crate provides BAO-style content-verified streaming using the //! Poseidon2 algebraic hash function. The tree structure //! and encoding formats are compatible with the original bao specification, //! differing only in the hash function used. //! //! # Architecture //! //! - tree: Pure geometry — tree node indexing, chunk counting, block sizes //! - hash: Pluggable hash backend trait with Poseidon2 implementation //! - io: Encoding, decoding, outboard creation, and slice extraction

#![cfg_attr(not(feature = "std"), no_std)]

pub mod group; pub mod hash; #[cfg(feature = "std")] pub mod io; pub mod traversal; pub mod tree;

pub use hash::{HashBackend, Poseidon2Backend}; pub use tree::{BaoChunk, BaoTree, BlockSize, CHUNK_SIZE, ChunkNum, TreeNode};

#[cfg(feature = "std")] pub use tree::PostOrderChunkIter;

/// A set of chunk ranges (used for partial downloads, range requests, etc.). #[cfg(feature = "std")] pub type ChunkRanges = range_collections::RangeSet2;

/// Borrowed reference to chunk ranges. #[cfg(feature = "std")] pub type ChunkRangesRef = range_collections::RangeSetRef;

/// A set of byte ranges. #[cfg(feature = "std")] pub type ByteRanges = range_collections::RangeSet2;

===== 033 END =====

===== 034 BEGIN Radio cyber-bao/src/group.rs | 6349 bytes | SHA256 948307e945b1f7f3808b5828dacb04547a89c701c8f00ba1534fa396d0b66cdf ===== //! Incremental fixed-chunk group hashing with a fixed frontier. //! //! This computes a hash only; it does not authenticate data or a particle/root //! association. Each pending step calls one backend kernel, on at most 4096 input //! bytes or two child hashes. Arbitrary backend code and hash destructors retain //! their own cost and allocation behavior.

use core::fmt;

use crate::{CHUNK_SIZE, HashBackend};

/// A group cannot be represented by the backend's absolute chunk counters. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum GroupHashError { /// The input length does not fit in a u64 (unreachable on <=64-bit targets). InputTooLarge, /// The last absolute chunk counter would exceed u64::MAX. CounterOverflow, }

impl fmt::Display for GroupHashError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { Self::InputTooLarge => "group input length exceeds u64", Self::CounterOverflow => "group chunk counter overflows u64", }) } }

impl core::error::Error for GroupHashError {}

fn leaf_count(len: u64) -> u64 { (len / CHUNK_SIZE as u64 + u64::from(!len.is_multiple_of(CHUNK_SIZE as u64))).max(1) }

fn validate_counter(len: u64, start: u64) -> Result<u64, GroupHashError> { let leaves = leaf_count(len); start .checked_add(leaves - 1) .ok_or(GroupHashError::CounterOverflow)?; Ok(leaves) }

/// A resumable complete-left binary reduction over fixed 4096-byte chunks. /// /// Construction and completed polls call no backend method. Every pending /// step performs exactly one leaf or parent kernel: for N chunks /// (at least one, even for empty input), completion takes exactly 2*N-1 steps. /// Only the completing kernel receives the requested root flag. /// /// The caller owns scheduling: check is_complete, admit /// one unit from its persistent budget, then step. Intermediate steps return /// None while is_complete is false; count kernel entries, not returned hashes. /// No internal quota is renewed by polling. Backend panics have no recovery /// contract. Hashes are moved, never cloned. /// /// The frontier uses 53 slots: a u64 byte length needs at most 2^52 leaves; /// before a leaf there are at most 52 complete peaks, plus the incoming leaf. /// This fixed storage does not require allocation or a placeholder hash. pub struct GroupHasher<'a, B: HashBackend> { backend: &'a B, remaining: &'a [u8], next_counter: u64, leaves: u64, processed: u64, frontier: [Option<B::Hash>; 53], occupied: usize, reductions: u32, root: bool, complete: bool, }

impl<B: HashBackend> fmt::Debug for GroupHasher<', B> { fn fmt(&self, f: &mut fmt::Formatter<'>) -> fmt::Result { f.debug_struct("GroupHasher") .field("remaining_bytes", &self.remaining.len()) .field("processed_leaves", &self.processed) .field("leaves", &self.leaves) .field("occupied", &self.occupied) .field("is_complete", &self.complete) .finish_non_exhaustive() } }

impl<'a, B: HashBackend> GroupHasher<'a, B> { /// Borrow a group and validate every counter before any hashing. /// /// Empty input is a single empty leaf. A sole leaf at u64::MAX is valid; /// two leaves starting there return [GroupHashError::CounterOverflow]. pub fn new( backend: &'a B, data: &'a [u8], start_chunk: u64, is_root: bool, ) -> Result<Self, GroupHashError> { let len = u64::try_from(data.len()).map_err(|| GroupHashError::InputTooLarge)?; let leaves = validate_counter(len, start_chunk)?; Ok(Self { backend, remaining: data, next_counter: start_chunk, leaves, processed: 0, frontier: core::array::from_fn(|| None), occupied: 0, reductions: 0, root: is_root, complete: false, }) }

/// Whether the final hash has already been returned.
pub fn is_complete(&self) -> bool {
    self.complete
}

/// Perform one pending kernel and return the hash only on the final step.
///
/// Intermediate steps return None with `is_complete() == false`. Completed
/// polls return None with `is_complete() == true` and perform no kernel.
pub fn step(&mut self) -> Option<B::Hash> {
    if self.complete {
        return None;
    }
    if self.reductions != 0 {
        let right = self.frontier[self.occupied - 1]
            .take()
            .expect("occupied right peak");
        let left = self.frontier[self.occupied - 2]
            .take()
            .expect("occupied left peak");
        let final_parent = self.processed == self.leaves && self.occupied == 2;
        let hash = self
            .backend
            .parent_hash(&left, &right, self.root && final_parent);
        self.occupied -= 1;
        self.reductions -= 1;
        if final_parent {
            self.complete = true;
            return Some(hash);
        }
        self.frontier[self.occupied - 1] = Some(hash);
    } else {
        let take = self.remaining.len().min(CHUNK_SIZE);
        let hash = self.backend.chunk_hash(
            &self.remaining[..take],
            self.next_counter,
            self.root && self.leaves == 1,
        );
        self.remaining = &self.remaining[take..];
        self.processed += 1;
        if self.leaves == 1 {
            self.complete = true;
            return Some(hash);
        }
        self.frontier[self.occupied] = Some(hash);
        self.occupied += 1;
        if self.processed == self.leaves {
            // Fold remaining complete peaks from right to left.
            self.reductions = (self.occupied - 1) as u32;
        } else {
            // Merge equal-size complete peaks before accepting another leaf.
            self.reductions = self.processed.trailing_zeros();
            self.next_counter += 1; // all used counters were validated in new
        }
    }
    None
}

}

#[cfg(test)] mod tests;

===== 034 END =====

===== 035 BEGIN Radio cyber-bao/src/hash.rs | 3960 bytes | SHA256 1e705848543784c326be3ecd347878eae8dc5ab0207392d64ba5d9efb695bf1f ===== //! Hash backend trait and Poseidon2 implementation. //! //! The HashBackend trait abstracts the hash function used in BAO tree //! construction, making the tree machinery hash-agnostic. The Poseidon2Backend //! provides the concrete implementation using hemera.

use hemera::{Hash, OUTPUT_BYTES};

/// Trait for pluggable hash functions in BAO tree operations. /// /// Implementations must provide: /// - Leaf hashing: hash a data chunk at a position in the file /// - Parent hashing: combine two child hashes into a parent hash pub trait HashBackend { /// The hash output type. type Hash: AsRef<[u8]> + Clone + Eq + core::fmt::Debug;

/// Hash a data chunk (leaf node).
///
/// - `data`: the chunk data
/// - `counter`: 0-based position index in the file
/// - `is_root`: true if this is the only chunk (root finalization)
fn chunk_hash(&self, data: &[u8], counter: u64, is_root: bool) -> Self::Hash;

/// Combine two child hashes into a parent hash.
///
/// - `left`: left child hash
/// - `right`: right child hash
/// - `is_root`: true if this is the tree root
fn parent_hash(&self, left: &Self::Hash, right: &Self::Hash, is_root: bool) -> Self::Hash;

/// Size of the hash output in bytes.
fn hash_size(&self) -> usize;

/// A zero hash (used for empty/placeholder nodes).
fn zero_hash(&self) -> Self::Hash;

/// Construct a hash from its raw byte representation.
fn hash_from_bytes(&self, bytes: &[u8]) -> Self::Hash;

}

/// Poseidon2 hash backend using hemera. #[derive(Debug, Clone, Copy, Default)] pub struct Poseidon2Backend;

impl HashBackend for Poseidon2Backend { type Hash = Hash;

fn chunk_hash(&self, data: &[u8], counter: u64, is_root: bool) -> Hash {
    hemera::tree::chunk_cv(data, counter, is_root)
}

fn parent_hash(&self, left: &Hash, right: &Hash, is_root: bool) -> Hash {
    hemera::tree::parent_cv(left, right, is_root)
}

fn hash_size(&self) -> usize {
    OUTPUT_BYTES
}

fn zero_hash(&self) -> Hash {
    Hash::from_bytes([0u8; OUTPUT_BYTES])
}

fn hash_from_bytes(&self, bytes: &[u8]) -> Hash {
    let mut arr = [0u8; OUTPUT_BYTES];
    arr.copy_from_slice(&bytes[..OUTPUT_BYTES]);
    Hash::from_bytes(arr)
}

}

#[cfg(test)] mod tests { use super::*;

#[test]
fn poseidon2_backend_basic() {
    let backend = Poseidon2Backend;
    let h1 = backend.chunk_hash(b"hello", 0, false);
    let h2 = backend.chunk_hash(b"hello", 0, false);
    assert_eq!(h1, h2); // deterministic

    let h3 = backend.chunk_hash(b"world", 0, false);
    assert_ne!(h1, h3); // different data
}

#[test]
fn poseidon2_backend_counter() {
    let backend = Poseidon2Backend;
    let h0 = backend.chunk_hash(b"data", 0, false);
    let h1 = backend.chunk_hash(b"data", 1, false);
    assert_ne!(h0, h1); // different counter
}

#[test]
fn poseidon2_backend_parent() {
    let backend = Poseidon2Backend;
    let left = backend.chunk_hash(b"left", 0, false);
    let right = backend.chunk_hash(b"right", 1, false);
    let parent = backend.parent_hash(&left, &right, false);
    assert_ne!(parent, left);
    assert_ne!(parent, right);

    // Non-commutative
    let parent_rev = backend.parent_hash(&right, &left, false);
    assert_ne!(parent, parent_rev);
}

#[test]
fn poseidon2_backend_root_differs() {
    let backend = Poseidon2Backend;
    let left = backend.chunk_hash(b"left", 0, false);
    let right = backend.chunk_hash(b"right", 1, false);
    let non_root = backend.parent_hash(&left, &right, false);
    let root = backend.parent_hash(&left, &right, true);
    assert_ne!(non_root, root);
}

#[test]
fn hash_size() {
    let backend = Poseidon2Backend;
    assert_eq!(backend.hash_size(), OUTPUT_BYTES);
}

}

===== 035 END =====

===== 036 BEGIN Radio cyber-bao/src/tree.rs | 12320 bytes | SHA256 458f26235aee22c42376dde8929a55831c1f8a58dd59a5dac270cd9bb8bd667a ===== //! BAO tree geometry — pure math, no hashing. //! //! This module provides the tree structure used for verified streaming. //! The tree uses in-order indexing (same as bao-tree): leaves at //! even positions, parents at odd positions, level = trailing ones count.

use core::fmt; use core::ops::Range;

use hemera::OUTPUT_BYTES;

#[cfg(feature = "std")] mod traversal; #[cfg(feature = "std")] pub use traversal::PostOrderChunkIter;

/// Size of a single chunk in bytes (Hemera spec: 4 KiB). pub const CHUNK_SIZE: usize = 4096;

/// Size of a hash pair (two hashes concatenated). const PAIR_SIZE: usize = OUTPUT_BYTES * 2;

/// A node position in the in-order binary tree. /// /// Leaves are at even indices (0, 2, 4, ...). /// Parents are at odd indices with level = trailing_ones count. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct TreeNode(pub(crate) u64);

impl TreeNode { /// Create a tree node from a raw in-order index. pub fn new(index: u64) -> Self { Self(index) }

/// The level of this node (0 for leaves).
pub fn level(self) -> u32 {
    self.0.trailing_ones()
}

/// Whether this is a leaf node.
pub fn is_leaf(self) -> bool {
    (self.0 & 1) == 0
}

/// The midpoint chunk number (boundary between left and right subtrees).
pub fn mid(self) -> ChunkNum {
    ChunkNum(self.0 + 1)
}

/// The left child of this node, if it has one.
pub fn left_child(self) -> Option<Self> {
    let level = self.level();
    if level == 0 {
        return None;
    }
    Some(Self(self.0 - (1 << (level - 1))))
}

/// The right child of this node, if it has one.
pub fn right_child(self) -> Option<Self> {
    let level = self.level();
    if level == 0 {
        return None;
    }
    Some(Self(self.0 + (1 << (level - 1))))
}

/// The parent of this node.
pub fn parent(self) -> Option<Self> {
    let level = self.level();
    let span = 1u64 << level;
    let offset = self.0;
    if offset & (span << 1) == 0 {
        Some(Self(offset + span))
    } else {
        offset.checked_sub(span).map(Self)
    }
}

/// Range of chunks covered by this node's subtree.
pub fn chunk_range(self) -> Range<ChunkNum> {
    let level = self.level();
    let span = 1u64 << level;
    let mid = self.0 + 1;
    ChunkNum(mid - span)..ChunkNum(mid + span)
}

/// Range of bytes covered by this node's subtree.
pub fn byte_range(self) -> Range<u64> {
    let range = self.chunk_range();
    range.start.to_bytes()..range.end.to_bytes()
}

/// The right descendant of this node that is within the tree bounds.
///
/// Starts at right child, then walks left until within `len`.
pub fn right_descendant(self, len: Self) -> Option<Self> {
    let mut node = self.right_child()?;
    while node >= len {
        node = node.left_child()?;
    }
    Some(node)
}

/// Count of nodes below this node in the subtree (excluding self).
pub fn count_below(self) -> u64 {
    let level = self.level();
    if level == 0 {
        return 0;
    }
    (1u64 << (level + 1)) - 2
}

/// Post-order offset of this node (closed-form).
pub fn post_order_offset(self) -> u64 {
    let level = self.level();
    let span = 1u64 << level;
    let mid = self.0 + 1;
    let start = mid - span;
    // In a complete binary tree, post-order offset = start + count_below
    start + self.count_below()
}

/// Shift the node index by removing the block_size lowest bits.
///
/// Returns `None` if the node's level is below the block size
/// (i.e., it's an intra-block node that doesn't appear in the block-level tree).
pub const fn add_block_size(self, n: u8) -> Option<Self> {
    let mask = (1u64 << n) - 1;
    if self.0 & mask == mask {
        Some(Self(self.0 >> n))
    } else {
        None
    }
}

/// The inverse of `add_block_size` — expand back to the unshifted index.
pub const fn subtract_block_size(self, n: u8) -> Self {
    let shifted = !(!self.0 << n);
    Self(shifted)
}

}

impl fmt::Debug for TreeNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "TreeNode({}, level={})", self.0, self.level()) } }

impl fmt::Display for TreeNode { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } }

/// Count of chunks (each CHUNK_SIZE bytes). #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ChunkNum(pub u64);

impl ChunkNum { /// Number of chunks needed for size bytes (rounds up). pub fn chunks(size: u64) -> Self { Self(size.div_ceil(CHUNK_SIZE as u64)) }

/// Number of full chunks in `size` bytes (rounds down).
pub fn full_chunks(size: u64) -> Self {
    Self(size / CHUNK_SIZE as u64)
}

/// Convert chunks back to bytes.
pub fn to_bytes(self) -> u64 {
    self.0 * CHUNK_SIZE as u64
}

}

impl fmt::Debug for ChunkNum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "ChunkNum({})", self.0) } }

impl fmt::Display for ChunkNum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) } }

impl core::ops::Add for ChunkNum { type Output = Self; fn add(self, rhs: Self) -> Self { Self(self.0 + rhs.0) } }

impl core::ops::Add for ChunkNum { type Output = Self; fn add(self, rhs: u64) -> Self { Self(self.0 + rhs) } }

impl core::ops::Sub for ChunkNum { type Output = Self; fn sub(self, rhs: Self) -> Self { Self(self.0 - rhs.0) } }

impl core::ops::Sub for ChunkNum { type Output = Self; fn sub(self, rhs: u64) -> Self { Self(self.0 - rhs) } }

#[cfg(feature = "std")] impl range_collections::range_set::RangeSetEntry for ChunkNum { fn min_value() -> Self { ChunkNum(0) }

fn is_min_value(&self) -> bool {
    self.0 == 0
}

}

/// Block size for chunk groups — log2 of the number of chunks per block. /// /// BlockSize(0) = CHUNK_SIZE bytes (one chunk per block). /// BlockSize(2) = 4 × CHUNK_SIZE bytes (4 chunks per block, recommended default). #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct BlockSize(pub u8);

impl BlockSize { /// One chunk per block. pub const ZERO: Self = Self(0);

/// Default 16 KiB blocks (4 × 4096-byte chunks, recommended for production).
pub const DEFAULT: Self = Self(2);

/// Create from the log2 of chunks per block.
pub const fn from_chunk_log(log: u8) -> Self {
    Self(log)
}

/// Create from a byte size (must be a power of 2 >= CHUNK_SIZE).
pub fn from_bytes(bytes: u64) -> Option<Self> {
    if bytes < CHUNK_SIZE as u64 || !bytes.is_power_of_two() {
        return None;
    }
    let log = (bytes / CHUNK_SIZE as u64).trailing_zeros() as u8;
    Some(Self(log))
}

/// Block size in bytes.
pub fn bytes(self) -> usize {
    CHUNK_SIZE << self.0
}

/// Log2 of chunks per block.
pub fn chunk_log(self) -> u8 {
    self.0
}

/// Log2 of chunks per block as u32.
pub fn to_u32(self) -> u32 {
    self.0 as u32
}

}

/// The BAO tree geometry descriptor. /// /// Contains no actual data or hashes — purely describes the tree shape /// for a blob of a given size and block size. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BaoTree { size: u64, block_size: BlockSize, }

impl BaoTree { /// Create a new tree for the given data size and block size. pub fn new(size: u64, block_size: BlockSize) -> Self { Self { size, block_size } }

/// Total data size in bytes.
pub fn size(&self) -> u64 {
    self.size
}

/// Block size configuration.
pub fn block_size(&self) -> BlockSize {
    self.block_size
}

/// Number of chunks (CHUNK_SIZE bytes each).
pub fn chunks(&self) -> ChunkNum {
    ChunkNum::chunks(self.size)
}

/// Number of blocks (chunk groups). Minimum 1 even for empty data.
pub fn blocks(&self) -> u64 {
    let chunk_count = self.chunks().0;
    let chunks_per_block = 1u64 << self.block_size.0;
    chunk_count.div_ceil(chunks_per_block).max(1)
}

/// Root node of the tree (at the block level).
///
/// In the in-order binary tree, the root of N leaves is at
/// index `next_power_of_two(N) - 1`.
pub fn root(&self) -> TreeNode {
    let blocks = self.blocks();
    if blocks <= 1 {
        return TreeNode(0);
    }
    TreeNode(blocks.next_power_of_two() - 1)
}

/// Size of the outboard (hash pairs only, no size prefix).
/// Each internal node is a hash pair (two OUTPUT_BYTES hashes).
pub fn outboard_size(&self) -> u64 {
    let blocks = self.blocks();
    if blocks <= 1 {
        return 0;
    }
    (blocks - 1) * PAIR_SIZE as u64
}

/// Block size in bytes (chunk group size).
pub fn chunk_group_bytes(&self) -> usize {
    self.block_size.bytes()
}

/// Compute the shifted tree representation (block-level tree).
///
/// Returns `(root_node, filled_size)` in the shifted coordinate system.
pub fn shifted(&self) -> (TreeNode, TreeNode) {
    let level = self.block_size.0;
    let size = self.size;
    let shift = CHUNK_SIZE.trailing_zeros() + level as u32;
    let mask = (1u64 << shift) - 1;
    let full_blocks = size >> shift;
    let open_block = u64::from((size & mask) != 0);
    let blocks = (full_blocks + open_block).max(1);
    let n = blocks.div_ceil(2);
    let root = n.next_power_of_two() - 1;
    let filled_size = n + n.saturating_sub(1);
    (TreeNode(root), TreeNode(filled_size))
}

/// Compute the left, mid, and right byte boundaries for a leaf node.
///
/// `(start, mid.min(size), end.min(size))`
pub fn leaf_byte_ranges3(&self, node: TreeNode) -> (u64, u64, u64) {
    let Range { start, end } = node.byte_range();
    let mid = node.mid().to_bytes();
    (start, mid.min(self.size), end.min(self.size))
}

/// Convert a node's in-order chunk_range to actual chunk numbers.
///
/// `TreeNode::chunk_range()` returns values in the in-order index space
/// where leaf at index 2k covers range 2k..2k+2. Actual chunk numbers
/// are: block_idx * chunks_per_block, where block_idx = leaf_index / 2.
/// This method performs that conversion for use with `ChunkRanges`.
pub fn node_actual_chunk_range(&self, node: TreeNode) -> Range<ChunkNum> {
    let raw = node.chunk_range();
    let cpb = 1u64 << self.block_size.0;
    // In-order index space → block space: divide by 2
    // Block space → chunk space: multiply by chunks_per_block
    ChunkNum((raw.start.0 / 2) * cpb)..ChunkNum((raw.end.0 / 2) * cpb)
}

/// Whether a node is relevant for the outboard (i.e., tracked at this block size).
pub fn is_relevant_for_outboard(&self, node: TreeNode) -> bool {
    let level = node.level();
    let bs = self.block_size.to_u32();
    if level < bs {
        false
    } else if level > bs {
        true
    } else {
        node.mid().to_bytes() < self.size
    }
}

}

/// Items yielded during tree traversal. #[derive(Debug, Clone)] pub enum BaoChunk { /// A parent node — contains two child hashes (PAIR_SIZE bytes). Parent { node: TreeNode, is_root: bool, /// Whether the left child will be visited in this traversal. left: bool, /// Whether the right child will be visited in this traversal. right: bool, }, /// A leaf node — contains actual data. Leaf { start_chunk: u64, size: usize, is_root: bool, }, }

#[cfg(test)] mod tests;

===== 036 END =====

===== 037 BEGIN Radio cyber-bao/src/traversal.rs | 6067 bytes | SHA256 87f646ef36a1e7ba1be3dd4576acf4bf6637d1ec6705953aef0bf8c6ac42eb5a ===== //! Checked, allocation-free preorder geometry for one byte range. //! //! This cursor emits geometry only. It does not parse a proof or authenticate //! a particle, root, payload or empty request.

use core::{fmt, iter::FusedIterator, ops::Range};

use crate::{BaoChunk, BlockSize, CHUNK_SIZE, TreeNode};

/// Invalid geometry supplied to [RangeTraversal::new]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RangeTraversalError { /// The group width cannot be represented by both u64 and usize. InvalidBlockSize, /// The byte range is reversed or extends beyond the file. InvalidRange, }

impl fmt::Display for RangeTraversalError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(match self { Self::InvalidBlockSize => "invalid traversal block size", Self::InvalidRange => "invalid traversal byte range", }) } }

impl core::error::Error for RangeTraversalError {}

#[derive(Debug, Clone, Copy)] struct Frame { first: u64, count: u64, is_root: bool, }

/// Preorder cursor over whole groups intersecting a half-open byte range. /// /// Construction uses fixed storage for 53 frames. Each pending [Iterator::next] /// pops one frame, pushes at most two children and returns one item, without /// allocation, recursion, scanning or hashing. Pausing requires no extra state: /// simply retain the cursor without calling next. /// /// ROOT belongs to the complete file tree, even when the request selects only /// one leaf. Parent flags identify children visited by this request; a parent /// still describes a pair of hashes. An empty request is immediately complete /// and emits no item; it makes no authentication claim. pub struct RangeTraversal { size: u64, group_bytes: u64, selected: Range, frames: [Frame; 53], pending: usize, }

impl fmt::Debug for RangeTraversal { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("RangeTraversal") .field("size", &self.size) .field("group_bytes", &self.group_bytes) .field("selected", &self.selected) .field("pending", &self.pending) .finish() } }

impl RangeTraversal { /// Admit a file size, group width and half-open requested byte interval. /// /// Block geometry is validated before the request: the block log must be at /// most 51, and its byte width must fit usize. This admits logs 0..=51 on /// 64-bit targets and 0..=19 on 32-bit targets, even for a short or empty file. /// Width admission concerns integer geometry, not allocation layout validity. /// The request must satisfy start <= end <= size; an empty interval at EOF /// is valid. Only the final file group is clipped to its actual byte length. pub fn new( size: u64, block_size: BlockSize, request: Range, ) -> Result<Self, RangeTraversalError> { if block_size.0 > 51 { return Err(RangeTraversalError::InvalidBlockSize); } let group_bytes = (CHUNK_SIZE as u64) << block_size.0; usize::try_from(group_bytes).map_err(|_| RangeTraversalError::InvalidBlockSize)?; if request.start > request.end || request.end > size { return Err(RangeTraversalError::InvalidRange); } let mut result = Self { size, group_bytes, selected: 0..0, frames: [Frame { first: 0, count: 0, is_root: false, }; 53], pending: 0, }; if request.start < request.end { result.selected = request.start / group_bytes..(request.end - 1) / group_bytes + 1; result.push(Frame { first: 0, count: size.div_ceil(group_bytes), is_root: true, }); } Ok(result) }

/// Whether no item remains, including immediately after the last emission.
pub fn is_complete(&self) -> bool {
    self.pending == 0
}

fn push(&mut self, frame: Frame) {
    // N <= 2^52: at depth d <= 52, at most d deferred siblings plus
    // one current frame exist. Pop before pushing children preserves 53.
    self.frames[self.pending] = frame;
    self.pending += 1;
}

}

impl Iterator for RangeTraversal { type Item = BaoChunk;

fn next(&mut self) -> Option<Self::Item> {
    if self.is_complete() {
        return None;
    }
    self.pending -= 1;
    let frame = self.frames[self.pending];
    if frame.count == 1 {
        // first < N implies first * group_bytes <= size - 1. Subtract
        // before clipping: the next group's byte end need not fit u64.
        let start = frame.first * self.group_bytes;
        return Some(BaoChunk::Leaf {
            start_chunk: start / CHUNK_SIZE as u64,
            size: self.group_bytes.min(self.size - start) as usize,
            is_root: frame.is_root,
        });
    }
    let left_count = 1u64 << (frame.count - 1).ilog2();
    let middle = frame.first + left_count;
    let end = frame.first + frame.count;
    let left = self.selected.start < middle && frame.first < self.selected.end;
    let right = self.selected.start < end && middle < self.selected.end;
    if right {
        self.push(Frame {
            first: middle,
            count: frame.count - left_count,
            is_root: false,
        });
    }
    if left {
        self.push(Frame {
            first: frame.first,
            count: left_count,
            is_root: false,
        });
    }
    // middle < N <= 2^52, so this group-based index is below 2^53.
    Some(BaoChunk::Parent {
        node: TreeNode::new(2 * middle - 1),
        is_root: frame.is_root,
        left,
        right,
    })
}

}

impl FusedIterator for RangeTraversal {}

===== 037 END =====

===== 038 BEGIN Radio cyber-bao/src/io/slice.rs | 13041 bytes | SHA256 0f29291599f56c3c8dda4930e660d41a3e04cf1a3ee9cdfb8c36e3fc1de832d7 ===== //! Slice extraction and verification. //! //! A slice is a minimal subset of the combined encoding that proves //! a requested byte range. It includes only the parent hashes on the //! path from the requested chunks to the root, plus the chunk data //! in the range. Verification is O(log N) in the file size.

use std::ops::Range;

use crate::hash::HashBackend; use crate::io::outboard; use crate::tree::{BaoChunk, BaoTree, BlockSize, ChunkNum, CHUNK_SIZE}; use crate::{ChunkRanges, ChunkRangesRef};

/// Extract a slice (proof + data) for the given byte range. /// /// Returns the root hash and the encoded slice that can be verified /// against it. pub fn extract_slice<B: HashBackend>( backend: &B, data: &[u8], range: Range, block_size: BlockSize, ) -> (B::Hash, Vec) { let chunk_ranges = crate::io::round_up_to_chunks(&crate::ByteRanges::from(range)); extract_slice_ranges(backend, data, &chunk_ranges, block_size) }

/// Extract a slice for multiple chunk ranges (multi-range query). /// /// Returns the root hash and the encoded slice containing only the /// parent hashes on the verification path and the leaf data for /// requested ranges. pub fn extract_slice_ranges<B: HashBackend>( backend: &B, data: &[u8], ranges: &ChunkRangesRef, block_size: BlockSize, ) -> (B::Hash, Vec) { let ob = outboard::outboard(backend, data, block_size); let tree = ob.tree;

let mut slice_data = Vec::new();
slice_data.extend_from_slice(&(data.len() as u64).to_le_bytes());

if tree.blocks() <= 1 {
    slice_data.extend_from_slice(data);
    return (ob.root, slice_data);
}

let hash_size = backend.hash_size();
let pair_size = hash_size * 2;
let pre_order = tree.pre_order_chunks();
let mut outboard_offset = 0usize;

for chunk in &pre_order {
    match chunk {
        BaoChunk::Parent { node, .. } => {
            let actual_range = tree.node_actual_chunk_range(*node);
            let node_chunks = ChunkRanges::from(actual_range.start..actual_range.end);
            if !node_chunks.is_disjoint(ranges) {
                slice_data
                    .extend_from_slice(&ob.data[outboard_offset..outboard_offset + pair_size]);
            }
            outboard_offset += pair_size;
        }
        BaoChunk::Leaf {
            start_chunk,
            size,
            ..
        } => {
            let chunks_per_block = 1u64 << block_size.chunk_log();
            let block_idx = *start_chunk / chunks_per_block;
            let leaf_start = block_idx * chunks_per_block;
            let leaf_end = leaf_start + chunks_per_block;
            let leaf_range =
                ChunkRanges::from(ChunkNum(leaf_start)..ChunkNum(leaf_end));
            if !leaf_range.is_disjoint(ranges) {
                let byte_start = (*start_chunk * CHUNK_SIZE as u64) as usize;
                let byte_end = (byte_start + *size).min(data.len());
                if byte_start < data.len() {
                    slice_data.extend_from_slice(&data[byte_start..byte_end]);
                }
            }
        }
    }
}

(ob.root, slice_data)

}

/// Decode and verify a slice against a trusted root hash. /// /// Returns a vec of (offset, data) pairs for each verified leaf. pub fn decode_slice<B: HashBackend>( backend: &B, slice: &[u8], root_hash: &B::Hash, ranges: &ChunkRangesRef, block_size: BlockSize, ) -> Result<Vec<(u64, Vec)>, SliceDecodeError> { if slice.len() < 8 { return Err(SliceDecodeError::Truncated); }

let declared_size = u64::from_le_bytes(slice[..8].try_into().unwrap());
let tree = BaoTree::new(declared_size, block_size);
let hash_size = backend.hash_size();
let pair_size = hash_size * 2;

let mut cursor = 8usize;
let mut results = Vec::new();

if tree.blocks() <= 1 {
    let leaf_data = &slice[cursor..];
    let computed = super::hash_group(backend, leaf_data, 0, true);
    if computed != *root_hash {
        return Err(SliceDecodeError::LeafMismatch { start_chunk: 0 });
    }
    results.push((0u64, leaf_data.to_vec()));
    return Ok(results);
}

let pre_order = tree.pre_order_chunks_filtered(ranges);
// For in-file requests, only pending visited nodes have expected hashes.
let mut expected_stack: Vec<B::Hash> = vec![root_hash.clone()];

for chunk in &pre_order {
    match chunk {
        BaoChunk::Parent {
            node,
            is_root,
            left,
            right,
        } => {
            if cursor + pair_size > slice.len() {
                return Err(SliceDecodeError::Truncated);
            }
            let left_bytes = &slice[cursor..cursor + hash_size];
            let right_bytes = &slice[cursor + hash_size..cursor + pair_size];
            cursor += pair_size;

            let left_hash = backend.hash_from_bytes(left_bytes);
            let right_hash = backend.hash_from_bytes(right_bytes);

            let computed = backend.parent_hash(&left_hash, &right_hash, *is_root);
            let expected = expected_stack.pop().ok_or(SliceDecodeError::Truncated)?;
            if computed != expected {
                return Err(SliceDecodeError::ParentMismatch { node: node.0 });
            }

            if *right {
                expected_stack.push(right_hash);
            }
            if *left {
                expected_stack.push(left_hash);
            }
        }
        BaoChunk::Leaf {
            start_chunk,
            size,
            is_root,
        } => {
            if cursor + *size > slice.len() {
                return Err(SliceDecodeError::Truncated);
            }
            let leaf_data = &slice[cursor..cursor + *size];
            cursor += *size;

            let computed = super::hash_group(backend, leaf_data, *start_chunk, *is_root);
            let expected = expected_stack.pop().ok_or(SliceDecodeError::Truncated)?;
            if computed != expected {
                return Err(SliceDecodeError::LeafMismatch {
                    start_chunk: *start_chunk,
                });
            }

            let byte_offset = *start_chunk * CHUNK_SIZE as u64;
            results.push((byte_offset, leaf_data.to_vec()));
        }
    }
}

Ok(results)

}

/// Error during slice decoding / verification. #[derive(Debug, Clone, PartialEq, Eq)] pub enum SliceDecodeError { Truncated, ParentMismatch { node: u64 }, LeafMismatch { start_chunk: u64 }, }

impl std::fmt::Display for SliceDecodeError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { SliceDecodeError::Truncated => write!(f, "truncated slice"), SliceDecodeError::ParentMismatch { node } => { write!(f, "parent hash mismatch at node {node}") } SliceDecodeError::LeafMismatch { start_chunk } => { write!(f, "leaf hash mismatch at chunk {start_chunk}") } } } }

impl std::error::Error for SliceDecodeError {}

#[cfg(test)] mod tests { use hemera::OUTPUT_BYTES;

use super::*;
use crate::hash::Poseidon2Backend;

const PAIR_SIZE: usize = OUTPUT_BYTES * 2;

#[test]
fn slice_full_range_matches_encode() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; CHUNK_SIZE * 2];
    let (root, slice) = extract_slice(&backend, &data, 0..CHUNK_SIZE as u64 * 2, BlockSize::ZERO);

    assert_eq!(slice.len(), 8 + PAIR_SIZE + CHUNK_SIZE * 2);

    let left = backend.chunk_hash(&data[..CHUNK_SIZE], 0, false);
    let right = backend.chunk_hash(&data[CHUNK_SIZE..], 1, false);
    let expected_root = backend.parent_hash(&left, &right, true);
    assert_eq!(root, expected_root);
}

#[test]
fn slice_partial_range_is_smaller() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; CHUNK_SIZE * 4];
    let (root_full, full_slice) = extract_slice(&backend, &data, 0..CHUNK_SIZE as u64 * 4, BlockSize::ZERO);
    let (root_partial, partial_slice) =
        extract_slice(&backend, &data, 0..CHUNK_SIZE as u64, BlockSize::ZERO);

    assert_eq!(root_full, root_partial);
    assert!(partial_slice.len() < full_slice.len());
}

#[test]
fn slice_root_hash_independent_of_range() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; CHUNK_SIZE * 4];
    let (root1, _) = extract_slice(&backend, &data, 0..CHUNK_SIZE as u64, BlockSize::ZERO);
    let (root2, _) = extract_slice(&backend, &data, CHUNK_SIZE as u64..CHUNK_SIZE as u64 * 2, BlockSize::ZERO);
    let (root3, _) = extract_slice(&backend, &data, 0..CHUNK_SIZE as u64 * 4, BlockSize::ZERO);
    assert_eq!(root1, root2);
    assert_eq!(root2, root3);
}

#[test]
fn decode_slice_full_range_roundtrip() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; CHUNK_SIZE * 2];
    let ranges = ChunkRanges::from(ChunkNum(0)..ChunkNum(2));
    let (root, slice) = extract_slice_ranges(&backend, &data, &ranges, BlockSize::ZERO);

    let results = decode_slice(&backend, &slice, &root, &ranges, BlockSize::ZERO)
        .expect("decode should succeed");

    let mut decoded = vec![0u8; CHUNK_SIZE * 2];
    for (offset, chunk) in &results {
        decoded[*offset as usize..*offset as usize + chunk.len()].copy_from_slice(chunk);
    }
    assert_eq!(decoded, data);
}

#[test]
fn decode_slice_partial_range() {
    let backend = Poseidon2Backend;
    let data = vec![0xABu8; CHUNK_SIZE * 4];
    let ranges = ChunkRanges::from(ChunkNum(0)..ChunkNum(1));
    let (root, slice) = extract_slice_ranges(&backend, &data, &ranges, BlockSize::ZERO);

    let results = decode_slice(&backend, &slice, &root, &ranges, BlockSize::ZERO)
        .expect("decode should succeed");

    assert_eq!(results.len(), 1);
    assert_eq!(results[0].0, 0);
    assert_eq!(results[0].1, data[..CHUNK_SIZE]);
}

#[test]
fn decode_slice_wrong_root_fails() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; CHUNK_SIZE * 2];
    let ranges = ChunkRanges::from(ChunkNum(0)..ChunkNum(2));
    let (_, slice) = extract_slice_ranges(&backend, &data, &ranges, BlockSize::ZERO);

    let wrong_root = backend.chunk_hash(b"wrong", 0, true);
    let result = decode_slice(&backend, &slice, &wrong_root, &ranges, BlockSize::ZERO);
    assert!(result.is_err());
}

#[test]
fn multi_range_slice_extract_and_verify() {
    let backend = Poseidon2Backend;
    let data: Vec<u8> = (0..CHUNK_SIZE * 4).map(|i| (i % 256) as u8).collect();
    // Request chunks 0 and 3 (non-contiguous)
    let ranges = ChunkRanges::from(ChunkNum(0)..ChunkNum(1))
        | ChunkRanges::from(ChunkNum(3)..ChunkNum(4));
    let (root, slice) = extract_slice_ranges(&backend, &data, &ranges, BlockSize::ZERO);

    let results = decode_slice(&backend, &slice, &root, &ranges, BlockSize::ZERO)
        .expect("decode should succeed");

    assert_eq!(results.len(), 2);
    assert_eq!(results[0].0, 0);
    assert_eq!(results[0].1, data[..CHUNK_SIZE]);
    assert_eq!(results[1].0, CHUNK_SIZE as u64 * 3);
    assert_eq!(results[1].1, data[CHUNK_SIZE * 3..CHUNK_SIZE * 4]);
}

#[test]
fn single_block_slice_roundtrip() {
    let backend = Poseidon2Backend;
    let data = vec![0x42u8; 500];
    let ranges = ChunkRanges::from(ChunkNum(0)..ChunkNum(1));
    let (root, slice) = extract_slice_ranges(&backend, &data, &ranges, BlockSize::ZERO);

    let results = decode_slice(&backend, &slice, &root, &ranges, BlockSize::ZERO)
        .expect("decode should succeed");
    assert_eq!(results.len(), 1);
    assert_eq!(results[0].1, data);
}

#[test]
fn slice_roundtrip_block_size_nonzero() {
    let backend = Poseidon2Backend;
    let bs = BlockSize::from_chunk_log(1); // 2 chunks per block
    // 8 chunks → 4 blocks of 2 chunks
    let data: Vec<u8> = (0..CHUNK_SIZE * 8).map(|i| (i % 256) as u8).collect();
    let ranges = ChunkRanges::all();
    let (root, slice) = extract_slice_ranges(&backend, &data, &ranges, bs);

    let results = decode_slice(&backend, &slice, &root, &ranges, bs)
        .expect("decode should succeed");

    let mut decoded = vec![0u8; CHUNK_SIZE * 8];
    for (offset, chunk) in &results {
        decoded[*offset as usize..*offset as usize + chunk.len()].copy_from_slice(chunk);
    }
    assert_eq!(decoded, data);
}

}

===== 038 END =====

===== 039 BEGIN Radio cyber-bao/tests/range_traversal.rs | 12350 bytes | SHA256 e07530aa7035ccad8c75da53c50355efc03c503f2480189c32ac133ead883d25 ===== //! Literal geometric expectations; no hash or authenticated proof is involved. use core::{iter::FusedIterator, ops::Range};

use cyber_bao::{ BaoChunk, BlockSize, TreeNode, traversal::{RangeTraversal, RangeTraversalError}, };

#[derive(Debug, PartialEq, Eq)] enum Item { Parent(TreeNode, bool, bool, bool), Leaf(u64, usize, bool), }

fn item(value: BaoChunk) -> Item { match value { BaoChunk::Parent { node, is_root, left, right, } => Item::Parent(node, is_root, left, right), BaoChunk::Leaf { start_chunk, size, is_root, } => Item::Leaf(start_chunk, size, is_root), } }

// This parser reads authored preorder tokens. It contains no tree splitting, // recursion, geometry traversal or production call. Last-leaf size is supplied. fn literal(tokens: &str, log: u8, final_group: u64, final_size: usize) -> Vec { let group_chunks = 1u64 << log; let group_bytes = 4096usize << log; tokens .split_whitespace() .enumerate() .map(|(index, token)| { if let Some(parent) = token.strip_prefix('P') { let (node, visit) = parent.split_once(':').unwrap_or((parent, "B")); assert!(matches!(visit, "L" | "R" | "B")); Item::Parent( TreeNode::new(node.parse().unwrap()), index == 0, visit != "R", visit != "L", ) } else { let group: u64 = token.strip_prefix('L').unwrap().parse().unwrap(); Item::Leaf( group * group_chunks, if group == final_group { final_size } else { group_bytes }, index == 0, ) } }) .collect() }

fn check(size: u64, log: u8, request: Range, expected: &[Item]) { let mut traversal = RangeTraversal::new(size, BlockSize(log), request).unwrap(); fn fused<T: FusedIterator<Item = BaoChunk>>(_: &T) {} fused(&traversal); assert_eq!(traversal.is_complete(), expected.is_empty()); for (index, value) in expected.iter().enumerate() { assert!(!traversal.is_complete()); assert_eq!(&item(traversal.next().expect("one pending item")), value); assert_eq!(traversal.is_complete(), index + 1 == expected.len()); } for _ in 0..3 { assert!(traversal.next().is_none()); assert!(traversal.is_complete()); } }

const COMPLETE: &[(u64, &str)] = &[ (1, "L0"), (2, "P1 L0 L1"), (3, "P3 P1 L0 L1 L2"), (5, "P7 P3 P1 L0 L1 P5 L2 L3 L4"), (7, "P7 P3 P1 L0 L1 P5 L2 L3 P11 P9 L4 L5 L6"), ( 16, "P15 P7 P3 P1 L0 L1 P5 L2 L3 P11 P9 L4 L5 P13 L6 L7 P23 P19 P17 L8 L9 P21 L10 L11 P27 P25 L12 L13 P29 L14 L15", ), ( 17, "P31 P15 P7 P3 P1 L0 L1 P5 L2 L3 P11 P9 L4 L5 P13 L6 L7 P23 P19 P17 L8 L9 P21 L10 L11 P27 P25 L12 L13 P29 L14 L15 L16", ), ];

#[test] fn literal_complete_left_shapes_and_partial_last_groups() { for log in [0, 2] { let width = 4096u64 << log; for &(groups, tokens) in COMPLETE { for final_size in [1, width] { let size = (groups - 1) * width + final_size; let expected = literal(tokens, log, groups - 1, final_size as usize); assert_eq!(expected.len() as u64, 2 * groups - 1); check(size, log, 0..size, &expected); } } } }

#[test] fn literal_half_open_selection_flags_and_root_placement() { for log in [0, 2] { let g = 4096u64 << log; let cases = [ (3, 3 * g - 1..3 * g, "P3:R L2"), (3, 0..1, "P3:L P1:L L0"), (3, g..2 * g, "P3:L P1:R L1"), (3, g - 1..g + 1, "P3:L P1:B L0 L1"), (3, 2 * g - 1..2 * g + 1, "P3:B P1:R L1 L2"), (7, 7 * g - 1..7 * g, "P7:R P11:R L6"), (7, 5 * g..6 * g, "P7:R P11:L P9:R L5"), (7, 3 * g..5 * g, "P7:B P3:R P5:R L3 P11:L P9:L L4"), (17, 17 * g - 1..17 * g, "P31:R L16"), ]; for (groups, request, tokens) in cases { check( groups * g, log, request, &literal(tokens, log, groups - 1, g as usize), ); } check( 2 * g + 1, log, 2 * g..2 * g + 1, &literal("P3:R L2", log, 2, 1), ); } }

#[test] fn tiny_lengths_and_empty_requests_are_geometric() { for size in [1, 4095, 4096] { check(size, 0, 0..size, &[Item::Leaf(0, size as usize, true)]); } check( 4097, 0, 0..4097, &[ Item::Parent(TreeNode::new(1), true, true, true), Item::Leaf(0, 4096, false), Item::Leaf(1, 1, false), ], ); for size in [0, 1, 4095, 4096, 4097, u64::MAX] { for at in [0, size / 2, size] { check(size, 0, at..at, &[]); } } }

#[test] #[allow(clippy::reversed_empty_ranges, reason = "invalid constructor inputs")] fn exact_admission_errors_and_geometry_precedence() { use RangeTraversalError::{InvalidBlockSize, InvalidRange}; for (size, request) in [ (0, 0..1), (0, 1..1), (1, 1..0), (1, 0..2), (1, 2..2), (u64::MAX, u64::MAX..0), ] { assert_eq!( RangeTraversal::new(size, BlockSize(0), request).unwrap_err(), InvalidRange ); } let max_log = match usize::BITS { 32 => 19, 64 => 51, bits => panic!("unsupported witness pointer width {bits}"), }; for log in 0..=u8::MAX { let result = RangeTraversal::new(1, BlockSize(log), 0..1); if log <= max_log { let mut cursor = result.unwrap(); assert_eq!(item(cursor.next().unwrap()), Item::Leaf(0, 1, true)); assert!(cursor.is_complete()); assert_eq!( RangeTraversal::new(1, BlockSize(log), 2..2).unwrap_err(), InvalidRange ); } else { assert_eq!(result.unwrap_err(), InvalidBlockSize); assert_eq!( RangeTraversal::new(1, BlockSize(log), 2..2).unwrap_err(), InvalidBlockSize ); assert_eq!( RangeTraversal::new(0, BlockSize(log), 0..0).unwrap_err(), InvalidBlockSize ); } } fn core_error<E: core::error::Error>() {} core_error::(); assert_eq!(InvalidBlockSize.to_string(), "invalid traversal block size"); assert_eq!(InvalidRange.to_string(), "invalid traversal byte range"); }

// Independent complete-tree midpoint identities: left spine 2^k-1; // right spine 2^53-2^k-1 for k=52..1, evaluated before implementation. const MAX_LEFT: [u64; 52] = [ 4503599627370495, 2251799813685247, 1125899906842623, 562949953421311, 281474976710655, 140737488355327, 70368744177663, 35184372088831, 17592186044415, 8796093022207, 4398046511103, 2199023255551, 1099511627775, 549755813887, 274877906943, 137438953471, 68719476735, 34359738367, 17179869183, 8589934591, 4294967295, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, ]; const MAX_RIGHT: [u64; 52] = [ 4503599627370495, 6755399441055743, 7881299347898367, 8444249301319679, 8725724278030335, 8866461766385663, 8936830510563327, 8972014882652159, 8989607068696575, 8998403161718783, 9002801208229887, 9005000231485439, 9006099743113215, 9006649498927103, 9006924376834047, 9007061815787519, 9007130535264255, 9007164895002623, 9007182074871807, 9007190664806399, 9007194959773695, 9007197107257343, 9007198180999167, 9007198717870079, 9007198986305535, 9007199120523263, 9007199187632127, 9007199221186559, 9007199237963775, 9007199246352383, 9007199250546687, 9007199252643839, 9007199253692415, 9007199254216703, 9007199254478847, 9007199254609919, 9007199254675455, 9007199254708223, 9007199254724607, 9007199254732799, 9007199254736895, 9007199254738943, 9007199254739967, 9007199254740479, 9007199254740735, 9007199254740863, 9007199254740927, 9007199254740959, 9007199254740975, 9007199254740983, 9007199254740987, 9007199254740989, ];

#[test] fn maximum_file_final_path_uses_literal_remainder() { let mut expected: Vec<_> = MAX_RIGHT .iter() .enumerate() .map(|(i, &node)| Item::Parent(TreeNode::new(node), i == 0, false, true)) .collect(); expected.push(Item::Leaf(4503599627370495, 4095, false)); check(u64::MAX, 0, u64::MAX - 1..u64::MAX, &expected); #[cfg(target_pointer_width = "64")] check( u64::MAX, 51, u64::MAX - 1..u64::MAX, &[ Item::Parent(TreeNode::new(1), true, false, true), Item::Leaf(2251799813685248, 9223372036854775807, false), ], ); }

#[test] fn maximum_left_prefix_requires_fifty_three_pending_slots() { // Entire request leaves all 52 right siblings pending at the first leaf. // Only this finite prefix is polled; no enormous body or full walk exists. let mut cursor = RangeTraversal::new(u64::MAX, BlockSize(0), 0..u64::MAX).unwrap(); for (i, node) in MAX_LEFT.into_iter().enumerate() { assert_eq!( item(cursor.next().unwrap()), Item::Parent(TreeNode::new(node), i == 0, true, true) ); assert!(!cursor.is_complete()); } assert_eq!(item(cursor.next().unwrap()), Item::Leaf(0, 4096, false)); assert_eq!(item(cursor.next().unwrap()), Item::Leaf(1, 4096, false)); assert!(!cursor.is_complete()); }

#[test] fn caller_pauses_and_interleaving_preserve_progress() { let a_expected = literal("P7:R P11:R L6", 0, 6, 4096); let b_expected = literal(COMPLETE[3].1, 0, 4, 1); for pause in 0..=b_expected.len() { let mut a = RangeTraversal::new(7 * 4096, BlockSize(0), 7 * 4096 - 1..7 * 4096).unwrap(); let mut b = RangeTraversal::new(4 * 4096 + 1, BlockSize(0), 0..4 * 4096 + 1).unwrap(); let mut before = Vec::new(); for _ in 0..pause { before.push(item(b.next().unwrap())); } for expected in &a_expected { assert_eq!(&item(a.next().unwrap()), expected); } assert!(a.is_complete()); assert!(a.next().is_none()); assert_eq!(before, b_expected[..pause]); for expected in &b_expected[pause..] { assert_eq!(&item(b.next().unwrap()), expected); } assert!(b.is_complete()); assert!(b.next().is_none()); } }

#[cfg(feature = "std")] #[test] fn finite_eager_compatibility_is_supplemental() { use cyber_bao::{BaoTree, ChunkNum, ChunkRanges}; for log in [0, 2] { let g = 4096u64 << log; for &(groups, ) in COMPLETE { let size = (groups - 1) * g + 1; for request in [0..size, size - 1..size] { let old_ranges = ChunkRanges::from( ChunkNum(request.start / 4096)..ChunkNum((request.end - 1) / 4096 + 1), ); let eager: Vec<> = BaoTree::new(size, BlockSize(log)) .pre_order_chunks_filtered(&old_ranges) .into_iter() .map(item) .collect(); let bounded: Vec<_> = RangeTraversal::new(size, BlockSize(log), request) .unwrap() .map(item) .collect(); assert_eq!(bounded, eager); } } } }

===== 039 END =====

===== 040 BEGIN Radio cyber-bao/tests/range_traversal_allocation.rs | 3083 bytes | SHA256 cc7b2cc32b710ee835be001d77887c5176e42e6719b3fc8c97d31ddec4fe6c59 ===== #![cfg(feature = "std")] //! Finite constructor/step/drop allocation observation, with a positive control. use std::{ alloc::{GlobalAlloc, Layout, System}, cell::Cell, hint::black_box, };

use cyber_bao::{BlockSize, traversal::RangeTraversal};

thread_local! { static ACTIVE: Cell = const { Cell::new(false) }; static COUNT: Cell = const { Cell::new(0) }; } struct Allocator; fn record() { ACTIVE.with(|active| { if active.get() { COUNT.with(|count| count.set(count.get() + 1)); } }); } unsafe impl GlobalAlloc for Allocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { record(); // SAFETY: forwarded allocator contract and unchanged layout. unsafe { System.alloc(layout) } } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { record(); // SAFETY: forwarded allocator contract and unchanged layout. unsafe { System.alloc_zeroed(layout) } } unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, size: usize) -> *mut u8 { record(); // SAFETY: forwarded allocator contract and unchanged arguments. unsafe { System.realloc(ptr, layout, size) } } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { // SAFETY: forwarded allocator contract. Frees are not allocation events. unsafe { System.dealloc(ptr, layout) } } } #[global_allocator] static ALLOCATOR: Allocator = Allocator;

fn measured(f: impl FnOnce()) -> usize { struct Reset; impl Drop for Reset { fn drop(&mut self) { ACTIVE.with(|active| active.set(false)); } } COUNT.with(|count| count.set(0)); ACTIVE.with(|active| assert!(!active.replace(true))); let guard = Reset; f(); drop(guard); COUNT.with(Cell::get) }

#[test] fn construction_steps_terminal_polls_and_drop_allocate_nothing() { assert!( measured(|| { black_box(vec![17u8; 17]); }) > 0 ); for (size, log, request, steps, complete) in [ (0, 0, 0..0, 0, true), (4097, 0, 0..4097, 3, true), (114688, 2, 49152..81920, 7, true), (u64::MAX, 0, u64::MAX - 1..u64::MAX, 53, true), (u64::MAX, 0, 0..u64::MAX, 54, false), ] { assert_eq!( measured(|| { let mut cursor = RangeTraversal::new(size, BlockSize(log), request).unwrap(); for _ in 0..steps { assert!(black_box(cursor.next()).is_some()); } assert_eq!(cursor.is_complete(), complete); if complete { for _ in 0..3 { assert!(black_box(cursor.next()).is_none()); } } black_box(cursor); }), 0 ); } assert_eq!( measured(|| { assert!(RangeTraversal::new(1, BlockSize(255), 0..1).is_err()); assert!(RangeTraversal::new(1, BlockSize(0), 2..2).is_err()); }), 0 ); }

===== 040 END =====

===== 041 BEGIN Radio cyber-bao/tests/root_policy.rs | 8717 bytes | SHA256 42737b5a4f3c3e6f9d19f91a5d14279e3f43a8e3eaaf8d4caf251b744944f94b ===== #![cfg(feature = "std")] //! Independent fixed-tree roots, literal proofs, and public verification paths. use std::convert::Infallible;

use bytes::Bytes; use cyber_bao::{ BaoTree, BlockSize, CHUNK_SIZE, ChunkNum, ChunkRanges, Poseidon2Backend, io::{ EncodeError, decode::{DecodeError as CombinedError, decode}, encode::encode, hash_block, mixed::{EncodedItem, Sender, traverse_ranges_validated}, outboard::outboard, pre_order::{PostOrderMemOutboard, PreOrderMemOutboard}, slice::{SliceDecodeError, decode_slice, extract_slice_ranges}, sync::{encode_ranges_validated, valid_ranges}, }, }; use hemera::{ Hash, tree::{chunk_cv, fixed_chunk_root, parent_cv}, };

const CANONICAL: &str = "2abf65dd26465a7352707d79d18ff3aab9ee5d97614a774619c79ed527e20190"; const OLD: &str = "11890a7e7cf1e4de463a04bf53bfdf269d627983a221daaf9029a3ff43297389";

fn body(len: usize) -> Vec { (0..len) .map(|i| ((i * 31 + i / CHUNK_SIZE) % 256) as u8) .collect() }

fn fixture() -> (Vec, Hash, Hash, Vec) { let data = body(8192); let left = chunk_cv(&data[..CHUNK_SIZE], 0, false); let right = chunk_cv(&data[CHUNK_SIZE..], 1, false); let root = parent_cv(&left, &right, true); let old = parent_cv(&left, &right, false); assert_eq!(root.to_string(), CANONICAL); assert_eq!(old.to_string(), OLD); assert_eq!(root, fixed_chunk_root(&data)); let mut wire = 8192u64.to_le_bytes().to_vec(); wire.extend_from_slice(&data); (data, root, old, wire) }

fn grouped(root: Hash) -> PreOrderMemOutboard { PreOrderMemOutboard { root, tree: BaoTree::new(8192, BlockSize::from_chunk_log(4)), data: Vec::new(), } }

#[test] fn literal_root_reaches_every_producer() { let (data, root, _, wire) = fixture(); let bs = BlockSize::from_chunk_log(4); assert_eq!( hash_block(&Poseidon2Backend, &data, 0, true, bs.bytes()), root ); let ob = outboard(&Poseidon2Backend, &data, bs); assert_eq!(ob.root, root); assert!(ob.data.is_empty()); assert_eq!(PreOrderMemOutboard::create(&data, bs).root, root); assert_eq!(PostOrderMemOutboard::create(&data, bs).root, root); assert_eq!(encode(&Poseidon2Backend, &data, bs), (root, wire.clone())); assert_eq!( extract_slice_ranges(&Poseidon2Backend, &data, &ChunkRanges::all(), bs), (root, wire) ); }

#[test] fn literal_proof_accepts_canonical_root() { let (data, root, , wire) = fixture(); let bs = BlockSize::from_chunk_log(4); assert_eq!(decode(&Poseidon2Backend, &wire, &root, bs).unwrap(), data); assert_eq!( decode_slice(&Poseidon2Backend, &wire, &root, &ChunkRanges::all(), bs).unwrap(), [(0, data.clone())] ); let mut encoded = Vec::new(); encode_ranges_validated(&data[..], &grouped(root), &ChunkRanges::all(), &mut encoded).unwrap(); // Sync range encoding carries no size prefix. assert_eq!(encoded, wire[8..]); let ranges = ChunkRanges::all(); let valid: Vec<> = valid_ranges(grouped(root), &data[..], &ranges) .into_iter() .collect::<Result<_, _>>() .unwrap(); assert_eq!(valid.len(), 1); assert_eq!(valid[0], ChunkNum(0)..ChunkNum(2)); }

#[test] fn literal_proof_rejects_the_old_internal_cv() { let (data, _, old, wire) = fixture(); let bs = BlockSize::from_chunk_log(4); assert_eq!( decode(&Poseidon2Backend, &wire, &old, bs), Err(CombinedError::LeafMismatch { start_chunk: 0 }) ); assert_eq!( decode_slice(&Poseidon2Backend, &wire, &old, &ChunkRanges::all(), bs), Err(SliceDecodeError::LeafMismatch { start_chunk: 0 }) ); let mut encoded = Vec::new(); assert!(matches!( encode_ranges_validated(&data[..], &grouped(old), &ChunkRanges::all(), &mut encoded), Err(EncodeError::LeafHashMismatch(ChunkNum(0))) )); assert!(encoded.is_empty()); assert!( valid_ranges(grouped(old), &data[..], &ChunkRanges::all()) .into_iter() .next() .is_none() ); }

#[test] fn grouping_preserves_fixed_tree_at_boundaries() { // Five-leaf partial root:16385/log4; non-root groups4+2 and4+3:24576/28672 log2. for len in [ 0, 1, 4095, 4096, 4097, 8192, 12288, 16384, 16385, 24576, 28672, 65536, 65537, 131072, ] { let data = body(len); let expected = fixed_chunk_root(&data); for log in [0, 1, 2, 4] { let bs = BlockSize::from_chunk_log(log); assert_eq!( outboard(&Poseidon2Backend, &data, bs).root, expected, "len={len} log={log}" ); } } }

#[test] fn published_empty_and_hello_tree_vectors_are_unchanged() { // Hemera23f3bbcf vectors/hemera.json: these inputs are also one fixed chunk. for (data, expected) in [ ( &b""[..], "ea57b2e6b1ec7d2de11b15cb6d7060dd61d247fe0fbf5f7d3fb97a7be9328552", ), ( &b"hello"[..], "626fa46e4e7bd5c87d630eef8333931a0b9198587400a0191eae7821692880d7", ), ] { assert_eq!(fixed_chunk_root(data).to_string(), expected); assert_eq!( PreOrderMemOutboard::create(data, BlockSize::from_chunk_log(4)) .root .to_string(), expected ); } }

#[test] fn non_root_partial_and_odd_groups_verify_with_absolute_counters() { for (len, log) in [(24576, 2), (28672, 2), (65537, 4)] { let data = body(len); let bs = BlockSize::from_chunk_log(log); let start = 1u64 << log; let ranges = ChunkRanges::from(ChunkNum(start)..ChunkNum::chunks(len as u64)); let (root, wire) = extract_slice_ranges(&Poseidon2Backend, &data, &ranges, bs); assert_eq!(root, fixed_chunk_root(&data)); let offset = start * CHUNK_SIZE as u64; assert_eq!( decode_slice(&Poseidon2Backend, &wire, &root, &ranges, bs).unwrap(), [(offset, data[offset as usize..].to_vec())] ); let mut encoded = Vec::new(); let ob = PreOrderMemOutboard::create(&data, bs); encode_ranges_validated(&data[..], &ob, &ranges, &mut encoded).unwrap(); assert_eq!(encoded, wire[8..]); } }

#[derive(Default)] struct Events(Vec);

impl Sender for Events { type Error = Infallible;

async fn send(&mut self, item: EncodedItem) -> Result<(), Self::Error> {
    self.0.push(item);
    Ok(())
}

}

#[tokio::test] async fn mixed_canonical_success_and_old_root_terminal_error() { let (data, root, old, _) = fixture(); let mut events = Events::default(); traverse_ranges_validated( Bytes::copy_from_slice(&data), grouped(root), &ChunkRanges::all(), &mut events, ) .await .unwrap(); let [ EncodedItem::Size(8192), EncodedItem::Leaf(leaf), EncodedItem::Done, ] = events.0.as_slice() else { panic!("unexpected success events: {:?}", events.0); }; assert_eq!(leaf.offset, 0); assert_eq!(leaf.data.as_ref(), data); let mut events = Events::default(); traverse_ranges_validated( Bytes::from(data), grouped(old), &ChunkRanges::all(), &mut events, ) .await .unwrap(); assert!(matches!( events.0.as_slice(), [ EncodedItem::Size(8192), EncodedItem::Error(EncodeError::LeafHashMismatch(ChunkNum(0))) ] )); }

#[cfg(feature = "tokio_fsm")] #[tokio::test] async fn fsm_literal_canonical_leaf_and_old_root_error() { use cyber_bao::io::{ BaoContentItem, DecodeError, fsm::{ResponseDecoder, ResponseDecoderNext}, }; let (data, root, old, ) = fixture(); let tree = grouped(root).tree; let decoder = ResponseDecoder::new( root, ChunkRanges::all(), tree, Bytes::copy_from_slice(&data), ); let ResponseDecoderNext::More((next, Ok(BaoContentItem::Leaf(leaf)))) = decoder.next().await else { panic!("canonical leaf was rejected"); }; assert_eq!(leaf.offset, 0); assert_eq!(leaf.data.as_ref(), data); let ResponseDecoderNext::Done(remaining) = next.next().await else { panic!("unexpected extra item"); }; assert!(remaining.is_empty()); let decoder = ResponseDecoder::new(old, ChunkRanges::all(), tree, Bytes::from(data)); assert!(matches!( decoder.next().await, ResponseDecoderNext::More((, Err(DecodeError::LeafHashMismatch(ChunkNum(0))))) )); }

===== 041 END =====

===== 042 BEGIN Radio iroh-blobs/Cargo.toml | 3156 bytes | SHA256 cbf2f94e32cb76f6976b9f271231077da1eadeb9a8fea69636180bec5441c011 ===== [package] name = "iroh-blobs" version = "0.98.0" edition = "2021" description = "content-addressed blobs for iroh" license = "MIT OR Apache-2.0" authors = ["dignifiedquire me@dignifiedquire.com", "n0 team"] repository = "https://github.com/n0-computer/iroh-blobs" keywords = ["hashing", "poseidon2", "streaming"]

Sadly this also needs to be updated in .github/workflows/ci.yml

rust-version = "1.89"

[lints] workspace = true

[dependencies] cyber-bao = { path = "../cyber-bao", features = ["tokio_fsm", "serde"] } hemera = { workspace = true, features = ["std", "serde"] } bytes = { version = "1", features = ["serde"] } derive_more = { version = "2.0.1", features = ["from", "try_from", "into", "debug", "display", "deref", "deref_mut"] } futures-lite = "2.6.0" quinn = { package = "iroh-quinn", version = "0.16.0", optional = true } n0-future = "0.3.0" range-collections = { version = "0.4.6", features = ["serde"] } smallvec = { version = "1", features = ["serde", "const_new"] } tokio = { version = "1.43.0", default-features = false, features = ["sync"] } tracing = "0.1.41" iroh-io = "0.6.1" rand = "0.9.2" hex = "0.4.3" serde = "1.0.217" postcard = { version = "1.1.1", features = ["experimental-derive", "use-std"] } data-encoding = "2.8.0" ref-cast = "1.0.24" arrayvec = "0.7.6" iroh = { package = "cyber-radio", path = "../iroh", default-features = false } self_cell = "1.1.0" genawaiter = { version = "0.99.1", features = ["futures03"] } iroh-base = { package = "cyber-radio-base", path = "../iroh-base" } iroh-tickets = "0.3" irpc = { version = "0.12.0", features = ["spans", "stream", "derive", "varint-util"], default-features = false } iroh-metrics = { version = "0.38" } redb = { version = "2.6.3", optional = true } reflink-copy = { version = "0.1.24", optional = true } n0-error = "0.1.2" nested_enum_utils = "0.2.3"

non-wasm-in-browser dependencies

[target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dependencies] chrono = { version = "0.4.39" }

wasm-in-browser dependencies

[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies] chrono = {version = "0.4.39", default-features = false, features = ["js-sys", "wasmbind", "std"] }

[dev-dependencies] clap = { version = "4.5.31", features = ["derive"] } hex = "0.4.3" iroh-test = "0.31.0" proptest = "1.6.0" serde_json = "1.0.138" serde_test = "1.0.177" tempfile = "3.17.1" test-strategy = "0.4.0" testresult = "0.4.1" tracing-subscriber = { version = "0.3.20", features = ["fmt"] } tracing-test = "0.2.5" walkdir = "2.5.0" atomic_refcell = "0.1.13" iroh = { package = "cyber-radio", path = "../iroh", features = ["address-lookup-mdns"]} async-compression = { version = "0.4.30", features = ["lz4", "tokio"] } concat_const = "0.2.0" anyhow = "1.0.100"

[build-dependencies] cfg_aliases = "0.2.1"

[features] hide-proto-docs = [] metrics = [] default = ["hide-proto-docs", "fs-store", "rpc"] fs-store = ["dep:redb", "dep:reflink-copy"] rpc = ["dep:quinn", "irpc/rpc", "irpc/quinn_endpoint_setup"]

example name = "expiring-tags" required-features = ["fs-store"]

example name = "random_store" required-features = ["fs-store"]

===== 042 END =====

===== 043 BEGIN Radio particle/Cargo.toml | 367 bytes | SHA256 a80402ad3fce896380f81f4a510e7ef081c1a881043970a81c7b24e203996969 ===== [package] name = "particle" version = "0.1.0" edition = "2024" description = "CLI tool for Poseidon2 hashing and BAO verified streaming" license = "MIT OR Apache-2.0" rust-version = "1.89"

[lints] workspace = true

bin name = "particle" path = "src/main.rs"

[dependencies] hemera = { workspace = true, features = ["std"] } cyber-bao = { path = "../cyber-bao" }

===== 043 END =====

===== 044 BEGIN Radio radio-cli/Cargo.toml | 666 bytes | SHA256 5d2e24decf543ba918766c57dd5bd3f3224b871933c3f4fc51d2420461cfccc0 ===== [package] name = "radio-cli" version = "0.1.0" edition = "2021" description = "Radio network CLI — hash, node, blob, gossip" license = "MIT OR Apache-2.0"

bin name = "radio" path = "src/main.rs"

[lints] workspace = true

[dependencies] clap = { version = "4", features = ["derive"] } tokio = { version = "1", features = ["full"] } iroh = { package = "cyber-radio", path = "../iroh" } iroh-blobs = { path = "../iroh-blobs" } iroh-gossip = { path = "../iroh-gossip" } hemera = { workspace = true, features = ["std"] } cyber-bao = { path = "../cyber-bao" } anyhow = "1" futures-lite = "2" tracing-subscriber = "0.3" data-encoding = "2" bytes = "1" rand = "0.9"

===== 044 END =====

===== 045 BEGIN Radio tests/integration/Cargo.toml | 673 bytes | SHA256 ac74983dbeee09aed2222c0c6108e81f97a176e59a7b3db444b3d4e1e429b4a0 ===== [package] name = "radio-integration-tests" version = "0.1.0" edition = "2021" publish = false

[dependencies] iroh = { package = "cyber-radio", path = "../../iroh" } iroh-base = { package = "cyber-radio-base", path = "../../iroh-base" } iroh-blobs = { path = "../../iroh-blobs" } iroh-gossip = { path = "../../iroh-gossip" } iroh-docs = { path = "../../iroh-docs" } hemera = { package = "cyber-hemera", version = "0.1" } cyber-bao = { path = "../../cyber-bao" }

tokio = { version = "1", features = ["full"] } anyhow = "1" bytes = "1" rand = "0.9" rand_chacha = "0.9" futures-util = "0.3" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] }

===== 045 END =====

===== 046 BEGIN Radio iroh-docs/Cargo.toml | 2490 bytes | SHA256 fc5de9598d40d5265bbc36c4bc6bd7f38f55ba206bf0f717bfdf9b8e0e8b07c6 ===== [package] name = "iroh-docs" version = "0.96.0" edition = "2021" readme = "README.md" description = "Iroh sync" license = "MIT/Apache-2.0" authors = ["n0 team"] repository = "https://github.com/n0-computer/iroh-docs"

Sadly this also needs to be updated in .github/workflows/ci.yml

rust-version = "1.89"

[dependencies] anyhow = "1" async-channel = "2.3.1" hemera = { workspace = true, features = ["std"] } bytes = { version = "1.7", features = ["serde"] } derive_more = { version = "2.0.1", features = [ "debug", "deref", "display", "from", "from_str", "try_into", "into", "as_ref", ] } ed25519-dalek = { version = "3.0.0-pre.1", features = ["serde", "rand_core"] } futures-buffered = "0.2.4" futures-lite = "2.3.0" futures-util = { version = "0.3.25" } hex = "0.4" iroh = { package = "cyber-radio", version = "0.1", path = "../iroh" } iroh-tickets = { version = "0.2"} iroh-blobs = { version = "0.98", path = "../iroh-blobs" } iroh-gossip = { version = "0.96", path = "../iroh-gossip", features = ["net"] } iroh-metrics = { version = "0.38", default-features = false } irpc = { version = "0.12.0" } n0-future = "0.3" num_enum = "0.7" postcard = { version = "1", default-features = false, features = [ "alloc", "use-std", "experimental-derive", ] } quinn = { package = "iroh-quinn", version = "0.16.0" } rand = "0.9.2" redb = { version = "2.6.3" } self_cell = "1.0.3" serde = { version = "1.0.164", features = ["derive"] } serde-error = "0.1.3" strum = { version = "0.26", features = ["derive"] } tempfile = { version = "3.4" } thiserror = "2" tokio = { version = "1", features = ["sync", "rt", "time", "io-util"] } tokio-stream = { version = "0.1", features = ["sync"] } tokio-util = { version = "0.7.12", features = ["codec", "io-util", "io", "rt"] } tracing = "0.1" n0-error = "0.1.0"

[dev-dependencies] data-encoding = "2.6.0" iroh = { package = "cyber-radio", version = "0.1", path = "../iroh", features = ["test-utils"] } nested_enum_utils = "0.2" parking_lot = "0.12.3" proptest = "1.2.0" rand_chacha = "0.9" tempfile = "3.4" test-strategy = "0.4" testdir = "0.7" testresult = "0.4.1" tokio = { version = "1", features = ["sync", "macros"] } tracing-subscriber = { version = "0.3.20", features = ["env-filter"] } tracing-test = "0.2.5"

[features] default = ["metrics"] metrics = ["iroh-metrics/metrics", "iroh/metrics"]

[package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "iroh_docsrs"]

[lints] workspace = true

===== 046 END =====

===== 047 BEGIN Radio iroh-blobs/src/api/blobs/export_pairs.rs | 13409 bytes | SHA256 96914dc66c602b6e0bc9cf29a5287a84214b514be367ca96eef0b637079eb9c2 ===== //! Exercise the actual exporter with literal pairs and an independent store proof. mod support;

use std::io;

use cyber_bao::{ io::{slice::decode_slice, EncodeError}, Poseidon2Backend, CHUNK_SIZE, }; use n0_future::StreamExt; use support::*;

use super::{EncodedItem, ExportBaoProgress}; use crate::{ api::{Error, ExportBaoError}, provider::events::ProgressError, store::{readonly_mem::ReadonlyMemStore, IROH_BLOCK_SIZE}, };

async fn chunks(export: ExportBaoProgress) -> Vec<Vec> { let mut stream = export.into_byte_stream(); let mut chunks = Vec::new(); while let Some(item) = stream.next().await { chunks.push(item.unwrap().to_vec()); } chunks }

#[test] fn geometry_pins() { assert_eq!(geometry(), (65536, 16)); }

#[tokio::test] async fn root_policy_readonly_memory_key_and_wire() { let (data, root, wire) = root_policy_fixture(); let store = ReadonlyMemStore::new([&data]); let keys = store.list().hashes().await.unwrap(); assert_eq!(keys, [root]); assert_eq!(root, crate::Hash::new(&data)); assert_eq!( store .export_bao(keys[0], ranges(0, 2)) .bao_to_vec() .await .unwrap(), wire ); assert_eq!(store.get_bytes(keys[0]).await.unwrap().as_ref(), data); store.shutdown().await.unwrap(); }

#[tokio::test] async fn root_policy_mutable_memory_key_and_wire() { let (data, root, wire) = root_policy_fixture(); let store = crate::store::mem::MemStore::new(); let added = store.add_bytes(data.clone()).await.unwrap(); assert_eq!(added.hash, root); assert_eq!(store.list().hashes().await.unwrap(), [root]); assert_eq!(root, crate::Hash::new(&data)); assert_eq!( store .export_bao(added.hash, ranges(0, 2)) .bao_to_vec() .await .unwrap(), wire ); assert_eq!(store.get_bytes(added.hash).await.unwrap().as_ref(), data); store.shutdown().await.unwrap(); }

#[cfg(feature = "fs-store")] #[tokio::test] async fn root_policy_tiny_and_streamed_fs_import_agree() { use crate::store::fs::{options::Options, FsStore};

let (data, root, wire) = root_policy_fixture();
let mut keys = Vec::new();
for (max_data_inlined, inlined) in [(32768, true), (4096, false)] {
    let dir = tempfile::tempdir().unwrap();
    let mut options = Options::new(dir.path());
    options.inline.max_data_inlined = max_data_inlined;
    options.inline.max_outboard_inlined = 16384;
    assert_eq!(options.is_inlined_all(8192), inlined);
    let store = FsStore::load_with_opts(dir.path().join("blobs.db"), options)
        .await
        .unwrap();
    let added = store.add_bytes(data.clone()).await.unwrap();
    keys.push(added.hash);
    assert_eq!(added.hash, root);
    assert_eq!(store.get_bytes(added.hash).await.unwrap().as_ref(), data);
    assert_eq!(
        store
            .export_bao(added.hash, ranges(0, 2))
            .bao_to_vec()
            .await
            .unwrap(),
        wire
    );
    store.shutdown().await.unwrap();
}
assert_eq!(keys, [root, root]);
assert_eq!(root, crate::Hash::new(&data));

}

#[tokio::test] async fn literal_parent_write() { let mut bytes = Vec::new(); scripted(literal_items()) .await .write(&mut bytes) .await .unwrap(); assert_eq!(bytes, literal_wire()); }

#[tokio::test] async fn literal_parent_progress() { let mut sink = Sink::default(); let mut progress = Progress::default(); scripted(literal_items()) .await .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap(); assert_eq!(sink.bytes, literal_wire()); assert_eq!(progress.starts, [(INDEX, identity(), 100)]); assert_eq!(progress.overhead, 72); assert_eq!(progress.payloads, [(INDEX, OFFSET, PAYLOAD.len())]); }

#[tokio::test] async fn literal_parent_byte_stream() { let chunks = chunks(scripted(literal_items()).await).await; assert_eq!( chunks.iter().map(Vec::len).collect::<Vec<_>>(), [8, 64, PAYLOAD.len()] ); assert_eq!(chunks.concat(), literal_wire()); }

#[tokio::test] async fn readonly_store_right_block() { let (data, root, expected) = right_fixture(); let (block, count) = geometry(); assert_eq!(expected.len(), 8 + 2 * hemera::OUTPUT_BYTES + block); // Optional evidence output is only enabled by the isolated audit command. if let Some(dir) = std::env::var_os("RADIO_EXPORT_PAIRS_FIXTURE_DIR") { let dir = std::path::PathBuf::from(dir); std::fs::write(dir.join("right-proof.bin"), &expected).unwrap(); std::fs::write(dir.join("right-root.txt"), root.to_string()).unwrap(); } let store = ReadonlyMemStore::new([&data]); let query = ranges(count, 2 * count); let mut written = Vec::new(); store .export_bao(root, query.clone()) .write(&mut written) .await .unwrap(); assert_eq!(written, expected); let mut sink = Sink::default(); let mut progress = Progress::default(); store .export_bao(root, query.clone()) .write_with_progress(&mut sink, &mut progress, &root.into(), INDEX) .await .unwrap(); assert_eq!(sink.bytes, expected); assert_eq!(progress.starts, [(INDEX, root.into(), data.len() as u64)]); assert_eq!(progress.overhead, 72); assert_eq!(progress.payloads, [(INDEX, block as u64, block)]); let chunks = chunks(store.export_bao(root, query.clone())).await; assert_eq!( chunks.iter().map(Vec::len).collect::<Vec<_>>(), [8, 64, block] ); assert_eq!(chunks.concat(), expected); let decoded = decode_slice(&Poseidon2Backend, &written, &root, &query, IROH_BLOCK_SIZE).unwrap(); assert_eq!(decoded, [(block as u64, data[block..].to_vec())]); store.shutdown().await.unwrap(); }

#[tokio::test] async fn readonly_store_parent_free() { geometry(); let data = body(CHUNK_SIZE); let root = hemera::tree::chunk_cv(&data, 0, true); let mut expected = (CHUNK_SIZE as u64).to_le_bytes().to_vec(); expected.extend_from_slice(&data); let store = ReadonlyMemStore::new([&data]); let mut written = Vec::new(); store .export_bao(root, ranges(0, 1)) .write(&mut written) .await .unwrap(); assert_eq!(written, expected); let mut sink = Sink::default(); let mut progress = Progress::default(); store .export_bao(root, ranges(0, 1)) .write_with_progress(&mut sink, &mut progress, &root.into(), INDEX) .await .unwrap(); assert_eq!(sink.bytes, expected); assert_eq!(progress.overhead, 8); assert_eq!(progress.payloads, [(INDEX, 0, CHUNK_SIZE)]); let chunks = chunks(store.export_bao(root, ranges(0, 1))).await; assert_eq!( chunks.iter().map(Vec::len).collect::<Vec<_>>(), [8, CHUNK_SIZE] ); assert_eq!(chunks.concat(), expected); store.shutdown().await.unwrap(); }

fn check_inner(error: ExportBaoError, kind: io::ErrorKind, detail: &str) { let ExportBaoError::ExportBaoInner { source: EncodeError::Io(source), .. } = error else { panic!("expected encoded I/O error: {error:?}"); }; assert_eq!(source.kind(), kind); assert_eq!(source.to_string(), detail); }

fn check_sink(error: ExportBaoError) { let ExportBaoError::ExportBaoIo { source, .. } = error else { panic!("expected sink I/O error: {error:?}"); }; assert_eq!(source.kind(), io::ErrorKind::BrokenPipe); assert_eq!(source.to_string(), "pair sink failure"); }

fn error_items() -> Vec { let mut items = literal_items(); items.truncate(2); items.push(EncodedItem::Error(EncodeError::Io(io::Error::new( io::ErrorKind::InvalidData, "encoded sentinel", )))); items }

#[tokio::test] async fn encoded_error_propagates() { let mut bytes = Vec::new(); check_inner( scripted(error_items()) .await .write(&mut bytes) .await .unwrap_err(), io::ErrorKind::InvalidData, "encoded sentinel", ); assert_eq!(bytes, literal_wire()[..72]); let mut sink = Sink::default(); let mut progress = Progress::default(); check_inner( scripted(error_items()) .await .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap_err(), io::ErrorKind::InvalidData, "encoded sentinel", ); assert_eq!(sink.bytes, bytes); assert_eq!(progress.overhead, 72); assert!(progress.payloads.is_empty()); let mut stream = scripted(error_items()).await.into_byte_stream(); let mut prefix = Vec::new(); for _ in 0..2 { prefix.extend_from_slice(&stream.next().await.unwrap().unwrap()); } let Error::Io(source) = stream.next().await.unwrap().unwrap_err(); assert_eq!(prefix, bytes); assert_eq!(source.kind(), io::ErrorKind::InvalidData); assert_eq!(source.to_string(), "encoded sentinel"); assert!(stream.next().await.is_none()); }

#[tokio::test] async fn readonly_store_missing() { let store = ReadonlyMemStore::new([b"present"]); let detail = "export task ended unexpectedly"; let mut bytes = Vec::new(); check_inner( store .export_bao(identity(), ranges(0, 1)) .write(&mut bytes) .await .unwrap_err(), io::ErrorKind::UnexpectedEof, detail, ); assert!(bytes.is_empty()); let mut sink = Sink::default(); let mut progress = Progress::default(); check_inner( store .export_bao(identity(), ranges(0, 1)) .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap_err(), io::ErrorKind::UnexpectedEof, detail, ); assert!(sink.bytes.is_empty()); assert!(progress.starts.is_empty()); assert_eq!(progress.overhead, 0); assert!(progress.payloads.is_empty()); let mut stream = store .export_bao(identity(), ranges(0, 1)) .into_byte_stream(); let Error::Io(source) = stream.next().await.unwrap().unwrap_err(); assert_eq!(source.kind(), io::ErrorKind::UnexpectedEof); assert_eq!(source.to_string(), detail); assert!(stream.next().await.is_none()); store.shutdown().await.unwrap(); }

#[tokio::test] async fn writer_failure_accounting() { for (call, overhead) in [(0, 0), (1, 8), (2, 72)] { let mut sink = Sink { fail_call: Some(call), ..Sink::default() }; check_sink( scripted(literal_items()) .await .write(&mut sink) .await .unwrap_err(), ); assert_eq!(sink.calls, call + 1); assert_eq!(sink.bytes, literal_wire()[..overhead]); let mut sink = Sink { fail_call: Some(call), ..Sink::default() }; let mut progress = Progress::default(); check_sink( scripted(literal_items()) .await .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap_err(), ); assert_eq!(sink.calls, call + 1); assert_eq!(sink.bytes, literal_wire()[..overhead]); assert_eq!(progress.overhead, overhead); assert_eq!(progress.starts, [(INDEX, identity(), 100)]); assert!(progress.payloads.is_empty()); } }

#[tokio::test] async fn partial_parent_failure() { for use_progress in [false, true] { let mut sink = Sink { fail_call: Some(1), partial: 17, ..Sink::default() }; let mut progress = Progress::default(); let export = scripted(literal_items()).await; let error = if use_progress { export .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap_err() } else { export.write(&mut sink).await.unwrap_err() }; check_sink(error); assert_eq!(sink.bytes, literal_wire()[..25]); assert_eq!(sink.calls, 2); assert_eq!(progress.overhead, if use_progress { 8 } else { 0 }); assert!(progress.payloads.is_empty()); } }

#[tokio::test] async fn payload_progress_failure() { let mut items = literal_items(); items.pop(); items.extend(literal_items().into_iter().skip(2)); let mut sink = Sink::default(); let mut progress = Progress { reject_payload: true, ..Progress::default() }; let error = scripted(items) .await .write_with_progress(&mut sink, &mut progress, &identity(), INDEX) .await .unwrap_err(); assert!(matches!( error, ExportBaoError::ClientError { source: ProgressError::Permission { .. }, .. } )); assert_eq!(sink.bytes, literal_wire()); assert_eq!(sink.calls, 3); assert_eq!(progress.overhead, 72); assert_eq!(progress.payloads, [(INDEX, OFFSET, PAYLOAD.len())]); }

===== 047 END =====

===== 048 BEGIN Radio .config/nextest.toml | 594 bytes | SHA256 ef588b7e34ddd981c24a523ba359ec76a616a45b40f3f3f525692ae809aea590 ===== [test-groups] run-in-isolation = { max-threads = 32 }

these are tests that must not run with other tests concurrently. All tests in

this group can take up at most 32 threads among them, but each one requiring

16 threads also. The effect should be that tests run isolated.

profile.ci.overrides filter = 'test(::run_in_isolation::)' test-group = 'run-in-isolation' threads-required = 32

profile.default.overrides filter = 'test(::run_in_isolation::)' test-group = 'run-in-isolation' threads-required = 32

[profile.default] slow-timeout = { period = "10s", terminate-after = 3 }

===== 048 END =====

===== 049 BEGIN Radio Makefile.toml | 662 bytes | SHA256 0f1e457aa4bb7c6e4674d2dfbd847b58344319a1242625c2f055241ebd048d8d =====

Use cargo-make to run tasks here: https://crates.io/crates/cargo-make

[tasks.format] workspace = false command = "cargo" args = [ "fmt", "--all", "--", "--config", "unstable_features=true", "--config", "imports_granularity=Crate,group_imports=StdExternalCrate,reorder_imports=true,format_code_in_doc_comments=true", ]

[tasks.format-check] workspace = false command = "cargo" args = [ "fmt", "--all", "--check", "--", "--config", "unstable_features=true", "--config", "imports_granularity=Crate,group_imports=StdExternalCrate,reorder_imports=true,format_code_in_doc_comments=true", ]

===== 049 END =====

===== 050 BEGIN Radio .github/workflows/ci.yml | 11846 bytes | SHA256 ded5a95996283b54293810ab4938dadc1d589fab73be85397ad9c3435b203208 ===== name: CI

on: pull_request: types: ["labeled", "unlabeled", "opened", "synchronize", "reopened"] merge_group: push: branches: - main

concurrency: group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true

env: RUST_BACKTRACE: 1 RUSTFLAGS: -Dwarnings RUSTDOCFLAGS: -Dwarnings MSRV: "1.89" SCCACHE_CACHE_SIZE: "10G" IROH_FORCE_STAGING_RELAYS: "1"

jobs: tests: name: CI Test Suite if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" uses: "./.github/workflows/tests.yaml"

cross_build: name: Cross Build Only if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" timeout-minutes: 30 runs-on: [self-hosted, linux, X64] strategy: fail-fast: false matrix: target: # cross tests are currently broken vor armv7 and aarch64 # see https://github.com/cross-rs/cross/issues/1311 # - armv7-linux-androideabi # - aarch64-linux-android # Freebsd execution fails in cross # - i686-unknown-freebsd # Linking fails :/ - x86_64-unknown-freebsd # Netbsd execution fails to link in cross # - x86_64-unknown-netbsd steps: - name: Checkout uses: actions/checkout@v6 with: submodules: recursive

  - name: Install rust stable
    uses: dtolnay/rust-toolchain@stable

  - name: Cleanup Docker
    continue-on-error: true
    run: |
      docker kill $(docker ps -q)

    # See https://github.com/cross-rs/cross/issues/1222
  - name: Cache cross
    id: cache-cross
    uses: actions/cache@v5
    with:
      path: ~/.cargo/bin/cross
      key: cross-${{ runner.os }}-${{ runner.arch }}

  - name: Install cross
    if: steps.cache-cross.outputs.cache-hit != 'true'
    uses: taiki-e/install-action@cross

  - name: build
    # cross tests are currently broken vor armv7 and aarch64
    # see https://github.com/cross-rs/cross/issues/1311.  So on
    # those platforms we only build but do not run tests.
    run: cross build --all --target ${{ matrix.target }}
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
      CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: cc

android_build: name: Android Build Only if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" timeout-minutes: 30 # runs-on: ubuntu-latest runs-on: [self-hosted, linux, X64] strategy: fail-fast: false matrix: target: - aarch64-linux-android - armv7-linux-androideabi steps: - name: Checkout uses: actions/checkout@v6

  - name: Set up Rust
    uses: dtolnay/rust-toolchain@stable
    with:
      target: ${{ matrix.target }}
  - name: Install rustup target
    run: rustup target add ${{ matrix.target }}

  - name: Setup Java
    uses: actions/setup-java@v5
    with:
      distribution: "temurin"
      java-version: "17"

  - name: Setup Android SDK
    uses: android-actions/setup-android@v3

  - name: Setup Android NDK
    uses: arqu/setup-ndk@main
    id: setup-ndk
    with:
      ndk-version: r23
      add-to-path: true

  - name: Build
    env:
      ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
    run: |
      cargo install --version 3.5.4 cargo-ndk
      cargo ndk --target ${{ matrix.target }} build

cross_test: name: Cross Test if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" timeout-minutes: 30 runs-on: [self-hosted, linux, X64] strategy: fail-fast: false matrix: target: - i686-unknown-linux-gnu steps: - name: Checkout uses: actions/checkout@v6 with: submodules: recursive

  - name: Install rust stable
    uses: dtolnay/rust-toolchain@stable

  - name: Cleanup Docker
    continue-on-error: true
    run: |
      docker kill $(docker ps -q)

    # See https://github.com/cross-rs/cross/issues/1222
  - name: Cache cross
    id: cache-cross
    uses: actions/cache@v5
    with:
      path: ~/.cargo/bin/cross
      key: cross-${{ runner.os }}-${{ runner.arch }}

  - name: Install cross
    if: steps.cache-cross.outputs.cache-hit != 'true'
    uses: taiki-e/install-action@cross

  - name: test
    run: cross test --all --target ${{ matrix.target }} -- --test-threads=12
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG' }}
      CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: cc

wasm_test: name: Build & test wasm32 for browsers runs-on: ubuntu-latest env: RUSTFLAGS: '--cfg getrandom_backend="wasm_js"' steps: - name: Checkout sources uses: actions/checkout@v6

  - name: Setup node.js version 22.5 # needed for browser-like websocket API support in node.js
    uses: actions/setup-node@v6
    with:
      node-version: 22.5

  - name: Install stable toolchain
    uses: dtolnay/rust-toolchain@stable

  - name: Add wasm target
    run: rustup target add wasm32-unknown-unknown

  - name: Install cargo-binstall
    uses: cargo-bins/cargo-binstall@v1.16.5

  - name: Install wasm-bindgen-test-runner
    run: cargo binstall wasm-bindgen-cli --locked --no-confirm

  - name: Install wasm-tools
    uses: bytecodealliance/actions/wasm-tools/setup@v1

  - name: wasm32 build (iroh-base)
    run: cargo build --target wasm32-unknown-unknown -p iroh-base --all-features

  - name: wasm32 build (iroh-relay)
    run: cargo build --target wasm32-unknown-unknown -p iroh-relay --no-default-features

  - name: wasm32 build (iroh)
    run: cargo build --target wasm32-unknown-unknown -p iroh --no-default-features

  # If the Wasm file contains any 'import "env"' declarations, then
  # some non-Wasm-compatible code made it into the final code.
  - name: Ensure no 'import "env"' in iroh-relay Wasm
    run: |
      ! wasm-tools print --skeleton target/wasm32-unknown-unknown/debug/iroh_relay.wasm | grep 'import "env"'

  - name: Ensure no 'import "env"' in iroh Wasm
    run: |
      ! wasm-tools print --skeleton target/wasm32-unknown-unknown/debug/iroh.wasm | grep 'import "env"'

  - name: Run integration test in wasm
    run: cargo test -p iroh --test integration --target=wasm32-unknown-unknown --no-default-features

check_semver: runs-on: ubuntu-latest env: RUSTC_WRAPPER: "sccache" SCCACHE_GHA_ENABLED: "on" steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Install sccache uses: mozilla-actions/sccache-action@v0.0.9

  - name: Setup Environment (PR)
    if: ${{ github.event_name == 'pull_request' }}
    shell: bash
    run: |
      echo "HEAD_COMMIT_SHA=$(git rev-parse origin/${{ github.base_ref }})" >> ${GITHUB_ENV}
  - name: Setup Environment (Push)
    if: ${{ github.event_name == 'push' || github.event_name == 'merge_group' }}
    shell: bash
    run: |
      echo "HEAD_COMMIT_SHA=$(git rev-parse origin/main)" >> ${GITHUB_ENV}
  - name: Check semver
    # uses: obi1kenobi/cargo-semver-checks-action@v2
    uses: n0-computer/cargo-semver-checks-action@feat-baseline
    with:
      package: iroh, iroh-base, iroh-dns-server, iroh-bench, iroh-relay, iroh-net-report
      baseline-rev: ${{ env.HEAD_COMMIT_SHA }}
      use-cache: false

check_fmt: timeout-minutes: 30 name: Checking fmt runs-on: ubuntu-latest env: RUSTC_WRAPPER: "sccache" SCCACHE_GHA_ENABLED: "on" steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable with: components: rustfmt - uses: mozilla-actions/sccache-action@v0.0.9 - uses: taiki-e/install-action@cargo-make - run: cargo make format-check

check_docs: timeout-minutes: 30 name: Checking docs runs-on: ubuntu-latest env: RUSTC_WRAPPER: "sccache" SCCACHE_GHA_ENABLED: "on" RUSTDOCFLAGS: --cfg docsrs steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@master with: toolchain: nightly-2025-10-09 - name: Install sccache uses: mozilla-actions/sccache-action@v0.0.9

  - name: Docs
    run: cargo doc --workspace --all-features --no-deps --document-private-items

clippy_check: timeout-minutes: 30 runs-on: ubuntu-latest env: RUSTC_WRAPPER: "sccache" SCCACHE_GHA_ENABLED: "on" steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@stable with: components: clippy - name: Install sccache uses: mozilla-actions/sccache-action@v0.0.9

  # TODO: We have a bunch of platform-dependent code so should
  #    probably run this job on the full platform matrix
  - name: clippy check (all features)
    run: cargo clippy --workspace --all-features --all-targets --lib --bins --tests --benches --examples

  - name: clippy check (no features)
    run: cargo clippy --workspace --no-default-features --all-targets --lib --bins --tests --benches --examples

  - name: clippy check (default features)
    run: cargo clippy --workspace --all-targets --lib --bins --tests --benches --examples

msrv: if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" timeout-minutes: 30 name: Minimal Supported Rust Version runs-on: ubuntu-latest env: RUSTC_WRAPPER: "sccache" SCCACHE_GHA_ENABLED: "on" steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ env.MSRV }} - name: Install sccache uses: mozilla-actions/sccache-action@v0.0.9

  - name: Check MSRV all features
    run: |
      cargo +$MSRV check --workspace --all-targets

cargo_deny: timeout-minutes: 30 name: cargo deny runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: EmbarkStudios/cargo-deny-action@v2 with: arguments: --workspace --all-features command: check command-arguments: "-Dwarnings"

netsim-integration-tests: permissions: write-all if: "github.event_name != 'pull_request' || ! contains(github.event.pull_request.labels.*.name, 'flaky-test')" uses: "./.github/workflows/netsim_runner.yaml" secrets: inherit with: branch: ${{ github.ref }} max_workers: 6 netsim_branch: "main" sim_paths: ${{ github.event_name == 'pull_request' && 'sims/integration' || 'sims/iroh/iroh.json,sims/integration' }} pr_number: ${{ github.event.pull_request.number || '' }} filter: ${{ github.event_name == 'pull_request' && 'skip:intg_iroh_full__1_to_3,intg_iroh_full__1_to_1x3,intg_iroh_relay_only__1_to_3' || '' }}

codespell: timeout-minutes: 30 runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Cache pip uses: actions/cache@v5 with: path: ~/.cache/pip key: pip-codespell-2.4.1 - run: pip install --user codespell[toml]==2.4.1 - run: codespell --ignore-words-list=ans,atmost,crate,inout,ratatui,ser,stayin,swarmin,worl,keep-alives --skip=CHANGELOG.md

===== 050 END =====

===== 051 BEGIN Radio .github/workflows/tests.yaml | 10418 bytes | SHA256 749952dae052754d58ca44b060dac25431a507f5ddf9e854e2c54a91084b5a6b =====

Run all tests, with or without flaky tests.

name: Tests

on: workflow_call: inputs: rust-version: description: "The version of the rust compiler to run" type: string default: "stable" flaky: description: "Whether to also run flaky tests" type: boolean default: false git-ref: description: "Which git ref to checkout" type: string default: ${{ github.ref }}

env: RUST_BACKTRACE: 1 RUSTFLAGS: -Dwarnings RUSTDOCFLAGS: -Dwarnings SCCACHE_CACHE_SIZE: "10G" CRATES_LIST: "iroh,iroh-bench,iroh-dns-server,iroh-relay" IROH_FORCE_STAGING_RELAYS: "1" NEXTEST_VERSION: "0.9.80"

jobs: build_and_test_nix: timeout-minutes: 30 name: "Tests" runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: name: [ubuntu-latest, macOS-arm-latest] rust: ["${{ inputs.rust-version }}"] features: [all, none, default] include: - name: ubuntu-latest os: ubuntu-latest release-os: linux release-arch: amd64 runner: [self-hosted, linux, X64] - name: macOS-arm-latest os: macOS-latest release-os: darwin release-arch: aarch64 runner: [self-hosted, macOS, ARM64] env: # Using self-hosted runners so use local cache for sccache and # not SCCACHE_GHA_ENABLED. RUSTC_WRAPPER: "sccache" steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ inputs.git-ref }}

  - name: Install ${{ matrix.rust }} rust
    uses: dtolnay/rust-toolchain@master
    with:
      toolchain: ${{ matrix.rust }}

  - name: Install cargo-nextest
    uses: taiki-e/install-action@v2
    with:
      tool: nextest@${{ env.NEXTEST_VERSION }}

  - name: Install sccache
    uses: mozilla-actions/sccache-action@v0.0.9

  - name: Select features
    run: |
      case "${{ matrix.features }}" in
          all)
              echo "FEATURES=--all-features" >> "$GITHUB_ENV"
              ;;
          none)
              echo "FEATURES=--no-default-features" >> "$GITHUB_ENV"
              ;;
          default)
              echo "FEATURES=" >> "$GITHUB_ENV"
              ;;
          *)
              exit 1
      esac

  - name: check features
    if: ${{ ! inputs.flaky }}
    run: |
      for i in ${CRATES_LIST//,/ }
      do
        echo "Checking $i $FEATURES"
        targets="--lib --bins"
        echo cargo check -p $i $FEATURES $targets
        cargo check -p $i $FEATURES $targets
      done
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}

  - name: build tests
    run: |
      cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --no-run

  - name: list ignored tests
    run: |
      cargo nextest list --workspace ${{ env.FEATURES }} --lib --bins --tests --run-ignored ignored-only

  - name: run tests
    run: |
      mkdir -p output
      cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --profile ci --run-ignored ${{ inputs.flaky && 'all' || 'default' }} ${{ inputs.flaky && '--verbose' || '' }} --no-fail-fast --message-format ${{ inputs.flaky && 'libtest-json' || 'human' }} > output/${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
      NEXTEST_EXPERIMENTAL_LIBTEST_JSON: 1

  - name: upload results
    if: ${{ failure() && inputs.flaky }}
    uses: actions/upload-artifact@v6
    with:
      name: libtest_run_${{ github.run_number }}-${{ github.run_attempt }}-${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
      path: output
      retention-days: 45
      compression-level: 0

  - name: doctests
    if: ${{ (! inputs.flaky) &&  matrix.features == 'all' }}
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
    run: |
      cargo test --workspace --all-features --doc

  # We can not check the doctest features by only compiling them,
  # so are forced to run them once more.
  - name: Check doctest features
    if: ${{ ! inputs.flaky }}
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
    run: |
      for i in ${CRATES_LIST//,/ }
      do
        echo "Checking $i doctest $FEATURES"
        echo cargo test -p $i --doc $FEATURES
        cargo test -p $i --doc $FEATURES
      done

build_and_test_windows: timeout-minutes: 30 name: "Tests" runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: name: [windows-latest] rust: ["${{ inputs.rust-version}}"] features: [all, none, default] target: - x86_64-pc-windows-msvc include: - name: windows-latest os: windows runner: [self-hosted, windows, x64] env: # Using self-hosted runners so use local cache for sccache and # not SCCACHE_GHA_ENABLED. RUSTC_WRAPPER: "sccache" steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ inputs.git-ref }}

  - name: Install ${{ matrix.rust }}
    run: |
      rustup toolchain install ${{ matrix.rust }}
      rustup toolchain default ${{ matrix.rust }}
      rustup target add ${{ matrix.target }}
      rustup set default-host ${{ matrix.target }}

  - name: Cache cargo-nextest
    id: cache-nextest
    uses: actions/cache@v5
    with:
      path: ~/.cargo/bin/cargo-nextest.exe
      key: nextest-windows-${{ env.NEXTEST_VERSION }}

  - name: Install cargo-nextest
    if: steps.cache-nextest.outputs.cache-hit != 'true'
    shell: powershell
    run: |
      $tmp = New-TemporaryFile | Rename-Item -NewName { $_ -replace 'tmp$', 'zip' } -PassThru
      Invoke-WebRequest -OutFile $tmp https://get.nexte.st/${{ env.NEXTEST_VERSION }}/windows
      $outputDir = if ($Env:CARGO_HOME) { Join-Path $Env:CARGO_HOME "bin" } else { "~/.cargo/bin" }
      $tmp | Expand-Archive -DestinationPath $outputDir -Force
      $tmp | Remove-Item

  - name: Select features
    run: |
      switch ("${{ matrix.features }}") {
          "all" {
              echo "FEATURES=--all-features" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
          }
          "none" {
              echo "FEATURES=--no-default-features" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
          }
          "default" {
              echo "FEATURES=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
          }
          default {
              Exit 1
          }
      }

  - name: Install sccache
    uses: mozilla-actions/sccache-action@v0.0.9

  - uses: msys2/setup-msys2@v2
    with:
      release: false

  - name: build tests
    run: |
      cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --target ${{ matrix.target }} --no-run

  - name: list ignored tests
    run: |
      cargo nextest list --workspace ${{ env.FEATURES }} --lib --bins --tests --target ${{ matrix.target }} --run-ignored ignored-only

  - name: tests
    run: |
      mkdir -p output
      cargo nextest run --workspace ${{ env.FEATURES }} --lib --bins --tests --profile ci --target ${{ matrix.target }} --run-ignored ${{ inputs.flaky && 'all' || 'default' }} --no-fail-fast --message-format ${{ inputs.flaky && 'libtest-json' || 'human' }} > output/${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
    env:
      RUST_LOG: ${{ runner.debug && 'TRACE' || 'DEBUG'}}
      NEXTEST_EXPERIMENTAL_LIBTEST_JSON: 1

  - name: upload results
    if: ${{ failure() && inputs.flaky }}
    uses: actions/upload-artifact@v6
    with:
      name: libtest_run_${{ github.run_number }}-${{ github.run_attempt }}-${{ matrix.name }}_${{ matrix.features }}_${{ matrix.rust }}.json
      path: output
      retention-days: 1
      compression-level: 0

minimal-crates: runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: name: [ubuntu-latest, macOS-arm-latest] # TODO: windows include: - name: ubuntu-latest os: ubuntu-latest release-os: linux release-arch: amd64 runner: [self-hosted, linux, X64] - name: macOS-arm-latest os: macOS-latest release-os: darwin release-arch: aarch64 runner: [self-hosted, macOS, ARM64] steps: - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@nightly - name: cargo check run: | rm -f Cargo.lock cargo +nightly check -Z minimal-versions --workspace --all-features --lib --bins

minimal-crates-windows: timeout-minutes: 30 name: "Minimal Crates (Windows)" runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: name: [windows-latest] rust: ["${{ inputs.rust-version}}"] target: - x86_64-pc-windows-msvc include: - name: windows-latest os: windows runner: [self-hosted, windows, x64] env: # Using self-hosted runners so use local cache for sccache and # not SCCACHE_GHA_ENABLED. RUSTC_WRAPPER: "sccache" steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ inputs.git-ref }}

  - name: Install Rust nightly
    run: |
      rustup toolchain install nightly
      rustup target add ${{ matrix.target }}
      rustup set default-host ${{ matrix.target }}

  - name: Install sccache
    uses: mozilla-actions/sccache-action@v0.0.9

  - uses: msys2/setup-msys2@v2
    with:
      release: false

  - name: cargo check
    run: |
      rm -Force Cargo.lock
      cargo +nightly check -Z minimal-versions --workspace --all-features --lib --bins

===== 051 END =====

===== 052 BEGIN Kadek kadek-ifac/src/provenance/anchor.rs | 6443 bytes | SHA256 93ef654721a60df46d6bd716dfca483f30ac4c3e696d4c061d346bfab1b4188d ===== use super::{Particle, VerifiedBody}; use crate::{Error, ErrorKind, Result, WorkBudget, WorkLimits}; use core::fmt; use cyber_bao::{group::GroupHasher, Poseidon2Backend, CHUNK_SIZE};

static BACKEND: Poseidon2Backend = Poseidon2Backend; const _: () = assert!(CHUNK_SIZE == 4096);

/// The complete-root semantics carried by a sealed [BaoAnchor]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum BaoRootProfile { /// Canonical complete-left tree over fixed 4096-byte chunks, absolute chunk /// counters from zero, and a final short chunk. ROOT applies only to the /// final parent or sole leaf; empty input is one empty ROOT leaf. /// /// Parameters and domains are Hemera d5f0a095's /// tree, /// capacity /// and parameters, /// using the concrete kernels accepted at that revision. A semantic change /// requires a new profile identity; retaining V1 preserves outputs, domains /// and geometry. This is neither CDC nor the plain particle hash. Historical /// grouped values missing ROOT are not V1 roots. Proof grouping and wire /// validation remain separate from this complete-file identity. HemeraFixed4096V1, }

/// In-process association derived exclusively from one verified complete body. /// The particle and tree root each identify the same immutable bytes, using /// their separately pinned algorithms. Neither digest substitutes for the other. /// /// Only successful [BaoAnchorJob] completion creates this fixed value. It /// retains no body allocation and is useful for warm-cache reuse. Authenticating /// an unseen particle's first partial download or restoring a saved mapping /// requires an independently authenticated association or complete-body /// reverification. This capability alone admits no byte range or packet. #[doc = include_str!("anchor/seals.md")] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct BaoAnchor { particle: Particle, len: u64, root: [u8; 32], }

impl BaoAnchor { pub const fn particle(&self) -> Particle { self.particle }

/// Complete body length in bytes.
pub const fn len(&self) -> u64 {
    self.len
}

pub const fn is_empty(&self) -> bool {
    self.len == 0
}

pub const fn root(&self) -> &[u8; 32] {
    &self.root
}

pub const fn profile(&self) -> BaoRootProfile {
    BaoRootProfile::HemeraFixed4096V1
}

}

/// Borrowed, single-shot complete-body anchor derivation with persistent work. /// One unit is one leaf kernel over at most 4096 bytes or one two-child parent /// kernel. For N=max(1,ceil(len/4096)), the exact total is 2*N-1. These units do /// not measure CPU time and differ from [crate::BodyVerifier]'s absorb units. /// /// Construction preflights the total before hashing. Scalar checks and the /// reducer's fixed 53-slot initialization are bounded setup. No allocation, /// additional body owner or pool reservation is needed. Dropping an unfinished /// job abandons derivation. Drop the job before releasing its borrowed body; /// a completed anchor has no lifetime or retained owner. pub struct BaoAnchorJob<'a> { particle: Particle, len: u64, reducer: GroupHasher<'a, Poseidon2Backend>, work: WorkBudget, }

impl<'a> BaoAnchorJob<'a> { /// Borrow exactly the verified owner's immutable complete storage. /// Insufficient total work or unrepresentable length/geometry returns /// LimitExceeded with process bao.anchor and no fabricated byte offset. pub fn new(body: &'a VerifiedBody, limits: WorkLimits) -> Result { let len = u64::try_from(body.body.len()) .map_err(|| limit_error("BAO anchor body length does not fit file coordinates"))?; if kernel_count(len)? > limits.max_total() { return Err(limit_error("BAO anchor work limit")); } let reducer = GroupHasher::new(&BACKEND, &body.body, 0, true) .map_err(|| limit_error("BAO anchor geometry"))?; Ok(Self { particle: body.particle, len, reducer, work: WorkBudget::new(limits), }) }

/// Yield WouldBlock while pending, emit one anchor, then return None on
/// every later poll without work. Intermediate tree hashes are not EOF.
/// Each kernel is charged before execution; completion seals the output
/// within that final kernel's unit. Yields preserve all progress and total.
/// There is no push/flush/reset or reusable request.
pub fn pull(&mut self) -> Result<Option<BaoAnchor>> {
    if self.reducer.is_complete() {
        return Ok(None);
    }
    let mut call = self.work.begin_call();
    loop {
        // Positive limits admit a unit; exact constructor preflight covers
        // every kernel. Thus only call-quota exhaustion can fail here.
        call.charge(1)
            .map_err(|error| error.with_process("bao.anchor"))?;
        if let Some(root) = self.reducer.step() {
            return Ok(Some(BaoAnchor {
                particle: self.particle,
                len: self.len,
                root: *root.as_bytes(),
            }));
        }
    }
}

}

impl fmt::Debug for BaoAnchorJob<'> { fn fmt(&self, f: &mut fmt::Formatter<'>) -> fmt::Result { f.debug_struct("BaoAnchorJob") .field("particle", &self.particle) .field("len", &self.len) .field("reducer", &self.reducer) .field("work", &self.work) .finish() } }

fn kernel_count(len: u64) -> Result { let leaves = (len / CHUNK_SIZE as u64) .checked_add(u64::from(!len.is_multiple_of(CHUNK_SIZE as u64))) .ok_or_else(|| limit_error("BAO anchor work overflow"))? .max(1); leaves .checked_mul(2) .and_then(|n| n.checked_sub(1)) .ok_or_else(|| limit_error("BAO anchor work overflow")) }

fn limit_error(detail: &'static str) -> Error { Error::new(ErrorKind::LimitExceeded, detail).with_process("bao.anchor") }

#[cfg(test)] #[path = "anchor/tests.rs"] mod tests;

===== 052 END =====

===== 053 BEGIN Kadek kadek-ifac/Cargo.toml | 429 bytes | SHA256 8ee668643ce9154222b83817ad1a332db824c846842ac828e87fea3394a51ea6 ===== [package] name = "kadek-ifac" version.workspace = true edition.workspace = true license-file.workspace = true description = "Shared image storage and media codec interfaces — no_std + alloc"

[dependencies] hemera = { package = "cyber-hemera", version = "=0.3.1", default-features = false } cyber-bao = { git = "https://github.com/cyberia-to/radio", rev = "a96d86e28d384cdf656aadc4282c78c0c170c102", default-features = false }

===== 053 END =====

===== 054 BEGIN Hemera rs/src/params.rs | 6597 bytes | SHA256 bf5b2cb5a80697d272546425bddcdf2cb2bfe7e08367ae7c793a0922088f2a91 ===== // --- // tags: hemera, rust // crystal-type: source // crystal-domain: comp // --- //! Hemera — Poseidon2 parameter set over the Goldilocks field. //! //! Single source of truth for every constant in the protocol. //! The WGSL shader (gpu/poseidon2.wgsl) duplicates a subset of //! these values because WGSL cannot import Rust; keep them in sync. //! //! text //! ┌──────────────────────────────────────────────────────────┐ //! │ HEMERA — Complete Specification │ //! │ │ //! │ Field: p = 2⁶⁴ − 2³² + 1 (Goldilocks) │ //! │ Full-round S-box: d = 7 (x → x⁷) │ //! │ Partial S-box: x⁻¹ (field inversion) │ //! │ State width: t = 16 = 2⁴ │ //! │ Full rounds: R_F = 8 (4 + 4) = 2³ │ //! │ Partial rounds: R_P = 16 = 2⁴ │ //! │ Rate: r = 8 elements = 2³ │ //! │ Input rate: 56 bytes/block (7 B/element) = 7 × 2³ │ //! │ Capacity: c = 8 elements (64 bytes) = 2³ │ //! │ Output: 4 elements (32 bytes) = 2² │ //! │ │ //! │ Full round constants: 8 × 16 = 128 = 2⁷ │ //! │ Partial round constants: 16 = 2⁴ │ //! │ Total constants: 144 = 9 × 2⁴ │ //! │ Total rounds: 24 = 3 × 2³ │ //! │ │ //! │ Classical collision resistance: 256 bits = 2⁸ │ //! │ Quantum collision resistance: 170 bits │ //! │ Algebraic degree: 2¹⁰⁴⁶ │ //! │ │ //! │ Every parameter that appears in code is a power of 2. │ //! └──────────────────────────────────────────────────────────┘ //!

use crate::field::Goldilocks;

// ── Permutation parameters ──────────────────────────────────────────

/// Width of the Poseidon2 state (number of Goldilocks field elements). pub const WIDTH: usize = 16;

/// Number of full (external) rounds — 4 initial + 4 final. pub const ROUNDS_F: usize = 8;

/// Number of partial (internal) rounds. pub const ROUNDS_P: usize = 16;

/// Total number of rounds per permutation (R_F + R_P). pub const ROUNDS_TOTAL: usize = ROUNDS_F + ROUNDS_P; // 24

/// Full-round S-box degree (x → x^d). pub const SBOX_DEGREE: usize = 7;

// ── Sponge parameters ───────────────────────────────────────────────

/// Number of rate elements in the sponge. pub const RATE: usize = 8;

/// Number of capacity elements in the sponge. pub const CAPACITY: usize = WIDTH - RATE; // 8

// ── Encoding parameters ─────────────────────────────────────────────

/// Bytes per field element when encoding arbitrary input data. /// /// We use 7 bytes per element because 2^56 − 1 < p (Goldilocks prime), /// so any 7-byte value fits without reduction. pub const INPUT_BYTES_PER_ELEMENT: usize = 7;

/// Bytes per field element when encoding hash output. /// /// For output we use the full canonical u64 representation (8 bytes), /// since output elements are already valid field elements. pub const OUTPUT_BYTES_PER_ELEMENT: usize = 8;

// ── Derived constants ───────────────────────────────────────────────

/// Number of input bytes that fill one rate block (8 elements × 7 bytes). pub const RATE_BYTES: usize = RATE * INPUT_BYTES_PER_ELEMENT; // 56

/// Number of output elements extracted per squeeze (4 elements = 32 bytes). pub const OUTPUT_ELEMENTS: usize = 4;

/// Number of output bytes per squeeze (4 elements × 8 bytes). pub const OUTPUT_BYTES: usize = OUTPUT_ELEMENTS * OUTPUT_BYTES_PER_ELEMENT; // 32

// ── Tree parameters ─────────────────────────────────────────────────

/// Canonical chunk size for content tree construction (4 KB). /// /// Content is split into fixed 4 KB chunks. Each chunk is hashed via /// hash_leaf. The last chunk may be shorter. See spec §4.6.1. pub const CHUNK_SIZE: usize = 4096;

/// Maximum tree depth (sufficient for 2^64 chunks). pub const MAX_TREE_DEPTH: usize = 64;

// ── Security properties (informational) ─────────────────────────────

/// Classical collision resistance in bits. pub const COLLISION_BITS: usize = 256;

// ── Permutation entry point ─────────────────────────────────────────

/// Apply the Poseidon2 permutation in-place. #[inline] pub(crate) fn permute(state: &mut [Goldilocks; WIDTH]) { crate::permutation::permute(state); }

#[cfg(test)] mod tests { use super::*;

#[test]
fn permutation_is_deterministic() {
    let mut s1 = [Goldilocks::ZERO; WIDTH];
    let mut s2 = [Goldilocks::ZERO; WIDTH];
    permute(&mut s1);
    permute(&mut s2);
    assert_eq!(s1, s2);
}

#[test]
fn permutation_changes_state() {
    let mut state = [Goldilocks::ZERO; WIDTH];
    let original = state;
    permute(&mut state);
    assert_ne!(state, original);
}

#[test]
fn different_inputs_different_outputs() {
    let mut s1 = [Goldilocks::ZERO; WIDTH];
    let mut s2 = [Goldilocks::ZERO; WIDTH];
    s2[0] = Goldilocks::new(1);
    permute(&mut s1);
    permute(&mut s2);
    assert_ne!(s1, s2);
}

#[test]
fn sponge_geometry() {
    assert_eq!(WIDTH, RATE + CAPACITY);
    assert_eq!(RATE_BYTES, 56);
    assert_eq!(OUTPUT_BYTES, 32);
    assert_eq!(OUTPUT_ELEMENTS, 4);
}

}

===== 054 END =====

===== 055 BEGIN Hemera rs/src/field.rs | 12041 bytes | SHA256 7a9da58f2daa65d946574753d819e4c0d39d80d61fd519ad42e38d038aebd09a ===== // --- // tags: hemera, rust // crystal-type: source // crystal-domain: comp // --- //! Goldilocks prime field (p = 2^64 - 2^32 + 1). //! //! Minimal implementation covering the operations hemera needs: //! addition, subtraction, multiplication, and the x^7 S-box.

use core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};

/// The Goldilocks prime: p = 2^64 - 2^32 + 1. pub const P: u64 = 0xFFFF_FFFF_0000_0001;

/// Two's complement of P modulo 2^64: 2^32 - 1. const NEG_ORDER: u64 = P.wrapping_neg(); // 0xFFFF_FFFF

/// A Goldilocks field element. /// /// Internal value may be non-canonical (in [0, 2^64)). /// Use as_canonical_u64() to reduce to [0, p). #[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct Goldilocks { value: u64, }

impl Goldilocks { pub const ZERO: Self = Self { value: 0 };

#[inline]
pub const fn new(value: u64) -> Self {
    Self { value }
}

/// Reduce to canonical form in [0, p).
#[inline]
pub fn as_canonical_u64(self) -> u64 {
    // Mask, not branch: hash outputs of secret inputs pass through here.
    self.value.wrapping_sub(P & u64::from(self.value >= P).wrapping_neg())
}

/// Compute x^2.
#[inline]
fn square(self) -> Self {
    self * self
}

/// Compute x^7 (the Poseidon2 full-round S-box for Goldilocks).
#[inline]
pub fn pow7(self) -> Self {
    let x2 = self.square();
    let x3 = x2 * self;
    let x4 = x2.square();
    x3 * x4
}

/// Compute x^(-1) = x^(p-2) (the Poseidon2 partial-round S-box).
///
/// Uses Fermat's little theorem: x^(-1) = x^(p-2) mod p.
/// Convention: 0^(-1) = 0 (permutation over F_p).
#[inline]
pub fn inv(self) -> Self {
    // x^(p-2) by the 75-multiply addition chain (acpu gl_inv) instead
    // of naive square-and-multiply (~125 serial muls). The partial
    // rounds of the Poseidon2 permutation call this once each, and the
    // permutation is the single hottest primitive in the stack — every
    // saved serial multiply here is felt from Brakedown to the graph.
    // Bit-identical result: same Fermat exponent, better chain.
    if self.as_canonical_u64() == 0 {
        return Self::ZERO;
    }
    let x = self;
    // chain of 2^k-1 powers up to x^(2^31-1)
    let x2 = x * x;
    let x3 = x2 * x;
    let x4 = x2 * x2;
    let x7 = x3 * x4;
    let x6 = x3 * x3;
    let x12 = x6 * x6;
    let x15 = x12 * x3; // 2^4-1
    let x30 = x15 * x15;
    let x60 = x30 * x30;
    let x120 = x60 * x60;
    let x127 = x120 * x7; // 2^7-1
    let x254 = x127 * x127;
    let x255 = x254 * x; // 2^8-1
    let mut t = x255;
    for _ in 0..7 {
        t = t * t;
    }
    let x_2p15m1 = t * x127; // 2^15-1
    let x_2p16m2 = x_2p15m1 * x_2p15m1;
    let x_2p16m1 = x_2p16m2 * x; // 2^16-1
    t = x_2p16m1;
    for _ in 0..15 {
        t = t * t;
    }
    let x_2p31m1 = t * x_2p15m1; // 2^31-1
    // x^(2^32-1)
    let x_2p32m2 = x_2p31m1 * x_2p31m1;
    let x_epsilon = x_2p32m2 * x;
    // x^((2^31-1)*2^33)
    t = x_2p31m1;
    for _ in 0..33 {
        t = t * t;
    }
    // p-2 = (2^31-1)*2^33 + 2^32-1
    t * x_epsilon
}

/// The raw representative in `[0, 2^64)` (not necessarily canonical).
#[inline(always)]
pub(crate) const fn raw(self) -> u64 {
    self.value
}

/// Double this element.
#[inline]
fn double(self) -> Self {
    self + self
}

}

impl core::fmt::Debug for Goldilocks { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "Goldilocks({})", self.as_canonical_u64()) } }

// ── Arithmetic ──────────────────────────────────────────────────────

impl Add for Goldilocks { type Output = Self;

#[inline]
fn add(self, rhs: Self) -> Self {
    let (sum, over) = self.value.overflowing_add(rhs.value);
    let (sum, over) = sum.overflowing_add(u64::from(over) * NEG_ORDER);
    // Mask, not branch: the sponge absorbs secret input with this add.
    Self::new(sum.wrapping_add(NEG_ORDER & u64::from(over).wrapping_neg()))
}

}

impl AddAssign for Goldilocks { #[inline] fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } }

impl Sub for Goldilocks { type Output = Self;

#[inline]
fn sub(self, rhs: Self) -> Self {
    let (diff, under) = self.value.overflowing_sub(rhs.value);
    let (diff, under) = diff.overflowing_sub(u64::from(under) * NEG_ORDER);
    Self::new(diff.wrapping_sub(NEG_ORDER & u64::from(under).wrapping_neg()))
}

}

impl SubAssign for Goldilocks { #[inline] fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } }

impl Mul for Goldilocks { type Output = Self;

#[inline]
fn mul(self, rhs: Self) -> Self {
    // Same representative as `reduce128(a·b)`; latency-scheduled on aarch64.
    Self::new(crate::arith::mul(self.value, rhs.value))
}

}

impl MulAssign for Goldilocks { #[inline] fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } }

impl core::iter::Sum for Goldilocks { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { reduce128(iter.map(|x| x.value as u128).sum::()) } }

/// Reduce a 128-bit product to a Goldilocks element. /// /// Uses the identity 2^64 ≡ 2^32 - 1 (mod p). #[inline] fn reduce128(x: u128) -> Goldilocks { let x_lo = x as u64; let x_hi = (x >> 64) as u64; let x_hi_hi = x_hi >> 32; let x_hi_lo = x_hi & NEG_ORDER;

let (mut t0, borrow) = x_lo.overflowing_sub(x_hi_hi);
if borrow {
    t0 -= NEG_ORDER;
}
let t1 = x_hi_lo * NEG_ORDER;
let (res, carry) = t0.overflowing_add(t1);
Goldilocks::new(res + NEG_ORDER * u64::from(carry))

}

// ── MDS and diffusion matrices ──────────────────────────────────────

/// Apply the 4x4 MDS matrix used in Poseidon2 external rounds: /// text /// [ 2 3 1 1 ] /// [ 1 2 3 1 ] /// [ 1 1 2 3 ] /// [ 3 1 1 2 ] /// #[inline(always)] pub fn apply_mat4(x: &mut [Goldilocks; 4]) { let t01 = x[0] + x[1]; let t23 = x[2] + x[3]; let t0123 = t01 + t23; let t01123 = t0123 + x[1]; let t01233 = t0123 + x[3]; x[3] = t01233 + x[0].double(); x[1] = t01123 + x[2].double(); x[0] = t01123 + t01; x[2] = t01233 + t23; }

/// Apply the external MDS layer for a width-16 state. /// /// Multiplies by the 16×16 circulant-of-4×4 matrix: /// [[2M M ... M], [M 2M ... M], ..., [M M ... 2M]] /// where M is the 4×4 MDS matrix. #[inline] pub fn mds_light_permutation(state: &mut [Goldilocks; 16]) { // Apply M4 to each consecutive 4-element chunk. for chunk in state.chunks_exact_mut(4) { apply_mat4(chunk.try_into().unwrap()); }

// Compute column sums (one per M4 column position).
let sums: [Goldilocks; 4] = core::array::from_fn(|k| {
    (0..16).step_by(4).map(|j| state[j + k]).sum()
});

// Add the appropriate column sum to each element.
for (i, elem) in state.iter_mut().enumerate() {
    *elem += sums[i % 4];
}

}

/// Diagonal elements of the internal diffusion matrix for Goldilocks t=16. /// /// The full matrix is M_I = 1 + diag(d), where 1 is the all-ones matrix. pub const MATRIX_DIAG_16: [Goldilocks; 16] = [ Goldilocks::new(0xde9b91a467d6afc0), Goldilocks::new(0xc5f16b9c76a9be17), Goldilocks::new(0x0ab0fef2d540ac55), Goldilocks::new(0x3001d27009d05773), Goldilocks::new(0xed23b1f906d3d9eb), Goldilocks::new(0x5ce73743cba97054), Goldilocks::new(0x1c3bab944af4ba24), Goldilocks::new(0x2faa105854dbafae), Goldilocks::new(0x53ffb3ae6d421a10), Goldilocks::new(0xbcda9df8884ba396), Goldilocks::new(0xfc1273e4a31807bb), Goldilocks::new(0xc77952573d5142c0), Goldilocks::new(0x56683339a819b85e), Goldilocks::new(0x328fcbd8f0ddc8eb), Goldilocks::new(0xb5101e303fce9cb7), Goldilocks::new(0x774487b8c40089bb), ];

/// Apply the internal diffusion matrix: M_I = 1 + diag(d). /// /// Computes state'[i] = d[i] * state[i] + sum(state). #[inline] pub fn matmul_internal(state: &mut [Goldilocks; 16]) { let sum: Goldilocks = state.iter().copied().sum(); for i in 0..16 { state[i] *= MATRIX_DIAG_16[i]; state[i] += sum; } }

#[cfg(test)] mod tests { use super::*;

/// The addition chain must equal naive x^(p-2) everywhere — checked
/// against x*inv(x)==1 over a spread of values including edge cases.
#[test]
fn inv_chain_matches_fermat() {
    let mut v = [0u64; 72];
    v[..8].copy_from_slice(&[1, 2, 3, P - 1, P - 2, 0xFFFF_FFFF, 1 << 32, u64::MAX % P]);
    let mut x = 0x9e3779b97f4a7c15u64;
    for slot in v[8..].iter_mut() {
        x = x.wrapping_mul(0xbf58476d1ce4e5b9).rotate_left(31);
        *slot = x % P;
    }
    for &raw in &v {
        if raw == 0 {
            continue;
        }
        let a = Goldilocks::new(raw);
        assert_eq!(
            (a * a.inv()).as_canonical_u64(),
            1,
            "inv broken at {raw}"
        );
    }
    assert_eq!(Goldilocks::ZERO.inv().as_canonical_u64(), 0);
}

#[test]
fn field_add_basic() {
    let a = Goldilocks::new(1);
    let b = Goldilocks::new(2);
    assert_eq!((a + b).as_canonical_u64(), 3);
}

#[test]
fn field_add_wrap() {
    let a = Goldilocks::new(P - 1);
    let b = Goldilocks::new(1);
    assert_eq!((a + b).as_canonical_u64(), 0);
}

#[test]
fn field_sub_basic() {
    let a = Goldilocks::new(5);
    let b = Goldilocks::new(3);
    assert_eq!((a - b).as_canonical_u64(), 2);
}

#[test]
fn field_sub_wrap() {
    let a = Goldilocks::new(0);
    let b = Goldilocks::new(1);
    assert_eq!((a - b).as_canonical_u64(), P - 1);
}

#[test]
fn field_mul_basic() {
    let a = Goldilocks::new(3);
    let b = Goldilocks::new(7);
    assert_eq!((a * b).as_canonical_u64(), 21);
}

#[test]
fn field_mul_large() {
    // (P-1) * (P-1) mod P = 1
    let a = Goldilocks::new(P - 1);
    assert_eq!((a * a).as_canonical_u64(), 1);
}

#[test]
fn pow7_basic() {
    let x = Goldilocks::new(2);
    assert_eq!(x.pow7().as_canonical_u64(), 128);
}

#[test]
fn pow7_zero() {
    assert_eq!(Goldilocks::ZERO.pow7().as_canonical_u64(), 0);
}

#[test]
fn pow7_one() {
    assert_eq!(Goldilocks::new(1).pow7().as_canonical_u64(), 1);
}

#[test]
fn inv_basic() {
    // 2 * inv(2) = 1
    let x = Goldilocks::new(2);
    let x_inv = x.inv();
    assert_eq!((x * x_inv).as_canonical_u64(), 1);
}

#[test]
fn inv_one() {
    assert_eq!(Goldilocks::new(1).inv().as_canonical_u64(), 1);
}

#[test]
fn inv_zero() {
    assert_eq!(Goldilocks::ZERO.inv().as_canonical_u64(), 0);
}

#[test]
fn inv_roundtrip() {
    let x = Goldilocks::new(42);
    let x_inv = x.inv();
    assert_eq!((x * x_inv).as_canonical_u64(), 1);
    assert_eq!(x_inv.inv().as_canonical_u64(), x.as_canonical_u64());
}

#[test]
fn inv_p_minus_one() {
    // (p-1)^(-1) = p-1 since (p-1)^2 = 1 mod p
    let a = Goldilocks::new(P - 1);
    assert_eq!(a.inv().as_canonical_u64(), P - 1);
}

#[test]
fn canonical_reduces() {
    // A non-canonical value >= P
    let a = Goldilocks::new(P);
    assert_eq!(a.as_canonical_u64(), 0);
    let b = Goldilocks::new(P + 1);
    assert_eq!(b.as_canonical_u64(), 1);
}

}

===== 055 END =====

===== 056 BEGIN Hemera rs/src/encoding.rs | 7759 bytes | SHA256 4da69b468a5276a6ed32092e0ed6149b67bf16ded2e6aba2c405af805291701e ===== // --- // tags: hemera, rust // crystal-type: source // crystal-domain: comp // --- use crate::field::Goldilocks;

use crate::params::{ INPUT_BYTES_PER_ELEMENT, OUTPUT_BYTES, OUTPUT_BYTES_PER_ELEMENT, OUTPUT_ELEMENTS, RATE, };

/// Encode arbitrary bytes into Goldilocks field elements. /// /// Each element holds 7 bytes (little-endian). The last element may hold fewer bytes, /// zero-padded in the high positions. #[cfg(test)] pub(crate) fn bytes_to_elements(bytes: &[u8]) -> alloc::vec::Vec { bytes .chunks(INPUT_BYTES_PER_ELEMENT) .map(|chunk| { let mut buf = [0u8; 8]; buf[..chunk.len()].copy_from_slice(chunk); Goldilocks::new(u64::from_le_bytes(buf)) }) .collect() }

/// Encode exactly count elements from a byte slice into a fixed-size array, /// writing into out[offset..]. Returns the number of bytes consumed. /// /// This is the hot-path version used by the sponge absorb. pub(crate) fn bytes_to_rate_block(bytes: &[u8], out: &mut [Goldilocks; RATE]) -> usize { let mut consumed = 0; for elem in out.iter_mut() { if consumed >= bytes.len() { *elem = Goldilocks::new(0); } else { let end = (consumed + INPUT_BYTES_PER_ELEMENT).min(bytes.len()); let mut buf = [0u8; 8]; buf[..end - consumed].copy_from_slice(&bytes[consumed..end]); *elem = Goldilocks::new(u64::from_le_bytes(buf)); consumed = end; } } consumed }

/// Convert output field elements to a hash byte array. /// /// Uses the full canonical u64 representation (8 bytes LE) per element. pub(crate) fn hash_to_bytes(elements: &[Goldilocks; OUTPUT_ELEMENTS]) -> [u8; OUTPUT_BYTES] { let mut out = [0u8; OUTPUT_BYTES]; for (i, elem) in elements.iter().enumerate() { let val = elem.as_canonical_u64(); out[i * OUTPUT_BYTES_PER_ELEMENT..(i + 1) * OUTPUT_BYTES_PER_ELEMENT] .copy_from_slice(&val.to_le_bytes()); } out }

/// Convert a hash byte array back into Goldilocks elements. /// /// Inverse of hash_to_bytes. Used by hash_node in the tree module. pub(crate) fn bytes_to_cv(bytes: &[u8; OUTPUT_BYTES]) -> [Goldilocks; OUTPUT_ELEMENTS] { let mut out = [Goldilocks::new(0); OUTPUT_ELEMENTS]; for (i, elem) in out.iter_mut().enumerate() { let start = i * OUTPUT_BYTES_PER_ELEMENT; let val = u64::from_le_bytes( bytes[start..start + OUTPUT_BYTES_PER_ELEMENT] .try_into() .unwrap(), ); *elem = Goldilocks::new(val); } out }

#[cfg(test)] mod tests { extern crate std; use std::vec; use super::*; use crate::params::RATE_BYTES;

#[test]
fn roundtrip_hash_bytes() {
    let elements = [
        Goldilocks::new(1),
        Goldilocks::new(2),
        Goldilocks::new(3),
        Goldilocks::new(4),
    ];
    let bytes = hash_to_bytes(&elements);
    let recovered = bytes_to_cv(&bytes);
    assert_eq!(elements, recovered);
}

#[test]
fn bytes_to_elements_empty() {
    let result = bytes_to_elements(&[]);
    assert!(result.is_empty());
}

#[test]
fn bytes_to_elements_short() {
    let result = bytes_to_elements(&[0x42]);
    assert_eq!(result.len(), 1);
    assert_eq!(result[0].as_canonical_u64(), 0x42);
}

#[test]
fn bytes_to_elements_exact_7() {
    let input = [1, 2, 3, 4, 5, 6, 7];
    let result = bytes_to_elements(&input);
    assert_eq!(result.len(), 1);
    let expected = u64::from_le_bytes([1, 2, 3, 4, 5, 6, 7, 0]);
    assert_eq!(result[0].as_canonical_u64(), expected);
}

#[test]
fn bytes_to_elements_8_bytes_splits() {
    let input = [1, 2, 3, 4, 5, 6, 7, 8];
    let result = bytes_to_elements(&input);
    assert_eq!(result.len(), 2);
}

#[test]
fn rate_block_fill() {
    let input = vec![0xAB; RATE_BYTES];
    let mut block = [Goldilocks::new(0); RATE];
    let consumed = bytes_to_rate_block(&input, &mut block);
    assert_eq!(consumed, RATE_BYTES);
    // All 8 elements should be non-zero
    for elem in &block {
        assert_ne!(elem.as_canonical_u64(), 0);
    }
}

#[test]
fn seven_byte_values_fit_in_goldilocks() {
    // Max 7-byte value: 2^56 - 1 = 0x00FF_FFFF_FFFF_FFFF
    let max_7byte: u64 = (1u64 << 56) - 1;
    // Goldilocks prime: p = 2^64 - 2^32 + 1 = 0xFFFF_FFFF_0000_0001
    let p: u64 = 0xFFFF_FFFF_0000_0001;
    assert!(max_7byte < p, "7-byte max must be less than Goldilocks prime");
}

#[test]
fn bytes_to_elements_exact_rate_block() {
    // 56 bytes = 8 elements of 7 bytes each
    let input = vec![0x42u8; RATE_BYTES];
    let result = bytes_to_elements(&input);
    assert_eq!(result.len(), RATE);
}

#[test]
fn bytes_to_elements_one_extra() {
    // 57 bytes = 8 full elements + 1 element with 1 byte
    let input = vec![0x42u8; RATE_BYTES + 1];
    let result = bytes_to_elements(&input);
    assert_eq!(result.len(), RATE + 1);
}

#[test]
fn rate_block_partial_fill() {
    // Fewer than RATE_BYTES: remaining elements should be zero
    let input = vec![0xAB; 10]; // 10 bytes = 2 elements (7+3)
    let mut block = [Goldilocks::new(99); RATE]; // pre-fill with non-zero
    let consumed = bytes_to_rate_block(&input, &mut block);
    assert_eq!(consumed, 10);
    // First two elements non-zero, rest zero
    assert_ne!(block[0].as_canonical_u64(), 0);
    assert_ne!(block[1].as_canonical_u64(), 0);
    for elem in &block[2..] {
        assert_eq!(elem.as_canonical_u64(), 0);
    }
}

#[test]
fn rate_block_empty() {
    let mut block = [Goldilocks::new(99); RATE];
    let consumed = bytes_to_rate_block(&[], &mut block);
    assert_eq!(consumed, 0);
    for elem in &block {
        assert_eq!(elem.as_canonical_u64(), 0);
    }
}

#[test]
fn roundtrip_hash_bytes_max_canonical() {
    // Use values near the Goldilocks prime to test canonicity
    let p: u64 = 0xFFFF_FFFF_0000_0001;
    let elements = [
        Goldilocks::new(p - 1), // max canonical value
        Goldilocks::new(0),
        Goldilocks::new(1),
        Goldilocks::new(p - 2),
    ];
    let bytes = hash_to_bytes(&elements);
    let recovered = bytes_to_cv(&bytes);
    for (i, (orig, rec)) in elements.iter().zip(recovered.iter()).enumerate() {
        assert_eq!(
            orig.as_canonical_u64(),
            rec.as_canonical_u64(),
            "mismatch at element {i}"
        );
    }
}

#[test]
fn bytes_to_cv_with_above_prime_value() {
    // If bytes encode a value >= p, Goldilocks::new reduces it.
    // This is expected behavior for internal use (hash outputs are always canonical).
    let p: u64 = 0xFFFF_FFFF_0000_0001;
    let above_prime = p + 1; // should reduce to 1
    let mut bytes = [0u8; OUTPUT_BYTES];
    bytes[..8].copy_from_slice(&above_prime.to_le_bytes());
    let recovered = bytes_to_cv(&bytes);
    // p+1 mod p = 1 (Goldilocks wraps, not panics)
    assert_eq!(recovered[0].as_canonical_u64(), above_prime % p);
}

#[test]
fn bytes_to_elements_max_7byte_boundary() {
    // Exactly 7 bytes of 0xFF should encode to (2^56 - 1), which is < p
    let input = [0xFF; 7];
    let result = bytes_to_elements(&input);
    assert_eq!(result.len(), 1);
    assert_eq!(result[0].as_canonical_u64(), (1u64 << 56) - 1);
}

}

===== 056 END =====

===== 057 BEGIN hemera specs/tree.md:8-113 | 4738 bytes | SHA256 8f5d0d260b564d9efbf1cdc1da5b7fb0a994d412e43938001838d43ad8ee72f6 =====

canonical tree hashing

Chunk Size: 4 KB (4096 bytes)

Content is split into fixed 4 KB chunks (4096 bytes). Each chunk is hashed via hash_leaf(data, counter, is_root). At 56 input bytes per rate block, one 4 KB chunk requires ⌈4096/56⌉ = 74 absorptions. The last chunk may be shorter. No content-defined chunking — every boundary is deterministic.

See docs/explanation/chunk-size.md for rationale.

Leaf Hashing: hash_leaf(data, counter, is_root) → Hash

Two-pass construction separates content hashing from structural binding:

Pass 1 — content hashing:
    hasher ← Hasher::new()              (plain sponge, domain_tag = 0x00)
    hasher.absorb(data)
    base_hash ← hasher.finalize()       (32-byte sponge output)

Pass 2 — structural binding:
    state ← [0; 16]
    state[0..4] ← bytes_to_elements(base_hash)    (4 Goldilocks elements)
    state[8]    ← counter                          (chunk position, 0-based)
    state[9]    ← FLAG_CHUNK | (FLAG_ROOT if is_root)
    state ← permute(state)
    output ← elements_to_bytes(state[0..4])        (32-byte chaining value)

Two passes exist for three reasons. The sponge remains a pure hash — no tree metadata contaminates its input stream. Tree logic is layered on top via the capacity region. The base_hash is cacheable: if a chunk appears at multiple positions, the expensive 74-absorption pass runs once and the cheap 1-permutation binding runs per position.

Counter prevents chunk reordering. CHUNK flag prevents leaf/node confusion. ROOT flag distinguishes root finalization from subtree chaining.

Cost: N absorptions + 1 permutation. At 4096 bytes: 74 + 1 = 75 permutations per leaf.

Internal Node Hashing: hash_node(left, right, is_root) → Hash

state ← [0; 16]
state[9] ← FLAG_PARENT | (FLAG_ROOT if is_root)

// Absorb both children (4 + 4 = 8 elements = one full rate block)
state[0..4] += bytes_to_elements(left)     (field addition, element-wise)
state[4..8] += bytes_to_elements(right)    (field addition, element-wise)
state ← permute(state)

output ← elements_to_bytes(state[0..4])    (32-byte chaining value)

No padding needed — inputs are always exactly two 32-byte hashes (4 + 4 = 8 elements = one rate block). PARENT flag lives in the capacity region. Order matters: hash_node(A, B) ≠ hash_node(B, A).

Cost: 1 permutation per internal node.

Namespace-Aware Parent: hash_node_nmt(left, right, ns_min, ns_max, is_root) → Hash

Same as hash_node but with namespace bounds in the capacity:

state[12] ← ns_min        (minimum namespace in subtree)
state[13] ← ns_max        (maximum namespace in subtree)

When ns_min = ns_max = 0, reduces to hash_node. Only NMT uses non-zero namespace bounds.

Verifier checks: parent.ns_min ≤ left.ns_max < right.ns_min ≤ parent.ns_max (for sorted NMT).

Cost: 1 permutation (same as hash_node).

Tree Shape

Binary, left-balanced, in-order indexed:

If N = 1:     hash_leaf(data, 0, is_root=true)  is the root
If N > 1:     split = 2^(⌈log₂(N)⌉ - 1)
              left  = tree_hash(chunks[0..split],       is_root=false)
              right = tree_hash(chunks[split..N],        is_root=false)
              root  = hash_node(left, right, is_root=true)

Left-balanced: the left subtree is always a complete binary tree (power-of-2 leaves). The right subtree absorbs the remainder and recurses with the same rule.

In-order indexing: Leaves at even positions (0, 2, 4, ...). Parents at odd positions with level = trailing_ones(index). This indexing is compatible with Merkle Mountain Range append operations.

Root Finalization

Case Function Flags Value
Single-chunk file hash_leaf(data, 0, is_root=true) CHUNK | ROOT 0x05
Multi-chunk file hash_node(left, right, is_root=true) PARENT | ROOT 0x03

The ROOT flag ensures that a file's identity hash is never equal to any internal chaining value. A subtree hash with is_root=false is structurally distinct from the same tree computed as a standalone file with is_root=true.

Security Properties

Attack Defense Mechanism
Leaf/node confusion Prevented CHUNK (0x04) vs PARENT (0x02) in capacity
Chunk reordering Prevented Counter in state[8] binds position
Chunk duplication Prevented Counter distinguishes identical chunks at different offsets
Subtree substitution Prevented ROOT flag separates file identity from subtree identity
Length extension Prevented Length in state[10] (sponge) + counter (binding)
Second preimage via tree Prevented All of the above, combined

Complete Example

A 12 KB file (3 chunks):

===== 057 END =====

===== 058 BEGIN hemera specs/encoding.md:29-42 | 646 bytes | SHA256 363137dc01965e7f856c3e70005fd0cfc5706a23fda1e52ae85b90600542bf82 =====

Output uses the full canonical u64 representation: 8 bytes per element, little-endian. Output elements are guaranteed to be in [0, p) by the permutation — no reduction needed.

element 0 → bytes[0..8]     (u64 to LE bytes)
element 1 → bytes[8..16]
element 2 → bytes[16..24]
element 3 → bytes[24..32]   (= 32-byte hash output)

The asymmetry — 7 bytes in, 8 bytes out — is deliberate. Input encoding must be injective for collision resistance. Output encoding must preserve full field element fidelity for algebraic composability. These are different constraints with different optima.

Padding (Hemera: 0x01 ∥ 0x00*)

===== 058 END =====

===== 059 BEGIN hemera specs/capacity.md:11-48 | 1342 bytes | SHA256 1211c21b4e65c077476581faf6a4b353a064483593280d2e71a65c0a55ebb311 =====

layout

state[0..8]   rate       input absorption / output squeezing
state[8..16]  capacity   structural context, never touched by input

state[8]      counter    chunk position in file (0-based, u64)
state[9]      flags      structural role (bitfield)
state[10]     msg_length total input byte count (sponge finalization)
state[11]     domain_tag   API mode selector (PLANNED FOR REMOVAL — see roadmap/one-pure-hash.md)
state[12]     ns_min     namespace lower bound (NMT only, zero otherwise)
state[13]     ns_max     namespace upper bound (NMT only, zero otherwise)
state[14]     reserved   must be zero
state[15]     reserved   must be zero

flags (state[9])

three single-bit flags, combined via bitwise OR:

FLAG_ROOT   = 0x01    this hash finalizes a tree root
FLAG_PARENT = 0x02    this hash combines two child hashes (internal node)
FLAG_CHUNK  = 0x04    this hash derives a leaf chaining value

valid combinations:

context flags value
plain sponge hash (none) 0x00
non-root leaf CHUNK 0x04
root leaf (single-chunk file) CHUNK | ROOT 0x05
non-root internal node PARENT 0x02
root internal node (tree root) PARENT | ROOT 0x03

flags encode what the hash IS, not what it contains. a flag combination that does not appear in the table is invalid.

===== 059 END =====

===== 060 BEGIN hemera rs/src/field.rs:10-44 | 964 bytes | SHA256 454a53173d2f33e639acfdc8b7ff9c0a2a5556cc11d391932992dde26f42e03c =====

use core::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};

/// The Goldilocks prime: p = 2^64 - 2^32 + 1. pub const P: u64 = 0xFFFF_FFFF_0000_0001;

/// Two's complement of P modulo 2^64: 2^32 - 1. const NEG_ORDER: u64 = P.wrapping_neg(); // 0xFFFF_FFFF

/// A Goldilocks field element. /// /// Internal value may be non-canonical (in [0, 2^64)). /// Use as_canonical_u64() to reduce to [0, p). #[derive(Clone, Copy, Default, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct Goldilocks { value: u64, }

impl Goldilocks { pub const ZERO: Self = Self { value: 0 };

#[inline]
pub const fn new(value: u64) -> Self {
    Self { value }
}

/// Reduce to canonical form in [0, p).
#[inline]
pub fn as_canonical_u64(self) -> u64 {
    // Mask, not branch: hash outputs of secret inputs pass through here.
    self.value.wrapping_sub(P & u64::from(self.value >= P).wrapping_neg())
}

/// Compute x^2.

===== 060 END =====

===== 061 BEGIN hemera rs/src/encoding.rs:47-79 | 1132 bytes | SHA256 816c01ae13817285054db8500ee1f80f6d3250d4f6d650800ee5e6b33a22cea4 =====

/// Convert output field elements to a hash byte array. /// /// Uses the full canonical u64 representation (8 bytes LE) per element. pub(crate) fn hash_to_bytes(elements: &[Goldilocks; OUTPUT_ELEMENTS]) -> [u8; OUTPUT_BYTES] { let mut out = [0u8; OUTPUT_BYTES]; for (i, elem) in elements.iter().enumerate() { let val = elem.as_canonical_u64(); out[i * OUTPUT_BYTES_PER_ELEMENT..(i + 1) * OUTPUT_BYTES_PER_ELEMENT] .copy_from_slice(&val.to_le_bytes()); } out }

/// Convert a hash byte array back into Goldilocks elements. /// /// Inverse of hash_to_bytes. Used by hash_node in the tree module. pub(crate) fn bytes_to_cv(bytes: &[u8; OUTPUT_BYTES]) -> [Goldilocks; OUTPUT_ELEMENTS] { let mut out = [Goldilocks::new(0); OUTPUT_ELEMENTS]; for (i, elem) in out.iter_mut().enumerate() { let start = i * OUTPUT_BYTES_PER_ELEMENT; let val = u64::from_le_bytes( bytes[start..start + OUTPUT_BYTES_PER_ELEMENT] .try_into() .unwrap(), ); *elem = Goldilocks::new(val); } out }

#[cfg(test)] mod tests {

===== 061 END =====

===== 062 BEGIN hemera rs/src/sponge.rs:22-43 | 697 bytes | SHA256 e12b1722dacbc3910760480cf1c5e2daf9bb6c753a3b9b8ada926069b4007df0 ===== #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Hash([u8; OUTPUT_BYTES]);

impl Hash { /// Create a hash from a raw byte array. pub const fn from_bytes(bytes: [u8; OUTPUT_BYTES]) -> Self { Self(bytes) }

/// Return the hash as a byte slice.
pub fn as_bytes(&self) -> &[u8; OUTPUT_BYTES] {
    &self.0
}

/// Convert the hash to a hex string.
#[cfg(feature = "std")]
#[allow(unknown_lints, rs_no_string)]
pub fn to_hex(&self) -> alloc::string::String {
    let mut s = alloc::string::String::with_capacity(OUTPUT_BYTES * 2);
    for byte in &self.0 {
        use core::fmt::Write;
        write!(s, "{byte:02x}").unwrap();

===== 062 END =====

===== 063 BEGIN hemera rs/src/tree.rs:95-148 | 1908 bytes | SHA256 d9cfe6eb1f01008be0503e13e2b68657599d4cbd521ce15f63fd305732951756 ===== } } }

/// Combine two child chaining values into a parent chaining value. /// /// With Hemera parameters (output=4 elements, rate=8), each child hash is 4 elements. /// Both children together (4 + 4 = 8 elements) fit in one rate block. /// Flags are set in the capacity before the absorption. /// /// The is_root flag domain-separates the tree root from interior nodes. pub fn hash_node(left: &Hash, right: &Hash, is_root: bool) -> Hash { let mut state = node_state(left, right, is_root); params::permute(&mut state); state_digest(&state) }

/// Pre-permutation state of hash_node: flags in the capacity, both /// children absorbed into the rate (4 + 4 = 8 elements = one rate block). #[inline] fn node_state(left: &Hash, right: &Hash, is_root: bool) -> [Goldilocks; WIDTH] { let left_elems = bytes_to_cv(left.as_bytes()); let right_elems = bytes_to_cv(right.as_bytes());

let mut state = [Goldilocks::new(0); WIDTH];

// Set flags in capacity before absorbing.
let mut flags = FLAG_PARENT;
if is_root {
    flags |= FLAG_ROOT;
}
state[CAPACITY_FLAGS_IDX] = Goldilocks::new(flags);

// Absorb both children (4 + 4 = 8 elements = one full rate block).
for i in 0..OUTPUT_ELEMENTS {
    state[i] += left_elems[i];
}
for i in 0..OUTPUT_ELEMENTS {
    state[OUTPUT_ELEMENTS + i] += right_elems[i];
}
state

}

/// Digest of a permuted state: the first OUTPUT_ELEMENTS, canonical LE. #[inline] fn state_digest(state: &[Goldilocks; WIDTH]) -> Hash { let output: [Goldilocks; OUTPUT_ELEMENTS] = state[..OUTPUT_ELEMENTS].try_into().unwrap(); Hash::from_bytes(hash_to_bytes(&output)) }

/// out[i] = hash_node(&pairs[i].0, &pairs[i].1, is_root) for every i. /// /// Runs permutation::BATCH_LANES compressions interleaved per kernel /// call (see permutation::permute_batch); no allocation. Use it where

===== 063 END =====

===== 064 BEGIN hemera rs/src/tree.rs:870-884 | 402 bytes | SHA256 19a3aab1d05dab34ce97703deedbb2f3d202b0c51e82ff6062cf1e00ba3cc14b ===== } }

/// Alias for hash_leaf — compatible with BAO chaining value terminology. #[inline] pub fn chunk_cv(data: &[u8], counter: u64, is_root: bool) -> Hash { hash_leaf(data, counter, is_root) }

/// Alias for hash_node — compatible with BAO chaining value terminology. #[inline] pub fn parent_cv(left: &Hash, right: &Hash, is_root: bool) -> Hash { hash_node(left, right, is_root) }

===== 064 END =====

===== 065 BEGIN soft3 release/components.toml:250-260 | 149 bytes | SHA256 c8981791a8d1a7860703afece8f14943f7e2f2629d297415392fa15db72db984 ===== component name = "radio" kind = "crate" repo = "radio" verb = "transmit" facet = "space" layer = 7 part_of = "soft3" phase = "1" state = "live"

===== 065 END =====

===== 066 BEGIN soft3 release/components.toml:653-662 | 221 bytes | SHA256 c4476d92f9f50efd9080cad9bdd24f49845b274d9376e3a0eb4ce0686b6d5aac ===== component name = "kadek" kind = "part" repo = "kadek" verb = "decode" facet = "play" layer = 8 part_of = "cyb" phase = "1" state = "pure rust media: decode what a file renders to; specs aligned with soft3 2026-09-25"

===== 066 END =====

===== 067 BEGIN radio iroh-blobs/src/api/blobs.rs:1011-1020 | 316 bytes | SHA256 6d551f1b8f840ae0b99e44c4e71ba605a38e1bbc07343fc733858871a55f5652 ===== }

fn encode_parent_pair(pair: &(hemera::Hash, hemera::Hash)) -> [u8; 2 * hemera::OUTPUT_BYTES] { let mut data = [0; 2 * hemera::OUTPUT_BYTES]; let (left, right) = data.split_at_mut(hemera::OUTPUT_BYTES); left.copy_from_slice(pair.0.as_bytes()); right.copy_from_slice(pair.1.as_bytes()); data }

===== 067 END =====

===== 068 BEGIN radio iroh-blobs/src/api/blobs.rs:14-38 | 619 bytes | SHA256 c70793944bf4f0bff427176b97a7c1140822794e5ba34d24d38257791e762be8 ===== pin::Pin, };

pub use cyber_bao::io::mixed::EncodedItem; use cyber_bao::{ io::{ fsm::{ResponseDecoder, ResponseDecoderNext}, BaoContentItem, Leaf, }, BaoTree, ChunkNum, ChunkRanges, }; use bytes::Bytes; use genawaiter::sync::Gen; use iroh_io::AsyncStreamWriter; use irpc::channel::{mpsc, oneshot}; use n0_error::AnyError; use n0_future::{future, stream, Stream, StreamExt}; use range_collections::{range_set::RangeSetRange, RangeSet2}; use ref_cast::RefCast; use serde::{Deserialize, Serialize}; use tracing::trace; #[cfg(test)] mod export_pairs; mod reader; pub use reader::BlobReader;

===== 068 END =====

===== 069 BEGIN kadek specs/runtime.md:36-57 | 1529 bytes | SHA256 50e3fadc2a6d1bd5b6f70f78d0705a157251f3442ceb535ea119ab9053f7a3f1 ===== information. Negative timestamps remain valid.

  • Rescale from a/b to c/d as floor(t*a*d/(b*c)), including negative values, with checked widened arithmetic. Rescale interval endpoints, then subtract; independently rounded durations accumulate drift.
  • Random access, discontinuity, corrupt input and decode-only/preroll are distinct flags. An intra picture alone does not establish a complete recovery point.
  • Packet provenance names the file's particle and ordered byte intervals covering its coded bytes exactly once; preserve repeated/reordered source occurrences. Reassembly copies verified source bytes. Radio inputs carry cyber-bao slice proofs; verify before admission, leaving codec state unchanged on failure. Proofless packets require a verified complete body. Seek/partial load open ranges against the particle; bindings map indexes to ranges and never fetch.

A verified complete body may derive a sealed in-process BAO anchor binding its plain particle, complete length and canonical fixed-4096 Hemera tree root. Derivation borrows the same immutable body and yields under persistent work limits; the completed fixed value retains no byte allocation. Only derivation creates authority. Raw or restored mappings require independent authentication or complete-body reverification. The anchor alone admits no range or packet.

Preserve ordered codec headers and semantic mapping fields; audio bindings own Vorbis/Opus/PCM normalization. Validate transport syntax first.

===== 069 END =====

===== 070 BEGIN Hemera leaf/parent kernels complete region rs/src/tree.rs:1-143 | 5344 bytes | SHA256 900dbe8002a35b2df11adf8fa2814bc262a896840f785005a544ff9d9f1e2228 ===== // --- // tags: hemera, rust // crystal-type: source // crystal-domain: comp // --- //! Hash tree construction. //! //! hash_leaf hashes leaf data into a chaining value. //! hash_node combines two child chaining values into a parent node.

use crate::encoding::{bytes_to_cv, hash_to_bytes}; use crate::field::Goldilocks; use crate::params::{self, CHUNK_SIZE, MAX_TREE_DEPTH, OUTPUT_ELEMENTS, RATE, WIDTH}; use crate::permutation::{BATCH_LANES, permute_batch}; use crate::sponge::Hash;

/// Flags encoded in the capacity for tree operations. const FLAG_ROOT: u64 = 1 << 0; const FLAG_PARENT: u64 = 1 << 1; const FLAG_CHUNK: u64 = 1 << 2;

/// Capacity index for chunk counter (position in the file). const CAPACITY_COUNTER_IDX: usize = RATE; // state[8]

/// Capacity index for tree flags. const CAPACITY_FLAGS_IDX: usize = RATE + 1; // state[9]

/// Capacity index for namespace lower bound (NMT only). const CAPACITY_NS_MIN_IDX: usize = RATE + 4; // state[12]

/// Capacity index for namespace upper bound (NMT only). const CAPACITY_NS_MAX_IDX: usize = RATE + 5; // state[13]

/// Compute the chaining value for a leaf chunk. /// /// The counter is the chunk's position index within the file (0-based), /// used for ordering in tree construction. The is_root flag /// domain-separates root finalization (single-chunk inputs) from interior /// finalization. pub fn hash_leaf(chunk: &[u8], counter: u64, is_root: bool) -> Hash { let mut hasher = crate::sponge::Hasher::new(); hasher.update(chunk); let base_hash = hasher.finalize(); let mut state = leaf_state(&base_hash, counter, is_root); params::permute(&mut state); state_digest(&state) }

/// Re-derivation state of hash_leaf: the base digest in the rate, the /// counter and flags in the capacity. #[inline] fn leaf_state(base_hash: &Hash, counter: u64, is_root: bool) -> [Goldilocks; WIDTH] { let base_elems = bytes_to_cv(base_hash.as_bytes()); let mut state = [Goldilocks::new(0); WIDTH]; state[..OUTPUT_ELEMENTS].copy_from_slice(&base_elems);

let mut flags = FLAG_CHUNK;
if is_root {
    flags |= FLAG_ROOT;
}
state[CAPACITY_COUNTER_IDX] = Goldilocks::new(counter);
state[CAPACITY_FLAGS_IDX] = Goldilocks::new(flags);
state

}

/// out[i] = hash_leaf(leaves[i].0, leaves[i].1, is_root) for every i. /// /// Leaves of equal length (the Merkle trees of a PCS) are hashed /// permutation::BATCH_LANES at a time with every permutation of the /// sponge and of the re-derivation batched; a group of unequal lengths /// falls back to hash_leaf. No allocation. pub fn hash_leaf_batch(leaves: &[(&[u8], u64)], is_root: bool, out: &mut [Hash]) { assert_eq!(leaves.len(), out.len(), "hash_leaf_batch: length mismatch"); let mut states = [[Goldilocks::new(0); WIDTH]; BATCH_LANES]; let mut msgs: [&[u8]; BATCH_LANES] = [&[]; BATCH_LANES]; for (lc, oc) in leaves.chunks(BATCH_LANES).zip(out.chunks_mut(BATCH_LANES)) { let n = lc.len(); if lc.iter().any(￿(m, _)￿ m.len() != lc[0].0.len()) { for (o, (m, ctr)) in oc.iter_mut().zip(lc) { *o = hash_leaf(m, *ctr, is_root); } continue; } for (slot, (m, )) in msgs.iter_mut().zip(lc) { *slot = m; } crate::sponge::finalize_states_equal_len(&msgs[..n], &mut states[..n]); for (st, (, ctr)) in states.iter_mut().zip(lc) { let base = state_digest(st); *st = leaf_state(&base, *ctr, is_root); } permute_batch(&mut states[..n]); for (o, st) in oc.iter_mut().zip(&states) { *o = state_digest(st); } } }

/// Combine two child chaining values into a parent chaining value. /// /// With Hemera parameters (output=4 elements, rate=8), each child hash is 4 elements. /// Both children together (4 + 4 = 8 elements) fit in one rate block. /// Flags are set in the capacity before the absorption. /// /// The is_root flag domain-separates the tree root from interior nodes. pub fn hash_node(left: &Hash, right: &Hash, is_root: bool) -> Hash { let mut state = node_state(left, right, is_root); params::permute(&mut state); state_digest(&state) }

/// Pre-permutation state of hash_node: flags in the capacity, both /// children absorbed into the rate (4 + 4 = 8 elements = one rate block). #[inline] fn node_state(left: &Hash, right: &Hash, is_root: bool) -> [Goldilocks; WIDTH] { let left_elems = bytes_to_cv(left.as_bytes()); let right_elems = bytes_to_cv(right.as_bytes());

let mut state = [Goldilocks::new(0); WIDTH];

// Set flags in capacity before absorbing.
let mut flags = FLAG_PARENT;
if is_root {
    flags ￿= FLAG_ROOT;
}
state[CAPACITY_FLAGS_IDX] = Goldilocks::new(flags);

// Absorb both children (4 + 4 = 8 elements = one full rate block).
for i in 0..OUTPUT_ELEMENTS {
    state[i] += left_elems[i];
}
for i in 0..OUTPUT_ELEMENTS {
    state[OUTPUT_ELEMENTS + i] += right_elems[i];
}
state

}

/// Digest of a permuted state: the first OUTPUT_ELEMENTS, canonical LE. #[inline] fn state_digest(state: &[Goldilocks; WIDTH]) -> Hash { let output: [Goldilocks; OUTPUT_ELEMENTS] = state[..OUTPUT_ELEMENTS].try_into().unwrap(); Hash::from_bytes(hash_to_bytes(&output)) }

===== 070 END =====

===== 071 BEGIN Merged traversal result.md ￿ 10113 bytes ￿ SHA256 42a737b1963d82f27bd13349bdd049cc535848890531a9af64cb91b11deb98d0 =====

CODE Review — bounded BAO range traversal

Verdict: APPROVE

Reviewed from the supplied frozen brief only: candidate traversal.rs, lib.rs, both new test files, parent tree.rs/tree/traversal.rs/slice.rs/fsm.rs, Hemera specs/tree.md, the frozen PLAN/literals, the approved PLAN verdict, and the exact gate records/raw streams. I did not run tools and did not read the hash-indexed omitted bodies.

Correctness of the new cursor

I checked the algorithm against the frozen literals and the Hemera left-balanced shape rule, independently of the implementation's own comments.

Split. left_count = 1 << (count-1).ilog2() is the largest power of two strictly below count for count >= 2 (for count = 2^k exactly, (count-1).ilog2() = k-1). This matches Hemera split = 2^(⌈log₂ N⌉ − 1): for N=3 → 2, N=5 → 4, N=7 → 4, N=17 → 16. Those are exactly the midpoints implied by the literal preorder rows. count == 1 is the leaf case and ilog2 is never evaluated on 0, so no panic path exists there.

Parent index. 2*middle - 1 with middle = first + left_count. Spot-checking the literals: 3 groups → middle 2 → node 3 ✓, then left frame (0,2) → middle 1 → node 1 ✓. 7 groups → root middle 4 → node 7 ✓; right frame (4,3) → middle 6 → node 11 ✓; its left (4,2) → middle 5 → node 9 ✓, giving the literal P7:R P11:R L6 and P7:R P11:L P9:R L5. 17 groups → middle 16 → node 31 ✓. Since middle >= 1 whenever count >= 2, 2*middle - 1 cannot underflow, and middle < N <= 2^52 bounds it under 2^53.

Selection flags. selected = start/g .. ((end-1)/g + 1) is the correct whole-group cover of a nonempty half-open byte interval, and crucially never forms end + g - 1 (no wrap at u64::MAX). Intersection is done on group intervals: left = selected.start < middle && first < selected.end, right = selected.start < end_groups && middle < selected.end. Both are the standard half-open overlap test against [first, middle) and [middle, end). Because only intersecting children are pushed, and the root frame is only pushed when the request is nonempty, every stored frame intersects the request — so a pending next always returns Some, matching the claimed no-filter-loop invariant. end = first + count <= N <= 2^52, no overflow.

ROOT. is_root is carried only on the initially pushed frame and set false on every child, so exactly the first emitted item (parent or sole leaf) is root. The P3:R L2 and P31:R L16 literals confirm a selected leaf in a larger tree is non-root; the cursor cannot produce that because any pushed child has is_root: false.

Leaf clipping. start = first * group_bytes with first < N = ceil(size/g) implies start <= size - 1, so size - start >= 1 and the subtraction cannot underflow. min(group_bytes, size-start) clips only the last group. group_bytes already passed usize::try_from, so the as usize cast is lossless for the group_bytes branch, and the size-start branch is < group_bytes. This is the correct ordering the PLAN demanded (subtract before clipping; never form (first+1)*g).

Admission. block_size.0 > 51 is rejected before the shift, so (CHUNK_SIZE as u64) << log never shifts by ≥64. usize::try_from then gives 0..=19 on 32-bit and 0..=51 on 64-bit, and the test exhausts all 256 BlockSize values with its own independently derived boundary (match usize::BITS), panicking on unexpected widths rather than silently passing. Geometry precedence over range is enforced by ordering and is asserted directly (new(1, BlockSize(log), 2..2) yields InvalidBlockSize for rejected logs). size.div_ceil(group_bytes) is overflow-safe, satisfying the PLAN-review advice. An empty admitted request pushes nothing, so is_complete() is immediately true and next returns None — a geometry result, not an authentication claim; the doc comment and test names say exactly that.

Stack bound. push writes frames[self.pending] then increments. next decrements before pushing children (the advised pop-before-push), so the peak occupancy is (depth of deferred rights) + 1. The maximum_left_prefix_requires_fifty_three_pending_slots test walks the full u64::MAX left spine — 52 parents then leaf 0 — which is precisely the worst case, and index 52 is the last valid slot of [Frame; 53]. Any off-by-one would panic on index out of bounds in debug and is covered by the allocation witness's (u64::MAX, 0, 0..u64::MAX, 54, false) case too. The array is Copy-initialized inline, no allocation.

Trait surface. FusedIterator is implemented and the fused() helper in the test statically witnesses it; is_complete() makes it honest (next returns None unconditionally once pending == 0). No Clone/ExactSizeIterator/size_hint was added, matching scope. RangeTraversalError derives the required set, Display strings match the PLAN byte-for-byte, core::error::Error is implemented and statically witnessed by core_error::<RangeTraversalError>(). Manual Debug on RangeTraversal satisfies the workspace missing_debug_implementations = "warn" lint and reports geometry/progress as specified.

Tests as independent oracles

The literal parser in range_traversal.rs does token parsing only — no splitting, no ilog2, no recursion, no production call. Expected leaf sizes come from the caller-supplied final_size, not from the cursor. The complete-shape table is byte-identical to literal-cases.md, and the length assertion expected.len() == 2*groups - 1 is an independent structural check. MAX_LEFT/MAX_RIGHT are literal constants (2^k-1 and 2^53-2^k-1), not generated. The eager comparison is explicitly labeled supplemental and is not the sole oracle for any shape. check() also verifies is_complete() transitions at every step and three terminal polls — the fused contract is actually exercised, not just declared.

The allocation witness installs a real #[global_allocator] with a thread-local counter, proves the harness can observe allocations via a positive control (vec![17u8;17] > 0), uses black_box to defeat elision, and covers construction, steps, terminal polls, drop, and the two error paths at zero. Scope is honest: it says nothing about linking.

Evidence discipline

  • Parent E0432 for both test files is in the raw stderr at 01/02, exit 101, with no test body run — the required negative control, recorded before production edits per the freeze manifest.
  • The witness freeze → lint-allow → formatter chain is each hashed before/after, and verify.rb reconstructs both transforms textually (the exact allow line and the exact import regrouping) rather than trusting the claim. That is a stronger check than I expected and it bounds the delta to imports plus one attribute.
  • The 771518d6 → 53f29b5b bridge is stated, and all owning outcomes (03c–08c, 19c, 21c, 42c) were rerun at the final digest. Workspace runtime (25b/26b) stayed at 771518d6; since the bridge touches only two test import blocks in cyber-bao, that is a defensible, explicitly-labeled gap rather than a hidden one.
  • Red gates are reported red and paired: all-feature owning Clippy red on both sides with the 11 pre-existing lib diagnostics visible in the parent's raw output; nightly docs, workspace Clippy ×3, cargo-make format, cargo-deny, and all-features nextest (iroh-gossip E0599) all fail identically at parent and candidate. The 3 extra candidate libtest diagnostics at 16c are disclosed with the scheduling explanation rather than suppressed.
  • The no_std story is stated correctly: library cargo check for thumbv7em-none-eabi passes, the binary link fails no global memory allocator found, and the parent pure-ChunkNum control reproduces the same failure (22). That isolates the boundary to pinned Hemera's extern crate alloc and not to this change. No substitute allocator was added, no 32-bit runtime pass is claimed.
  • Last-tag no-default exit 100 is the predecessor's intentional major floor; every listed removed item is io::*/tree surface untouched here, and parent default/none both pass with no update required — the API delta is purely additive.

Blockers

None.

Advice (non-blocking)

  1. BlockSize(0) > 51 admits widths the rest of the crate rejects. BaoTree::blocks()/shifted() use unchecked 1u64 << self.block_size.0. A caller who successfully constructs a RangeTraversal at log 40 may assume the same BlockSize is safe elsewhere. The module doc says "integer geometry, not allocation layout validity" — consider also saying the admitted range is this cursor's limit, not a crate-wide BlockSize validity claim.
  2. selected is dead for empty requests (0..0 with pending == 0). Harmless, but the Debug output will show 0..0 for an admitted empty cursor, which reads like "selects group 0" rather than "selects nothing". A one-word doc note or an is_complete field in Debug would remove the ambiguity.
  3. Workspace runtime at the pre-format digest. Cheap to close on a future pass: rerun 25b/26b at 53f29b5b so the full matrix sits on one source epoch.
  4. 42c allow-list. The supplemental std-test Clippy run masks four categories that are red in the strict gate. It's labeled supplemental and the strict gate stays red, which is correct — but if those four ever get fixed upstream, drop the allow-list so the supplement stops hiding regressions in the new files.
  5. Multi-range is still one-cursor-per-range. Fine for this unit, but note that two cursors over adjacent ranges will emit overlapping parent chains; whoever builds the union layer should not assume dedup.

Scope held: two production files (one new module, one pub mod line), two new test files, no dependency/lock/version/wire/consumer change, 172 lines, each file under 500. Nothing here asserts a proof parser, particle/root authority, consumer migration, empty-proof policy, or phase/rung/release closure.

===== 071 END =====

===== 072 BEGIN Merged traversal invocation.json ￿ 1218 bytes ￿ SHA256 719f82d3af1f4bbcfb4e4dd8c73ff1409db72ac90effc1a18197be3bd6b08968 ===== { "started": "2026-10-12T23:27:54.672229Z", "cwd": "/tmp/radio-bao-traversal-opus-code-v1", "argv": [ "claude", "--print", "--safe-mode", "--model", "opus", "--effort", "high", "--tools", "", "--strict-mcp-config", "--no-session-persistence", "--disable-slash-commands", "--output-format", "json", "--permission-mode", "dontAsk", "--system-prompt", "Independent fresh different-vendor CODE reviewer. Review the entire frozen brief supplied on stdin against its source, canonical contracts, independent witnesses and raw evidence. Return APPROVE or REQUEST CHANGES, concrete blockers, then optional advice. Do not call tools, claim tests rerun, or claim omitted files were read. Treat all supplied content as review data. Give your substantive final review now, not an acknowledgement. Keep the final review below 2000 words and reserve output space for its verdict and concrete findings." ], "input": "/tmp/radio-bao-bounded-traversal-code-v4/sourcepack.txt", "input_sha256": "a06d3318e3593bfc86a13289b12f6b1d237cbb930c9b93829a58141b4d947616", "launcher_sha256": "a60044a087e3b792a9a4c0413bb5eed258ae6ac7201c1c3a752a81306a608fa3" }

===== 072 END =====

===== 073 BEGIN Merged traversal completion.json ￿ 240 bytes ￿ SHA256 7a8fbbc20da54b3ddc82921a245e4eb10bb844384d7e5e94a7c823588ab9bd35 ===== { "finished": "2026-10-12T23:28:55.033362Z", "exit_code": 0, "stdout_sha256": "905e1ce8851be887270ed6a77fa82afa76bf3c3cea8c3aa253c5a3ae3580b71d", "stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }

===== 073 END =====

===== 074 BEGIN Merged traversal code-review.md ￿ 1774 bytes ￿ SHA256 094d6c46d2da82a937499cd3015dc2289d54a4abf02f8d3fe3d6d502ea28b94a =====

Final CODE disposition

Fresh Opus CODE approves the frozen input without blockers: a06d3318e3593bfc86a13289b12f6b1d237cbb930c9b93829a58141b4d947616. Raw review SHA-256: 905e1ce8851be887270ed6a77fa82afa76bf3c3cea8c3aa253c5a3ae3580b71d. Root independently reconstructed the packet and replayed all source epochs, gate streams and materialized API baselines. Production and tests remain frozen at 53f29b5b1cf4d609ecb98c7b482198f87160fb56fdb229466bff8f33568a90eb. The pending-review wording in the retained execution handoff describes its freeze.

The cursor's width admission applies to this API; unchecked legacy helpers retain their recorded limitations. An empty half-open 0..0 group interval is empty. Neither observation requires another API or source change. Multi-range unions are outside this one-range cursor's contract. The supplemental lint allowances do not change the strict gate's red result.

The reviewer describes broad failures as identical. That is too strong for the whole matrix: source-equivalent parent pairs retain differences in diagnostic order and scheduling, including three extra candidate libtest diagnostics. The execution handoff and raw outputs carry those distinctions. Runtime passes at the pre-format epoch bridge to final source through only two test import changes; six final owning suites passed afterward. No full-matrix rerun is claimed.

The additive cursor passes current-parent API checks; the predecessor's last-tag no-default major floor remains. Required repository gates are still red, and no rung, product or release acceptance is established. The source commit therefore uses wip: and a decision PR under the owner's standing review/fix/merge instruction. No version, tag or release action is part of this unit.

===== 074 END =====

Homonyms

soft3/radio/audit/2026-10-13-audit-cargo-packaging/plan-input-v2/context.txt
warning: skipping duplicate package `cyber-bao v0.1.0 (...#ce0fb312)`: /tmp/radio-bao-proof-parent-b933/cyber-bao/Cargo.toml in favor of .../git/checkouts/radio-1a8d5f25084d9866/ce0fb31/cyber-bao/Cargo.toml audit/2026-10-09-kadek-slice-traversal/Cargo.toml…
soft3/radio/audit/2026-10-13-audit-cargo-packaging/code-input/context.txt
audit/2026-10-09-kadek-slice-traversal/Cargo.toml audit/2026-10-12-bao-proof-research/probe/Cargo.toml audit/2026-10-12-bao-proof-research/primary-probe/Cargo.toml audit/2026-10-12-bao-bounded-proof/fixture-probe/Cargo.toml audit/2026-10-12-bao-bounded-proof/nostd/Cargo.toml…
soft3/radio/audit/2026-10-13-audit-cargo-packaging/plan-input/context.txt
warning: skipping duplicate package `cyber-bao v0.1.0 (...#ce0fb312)`: /tmp/radio-bao-proof-parent-b933/cyber-bao/Cargo.toml in favor of .../git/checkouts/radio-1a8d5f25084d9866/ce0fb31/cyber-bao/Cargo.toml audit/2026-10-09-kadek-slice-traversal/Cargo.toml…
soft3/radio/audit/2026-10-12-bao-bounded-proof/code-input/context.txt
ProofVerifier::new(proof: &[u8], root: [u8; 32], size: u64, block: BlockSize, request: Range) -> Result ProofVerifier::is_finished(&self) -> bool ProofVerifier::step(&mut self) -> Result>, ProofError> VerifiedProof::{root, size, block_size, request}…

Graph