commit ddfc4b1719b7dbc0bbd5eec5d6697d10b44a570e
parent 432afc55df83633f43936c95dd5613c45a4e63c2
Author: triesap <tyson@radroots.org>
Date: Sun, 23 Aug 2026 20:02:38 +0000
build: adopt service source-lock v2
- pin shared service-host and service-SQLite packages to the final Lib revision
- replace the predecessor lock and Nix command surface with native extbuild policy
- add source, package, and public-boundary guards
Diffstat:
11 files changed, 700 insertions(+), 278 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
@@ -32,8 +32,8 @@
## 2. Authority and preflight
- Before editing, read this file, `README`, `Cargo.toml`,
- `radroots.lib.source-lock.v1.toml`, the relevant implementation and tests,
- and `config.toml` or `flake.nix` when they are in scope.
+ `radroots.service.source-lock.v2.toml`, the relevant implementation and tests,
+ and `config.toml` when it is in scope.
- `.radroots-consumer-root` is the standalone source-lock identity and must
remain exactly `rhi`. The reserved pre-implementation evidence authority is
`contracts/services_hardening/evidence_policy.v1.json`, and the reserved
@@ -264,8 +264,8 @@
## 9. Rust and test discipline
- The final Rust baseline is edition 2024, resolver 3, and Rust/toolchain
- 1.97.1. Keep `Cargo.toml`, `rust-toolchain.toml`, Cargo metadata, and Nix
- toolchain resolution in exact agreement.
+ 1.97.1. Keep `Cargo.toml`, `rust-toolchain.toml`, and Cargo metadata in exact
+ agreement.
- Keep `#![forbid(unsafe_code)]` at crate roots; unsafe code is forbidden. Deny
broken rustdoc links, `dbg!`, `todo!`, and `unimplemented!` in production.
- Prefer pure transformations, explicit state machines, validated newtypes,
@@ -286,22 +286,27 @@
## 10. Canonical verification
-Use the repository-owned Nix lanes as standalone command surfaces:
+Through RCLD-RSHR-170, run the standalone native command authority through
+extbuild. Do not install, repair, invoke, or require Nix, and do not claim Nix,
+NixOS-module, or Nix-produced OCI qualification:
```text
-nix run .#fmt
-nix run .#check
-nix run .#test
+cargo extbuild doctor
+cargo extbuild run -- cargo fmt --all --check
+cargo extbuild run -- cargo check --workspace --all-targets --locked
+cargo extbuild run -- cargo test --workspace --all-targets --locked
+cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings
+cargo extbuild run -- env RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --no-deps --locked
```
The complete release contract also requires locked all-target check and test
with serialized tests, warnings-denied all-target Clippy, warnings-denied
-rustdoc, the `source_guards` integration test, and diff hygiene. Run those gates
-explicitly until a repository-owned aggregate enforces them; do not describe a
-partial Nix lane as complete release acceptance. Run coverage, SQLx freshness,
-source-lock, Nix flake, package, OCI, systemd, SBOM, checksum, notice, and
-fresh-install gates when their surfaces change. Use narrower commands only for
-iteration, and never claim a command passed unless it ran successfully.
+rustdoc, the source-lock and package-boundary tests, and diff hygiene. Run
+additional coverage, SQLx freshness, source-lock, package, systemd, SBOM,
+checksum, notice, and fresh-install gates when their surfaces change. Nix and
+OCI remain deferred and unclaimed through RCLD-RSHR-170. Use narrower commands
+only for iteration, and never claim a command passed unless it ran
+successfully.
## 11. Commits and irreversible actions
diff --git a/Cargo.lock b/Cargo.lock
@@ -146,12 +146,27 @@ dependencies = [
]
[[package]]
+name = "atoi"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
name = "atomic-destructor"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4"
[[package]]
+name = "atomic-waker"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
+
+[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -394,6 +409,21 @@ dependencies = [
]
[[package]]
+name = "crc"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853"
+
+[[package]]
name = "crossbeam-channel"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -403,6 +433,15 @@ dependencies = [
]
[[package]]
+name = "crossbeam-queue"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -479,10 +518,19 @@ dependencies = [
]
[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
+[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+dependencies = [
+ "serde",
+]
[[package]]
name = "elliptic-curve"
@@ -527,6 +575,16 @@ dependencies = [
]
[[package]]
+name = "event-listener"
+version = "5.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2"
+dependencies = [
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
name = "fancy-regex"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -571,6 +629,17 @@ dependencies = [
]
[[package]]
+name = "flume"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "spin",
+]
+
+[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -602,6 +671,16 @@ dependencies = [
]
[[package]]
+name = "fs2"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
name = "futures"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -609,6 +688,7 @@ checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
+ "futures-executor",
"futures-io",
"futures-sink",
"futures-task",
@@ -643,12 +723,34 @@ dependencies = [
]
[[package]]
+name = "futures-intrusive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot",
+]
+
+[[package]]
name = "futures-io"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
+name = "futures-macro"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
name = "futures-sink"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -669,6 +771,7 @@ dependencies = [
"futures-channel",
"futures-core",
"futures-io",
+ "futures-macro",
"futures-sink",
"futures-task",
"memchr",
@@ -764,6 +867,11 @@ name = "hashbrown"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash 0.2.0",
+]
[[package]]
name = "hashbrown"
@@ -777,6 +885,15 @@ dependencies = [
]
[[package]]
+name = "hashlink"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f"
+dependencies = [
+ "hashbrown 0.16.1",
+]
+
+[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -817,12 +934,76 @@ dependencies = [
]
[[package]]
+name = "http-body"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "http",
+ "http-body",
+ "pin-project-lite",
+]
+
+[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72"
+dependencies = [
+ "atomic-waker",
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "smallvec",
+ "tokio",
+ "want",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
+dependencies = [
+ "bytes",
+ "http",
+ "http-body",
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
name = "icu_collections"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1083,6 +1264,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
[[package]]
+name = "libsqlite3-sys"
+version = "0.37.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f111c8c41e7c61a49cd34e44c7619462967221a6443b0ec299e0ac30cfb9b1"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1356,6 +1548,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1412,6 +1610,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
+name = "pkg-config"
+version = "0.3.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548"
+
+[[package]]
name = "poly1305"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1596,6 +1800,58 @@ dependencies = [
]
[[package]]
+name = "radroots_service_host"
+version = "0.1.0-alpha"
+source = "git+https://github.com/radrootslabs/lib?rev=7d7b454b4c9ed86569671993bd03ca868b676665#7d7b454b4c9ed86569671993bd03ca868b676665"
+dependencies = [
+ "bytes",
+ "fs2",
+ "getrandom 0.2.17",
+ "http",
+ "http-body-util",
+ "hyper",
+ "hyper-util",
+ "radroots_runtime_paths",
+ "rustix",
+ "serde",
+ "serde_json",
+ "tokio",
+ "tokio-util",
+ "toml",
+]
+
+[[package]]
+name = "radroots_service_sqlite"
+version = "0.1.0-alpha"
+source = "git+https://github.com/radrootslabs/lib?rev=7d7b454b4c9ed86569671993bd03ca868b676665#7d7b454b4c9ed86569671993bd03ca868b676665"
+dependencies = [
+ "fs2",
+ "futures",
+ "libsqlite3-sys",
+ "radroots_runtime_paths",
+ "radroots_storage",
+ "rustix",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx",
+ "tokio",
+]
+
+[[package]]
+name = "radroots_storage"
+version = "0.1.0-alpha"
+source = "git+https://github.com/radrootslabs/lib?rev=7d7b454b4c9ed86569671993bd03ca868b676665#7d7b454b4c9ed86569671993bd03ca868b676665"
+dependencies = [
+ "radroots_event",
+ "radroots_event_codec",
+ "radroots_protocol",
+ "radroots_trade",
+ "radroots_transport",
+ "sha2",
+]
+
+[[package]]
name = "radroots_trade"
version = "0.1.0-alpha"
source = "git+https://github.com/radrootslabs/lib?rev=7d7b454b4c9ed86569671993bd03ca868b676665#7d7b454b4c9ed86569671993bd03ca868b676665"
@@ -1610,6 +1866,17 @@ dependencies = [
]
[[package]]
+name = "radroots_transport"
+version = "0.1.0-alpha"
+source = "git+https://github.com/radrootslabs/lib?rev=7d7b454b4c9ed86569671993bd03ca868b676665#7d7b454b4c9ed86569671993bd03ca868b676665"
+dependencies = [
+ "radroots_event",
+ "radroots_identity",
+ "radroots_protocol",
+ "sha2",
+]
+
+[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1761,6 +2028,8 @@ dependencies = [
"radroots_protocol",
"radroots_runtime_paths",
"radroots_secrets",
+ "radroots_service_host",
+ "radroots_service_sqlite",
"radroots_trade",
"rand 0.9.2",
"serde",
@@ -2043,6 +2312,119 @@ dependencies = [
]
[[package]]
+name = "spin"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+ "sqlx-sqlite",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb"
+dependencies = [
+ "base64",
+ "bytes",
+ "cfg-if",
+ "crc",
+ "crossbeam-queue",
+ "either",
+ "event-listener",
+ "futures-core",
+ "futures-intrusive",
+ "futures-io",
+ "futures-util",
+ "hashbrown 0.16.1",
+ "hashlink",
+ "indexmap",
+ "log",
+ "memchr",
+ "percent-encoding",
+ "serde",
+ "sha2",
+ "smallvec",
+ "thiserror 2.0.18",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+ "url",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "sqlx-core",
+ "sqlx-macros-core",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "sqlx-macros-core"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3"
+dependencies = [
+ "cfg-if",
+ "dotenvy",
+ "either",
+ "heck",
+ "hex",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx-core",
+ "sqlx-sqlite",
+ "syn 2.0.117",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "sqlx-sqlite"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c"
+dependencies = [
+ "atoi",
+ "flume",
+ "form_urlencoded",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "libsqlite3-sys",
+ "log",
+ "percent-encoding",
+ "serde",
+ "sqlx-core",
+ "thiserror 2.0.18",
+ "tracing",
+ "url",
+]
+
+[[package]]
name = "stable_deref_trait"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2283,6 +2665,17 @@ dependencies = [
]
[[package]]
+name = "tokio-stream"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
name = "tokio-tungstenite"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2299,6 +2692,20 @@ dependencies = [
]
[[package]]
+name = "tokio-util"
+version = "0.7.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
name = "toml"
version = "0.8.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2345,6 +2752,7 @@ version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
+ "log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -2413,6 +2821,12 @@ dependencies = [
]
[[package]]
+name = "try-lock"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
+
+[[package]]
name = "tungstenite"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2546,6 +2960,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2558,6 +2978,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2703,6 +3132,28 @@ dependencies = [
]
[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -6,35 +6,53 @@ authors = ["Radroots Authors"]
rust-version = "1.97.1"
license = "AGPL-3.0-or-later"
description = "Radroots trade agreement attestation worker"
+repository = "https://github.com/radrootslabs/rhi"
+readme = "README"
+publish = false
[workspace]
resolver = "3"
-[workspace.dependencies]
-radroots_event = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_event_codec = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_identity = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_nostr = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_protocol = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_runtime_paths = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_secrets = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
-radroots_trade = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+[workspace.metadata.radroots.service_source_lock]
+service = "rhi"
+host_feature_profile = "service-host"
+nix_material = "absent"
+config_contract_version = 1
+state_contract_version = 1
+admin_contract_version = 1
+status_contract_version = 1
+provider_contract_version = 1
+
+[workspace.lints.rust]
+unsafe_code = "deny"
+unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] }
+
+[workspace.lints.rustdoc]
+broken_intra_doc_links = "deny"
+
+[workspace.lints.clippy]
+dbg_macro = "deny"
+todo = "deny"
+unimplemented = "deny"
[features]
-default = []
+default = ["service-host"]
+service-host = []
-[lints.rust]
-unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] }
+[lints]
+workspace = true
[dependencies]
-radroots_event = { workspace = true, features = ["serde"] }
-radroots_event_codec = { workspace = true, features = ["json"] }
-radroots_identity = { workspace = true }
-radroots_nostr = { workspace = true, features = ["events"] }
-radroots_protocol = { workspace = true }
-radroots_runtime_paths = { workspace = true }
-radroots_secrets = { workspace = true }
-radroots_trade = { workspace = true }
+radroots_event = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha", features = ["serde"] }
+radroots_event_codec = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha", features = ["json"] }
+radroots_identity = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_nostr = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha", features = ["events"] }
+radroots_protocol = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_runtime_paths = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_service_host = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_service_sqlite = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_secrets = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
+radroots_trade = { git = "https://github.com/radrootslabs/lib", rev = "7d7b454b4c9ed86569671993bd03ca868b676665", version = "=0.1.0-alpha" }
anyhow = { version = "1" }
chacha20poly1305 = { version = "0.10" }
diff --git a/README b/README
@@ -77,16 +77,21 @@ injected host environment defined by `radroots_runtime_paths`; repo-local uses
one explicit absolute base and the same `services/rhi/<instance>` namespace.
Path resolution performs no directory creation or filesystem I/O.
-Use the repository-owned Nix lanes for validation:
+Validate the standalone crate through extbuild:
```text
-nix run .#fmt
-nix run .#check
-nix run .#test
+cargo extbuild doctor
+cargo extbuild run -- cargo fmt --all --check
+cargo extbuild run -- cargo check --workspace --all-targets --locked
+cargo extbuild run -- cargo test --workspace --all-targets --locked
+cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings
+cargo extbuild run -- env RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --no-deps --locked
```
-Use `nix develop` to enter the repository's development shell before running
-narrower ad hoc Cargo commands from this repository root.
+Through RCLD-RSHR-170, Nix evaluation, builds, packages, NixOS modules, and
+Nix-produced OCI artifacts are deferred and unclaimed. Do not install, repair,
+invoke, or require Nix for these checkpoints. Run narrower ad hoc Cargo
+commands through `cargo extbuild run --` from this repository root.
## Copyright
diff --git a/flake.lock b/flake.lock
@@ -1,48 +0,0 @@
-{
- "nodes": {
- "nixpkgs": {
- "locked": {
- "lastModified": 1774799055,
- "narHash": "sha256-Tsq9BCz0q47ej1uFF39m4tuhcwru/ls6vCCJzutEpaw=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "107cba9eb4a8d8c9f8e9e61266d78d340867913a",
- "type": "github"
- },
- "original": {
- "owner": "NixOS",
- "ref": "nixos-25.11",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "root": {
- "inputs": {
- "nixpkgs": "nixpkgs",
- "rust-overlay": "rust-overlay"
- }
- },
- "rust-overlay": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1786160316,
- "narHash": "sha256-oLoc3ZLg1LX/S5Jb3v6MrF415AzDyC4vgeWy9UcYTQk=",
- "owner": "oxalica",
- "repo": "rust-overlay",
- "rev": "4e1c940c96560ceab7c547f89642231371a66646",
- "type": "github"
- },
- "original": {
- "owner": "oxalica",
- "repo": "rust-overlay",
- "type": "github"
- }
- }
- },
- "root": "root",
- "version": 7
-}
diff --git a/flake.nix b/flake.nix
@@ -1,174 +0,0 @@
-{
- description = "rhi";
-
- inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
- rust-overlay = {
- url = "github:oxalica/rust-overlay";
- inputs.nixpkgs.follows = "nixpkgs";
- };
- };
-
- outputs =
- { nixpkgs, rust-overlay, ... }:
- let
- systems = [
- "aarch64-darwin"
- "aarch64-linux"
- "x86_64-darwin"
- "x86_64-linux"
- ];
- forAllSystems =
- f:
- nixpkgs.lib.genAttrs systems (
- system:
- let
- pkgs = import nixpkgs {
- inherit system;
- overlays = [ rust-overlay.overlays.default ];
- };
- rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
- basePackages =
- [
- pkgs.git
- rustToolchain
- pkgs.clang
- pkgs.llvmPackages.libclang
- pkgs.libsodium
- pkgs.openssl
- pkgs.pkg-config
- pkgs.sqlite
- ]
- ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
- pkgs.darwin.libiconv
- ];
- libraryPath = pkgs.lib.makeLibraryPath basePackages;
- includePath = pkgs.lib.makeSearchPathOutput "dev" "include" basePackages;
- llvmToolsBin = "${pkgs.llvmPackages.llvm}/bin";
- darwinLdFlags = pkgs.lib.optionalString pkgs.stdenv.isDarwin "-L${pkgs.darwin.libiconv}/lib";
- darwinRustFlags = pkgs.lib.optionalString pkgs.stdenv.isDarwin "-L native=${pkgs.darwin.libiconv}/lib";
- coveragePackages = basePackages ++ [
- pkgs.llvmPackages.llvm
- ];
- mkApp =
- name:
- {
- runtimeInputs ? basePackages,
- text,
- }:
- let
- script = pkgs.writeShellApplication {
- inherit name;
- inherit runtimeInputs;
- text = ''
- set -euo pipefail
- repo_root="$(git rev-parse --show-toplevel)"
- cd "$repo_root"
- export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib"
- export LIBRARY_PATH="${libraryPath}:''${LIBRARY_PATH:-}"
- export DYLD_FALLBACK_LIBRARY_PATH="${libraryPath}:''${DYLD_FALLBACK_LIBRARY_PATH:-}"
- export LDFLAGS="${darwinLdFlags} ''${LDFLAGS:-}"
- export NIX_LDFLAGS="${darwinLdFlags} ''${NIX_LDFLAGS:-}"
- export RUSTFLAGS="${darwinRustFlags} ''${RUSTFLAGS:-}"
- export CPATH="${includePath}:''${CPATH:-}"
- ${text}
- '';
- };
- in
- {
- type = "app";
- program = "${script}/bin/${name}";
- };
- in
- f {
- inherit
- basePackages
- coveragePackages
- darwinLdFlags
- darwinRustFlags
- includePath
- libraryPath
- llvmToolsBin
- mkApp
- pkgs
- rustToolchain
- ;
- }
- );
- in
- {
- apps = forAllSystems (
- {
- coveragePackages,
- llvmToolsBin,
- mkApp,
- ...
- }:
- rec {
- default = check;
- check = mkApp "check" {
- text = ''
- cargo metadata --format-version 1 --no-deps
- cargo check --workspace --all-targets
- '';
- };
- coverage-report = mkApp "coverage-report" {
- runtimeInputs = coveragePackages;
- text = ''
- export PATH="$HOME/.cargo/bin:$PATH"
- cargo +nightly llvm-cov --version >/dev/null 2>&1 || {
- echo "cargo +nightly llvm-cov must be available to run coverage-report" >&2
- exit 1
- }
- export LLVM_COV="${llvmToolsBin}/llvm-cov"
- export LLVM_PROFDATA="${llvmToolsBin}/llvm-profdata"
- mkdir -p target/coverage
- cargo +nightly llvm-cov clean --workspace
- cargo +nightly llvm-cov --workspace --all-features --branch --no-report
- cargo +nightly llvm-cov report --json --summary-only --output-path target/coverage/summary.json
- cargo +nightly llvm-cov report --lcov --output-path target/coverage/lcov.info
- cargo +nightly llvm-cov report --summary-only
- echo "coverage summary: target/coverage/summary.json"
- echo "coverage lcov: target/coverage/lcov.info"
- '';
- };
- fmt = mkApp "fmt" {
- text = ''
- cargo fmt --all --check
- '';
- };
- test = mkApp "test" {
- text = ''
- cargo test -- --test-threads=1
- '';
- };
- }
- );
-
- devShells = forAllSystems (
- {
- basePackages,
- darwinLdFlags,
- darwinRustFlags,
- includePath,
- libraryPath,
- pkgs,
- ...
- }:
- {
- default = pkgs.mkShell {
- packages = basePackages;
- shellHook = ''
- export LIBCLANG_PATH="${pkgs.llvmPackages.libclang.lib}/lib"
- export LIBRARY_PATH="${libraryPath}:''${LIBRARY_PATH:-}"
- export DYLD_FALLBACK_LIBRARY_PATH="${libraryPath}:''${DYLD_FALLBACK_LIBRARY_PATH:-}"
- export LDFLAGS="${darwinLdFlags} ''${LDFLAGS:-}"
- export NIX_LDFLAGS="${darwinLdFlags} ''${NIX_LDFLAGS:-}"
- export RUSTFLAGS="${darwinRustFlags} ''${RUSTFLAGS:-}"
- export CPATH="${includePath}:''${CPATH:-}"
- '';
- };
- }
- );
- };
-}
diff --git a/radroots.lib.source-lock.v1.toml b/radroots.lib.source-lock.v1.toml
@@ -1,9 +0,0 @@
-schema = "radroots.lib.source-lock.v1"
-repository = "https://github.com/radrootslabs/lib"
-revision = "7d7b454b4c9ed86569671993bd03ca868b676665"
-architecture = "radroots.crates.release.v2"
-workspace_catalog_sha256 = "deca0c080deae187ff8186c0708903e42f41ea57f77c5f91581e23aa561164a4"
-version = "0.1.0-alpha"
-source_archive_sha256 = "b425371c134be96cce46b37f7035d6212f1efe8cff50bef366631ba5632991b0"
-lockfile = "Cargo.lock"
-lockfile_sha256 = "42a3f375556257d05db86bbeaa59d3a96f040afaa85b4293f238a7da98d95fde"
diff --git a/radroots.service.source-lock.v2.toml b/radroots.service.source-lock.v2.toml
@@ -0,0 +1,22 @@
+schema = "radroots.service.source-lock.v2"
+contract_version = 2
+service = "rhi"
+repository = "https://github.com/radrootslabs/lib"
+revision = "7d7b454b4c9ed86569671993bd03ca868b676665"
+architecture = "radroots.crates.release.v2"
+workspace_catalog_sha256 = "deca0c080deae187ff8186c0708903e42f41ea57f77c5f91581e23aa561164a4"
+version = "0.1.0-alpha"
+source_archive_sha256 = "b425371c134be96cce46b37f7035d6212f1efe8cff50bef366631ba5632991b0"
+cargo_lock_sha256 = "ba1cca624b0b2fbc49e82bc392b4cc1bf80a9ffcb5bd86e15ffed2818075f565"
+rust_version = "1.97.1"
+host_feature_profile = "service-host"
+
+[nix]
+material = "absent"
+
+[contract_versions]
+config = 1
+state = 1
+admin = 1
+status = 1
+provider = 1
diff --git a/tests/build_policy.rs b/tests/build_policy.rs
@@ -0,0 +1,81 @@
+#![forbid(unsafe_code)]
+
+use sha2::{Digest, Sha256};
+
+const MANIFEST: &str = include_str!("../Cargo.toml");
+const SOURCE_LOCK: &str = include_str!("../radroots.service.source-lock.v2.toml");
+
+#[test]
+fn manifest_freezes_the_native_service_policy() {
+ assert!(MANIFEST.contains(
+ "repository = \"https://github.com/radrootslabs/rhi\"\nreadme = \"README\"\npublish = false"
+ ));
+ assert!(MANIFEST.contains("[workspace]\nresolver = \"3\""));
+ assert!(MANIFEST.contains("[workspace.lints.rust]\nunsafe_code = \"deny\""));
+ assert!(MANIFEST.contains("[workspace.lints.rustdoc]\nbroken_intra_doc_links = \"deny\""));
+ assert!(MANIFEST.contains(
+ "[workspace.lints.clippy]\ndbg_macro = \"deny\"\ntodo = \"deny\"\nunimplemented = \"deny\""
+ ));
+ assert!(MANIFEST.contains("[lints]\nworkspace = true"));
+ assert!(MANIFEST.contains("[features]\ndefault = [\"service-host\"]\nservice-host = []"));
+}
+
+#[test]
+fn source_lock_metadata_is_exact_and_nix_is_absent() {
+ assert!(MANIFEST.contains(
+ "[workspace.metadata.radroots.service_source_lock]\nservice = \"rhi\"\nhost_feature_profile = \"service-host\"\nnix_material = \"absent\""
+ ));
+ for field in [
+ "config_contract_version = 1",
+ "state_contract_version = 1",
+ "admin_contract_version = 1",
+ "status_contract_version = 1",
+ "provider_contract_version = 1",
+ ] {
+ assert!(
+ MANIFEST.contains(field),
+ "missing source-lock field {field}"
+ );
+ }
+}
+
+#[test]
+fn shared_host_packages_are_exactly_source_locked() {
+ for dependency in ["radroots_service_host", "radroots_service_sqlite"] {
+ assert!(MANIFEST.contains(&format!(
+ "{dependency} = {{ git = \"https://github.com/radrootslabs/lib\", rev = \"7d7b454b4c9ed86569671993bd03ca868b676665\", version = \"=0.1.0-alpha\" }}"
+ )));
+ }
+}
+
+#[test]
+fn source_lock_binds_the_current_cargo_lock() {
+ let digest = lower_hex(&Sha256::digest(include_bytes!("../Cargo.lock")));
+ assert!(SOURCE_LOCK.starts_with(
+ "schema = \"radroots.service.source-lock.v2\"\ncontract_version = 2\nservice = \"rhi\"\n"
+ ));
+ assert!(SOURCE_LOCK.contains(&format!("cargo_lock_sha256 = \"{digest}\"")));
+ assert!(SOURCE_LOCK.contains("revision = \"7d7b454b4c9ed86569671993bd03ca868b676665\""));
+ assert!(SOURCE_LOCK.contains(
+ "workspace_catalog_sha256 = \"deca0c080deae187ff8186c0708903e42f41ea57f77c5f91581e23aa561164a4\""
+ ));
+ assert!(SOURCE_LOCK.contains(
+ "source_archive_sha256 = \"b425371c134be96cce46b37f7035d6212f1efe8cff50bef366631ba5632991b0\""
+ ));
+ assert!(SOURCE_LOCK.contains("\n[nix]\nmaterial = \"absent\"\n"));
+ assert!(!SOURCE_LOCK.contains("flake_lock_sha256"));
+ assert!(!SOURCE_LOCK.contains("lib_revision ="));
+ assert!(SOURCE_LOCK.ends_with(
+ "[contract_versions]\nconfig = 1\nstate = 1\nadmin = 1\nstatus = 1\nprovider = 1\n"
+ ));
+}
+
+fn lower_hex(bytes: &[u8]) -> String {
+ const DIGITS: &[u8; 16] = b"0123456789abcdef";
+ let mut output = String::with_capacity(bytes.len() * 2);
+ for byte in bytes {
+ output.push(char::from(DIGITS[usize::from(byte >> 4)]));
+ output.push(char::from(DIGITS[usize::from(byte & 0x0f)]));
+ }
+ output
+}
diff --git a/tests/package_boundary.rs b/tests/package_boundary.rs
@@ -0,0 +1,62 @@
+#![forbid(unsafe_code)]
+
+const MANIFEST: &str = include_str!("../Cargo.toml");
+const README: &str = include_str!("../README");
+const ROOT: &str = include_str!("../src/lib.rs");
+
+#[test]
+fn package_identity_is_standalone_and_non_publishable() {
+ assert!(MANIFEST.contains("name = \"rhi\""));
+ assert!(MANIFEST.contains("repository = \"https://github.com/radrootslabs/rhi\""));
+ assert!(MANIFEST.contains("readme = \"README\""));
+ assert!(MANIFEST.contains("publish = false"));
+ for forbidden in [
+ "path = \"../",
+ "path = \"../../",
+ "enterprise/",
+ "ops/",
+ "foundation/",
+ ] {
+ assert!(
+ !MANIFEST.contains(forbidden),
+ "standalone package retains forbidden dependency surface {forbidden}"
+ );
+ }
+}
+
+#[test]
+fn shared_host_implementations_do_not_escape_the_public_api() {
+ for forbidden in [
+ "pub use radroots_service_host",
+ "pub use radroots_service_sqlite",
+ "pub mod service_host",
+ "pub mod service_sqlite",
+ "sqlx::Pool",
+ "sqlx::SqliteConnection",
+ ] {
+ assert!(
+ !ROOT.contains(forbidden),
+ "RHI public root exposes private host implementation {forbidden}"
+ );
+ }
+}
+
+#[test]
+fn human_verification_contract_is_extbuild_only_through_rcld_170() {
+ for required in [
+ "cargo extbuild doctor",
+ "cargo extbuild run -- cargo fmt --all --check",
+ "cargo extbuild run -- cargo check --workspace --all-targets --locked",
+ "cargo extbuild run -- cargo test --workspace --all-targets --locked",
+ "cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings",
+ "Nix-produced OCI artifacts are deferred and unclaimed",
+ ] {
+ assert!(README.contains(required), "README is missing {required}");
+ }
+ for forbidden in ["nix run", "nix develop", "nix build", "nix flake"] {
+ assert!(
+ !README.contains(forbidden),
+ "README retains forbidden active Nix command {forbidden}"
+ );
+ }
+}
diff --git a/tests/source_guards.rs b/tests/source_guards.rs
@@ -13,7 +13,6 @@ fn rhi_manifest_has_no_sdk_or_legacy_proof_dependency() {
"sp1_proving",
"sp1_cuda_proving",
"reqwest",
- "sqlx",
"libsqlite3-sys",
] {
assert!(
@@ -26,19 +25,29 @@ fn rhi_manifest_has_no_sdk_or_legacy_proof_dependency() {
#[test]
fn rhi_manifest_exact_pins_radroots_contract() {
let manifest: toml::Value = toml::from_str(&read_repo_file("Cargo.toml")).expect("manifest");
- let dependencies = manifest["workspace"]["dependencies"]
+ let dependencies = manifest["dependencies"]
.as_table()
- .expect("workspace dependencies");
+ .expect("package dependencies");
for (name, dependency) in dependencies {
if !name.starts_with("radroots_") {
continue;
}
- let version = dependency
- .as_str()
- .or_else(|| dependency.get("version").and_then(toml::Value::as_str));
+ let dependency = dependency
+ .as_table()
+ .unwrap_or_else(|| panic!("{name} must use an explicit dependency table"));
assert_eq!(
- version,
+ dependency.get("git").and_then(toml::Value::as_str),
+ Some("https://github.com/radrootslabs/lib"),
+ "RHI must source {name} from the governed public Lib repository"
+ );
+ assert_eq!(
+ dependency.get("rev").and_then(toml::Value::as_str),
+ Some("7d7b454b4c9ed86569671993bd03ca868b676665"),
+ "RHI must source-lock {name} to the exact promoted Lib revision"
+ );
+ assert_eq!(
+ dependency.get("version").and_then(toml::Value::as_str),
Some("=0.1.0-alpha"),
"RHI must exact-pin {name} to the governed event contract release"
);