diff --git a/AUDIT-MANIFEST.sha256 b/AUDIT-MANIFEST.sha256 new file mode 100644 index 0000000..fcd2cf7 --- /dev/null +++ b/AUDIT-MANIFEST.sha256 @@ -0,0 +1 @@ +3cdb7cab4b1a6e0ebc8f0aa85c0b521c8cccc2d81f1ea45a82c53a15abbd8e04 audit-output.json diff --git a/AUDIT-TRAIL.ndjson b/AUDIT-TRAIL.ndjson new file mode 100644 index 0000000..b6de548 --- /dev/null +++ b/AUDIT-TRAIL.ndjson @@ -0,0 +1,5 @@ +{"generated_at_utc":"2026-05-04T21:32:58.145Z","auditor":"Riverbraid Byte Floor Auditor","report_version":"1.0.0","target_ring":2,"byte_gate_status":"BYTE_GATE_BLOCKED","audit_output_sha256":"dd7f762705f35b7f08aa3e9e44b072281f60dc3a2ba3524244da777cb3c29002","blocked_repos":[{"name":"Riverbraid-RDK","failure_codes":["BOM_PRESENT","DIRTY_WORKTREE"]},{"name":"Riverbraid-Gold-UI","failure_codes":["BOM_PRESENT","DIRTY_WORKTREE"]},{"name":"Riverbraid-Wasm-Bridge","failure_codes":["BOM_PRESENT","DIRTY_WORKTREE"]},{"name":"riverbraid-tsh","failure_codes":["BOM_PRESENT","DIRTY_WORKTREE"]},{"name":"Riverbraid-Lite","failure_codes":["BOM_PRESENT","DIRTY_WORKTREE"]},{"name":"Riverbraid-Lang","failure_codes":["BOM_PRESENT"]}]} +{"generated_at_utc":"2026-05-04T21:39:28.877Z","auditor":"Riverbraid Byte Floor Auditor","report_version":"1.0.0","target_ring":2,"byte_gate_status":"BYTE_GATE_BLOCKED","audit_output_sha256":"ed24833ebe2b9d01f8b2e7125a82460678b7c3b5ab336a2ffcbb55f9688f8cc8","blocked_repos":[{"name":"Riverbraid-RDK","failure_codes":["DIRTY_WORKTREE"]},{"name":"Riverbraid-Gold-UI","failure_codes":["DIRTY_WORKTREE"]},{"name":"Riverbraid-Wasm-Bridge","failure_codes":["DIRTY_WORKTREE"]},{"name":"riverbraid-tsh","failure_codes":["DIRTY_WORKTREE"]},{"name":"Riverbraid-Lite","failure_codes":["DIRTY_WORKTREE"]},{"name":"Riverbraid-Lang","failure_codes":["DIRTY_WORKTREE"]}]} +{"generated_at_utc":"2026-05-04T21:49:44.530Z","auditor":"Riverbraid Byte Floor Auditor","report_version":"1.0.0","target_ring":2,"byte_gate_status":"BYTE_GATE_BLOCKED","audit_output_sha256":"ed24177e155483c68dad588e157e5d9d7e06d58d4aac4967c7aa9138c40e8212","blocked_repos":[{"name":"Riverbraid-RDK","failure_codes":["DIRTY_WORKTREE"]},{"name":"Riverbraid-Gold-UI","failure_codes":["DIRTY_WORKTREE"]},{"name":"riverbraid-tsh","failure_codes":["DIRTY_WORKTREE"]}]} +{"generated_at_utc":"2026-05-04T21:52:03.858Z","auditor":"Riverbraid Byte Floor Auditor","report_version":"1.0.0","target_ring":2,"byte_gate_status":"BYTE_GATE_PASS_VERIFIED","audit_output_sha256":"3cdb7cab4b1a6e0ebc8f0aa85c0b521c8cccc2d81f1ea45a82c53a15abbd8e04","blocked_repos":[]} +{"generated_at_utc":"2026-05-04T21:55:48.557Z","auditor":"Riverbraid Byte Floor Auditor","report_version":"1.0.0","target_ring":2,"byte_gate_status":"BYTE_GATE_PASS_VERIFIED","audit_output_sha256":"3cdb7cab4b1a6e0ebc8f0aa85c0b521c8cccc2d81f1ea45a82c53a15abbd8e04","blocked_repos":[]} diff --git a/audit-output.json b/audit-output.json new file mode 100644 index 0000000..8ed8304 --- /dev/null +++ b/audit-output.json @@ -0,0 +1 @@ +{"audit_preimage_sha256":"237c56f6844b71f6047caa07cb828b24394d3bde759a6182cd62314907b5cebd","auditor":"Riverbraid Byte Floor Auditor","claim_boundary":"byte-level-local-audit-trail","manifest":{"cluster_version":"v1.5.0-STATIONARY","constellation_root":"de2062","full_constellation_claimed":false,"path":"cluster-manifest-v2.json","schema":"riverbraid-cluster-manifest","sha256":"8bf7c8e4e8808d62bbca742ec804be4b228e2c4fc9c717eab9fd172fd3d68d6e","version":"2.0.0"},"report_version":"1.0.0","repos":[{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"sdk","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"09ab691b8b6305e0d1077f58a4d85cfe4eda9359","missing_required_files":[],"name":"Riverbraid-RDK","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-RDK","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":13,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"99b048e9973c093bbecdc4128b887cd4eab1978e0bfe2b928446d86f0ceaecd4","size_bytes":36},{"bom_present":false,"path":".gitattributes","sha256":"a79691a93b46e49ce460c26ef22afcc03d6eca1e63bf2edbc20e96159510f6c9","size_bytes":14},{"bom_present":false,"path":"AUTHORITY.md","sha256":"ba207933dc4e1490df154350623f424eb1a209dbb504ed857b992309cb926f60","size_bytes":757},{"bom_present":false,"path":"README.md","sha256":"eaca78e0c9fce7522b2ffdaebd5647464a236883e3f9befda47fe9e2b2a85da5","size_bytes":550},{"bom_present":false,"path":"RING.md","sha256":"e0522897a4cc5348501e2cbf146913b62601b3ad75b7dc768dc620fa8ed15ff9","size_bytes":595},{"bom_present":false,"path":"manifest.json","sha256":"88a93d67d64ce8b67e80fb4f904a130a8cb8a0eed0022caff652d1774314a8f7","size_bytes":245},{"bom_present":false,"path":"package.json","sha256":"f373d2926ceb86b260b64f740b5bef97eed36460c4d381a8f1c5784aac3d1b66","size_bytes":189},{"bom_present":false,"path":"repo.role.json","sha256":"a8984603a2cf9bb3556bcdd218ec07e443caf021480971de08f4f19681543248","size_bytes":135},{"bom_present":false,"path":"riverbraid","sha256":"1332d1e5f895dfd17dd45d025708b95bdebc5c05515f0ebc3640e845c60b91d9","size_bytes":1240},{"bom_present":false,"path":"tests/baseline.test.js","sha256":"c139253429bc03126d36f5533eb2fa046d661224ad6411acb88c82656cec7873","size_bytes":167},{"bom_present":false,"path":"v2.1.0-release.json","sha256":"2e794ac440a4b8dd35f96e5d347f8dcb47b6f965ab35a9698e6b1d7f00c9a9af","size_bytes":150},{"bom_present":false,"path":"verify-output.json","sha256":"ab5fe47a51fda28d770de10adad16aff884dd34c74c3793acd08c7428d71daa1","size_bytes":636},{"bom_present":false,"path":"verify.mjs","sha256":"3e091486fc533d3cd011690713bf2a8da8db6985261c83482a265eb385526f71","size_bytes":1951}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"ab5fe47a51fda28d770de10adad16aff884dd34c74c3793acd08c7428d71daa1","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"ui-runtime","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"be2d1b71e5992544d9aba01051800e531143efa0","missing_required_files":[],"name":"Riverbraid-Gold-UI","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-Gold-UI","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":34,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"4525870f3636eb1b6710e54eeb1da681f6d52df6b1f4e000a5e5b7dfa3e76a8c","size_bytes":37},{"bom_present":false,"path":".github/workflows/deploy.yml","sha256":"ddc294458317dd85667d0e4cea8753ba73483d03530e025b4422a414a71f36c1","size_bytes":864},{"bom_present":false,"path":".gitignore","sha256":"b4c1f4ee98933599ec3e0b98b771f3590e178bca86923235b408201bce778ccb","size_bytes":285},{"bom_present":false,"path":"AUTHORITY.md","sha256":"a7ea66554f226072b4f11cc24e1361613a9363dc18891408363083b0b587f1d7","size_bytes":791},{"bom_present":false,"path":"README.md","sha256":"dc23d443277b72ae63277447f67a659216dcfff010b666eced76855106ff4bf5","size_bytes":980},{"bom_present":false,"path":"RING.md","sha256":"562c32da399b4fa81371ad30ee02b384d10034d42ce807a5c5ead2ff7ca5c2cb","size_bytes":651},{"bom_present":false,"path":"eslint.config.js","sha256":"f19395caf80173ffbd41ab74f8eef4fc26c042f84a937de4a6286ec5c13ad401","size_bytes":613},{"bom_present":false,"path":"feature-flow.json","sha256":"2d6f0a3445039ef920c14736ddd87a9f72759a78b09fbcf5c285514f17e31ab5","size_bytes":773},{"bom_present":false,"path":"index.html","sha256":"b38e33dfe5c407e74ef22e4f7ad4e44c546233d7c2561a24172af4a79ba4224f","size_bytes":383},{"bom_present":false,"path":"merkle-root.json","sha256":"bf17a04b7b23e3820331c37acaa84b15c1a5d2421433c18976978d7e8a62dc92","size_bytes":3751},{"bom_present":false,"path":"package-lock.json","sha256":"60ee82071a413cbece6e89c0f60124fb449edf13d2a56000e955cc7f829845e2","size_bytes":98898},{"bom_present":false,"path":"package.json","sha256":"a86c40c825d794a8b86286cb115ad00105a4875e8054c9c3ede589efaaf005c2","size_bytes":1560},{"bom_present":false,"path":"public/favicon.svg","sha256":"61bc9a161de58248288e6905425d7180f0624c2865007b97d763fdac12043a66","size_bytes":9522},{"bom_present":false,"path":"public/icons.svg","sha256":"7ca2d67c9c3aebf50cdc8709ee8aacf8cdb8cc7ea6325ea94939caef5da1c53d","size_bytes":5055},{"bom_present":true,"path":"rb.ps1","sha256":"9f58e016057b8f3afba610bebaf37f9cca63830c68afcd852dfaaa17daa85506","size_bytes":468},{"bom_present":false,"path":"rb.sh","sha256":"311082852890bde1b8e551ebc196cfe3f63cd671b8094446acc5ea76a26f1506","size_bytes":403},{"bom_present":false,"path":"riverbraid-manifest.json","sha256":"4485c1bb328c88842a5ec1b3070bd87eb41cc035c5981426be5926cc11fad413","size_bytes":339},{"bom_present":false,"path":"src/App.css","sha256":"c2571ce7245629994b8adc84f6c48e1920f047a4e7e29c89a4aeb51eeb1b5433","size_bytes":3075},{"bom_present":false,"path":"src/App.tsx","sha256":"8a32e9a97fb8a909806f24078a73138853b16d3276a1ade50904c1be05030fcb","size_bytes":4222},{"bom_present":false,"path":"src/assets/hero.png","sha256":"881ffbcaafc212e49addad08846a5b82761355fa20624253af3477ba33262c5c","size_bytes":13057},{"bom_present":false,"path":"src/assets/react.svg","sha256":"35ef61ed53b323ae94a16a8ec659b3d0af3880698791133f23b084085ab1c2e5","size_bytes":4126},{"bom_present":false,"path":"src/assets/vite.svg","sha256":"2f1f6c6f90a0ef7422cbb4cfafcd8ad329c507a18afdc34cc21fa72179b9c54a","size_bytes":8710},{"bom_present":false,"path":"src/index.css","sha256":"5fbfd1a31f47b772a2b90b54c4e8312e8d874ae7d994590a93c191cde97873d0","size_bytes":2280},{"bom_present":false,"path":"src/main.tsx","sha256":"138bf3b31a2cd1a6b2804a5f706941d9243034c52af497d42746f50f191ceb79","size_bytes":394},{"bom_present":false,"path":"src/services/bridge.ts","sha256":"fb1714e98b19211ad40deccad68534ffc8fdc38a56d6adcf41922caa8692b2e2","size_bytes":1447},{"bom_present":false,"path":"src/types/riverbraid.ts","sha256":"40378493bc1e513ddf0f3f85ed6099efdfd3a5fb32988bab5701b0fc742d77ae","size_bytes":419},{"bom_present":false,"path":"stationary.lock","sha256":"09fcb313596e0ea70c6bd5a0bf45af94b47e115734599fbc44a8af2a38088344","size_bytes":103},{"bom_present":false,"path":"tsconfig.app.json","sha256":"61ab483a94a0556e57ea95cc7353bb07b9f3084c0691364070bbf853910646e8","size_bytes":642},{"bom_present":false,"path":"tsconfig.json","sha256":"ad28d132ee48d6e23917cf5827cace785d0fc01a44ca68b0dda51cc8c3fd3f52","size_bytes":126},{"bom_present":false,"path":"tsconfig.node.json","sha256":"e0f1936992f77a707102795e8ea311ae74cb54de87b221bb32b44055af66ff7e","size_bytes":615},{"bom_present":false,"path":"verify-feature-flow.cjs","sha256":"a4b6a33d702c45970d97406ec37ed88fb419fc180dc2e8d5359974bf29d4b555","size_bytes":574},{"bom_present":false,"path":"verify-output.json","sha256":"fbe1dc7428af101bea447ad768ebd11f2b121c607eb420c9c594238a75a4b865","size_bytes":654},{"bom_present":false,"path":"verify.mjs","sha256":"8830631261140af186410b2316634c8cc0a7c7f16c479f9fed8d344b8a7de511","size_bytes":2211},{"bom_present":false,"path":"vite.config.ts","sha256":"5cabb639b6b62e19064337abc9f5b4fda0f83e50a47396ca9a3bba388abfdd13","size_bytes":168}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"fbe1dc7428af101bea447ad768ebd11f2b121c607eb420c9c594238a75a4b865","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"bridge","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"6fb8b2554254cdfdc07d17c810a1ebe86d49a6b8","missing_required_files":[],"name":"Riverbraid-Wasm-Bridge","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-Wasm-Bridge","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":19,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"4525870f3636eb1b6710e54eeb1da681f6d52df6b1f4e000a5e5b7dfa3e76a8c","size_bytes":37},{"bom_present":false,"path":".gitignore","sha256":"1e1eddd704e23d88caca1a9a46d9d1747dae67489a98a62afa9516bd4a35f90d","size_bytes":24},{"bom_present":false,"path":"AUTHORITY.md","sha256":"281a795cfcaea0117a414e59174f710bafc90b5affed8019f0678af3fab17c57","size_bytes":841},{"bom_present":false,"path":"Cargo.lock","sha256":"9e251f0d524d30a61fb2886d60e26b9dd24c2fb91ed94cec910022cd1f570569","size_bytes":2903},{"bom_present":false,"path":"Cargo.toml","sha256":"198981c326cb7af926f3f762157df878d37ca03863c0436530d350048b50fc12","size_bytes":224},{"bom_present":false,"path":"README.md","sha256":"4bdafaa91eb86523342678afaf38996c9928575ae4176a5b966fc5ac79eba2cc","size_bytes":748},{"bom_present":false,"path":"RING.md","sha256":"88a04a3ffdca885c58b8b6474de5ed748c4504066688df30ae190631d8ee4f79","size_bytes":634},{"bom_present":false,"path":"feature-flow.json","sha256":"02a80aa6690725e1c90374768d26f27dd6e4050fd5cbb69c88889a4ea55c6f39","size_bytes":781},{"bom_present":false,"path":"package-lock.json","sha256":"0067837dc89c18c95f9e6fd6bd913826b0e5a0f79dcd1807ba11f0753b681824","size_bytes":244},{"bom_present":false,"path":"package.json","sha256":"327e3dc737db0698869d59c37afce329d69eb81d92b81034d941fcf376c34ff9","size_bytes":988},{"bom_present":true,"path":"rb.ps1","sha256":"9f58e016057b8f3afba610bebaf37f9cca63830c68afcd852dfaaa17daa85506","size_bytes":468},{"bom_present":false,"path":"rb.sh","sha256":"311082852890bde1b8e551ebc196cfe3f63cd671b8094446acc5ea76a26f1506","size_bytes":403},{"bom_present":false,"path":"riverbraid.contract.json","sha256":"a7a192851a31990598b0300a1459daed128e71f732f9ece111b5f6bb6e47cd4e","size_bytes":142},{"bom_present":false,"path":"run-vectors.cjs","sha256":"becd95d631115108020a9bb2137c9ba013853e0dafa3af13297575025548a8f1","size_bytes":2185},{"bom_present":true,"path":"src/main.rs","sha256":"33a884f5081bfece0760c039b936d8147802cdb3e3f86a9596758c12c5a1e391","size_bytes":1011},{"bom_present":false,"path":"verify-feature-flow.cjs","sha256":"a4b6a33d702c45970d97406ec37ed88fb419fc180dc2e8d5359974bf29d4b555","size_bytes":574},{"bom_present":false,"path":"verify-output.json","sha256":"4ffcc0069486a775202a71c4d4aae325beb7e7e44d536d76c819180f5ef51e9b","size_bytes":650},{"bom_present":false,"path":"verify.mjs","sha256":"b93490ccdbb8559272ed2c7b1aa93ad7be37271a6c3051231670a384ec75592f","size_bytes":2181},{"bom_present":false,"path":"wasm-verify.cjs","sha256":"9312e6998fd564dc4801969a94864e6415f5e0bbc4c95961e50121d5e48d561e","size_bytes":1175}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"4ffcc0069486a775202a71c4d4aae325beb7e7e44d536d76c819180f5ef51e9b","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"signing-tool","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"0c48bec4563b5058f3acbb3296be6a5dc5a3ba2a","missing_required_files":[],"name":"riverbraid-tsh","repo_exists":true,"repo_path":"C:\\Riverbraid\\riverbraid-tsh","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":13,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"4525870f3636eb1b6710e54eeb1da681f6d52df6b1f4e000a5e5b7dfa3e76a8c","size_bytes":37},{"bom_present":false,"path":".gitignore","sha256":"f61c42065f048ea8fa74560cdb2ce376ca780b0904950df8b77d7a1156185c7f","size_bytes":9},{"bom_present":false,"path":"AUTHORITY.md","sha256":"d375d5a08b12d16830374ae65ca2849fe96c5b48672e908425c8daf94ccac781","size_bytes":163},{"bom_present":false,"path":"Cargo.lock","sha256":"682826f294a52015f93471ab5c293ddc7db1ad0794d3345c1b3732b1169aaf43","size_bytes":3106},{"bom_present":false,"path":"Cargo.toml","sha256":"0f6886e755b133015fa81d5f2d2b90469ada14fc3b4f668cc57f081868059de3","size_bytes":370},{"bom_present":false,"path":"RING.md","sha256":"8a951b2875da79c01c0a1726b992efdd53d43c8d8be34b2d664c8bd6f07fc4b5","size_bytes":167},{"bom_present":false,"path":"package.json","sha256":"20f292399c4db1a5913270d79c9d511a22f6a537d132475234f686a0ecbf9f2d","size_bytes":102},{"bom_present":true,"path":"rb.ps1","sha256":"9f58e016057b8f3afba610bebaf37f9cca63830c68afcd852dfaaa17daa85506","size_bytes":468},{"bom_present":false,"path":"rb.sh","sha256":"311082852890bde1b8e551ebc196cfe3f63cd671b8094446acc5ea76a26f1506","size_bytes":403},{"bom_present":true,"path":"src/lib.rs","sha256":"484d5d1010cdcabadba0fb111d8f9a050ee50d36930b4a980fe37a4ecd6e6592","size_bytes":1778},{"bom_present":true,"path":"src/main.rs","sha256":"9291c59722e642b32132d02b5bd49aad0b6a23cbd6191294446f15417fd4d091","size_bytes":1646},{"bom_present":false,"path":"verify-output.json","sha256":"f007f77c1bea6fa914bf1044868b7aa05f2730c834f8900f7a131778a3488ad8","size_bytes":654},{"bom_present":false,"path":"verify.mjs","sha256":"9ceb2d55315b130462aaf58414f5a9055e1e55721cde454cc65681877e167baa","size_bytes":1118}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"f007f77c1bea6fa914bf1044868b7aa05f2730c834f8900f7a131778a3488ad8","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"embedded-port","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"7416accd45c92672ee760204d9c85a61983b523d","missing_required_files":[],"name":"Riverbraid-Lite","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-Lite","required_files":["AUTHORITY.md","CMakeLists.txt","RING.md"],"ring":2,"tracked_file_count":17,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"20ff31b4e6e7fc0fe3b85cada3b89b8c6ea105253d4aa9f1abd2bc18483bafd9","size_bytes":35},{"bom_present":false,"path":".gitattributes","sha256":"79eac80e99dad292880e71c02ab02f2b4a5a39eb88e4fadb9b0891cbc9a2f3e4","size_bytes":72},{"bom_present":false,"path":".github/workflows/verify.yml","sha256":"f632c369f9f1c47a78ec9bd7dadae6d41d7982b843d0923120bb02b5d4088660","size_bytes":344},{"bom_present":false,"path":".gitignore","sha256":"4d56952b0fb13bf8f9b6c13a6d4c34a075bac3af447636a1df4335d7576e2f97","size_bytes":14},{"bom_present":false,"path":"AUTHORITY.md","sha256":"f7637cb574d4ade0efd12921cdacd33586f14c27581f56c6a7aeef3e330b9ba5","size_bytes":151},{"bom_present":false,"path":"CMakeLists.txt","sha256":"a714426c3019f4d1f97cea0d5e015c20046f99c7d7e088b2488fde084c792517","size_bytes":341},{"bom_present":false,"path":"README.md","sha256":"7a5b22f8ab4fcbf0d2fbd88b3f4ad9c4f025b24375412c94f7c93e89d0a8f05b","size_bytes":1187},{"bom_present":false,"path":"RING.md","sha256":"0b7118ed8a389359a5bc0d3c8ebd39780f1fa92d238490f60c94dda6af69745b","size_bytes":163},{"bom_present":false,"path":"index.js","sha256":"fbcf5b87357c728b582c40af9a76a2edb59d564efa4d48ec0eb7ddf9b6c15cf6","size_bytes":420},{"bom_present":false,"path":"package-lock.json","sha256":"086efd22b2b9c31b2c090746f20e9f5679ddccda3c721edb44e83f66e6dfc530","size_bytes":132052},{"bom_present":false,"path":"package.json","sha256":"a60132fa8752ab3810979c5d7a4fee8a20325df3bcf2521c0a8eece5c2aed8f4","size_bytes":143},{"bom_present":false,"path":"riverbraid.contract.json","sha256":"8e6a1f856494274fe019e4d17f8ac90d4a5f64eb81a1dfca45b50ff01fe8a53c","size_bytes":128},{"bom_present":false,"path":"spatial.js","sha256":"cae6b13e441a5c1fe40926c1b6d29c483af833fe3c7eb00c08a8e2c524bb8530","size_bytes":442},{"bom_present":false,"path":"tests/perimeter.test.js","sha256":"4622b9650cd21229e1b1fbf5804414180a4ad4247ae0052638716e6cb22d897a","size_bytes":493},{"bom_present":false,"path":"tests/signal.test.js","sha256":"5b98757e63c15584ec119068f0686806e70828f426a8d2f722b055df80413617","size_bytes":608},{"bom_present":false,"path":"verify-output.json","sha256":"98dfbbba29499bff749767339136a365168cbba5223de6376c94df847750fe24","size_bytes":679},{"bom_present":false,"path":"verify.mjs","sha256":"cb20ba499652baf625c313cf862ecae6051c696145ccc7670f18a738ee960094","size_bytes":1110}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"98dfbbba29499bff749767339136a365168cbba5223de6376c94df847750fe24","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"language-layer","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"9d18a7d68d75784c764bb30cb5789a1a34b6b79a","missing_required_files":[],"name":"Riverbraid-Lang","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-Lang","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":32,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"99b048e9973c093bbecdc4128b887cd4eab1978e0bfe2b928446d86f0ceaecd4","size_bytes":36},{"bom_present":false,"path":".eternal_seal","sha256":"4ba2165094cc656486214e9daee1f670f43aac3fdd5fd1115d7e9ffe6c675136","size_bytes":27},{"bom_present":false,"path":".gitattributes","sha256":"5a0188f970af2e037db6c26fcb0beb47fcf0efa3b778001516cb0758c8be797a","size_bytes":72},{"bom_present":false,"path":".gitignore","sha256":"69bd8b8e17d79f6b1d5a814b5a1c14cd8acac5640b78d0447d91d1ddd7f72d52","size_bytes":105},{"bom_present":false,"path":".gitmodules","sha256":"e67abb0d2f618cb42058aba9872bb82ee4849dd91c1a8ebc6822dac1f89fa187","size_bytes":111},{"bom_present":false,"path":".riverbraid/authority.json","sha256":"1e46060ba1141c7df6d33a8820fa45b4d613a794d2faf3c428d0d8c540897418","size_bytes":164},{"bom_present":false,"path":".stationary","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","size_bytes":0},{"bom_present":false,"path":"AUTHORITY.md","sha256":"9df9cf1620ab9111bb992c3f886b25b4afcf18f06aad646eee3fc4ce0819b53b","size_bytes":825},{"bom_present":false,"path":"GOVERNANCE.md","sha256":"7b79f60795a92139cf2a6e9d66f34a78dc72dbeb6fd41e278ab7e6e1c244e813","size_bytes":194},{"bom_present":false,"path":"README.md","sha256":"66c74e66c73258753127b64c34fad0d43be698c3daebd5d69cec4b1f0244cb73","size_bytes":913},{"bom_present":false,"path":"RING.md","sha256":"6abc9f32bf639ed3fcbeb7dd437114ac2447cd5ef906f7f729c1ec00c2d00c65","size_bytes":608},{"bom_present":false,"path":"SECURITY.md","sha256":"3985dcf7f58d6697d1ef0b2aec0027370a223d0df459e545b4a0a126f53292e0","size_bytes":296},{"bom_present":false,"path":"SPEC.md","sha256":"097ab262d5655624874c0e0f059deddd93808a3f5a129777fcf7844501c49afa","size_bytes":179},{"bom_present":false,"path":"constitution.snapshot.json","sha256":"287a5e5439f6ef8f5ff99901cde7d55429901ac7f0010f609d75040f744438cd","size_bytes":31034},{"bom_present":false,"path":"constitution.threshold.json","sha256":"cba982b49f5bb7b583afd8b59c7993bc788a5d7e132127bf583f2b5413a22aff","size_bytes":55},{"bom_present":false,"path":"feature-flow.json","sha256":"b83bb2673e4fdae9911f95a24d04b1be0b25c6f9bb5a4e0209fd4cca97f661fc","size_bytes":743},{"bom_present":false,"path":"index.js","sha256":"a8c361eb6db3ca999e51e559c485d5f8b7bd1056e446720fb091f09a3868f9d7","size_bytes":2061},{"bom_present":false,"path":"integrity-floor.json","sha256":"715432591d3d0f2785e8fa9ecb758454b4a34475981d3ef777ab16bc8fe0f6fd","size_bytes":155},{"bom_present":false,"path":"merkle-root.json","sha256":"98b81ccfe8bb6bf3b5398fce51ff5b2eabc3f23e5b5de12fa7c63fea5f32db36","size_bytes":166},{"bom_present":false,"path":"package-lock.json","sha256":"a5f3e667b054191dcda5c27d8d7e76472bdc0b4ed080cef1bd3cf852a5f26fd3","size_bytes":3062},{"bom_present":false,"path":"package.json","sha256":"df2d73065ecc6b4c974e5d4f427d59a76a476b922b1d9e6c81897ad379ca0c9b","size_bytes":876},{"bom_present":true,"path":"rb.ps1","sha256":"663b61e79e25e4d1dfc59b91a226a2a1a1f73f3df5584203819fc5562d0a81cf","size_bytes":451},{"bom_present":false,"path":"rb.sh","sha256":"3b042fad9aa980a05c115c27e0bdead8ea01bbd22380cd519a7ddca4578db248","size_bytes":388},{"bom_present":false,"path":"relational_ledger.jsonl","sha256":"68e92104609ecdbe79bb8a45f5951c2d9202af67e81cc7c4353767e27b1ac6c2","size_bytes":157},{"bom_present":false,"path":"riverbraid-verify-chain.js","sha256":"e3652b7d60d50a64f582a36c52b0768f7b0e27a75fef1fc57013769c15f1d78b","size_bytes":239},{"bom_present":false,"path":"riverbraid.contract.json","sha256":"38917705dd7212ee6e8de46f407a224cdea9594a6e1c48c727c9a43fda412ec4","size_bytes":135},{"bom_present":false,"path":"run-vectors.cjs","sha256":"26e737cba07051fb275a624236e6b8f14adda4db835f97381ab328caa3f13860","size_bytes":2136},{"bom_present":false,"path":"test-gate.sh","sha256":"c0c3ed04fb3d1554c853c9b34a528c45d78897190d5e3d6dd9206241e7f0244a","size_bytes":264},{"bom_present":false,"path":"verify-feature-flow.cjs","sha256":"cd0927bc675f4d75853b7aa267af7ad504695026fec2eb0abd84de59fc2b0271","size_bytes":562},{"bom_present":false,"path":"verify-output.json","sha256":"f0987f44372f9d297802822877b60b9702b84f3a9c3e80c3e4e47e68668b2247","size_bytes":653},{"bom_present":false,"path":"verify.mjs","sha256":"51d23e311bce0029a182f4d3c4a13b26d97d55cf4aee4979fdb3108539af5200","size_bytes":2094}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"f0987f44372f9d297802822877b60b9702b84f3a9c3e80c3e4e47e68668b2247","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"runtime-fork","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"d9059b137fa03ae511d19fe46c0cdfd32de439f6","missing_required_files":[],"name":"Riverbraid-p5","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-p5","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":27,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"99b048e9973c093bbecdc4128b887cd4eab1978e0bfe2b928446d86f0ceaecd4","size_bytes":36},{"bom_present":false,"path":".eternal_seal","sha256":"4ba2165094cc656486214e9daee1f670f43aac3fdd5fd1115d7e9ffe6c675136","size_bytes":27},{"bom_present":false,"path":".gitattributes","sha256":"5a0188f970af2e037db6c26fcb0beb47fcf0efa3b778001516cb0758c8be797a","size_bytes":72},{"bom_present":false,"path":".gitignore","sha256":"55311a99f8280d89946ebca753c44bf5aa524b2f405347d000d8c2a4adf9e00d","size_bytes":11},{"bom_present":false,"path":".gitmodules","sha256":"e67abb0d2f618cb42058aba9872bb82ee4849dd91c1a8ebc6822dac1f89fa187","size_bytes":111},{"bom_present":false,"path":".riverbraid/authority.json","sha256":"1e46060ba1141c7df6d33a8820fa45b4d613a794d2faf3c428d0d8c540897418","size_bytes":164},{"bom_present":false,"path":".stationary","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","size_bytes":0},{"bom_present":false,"path":"AUTHORITY.md","sha256":"c0a6a19461e9d1360db603bdb7250a848e0d15f8c3badf98fae01541974f4d85","size_bytes":778},{"bom_present":false,"path":"GOVERNANCE.md","sha256":"7b79f60795a92139cf2a6e9d66f34a78dc72dbeb6fd41e278ab7e6e1c244e813","size_bytes":194},{"bom_present":false,"path":"README.md","sha256":"e81deb81ed669cee2b6edc85aaa8d7b1dbcf465c523b1b27ecbad5944cc9865b","size_bytes":1327},{"bom_present":false,"path":"RING.md","sha256":"0d811f3f5dfa1380a580b73796c2fa8792e851d6df26161191fc64e1978b5cdf","size_bytes":602},{"bom_present":false,"path":"SECURITY.md","sha256":"3985dcf7f58d6697d1ef0b2aec0027370a223d0df459e545b4a0a126f53292e0","size_bytes":296},{"bom_present":false,"path":"SPEC.md","sha256":"097ab262d5655624874c0e0f059deddd93808a3f5a129777fcf7844501c49afa","size_bytes":179},{"bom_present":false,"path":"constitution.snapshot.json","sha256":"ecad54628ac731cd474652cb2bf7c01a09da50184ba538dc924228e023561128","size_bytes":31024},{"bom_present":false,"path":"constitution.threshold.json","sha256":"cba982b49f5bb7b583afd8b59c7993bc788a5d7e132127bf583f2b5413a22aff","size_bytes":55},{"bom_present":false,"path":"feature-flow.json","sha256":"413795e4b540c8e81f6872fc160c8488bfb50a97eea676badeec43c44a5ccda9","size_bytes":739},{"bom_present":false,"path":"merkle-root.json","sha256":"69a0641d31abae8d2aac8f3914e1475bc4f923cb036bc284358c09f9d2286e04","size_bytes":166},{"bom_present":false,"path":"package.json","sha256":"b448ba9ec034250ab6587d24be516665be6d36d153063cd87858da1f7f04a819","size_bytes":247},{"bom_present":true,"path":"rb.ps1","sha256":"663b61e79e25e4d1dfc59b91a226a2a1a1f73f3df5584203819fc5562d0a81cf","size_bytes":451},{"bom_present":false,"path":"rb.sh","sha256":"3b042fad9aa980a05c115c27e0bdead8ea01bbd22380cd519a7ddca4578db248","size_bytes":388},{"bom_present":false,"path":"run-vectors.cjs","sha256":"26e737cba07051fb275a624236e6b8f14adda4db835f97381ab328caa3f13860","size_bytes":2136},{"bom_present":false,"path":"test-gate.sh","sha256":"c0c3ed04fb3d1554c853c9b34a528c45d78897190d5e3d6dd9206241e7f0244a","size_bytes":264},{"bom_present":false,"path":"verify-feature-flow.cjs","sha256":"cd0927bc675f4d75853b7aa267af7ad504695026fec2eb0abd84de59fc2b0271","size_bytes":562},{"bom_present":false,"path":"verify-output.json","sha256":"6deebef086e32a58a722313f37cbbccb307ad4c9fc0c2ffb7d4ea56195821ab4","size_bytes":653},{"bom_present":false,"path":"verify-sketch.js","sha256":"3b064b2db48e5499a98a2d57d7c8684d5ae408a759e2f38a35014d477af7850f","size_bytes":312},{"bom_present":false,"path":"verify.mjs","sha256":"49b43f13f4affb44b4554cc15c34b5b84089b5957f91ffa1b1191d1925618156","size_bytes":2092}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"6deebef086e32a58a722313f37cbbccb307ad4c9fc0c2ffb7d4ea56195821ab4","status":"VERIFIED"}},{"bom_failures":[],"byte_status":"BYTE_VERIFIED","class":"runtime-fork","dirty":false,"dirty_entries":[],"failure_codes":[],"git_branch":"main","git_commit":"9ae772f95b1787d3754a24653a810bafcd55f98b","missing_required_files":[],"name":"Riverbraid-Hydra","repo_exists":true,"repo_path":"C:\\Riverbraid\\Riverbraid-Hydra","required_files":["AUTHORITY.md","RING.md","package.json"],"ring":2,"tracked_file_count":27,"tracked_files":[{"bom_present":false,"path":".anchor","sha256":"99b048e9973c093bbecdc4128b887cd4eab1978e0bfe2b928446d86f0ceaecd4","size_bytes":36},{"bom_present":false,"path":".eternal_seal","sha256":"4ba2165094cc656486214e9daee1f670f43aac3fdd5fd1115d7e9ffe6c675136","size_bytes":27},{"bom_present":false,"path":".gitattributes","sha256":"5a0188f970af2e037db6c26fcb0beb47fcf0efa3b778001516cb0758c8be797a","size_bytes":72},{"bom_present":false,"path":".gitignore","sha256":"55311a99f8280d89946ebca753c44bf5aa524b2f405347d000d8c2a4adf9e00d","size_bytes":11},{"bom_present":false,"path":".gitmodules","sha256":"e67abb0d2f618cb42058aba9872bb82ee4849dd91c1a8ebc6822dac1f89fa187","size_bytes":111},{"bom_present":false,"path":".riverbraid/authority.json","sha256":"1e46060ba1141c7df6d33a8820fa45b4d613a794d2faf3c428d0d8c540897418","size_bytes":164},{"bom_present":false,"path":".stationary","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","size_bytes":0},{"bom_present":false,"path":"AUTHORITY.md","sha256":"eec7fa8c89310d6b04f1e53d38645141f81a58f5a50592de2ae1d119afdcf808","size_bytes":782},{"bom_present":false,"path":"GOVERNANCE.md","sha256":"7b79f60795a92139cf2a6e9d66f34a78dc72dbeb6fd41e278ab7e6e1c244e813","size_bytes":194},{"bom_present":false,"path":"README.md","sha256":"e18588a4c1e3191c3f7f2b574944fa5534ed40f876e8e459d437cf4ab8e204cf","size_bytes":1310},{"bom_present":false,"path":"RING.md","sha256":"de8dae46e62933323ee6caeb472ee439a4d956563623ab50fc3be833ae394628","size_bytes":608},{"bom_present":false,"path":"SECURITY.md","sha256":"3985dcf7f58d6697d1ef0b2aec0027370a223d0df459e545b4a0a126f53292e0","size_bytes":296},{"bom_present":false,"path":"SPEC.md","sha256":"097ab262d5655624874c0e0f059deddd93808a3f5a129777fcf7844501c49afa","size_bytes":179},{"bom_present":false,"path":"constitution.snapshot.json","sha256":"4345914fbda17fb762388004421d58e3eded39ac4e34bfb228649fdb3cddd76f","size_bytes":31029},{"bom_present":false,"path":"constitution.threshold.json","sha256":"cba982b49f5bb7b583afd8b59c7993bc788a5d7e132127bf583f2b5413a22aff","size_bytes":55},{"bom_present":false,"path":"feature-flow.json","sha256":"8e376a6042d1b43ec8db236f9c42d00c7388e7c1dbfe5c1e84c74764a319517e","size_bytes":745},{"bom_present":false,"path":"merkle-root.json","sha256":"69a0641d31abae8d2aac8f3914e1475bc4f923cb036bc284358c09f9d2286e04","size_bytes":166},{"bom_present":false,"path":"package.json","sha256":"dc4eacd5af84cece89909ad713f76c74c79d9b055fcadd41dfc1dfc52e911c5a","size_bytes":319},{"bom_present":true,"path":"rb.ps1","sha256":"663b61e79e25e4d1dfc59b91a226a2a1a1f73f3df5584203819fc5562d0a81cf","size_bytes":451},{"bom_present":false,"path":"rb.sh","sha256":"3b042fad9aa980a05c115c27e0bdead8ea01bbd22380cd519a7ddca4578db248","size_bytes":388},{"bom_present":false,"path":"riverbraid-monitor.js","sha256":"25ebc7177a22c1b1c9929da54bcae10900ece7e5ddb011437642db51c0d5c62b","size_bytes":166},{"bom_present":false,"path":"run-vectors.cjs","sha256":"26e737cba07051fb275a624236e6b8f14adda4db835f97381ab328caa3f13860","size_bytes":2136},{"bom_present":false,"path":"test-gate.sh","sha256":"c0c3ed04fb3d1554c853c9b34a528c45d78897190d5e3d6dd9206241e7f0244a","size_bytes":264},{"bom_present":false,"path":"verify-feature-flow.cjs","sha256":"cd0927bc675f4d75853b7aa267af7ad504695026fec2eb0abd84de59fc2b0271","size_bytes":562},{"bom_present":false,"path":"verify-output.json","sha256":"2fffe22f956c14b342726c33066cbcefbc3e0c491a2cea7cd49c9771806c6963","size_bytes":656},{"bom_present":false,"path":"verify.mjs","sha256":"73a7cb38f4a1fa0168c15aadc75a5e2b6be796d1b8ae68592e70665b3fd675b6","size_bytes":2093}],"verify_output":{"bom_present":false,"failure_codes":[],"parse_ok":true,"present":true,"sha256":"2fffe22f956c14b342726c33066cbcefbc3e0c491a2cea7cd49c9771806c6963","status":"VERIFIED"}}],"summary":{"byte_blocked_count":0,"byte_gate_status":"BYTE_GATE_PASS_VERIFIED","byte_verified_count":8,"repo_count":8,"target_ring":2}} diff --git a/byte-audit.mjs b/byte-audit.mjs new file mode 100644 index 0000000..5e1de1b --- /dev/null +++ b/byte-audit.mjs @@ -0,0 +1,292 @@ +import fs from "node:fs"; +import path from "node:path"; +import crypto from "node:crypto"; +import { execFileSync } from "node:child_process"; + +const GENERATED_AUDIT_FILES = new Set([ + "audit-output.json", + "AUDIT-MANIFEST.sha256", + "AUDIT-TRAIL.ndjson" +]); + +const TEXT_EXTENSIONS = new Set([ + ".js", ".mjs", ".cjs", ".json", ".md", ".txt", ".yml", ".yaml", + ".toml", ".cmake", ".c", ".h", ".cpp", ".hpp", ".ts", ".tsx", + ".jsx", ".html", ".css", ".gitignore", ".gitattributes" +]); + +function fail(message) { + console.error(JSON.stringify({ status: "FAILED", reason: message }, null, 2)); + process.exit(1); +} + +function sha256Bytes(bytes) { + return crypto.createHash("sha256").update(bytes).digest("hex"); +} + +function readBytes(filePath) { + return fs.readFileSync(filePath); +} + +function hasBom(bytes) { + return bytes.length >= 3 && bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf; +} + +function readJsonNoBom(filePath) { + return JSON.parse(fs.readFileSync(filePath, "utf8").replace(/^\uFEFF/, "")); +} + +function stable(value) { + if (value === null || typeof value !== "object") { + return JSON.stringify(value); + } + if (Array.isArray(value)) { + return "[" + value.map(stable).join(",") + "]"; + } + const keys = Object.keys(value).sort(); + return "{" + keys.map((key) => JSON.stringify(key) + ":" + stable(value[key])).join(",") + "}"; +} + +function runGit(repoPath, args, allowFailure = false) { + try { + return execFileSync("git", args, { + cwd: repoPath, + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"] + }); + } catch (error) { + if (allowFailure) { + return ""; + } + throw error; + } +} + +function parseGitStatus(raw) { + return raw + .split(/\r?\n/) + .map((line) => line.trimEnd()) + .filter(Boolean) + .map((line) => { + const status = line.slice(0, 2); + const filePath = line.slice(3).replace(/^"|"$/g, ""); + return { status, path: filePath.replaceAll("\\", "/") }; + }) + .filter((entry) => !GENERATED_AUDIT_FILES.has(entry.path)); +} + +function gitTrackedFiles(repoPath) { + const raw = runGit(repoPath, ["ls-files", "-z"], true); + return raw + .split("\0") + .filter(Boolean) + .map((file) => file.replaceAll("\\", "/")) + .filter((file) => !GENERATED_AUDIT_FILES.has(file)) + .sort(); +} + +function isTextCandidate(filePath) { + const base = path.basename(filePath); + const ext = path.extname(filePath).toLowerCase(); + return TEXT_EXTENSIONS.has(ext) || TEXT_EXTENSIONS.has(base); +} + +function safeVerifyOutput(repoPath) { + const verifyPath = path.join(repoPath, "verify-output.json"); + if (!fs.existsSync(verifyPath)) { + return { + present: false, + parse_ok: false, + status: "UNAUDITED", + sha256: null, + failure_codes: ["VERIFY_OUTPUT_MISSING"] + }; + } + const bytes = readBytes(verifyPath); + try { + const parsed = readJsonNoBom(verifyPath); + return { + present: true, + parse_ok: true, + status: parsed.status || "STATUS_MISSING", + sha256: sha256Bytes(bytes), + bom_present: hasBom(bytes), + failure_codes: Array.isArray(parsed.failure_codes) ? parsed.failure_codes : [] + }; + } catch (error) { + return { + present: true, + parse_ok: false, + status: "FAILED", + sha256: sha256Bytes(bytes), + bom_present: hasBom(bytes), + failure_codes: ["VERIFY_OUTPUT_PARSE_FAILED"], + error: error.message + }; + } +} + +function auditRepo(repo, rootDir) { + const repoPath = path.resolve(rootDir, "..", repo.name); + const exists = fs.existsSync(repoPath); + const result = { + name: repo.name, + ring: repo.ring, + class: repo.class || null, + repo_path: repoPath, + repo_exists: exists, + git_branch: null, + git_commit: null, + dirty: false, + dirty_entries: [], + required_files: Array.isArray(repo.required_files) ? repo.required_files.slice().sort() : [], + missing_required_files: [], + verify_output: null, + tracked_file_count: 0, + tracked_files: [], + bom_failures: [], + byte_status: "UNAUDITED" + }; + + if (!exists) { + result.byte_status = "REPO_MISSING"; + return result; + } + + result.git_branch = runGit(repoPath, ["branch", "--show-current"], true).trim() || null; + result.git_commit = runGit(repoPath, ["rev-parse", "HEAD"], true).trim() || null; + result.dirty_entries = parseGitStatus(runGit(repoPath, ["status", "--porcelain=v1"], true)); + result.dirty = result.dirty_entries.length > 0; + + result.missing_required_files = result.required_files.filter((file) => { + return !fs.existsSync(path.join(repoPath, file)); + }); + + result.verify_output = safeVerifyOutput(repoPath); + + const tracked = gitTrackedFiles(repoPath); + result.tracked_file_count = tracked.length; + + for (const relPath of tracked) { + const absolutePath = path.join(repoPath, relPath); + if (!fs.existsSync(absolutePath) || !fs.statSync(absolutePath).isFile()) { + continue; + } + const bytes = readBytes(absolutePath); + const bomPresent = hasBom(bytes); + const fileRecord = { + path: relPath, + size_bytes: bytes.length, + sha256: sha256Bytes(bytes), + bom_present: bomPresent + }; + result.tracked_files.push(fileRecord); + if (bomPresent && isTextCandidate(relPath)) { + result.bom_failures.push(relPath); + } + } + + const failures = []; + if (result.missing_required_files.length > 0) failures.push("REQUIRED_FILES_MISSING"); + if (!result.verify_output.present) failures.push("VERIFY_OUTPUT_MISSING"); + if (result.verify_output.present && !result.verify_output.parse_ok) failures.push("VERIFY_OUTPUT_PARSE_FAILED"); + if (result.verify_output.bom_present) failures.push("VERIFY_OUTPUT_BOM_PRESENT"); + if (result.verify_output.status !== "VERIFIED") failures.push("VERIFY_OUTPUT_NOT_VERIFIED"); + if (result.bom_failures.length > 0) failures.push("BOM_PRESENT"); + if (result.dirty) failures.push("DIRTY_WORKTREE"); + + result.failure_codes = failures; + result.byte_status = failures.length === 0 ? "BYTE_VERIFIED" : "BYTE_BLOCKED"; + return result; +} + +const rootDir = process.cwd(); +const manifestPath = path.join(rootDir, "cluster-manifest-v2.json"); + +if (!fs.existsSync(manifestPath)) { + fail("MISSING_CLUSTER_MANIFEST"); +} + +const manifestBytes = readBytes(manifestPath); +const manifest = readJsonNoBom(manifestPath); +const repos = Array.isArray(manifest.repos) ? manifest.repos : []; + +const ringIndex = process.argv.indexOf("--ring"); +const targetRing = ringIndex >= 0 ? Number(process.argv[ringIndex + 1]) : null; + +if (ringIndex >= 0 && !Number.isInteger(targetRing)) { + fail("INVALID_RING_ARGUMENT"); +} + +const selectedRepos = targetRing === null ? repos : repos.filter((repo) => repo.ring === targetRing); +const auditedRepos = selectedRepos.map((repo) => auditRepo(repo, rootDir)); + +const blocked = auditedRepos.filter((repo) => repo.byte_status !== "BYTE_VERIFIED"); + +const summary = { + target_ring: targetRing, + repo_count: auditedRepos.length, + byte_verified_count: auditedRepos.length - blocked.length, + byte_blocked_count: blocked.length, + byte_gate_status: blocked.length === 0 ? "BYTE_GATE_PASS_VERIFIED" : "BYTE_GATE_BLOCKED" +}; + +const report = { + auditor: "Riverbraid Byte Floor Auditor", + report_version: "1.0.0", + claim_boundary: "byte-level-local-audit-trail", + manifest: { + path: "cluster-manifest-v2.json", + sha256: sha256Bytes(manifestBytes), + schema: manifest._schema || null, + version: manifest._version || null, + constellation_root: manifest._constellation_root || null, + cluster_version: manifest._cluster_version || null, + full_constellation_claimed: manifest.full_constellation_claimed === true + }, + summary, + repos: auditedRepos +}; + +const preimage = stable(report); +report.audit_preimage_sha256 = sha256Bytes(Buffer.from(preimage, "utf8")); + +const finalJson = stable(report) + "\n"; +const finalDigest = sha256Bytes(Buffer.from(finalJson, "utf8")); + +fs.writeFileSync(path.join(rootDir, "audit-output.json"), finalJson, "utf8"); +fs.writeFileSync(path.join(rootDir, "AUDIT-MANIFEST.sha256"), finalDigest + " audit-output.json\n", "utf8"); + +const trailRecord = { + generated_at_utc: new Date().toISOString(), + auditor: report.auditor, + report_version: report.report_version, + target_ring: targetRing, + byte_gate_status: summary.byte_gate_status, + audit_output_sha256: finalDigest, + blocked_repos: blocked.map((repo) => ({ + name: repo.name, + failure_codes: repo.failure_codes + })) +}; + +fs.appendFileSync( + path.join(rootDir, "AUDIT-TRAIL.ndjson"), + JSON.stringify(trailRecord) + "\n", + "utf8" +); + +console.log(JSON.stringify({ + status: summary.byte_gate_status, + target_ring: targetRing, + repo_count: summary.repo_count, + byte_verified_count: summary.byte_verified_count, + byte_blocked_count: summary.byte_blocked_count, + audit_output_sha256: finalDigest, + blocked_repos: trailRecord.blocked_repos +}, null, 2)); + +if (blocked.length > 0) { + process.exit(1); +} +process.exit(0); diff --git a/package.json b/package.json index d74b0dd..d84a8d5 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,16 @@ { - "name": "riverbraid-core", - "version": "1.0.0", - "scripts": { - "test": "jest", - "test:riverbraid": "node verify-vector.cjs" - }, - "devDependencies": { - "jest": "^29.0.0" - }, - "riverbraid": { - "role": "spine" - } + "name": "riverbraid-core", + "version": "1.0.0", + "scripts": { + "test": "jest", + "test:riverbraid": "node verify-vector.cjs", + "audit:ring2": "node byte-audit.mjs --ring 2", + "audit:all": "node byte-audit.mjs" + }, + "devDependencies": { + "jest": "^29.0.0" + }, + "riverbraid": { + "role": "spine" + } }