commit 49d01b6deecb3724b83442ca3c41c89861a75fda
parent 4b6d7b86985b21f5d146fbf265554954ea7147c5
Author: triesap <tyson@radroots.org>
Date: Fri, 21 Aug 2026 09:09:08 +0000
build: align myc rust policy
- adopt Cargo resolver 3 and the shared deny-lint baseline
- define service-host as the exact default feature profile
- minimize direct runtime features and bind the refreshed lock digest
- route native release acceptance through extbuild with Nix deferred
Diffstat:
7 files changed, 89 insertions(+), 22 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
@@ -163,13 +163,17 @@
## 9. Canonical verification
-Use the repository-owned Nix lanes as the standalone command authority:
+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
-nix run .#release-acceptance
+cargo extbuild doctor
+cargo extbuild run -- cargo fmt --all --check
+cargo extbuild run -- cargo check --workspace --locked
+cargo extbuild run -- cargo test --workspace --all-targets --locked
+cargo extbuild run -- cargo clippy --workspace --all-targets --locked -- -D warnings
+cargo extbuild run -- ./scripts/release-acceptance.sh
```
The release-acceptance contract requires formatting, locked metadata, locked
@@ -177,9 +181,11 @@ all-target checking and testing, warnings-denied all-target Clippy, rustdoc with
warnings denied, and diff hygiene. Run any gate not yet covered by the current
release script explicitly; do not describe the script as sufficient until it
enforces the complete contract. Run additional SQLx freshness, source-lock,
-Nix, OCI, systemd, package, SBOM, checksum, notice, and fresh-install gates when
-their surfaces change. Use narrower checked-in commands only for iteration,
-and never claim a command passed unless it ran successfully.
+independently produced OCI, systemd, package, SBOM, checksum, notice, and
+fresh-install gates when their surfaces change. Checked-in Nix material remains
+deferred source data through RCLD-RSHR-170 and is not a verification gate. Use
+narrower checked-in commands only for iteration, and never claim a command
+passed unless it ran successfully.
## 10. Commits and irreversible actions
diff --git a/Cargo.lock b/Cargo.lock
@@ -1369,7 +1369,6 @@ dependencies = [
"clap",
"futures-executor",
"futures-util",
- "getrandom 0.2.17",
"hex",
"keyring",
"nostr",
diff --git a/Cargo.toml b/Cargo.toml
@@ -8,19 +8,34 @@ license = "AGPL-3.0-or-later"
description = "Radroots NIP-46 remote signer for delegated Nostr accounts"
[workspace]
-resolver = "2"
+resolver = "3"
-[lints.rust]
+[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"
+
+[lints]
+workspace = true
+
+[features]
+default = ["service-host"]
+service-host = []
+
[dependencies]
axum = { version = "0.8", default-features = false, features = ["http1", "json", "tokio"] }
chacha20poly1305 = "0.10"
clap = { version = "4.5", features = ["derive"] }
-getrandom = "0.2"
futures-executor = "0.3"
hex = "0.4"
-keyring = { version = "3.6", features = ["apple-native", "windows-native", "sync-secret-service"] }
+keyring = { version = "3.6", default-features = false, features = ["apple-native", "windows-native", "sync-secret-service"] }
nostr = { version = "0.44.2", features = ["nip04", "nip44", "nip46", "nip49"] }
nostr-sdk = { version = "0.44.1" }
radroots_identity = { git = "https://github.com/radrootslabs/lib", rev = "09065a610d95e57acdc895a14c07580fa099e7c3", version = "=0.1.0-alpha" }
@@ -36,7 +51,7 @@ sqlx = { version = "0.9.0", default-features = false, features = ["derive", "sql
rand = "0.9"
thiserror = "2.0"
tempfile = "3.17"
-tokio = { version = "1.48", features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync", "time"] }
+tokio = { version = "1.48", default-features = false, features = ["io-util", "macros", "net", "process", "rt-multi-thread", "sync", "time"] }
tracing = "0.1"
tracing-appender = "0.2"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
diff --git a/README b/README
@@ -36,17 +36,18 @@ out helpers, and releases Myc's multi-thread Tokio worker while waiting.
Helper-provided stderr and protocol error text are never copied into operator
errors.
-Use the repository-owned Nix lanes for validation:
+The default Cargo feature profile is `service-host`. Validate the standalone
+crate through extbuild:
```text
-nix run .#fmt
-nix run .#check
-nix run .#test
-nix run .#release-acceptance
+cargo extbuild doctor
+cargo extbuild run -- ./scripts/release-acceptance.sh
```
-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/radroots.lib.source-lock.v1.toml b/radroots.lib.source-lock.v1.toml
@@ -6,4 +6,4 @@ workspace_catalog_sha256 = "8c27cebf6825f9ed74e122513c661f6dd31837dddb39d0988014
version = "0.1.0-alpha"
source_archive_sha256 = "68badd1fb02d9396682d368e62dfe79969d8da48529760789c823fb4ab54aea3"
lockfile = "Cargo.lock"
-lockfile_sha256 = "d46a79ad905cbc8e67752eb214d125702c617328e109450e442f13740d2d8e96"
+lockfile_sha256 = "3a26058ad786e73e88b04a505d56845c5cdc6bf6d3d8216f03d1b1593dba2ea7"
diff --git a/scripts/release-acceptance.sh b/scripts/release-acceptance.sh
@@ -6,6 +6,8 @@ cd "$repo_root"
cargo fmt --all --check
cargo metadata --locked --format-version 1 --no-deps >/dev/null
+cargo check --locked --all-targets --no-default-features
+cargo check --locked --all-targets --no-default-features --features service-host
cargo check --locked --all-targets
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
diff --git a/tests/build_policy.rs b/tests/build_policy.rs
@@ -0,0 +1,44 @@
+#![forbid(unsafe_code)]
+
+use sha2::{Digest, Sha256};
+
+const MANIFEST: &str = include_str!("../Cargo.toml");
+const RELEASE_ACCEPTANCE: &str = include_str!("../scripts/release-acceptance.sh");
+const SOURCE_LOCK: &str = include_str!("../radroots.lib.source-lock.v1.toml");
+
+#[test]
+fn manifest_freezes_the_final_rust_policy() {
+ 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"));
+}
+
+#[test]
+fn service_host_is_the_exact_default_feature_profile() {
+ assert!(MANIFEST.contains("[features]\ndefault = [\"service-host\"]\nservice-host = []"));
+ assert!(!MANIFEST.contains("getrandom = \"0.2\""));
+ assert!(MANIFEST.contains(
+ "tokio = { version = \"1.48\", default-features = false, features = [\"io-util\", \"macros\", \"net\", \"process\", \"rt-multi-thread\", \"sync\", \"time\"] }"
+ ));
+}
+
+#[test]
+fn release_acceptance_checks_both_feature_profiles() {
+ assert!(
+ RELEASE_ACCEPTANCE.contains("cargo check --locked --all-targets --no-default-features\n")
+ );
+ assert!(RELEASE_ACCEPTANCE.contains(
+ "cargo check --locked --all-targets --no-default-features --features service-host\n"
+ ));
+ assert!(!RELEASE_ACCEPTANCE.contains("nix "));
+}
+
+#[test]
+fn source_lock_binds_the_current_cargo_lock() {
+ let digest = hex::encode(Sha256::digest(include_bytes!("../Cargo.lock")));
+ assert!(SOURCE_LOCK.contains(&format!("lockfile_sha256 = \"{digest}\"")));
+}