commit 3e67c7d9d5f0b12cbc5b8ab0c2ad36c25ed7caa7
parent 8ed1e0500f232489c23620f2ceb445bcafbb079e
Author: triesap <tyson@radroots.org>
Date: Mon, 27 Jul 2026 09:30:00 +0000
workspace: standardize lint and rustdoc policy
- make final public packages inherit the approved lint baseline
- repair Rust 1.97.1 Clippy findings in release policy checks
- enable legacy ingest only for existing private preview consumers
- refresh the lock evidence after the feature-boundary repair
Diffstat:
8 files changed, 89 insertions(+), 43 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -2173,6 +2173,7 @@ dependencies = [
name = "radroots_replica_sync"
version = "1.0.0-alpha.1"
dependencies = [
+ "base64 0.22.1",
"hex",
"radroots_core",
"radroots_event",
@@ -2183,6 +2184,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
+ "uuid",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
@@ -32,6 +32,17 @@ version = "0.1.0"
authors = ["Tyson Lupul <tyson@radroots.org>"]
readme = "README.md"
+[workspace.lints.rust]
+unsafe_code = "forbid"
+
+[workspace.lints.rustdoc]
+broken_intra_doc_links = "deny"
+
+[workspace.lints.clippy]
+dbg_macro = "deny"
+todo = "deny"
+unimplemented = "deny"
+
[workspace.dependencies]
dto_bindgen = { version = "0.1.0" }
dto_bindgen_backend_ts = { version = "0.1.0" }
diff --git a/crates/radroots/Cargo.toml b/crates/radroots/Cargo.toml
@@ -11,6 +11,9 @@ authors.workspace = true
readme = "README.md"
publish = false
+[lints]
+workspace = true
+
[lib]
name = "radroots"
path = "src/lib.rs"
diff --git a/crates/replica_sync_wasm/Cargo.toml b/crates/replica_sync_wasm/Cargo.toml
@@ -20,7 +20,7 @@ radroots_event = { workspace = true, default-features = false, features = [
"serde",
] }
radroots_sdk_sql_wasm_runtime = { workspace = true }
-radroots_replica_sync = { workspace = true, features = ["std"] }
+radroots_replica_sync = { workspace = true, features = ["std", "legacy-ingest"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
serde-wasm-bindgen = { workspace = true }
diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml
@@ -214,7 +214,7 @@ radroots_replica_store = { workspace = true, default-features = false, features
"native",
] }
radroots_replica_schema = { workspace = true }
-radroots_replica_sync = { workspace = true, features = ["std"] }
+radroots_replica_sync = { workspace = true, features = ["std", "legacy-ingest"] }
radroots_sql_core = { workspace = true, features = ["native"] }
radroots_nostr = { workspace = true, default-features = false, features = [
"std",
diff --git a/docs/implementation/DEPENDENCY_RESOLUTION.md b/docs/implementation/DEPENDENCY_RESOLUTION.md
@@ -9,15 +9,14 @@ resolution. It added 12 missing transitive package records, added the new
`radroots` workspace package, and refreshed dependency lists without upgrading
existing locked package versions. The resulting checksum is
`422787033afa12d00be7a402f6772bfed194ef420320189b517ca151765eae9c`.
-Repeated locked architecture tests leave it unchanged.
-The repaired lock lets `cargo test --workspace --locked` reach compilation. It
-currently stops in the private preview wrapper `radroots_replica_sync_wasm`:
-that crate imports `RadrootsReplicaIngestOutcome` without enabling the
-`radroots_replica_sync/legacy-ingest` feature that gates the type. This is a
-source/feature boundary failure, not lockfile drift, and remains owned by a
-later crate-surface checkpoint. It must not be described as a green workspace
-lane until repaired or retired by the final architecture.
+Step 020 repaired the private preview/test feature boundary by explicitly
+enabling `radroots_replica_sync/legacy-ingest` only for the existing wrapper and
+SDK development test that consume that gated API. Cargo refreshed only the
+local package dependency list; no package version changed. The resulting
+checksum is
+`246de979d4b2b249182860c4b0adc37fc90c11143c3a279c49201227501d84d9`.
+The full locked workspace check, test, Clippy, and rustdoc lanes now pass.
Dependency changes must use repository-owned extbuild commands, preserve
`--locked` zero-diff validation, and update this evidence when the resolved
diff --git a/tools/xtask/src/architecture.rs b/tools/xtask/src/architecture.rs
@@ -85,6 +85,31 @@ struct WorkspaceMembers {
resolver: String,
package: WorkspacePackage,
metadata: WorkspaceMetadata,
+ lints: WorkspaceLints,
+}
+
+#[derive(Debug, Deserialize)]
+struct WorkspaceLints {
+ rust: WorkspaceRustLints,
+ rustdoc: WorkspaceRustdocLints,
+ clippy: WorkspaceClippyLints,
+}
+
+#[derive(Debug, Deserialize)]
+struct WorkspaceRustLints {
+ unsafe_code: String,
+}
+
+#[derive(Debug, Deserialize)]
+struct WorkspaceRustdocLints {
+ broken_intra_doc_links: String,
+}
+
+#[derive(Debug, Deserialize)]
+struct WorkspaceClippyLints {
+ dbg_macro: String,
+ todo: String,
+ unimplemented: String,
}
#[derive(Debug, Deserialize)]
@@ -176,6 +201,18 @@ fn validate_workspace_toolchain(
"public package readme source must be {PUBLIC_README}"
));
}
+ let lints = &manifest.workspace.lints;
+ if lints.rust.unsafe_code != "forbid"
+ || lints.rustdoc.broken_intra_doc_links != "deny"
+ || lints.clippy.dbg_macro != "deny"
+ || lints.clippy.todo != "deny"
+ || lints.clippy.unimplemented != "deny"
+ {
+ return Err(
+ "workspace lints must forbid unsafe code and deny the approved rustdoc/Clippy baseline"
+ .to_owned(),
+ );
+ }
if workspace_package.edition != architecture.edition || architecture.edition != "2024" {
return Err(format!(
"workspace edition {} must match architecture edition {}",
@@ -341,6 +378,18 @@ fn validate_public_package_metadata(
"public package {name} must remain publish = false during migration"
));
}
+ let inherits_lints = manifest
+ .get("lints")
+ .and_then(toml::Value::as_table)
+ .is_some_and(|lints| {
+ lints.len() == 1
+ && lints.get("workspace").and_then(toml::Value::as_bool) == Some(true)
+ });
+ if !inherits_lints {
+ return Err(format!(
+ "public package {name} must inherit the workspace lint policy"
+ ));
+ }
}
Ok(())
}
@@ -659,7 +708,7 @@ adr_required = false
fn complete_workspace_manifest(members: &str) -> String {
format!(
- "[workspace]\nmembers = [{members}]\nresolver = \"3\"\n\n[workspace.package]\nversion = \"0.1.0\"\nedition = \"2024\"\nrust-version = \"1.97.1\"\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/radrootslabs/sdk\"\nhomepage = \"https://radroots.org\"\nreadme = \"README\"\nauthors = [\"Tyson Lupul <tyson@radroots.org>\"]\n\n[workspace.metadata.radroots.public-package]\nversion = \"0.1.0\"\nauthors = [\"Tyson Lupul <tyson@radroots.org>\"]\nreadme = \"README.md\"\n"
+ "[workspace]\nmembers = [{members}]\nresolver = \"3\"\n\n[workspace.package]\nversion = \"0.1.0\"\nedition = \"2024\"\nrust-version = \"1.97.1\"\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/radrootslabs/sdk\"\nhomepage = \"https://radroots.org\"\nreadme = \"README\"\nauthors = [\"Tyson Lupul <tyson@radroots.org>\"]\n\n[workspace.metadata.radroots.public-package]\nversion = \"0.1.0\"\nauthors = [\"Tyson Lupul <tyson@radroots.org>\"]\nreadme = \"README.md\"\n\n[workspace.lints.rust]\nunsafe_code = \"forbid\"\n\n[workspace.lints.rustdoc]\nbroken_intra_doc_links = \"deny\"\n\n[workspace.lints.clippy]\ndbg_macro = \"deny\"\ntodo = \"deny\"\nunimplemented = \"deny\"\n"
)
}
@@ -748,7 +797,7 @@ adr_required = false
complete_workspace_manifest("\"crates/radroots\""),
)
.expect("write workspace manifest");
- let manifest = "[package]\nname = \"radroots\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nlicense.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\nauthors.workspace = true\nreadme = \"README.md\"\npublish = false\n";
+ let manifest = "[package]\nname = \"radroots\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nlicense.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\nauthors.workspace = true\nreadme = \"README.md\"\npublish = false\n\n[lints]\nworkspace = true\n";
fs::write(root.join("crates/radroots/Cargo.toml"), manifest)
.expect("write public manifest");
fs::write(root.join("crates/radroots/README.md"), "fixture\n")
@@ -757,12 +806,12 @@ adr_required = false
fs::write(
root.join("crates/radroots/Cargo.toml"),
- manifest.replace("authors.workspace = true\n", ""),
+ manifest.replace("[lints]\nworkspace = true\n", ""),
)
.expect("write incomplete public manifest");
let error = validate_public_package_metadata(&root, &architecture())
- .expect_err("missing authors must fail");
- assert!(error.contains("must declare authors"));
+ .expect_err("missing lint inheritance must fail");
+ assert!(error.contains("must inherit the workspace lint policy"));
let _ = fs::remove_dir_all(root);
}
}
diff --git a/tools/xtask/src/check.rs b/tools/xtask/src/check.rs
@@ -326,24 +326,15 @@ fn check_publication_policy(root: &Path) -> Result<(), String> {
policy.spec_id, architecture.spec_id
));
}
- let approved = policy_set(
- policy.approved_packages.into_iter(),
- "publication.approved_packages",
- )?;
- let local = policy_set(
- policy.local_packages.into_iter(),
- "publication.local_packages",
- )?;
- let external = policy_set(
- policy.external_packages.into_iter(),
- "publication.external_packages",
- )?;
+ let approved = policy_set(policy.approved_packages, "publication.approved_packages")?;
+ let local = policy_set(policy.local_packages, "publication.local_packages")?;
+ let external = policy_set(policy.external_packages, "publication.external_packages")?;
let expected_local = policy_set(
- architecture.repositories.sdk.packages.into_iter(),
+ architecture.repositories.sdk.packages,
"architecture.repositories.sdk.packages",
)?;
let expected_external = policy_set(
- architecture.repositories.lib.packages.into_iter(),
+ architecture.repositories.lib.packages,
"architecture.repositories.lib.packages",
)?;
for (field, actual, expected) in [
@@ -437,26 +428,17 @@ fn check_publication_policy(root: &Path) -> Result<(), String> {
));
}
let classification = policy_file.workspace_classification;
- let private = policy_set(
- classification.private.into_iter(),
- "workspace_classification.private",
- )?;
+ let private = policy_set(classification.private, "workspace_classification.private")?;
let build_codegen = policy_set(
- classification.build_codegen.into_iter(),
+ classification.build_codegen,
"workspace_classification.build_codegen",
)?;
let test_support = policy_set(
- classification.test_support.into_iter(),
+ classification.test_support,
"workspace_classification.test_support",
)?;
- let preview = policy_set(
- classification.preview.into_iter(),
- "workspace_classification.preview",
- )?;
- let retired = policy_set(
- classification.retired.into_iter(),
- "workspace_classification.retired",
- )?;
+ let preview = policy_set(classification.preview, "workspace_classification.preview")?;
+ let retired = policy_set(classification.retired, "workspace_classification.retired")?;
let classes = [
("private", &private),
("build-codegen", &build_codegen),