{
"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<u64>,\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<u64>,\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) -> Option<Self::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
}