chore(release): prepare public source release
This commit is contained in:
@@ -0,0 +1,484 @@
|
||||
//! Workspace policy tests for Jade Discipline.
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn workspace_root() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("..")
|
||||
.join("..")
|
||||
.canonicalize()
|
||||
.expect("workspace root")
|
||||
}
|
||||
|
||||
fn workspace_path(components: &[&str]) -> PathBuf {
|
||||
components
|
||||
.iter()
|
||||
.fold(workspace_root(), |path, component| path.join(component))
|
||||
}
|
||||
|
||||
fn script_path(script_name: &str) -> PathBuf {
|
||||
workspace_path(&["scripts", script_name])
|
||||
}
|
||||
|
||||
fn read_workspace_text(components: &[&str], label: &str) -> String {
|
||||
fs::read_to_string(workspace_path(components))
|
||||
.unwrap_or_else(|error| panic!("failed to read {label}: {error}"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workspace_cargo_toml_publishes_jade_lints_and_profiles() {
|
||||
let cargo_toml = read_workspace_text(&["Cargo.toml"], "Cargo.toml");
|
||||
|
||||
for required_line in [
|
||||
"rust-version = \"1.86\"",
|
||||
"missing_docs = \"deny\"",
|
||||
"pedantic = { level = \"deny\", priority = -3 }",
|
||||
"nursery = { level = \"deny\", priority = -2 }",
|
||||
"[profile.release-fast]",
|
||||
"lto = \"fat\"",
|
||||
"[profile.release-size]",
|
||||
"opt-level = \"z\"",
|
||||
] {
|
||||
assert!(
|
||||
cargo_toml.contains(required_line),
|
||||
"Cargo.toml should contain {required_line:?}"
|
||||
);
|
||||
}
|
||||
|
||||
for forbidden_line in [
|
||||
"missing_copy_implementations",
|
||||
"implicit_return",
|
||||
"missing_const_for_fn",
|
||||
"module_name_repetitions",
|
||||
"multiple_crate_versions",
|
||||
"must_use_candidate",
|
||||
"needless_pass_by_value",
|
||||
] {
|
||||
assert!(
|
||||
!cargo_toml.contains(forbidden_line),
|
||||
"Cargo.toml should not contain {forbidden_line:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_config_and_jade_docs_exist() {
|
||||
let config = read_workspace_text(&[".cargo", "config.toml"], ".cargo/config.toml");
|
||||
assert!(config.contains("git-fetch-with-cli = true"));
|
||||
assert!(config.contains("rustflags = [\"-Dwarnings\"]"));
|
||||
assert!(config.contains("frequency = \"always\""));
|
||||
assert!(workspace_path(&["justfile"]).is_file(), "missing justfile");
|
||||
assert!(
|
||||
workspace_path(&["bacon.toml"]).is_file(),
|
||||
"missing bacon.toml"
|
||||
);
|
||||
|
||||
let docs = read_workspace_text(&["docs", "jade-discipline.md"], "jade discipline docs");
|
||||
let maintainer_notes =
|
||||
read_workspace_text(&["docs", "maintainer-notes.md"], "maintainer notes");
|
||||
assert!(docs.contains("Jade Discipline"));
|
||||
assert!(docs.contains("cargo clippy --all-targets --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery"));
|
||||
assert!(docs.contains("Miri, fuzzing, sanitizer, no-panic, and Loom checks are Jade gates"));
|
||||
assert!(docs.contains(
|
||||
"Missing tools, missing harnesses, or platform discomfort are failures by default"
|
||||
));
|
||||
assert!(docs.contains("Global `allow` is reserved for two cases only"));
|
||||
assert!(docs.contains("smallest code-local scope"));
|
||||
assert!(docs.contains("Install"));
|
||||
assert!(docs.contains("just"));
|
||||
assert!(docs.contains("bacon"));
|
||||
assert!(maintainer_notes.contains("Jade has no optional safety tier"));
|
||||
assert!(maintainer_notes.contains("Every JSON-capable Mercury tool"));
|
||||
assert!(maintainer_notes.contains("is the shared AST/indexing engine"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_packaging_scripts_and_docs_exist() {
|
||||
for script_name in [
|
||||
"package-toolbox.ps1",
|
||||
"install-package-toolbox.ps1",
|
||||
"uninstall-package-toolbox.ps1",
|
||||
"generate-ai-skill.ps1",
|
||||
"check-ai-skill.ps1",
|
||||
] {
|
||||
assert!(
|
||||
script_path(script_name).is_file(),
|
||||
"missing packaging script {script_name}"
|
||||
);
|
||||
}
|
||||
|
||||
let readme = read_workspace_text(&["README.md"], "README.md");
|
||||
assert!(readme.contains("just"));
|
||||
assert!(readme.contains("bacon"));
|
||||
assert!(readme.contains("## Portable Package"));
|
||||
assert!(readme.contains(r".\scripts\package-toolbox.ps1"));
|
||||
assert!(readme.contains("install-package-toolbox.ps1"));
|
||||
assert!(readme.contains("mercury-toolbox-package.json"));
|
||||
assert!(readme.contains("SHA256SUMS.txt"));
|
||||
assert!(readme.contains("generate-ai-skill.ps1"));
|
||||
assert!(readme.contains(r".\skills\mercury-toolbox\"));
|
||||
assert!(readme.contains("### `msudo`"));
|
||||
assert!(readme.contains("HIGH RISK"));
|
||||
assert!(readme.contains("top-level high-risk toolbox command"));
|
||||
assert!(readme.contains("msudo status --json"));
|
||||
assert!(readme.contains("Select-Object ok,host,supports_runas,is_elevated"));
|
||||
assert!(readme.contains("msudo --help"));
|
||||
assert!(readme.contains("msudo run --help"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn powershell_gate_assets_and_docs_exist() {
|
||||
let root = workspace_root();
|
||||
assert!(
|
||||
script_path("check-powershell.ps1").is_file(),
|
||||
"missing PowerShell gate script"
|
||||
);
|
||||
assert!(
|
||||
script_path("cargo-flamegraph-windows.ps1").is_file(),
|
||||
"missing Windows flamegraph wrapper script"
|
||||
);
|
||||
assert!(
|
||||
workspace_path(&["PSScriptAnalyzerSettings.psd1"]).is_file(),
|
||||
"missing PowerShell analyzer settings"
|
||||
);
|
||||
|
||||
let check_jade = read_workspace_text(&["scripts", "check-jade.ps1"], "scripts/check-jade.ps1");
|
||||
assert!(check_jade.contains("check-powershell.ps1"));
|
||||
assert!(check_jade.contains("check-ai-skill.ps1"));
|
||||
assert!(check_jade.contains("check-jade-hardening.ps1"));
|
||||
assert!(
|
||||
check_jade.contains("Invoke-TimedNativeWithEnvironment"),
|
||||
"Jade coverage gate should be able to isolate cargo-llvm-cov environment"
|
||||
);
|
||||
assert!(
|
||||
check_jade.contains("CARGO_INCREMENTAL") && check_jade.contains("RUSTC_WRAPPER"),
|
||||
"Jade coverage gate should disable incremental and rustc-wrapper for cargo-llvm-cov"
|
||||
);
|
||||
assert!(
|
||||
check_jade.contains("CARGO_TARGET_DIR")
|
||||
&& check_jade.contains("mercury-jade-llvm-cov")
|
||||
&& check_jade.contains("cargo llvm-cov clean")
|
||||
&& check_jade
|
||||
.contains("Invoke-TimedNativeWithEnvironment -Name 'cargo llvm-cov clean'"),
|
||||
"Jade coverage gate should use a per-run isolated cargo target dir for clean and nextest"
|
||||
);
|
||||
assert!(
|
||||
check_jade.contains("MERCURY_JADE_COVERAGE_ROOT")
|
||||
&& check_jade.contains("C:\\tmp")
|
||||
&& check_jade.contains("'mtcov'")
|
||||
&& check_jade.contains(".Substring(0, 8)"),
|
||||
"Jade coverage target dir should stay short enough for Windows llvm-cov object argv"
|
||||
);
|
||||
assert!(
|
||||
check_jade.contains(
|
||||
"'llvm-cov',\n '--jobs',\n '1',\n 'nextest'"
|
||||
),
|
||||
"Jade coverage gate should limit cargo-llvm-cov build jobs before the nextest subcommand"
|
||||
);
|
||||
|
||||
assert_justfile_test_recipes(&root);
|
||||
|
||||
let ecosystem = read_workspace_text(
|
||||
&["scripts", "check-ecosystem.ps1"],
|
||||
"ecosystem check script",
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:all-binaries-report-version")
|
||||
&& ecosystem.contains("Test-ToolboxBinaryVersions"),
|
||||
"ecosystem gate should prove every toolbox binary reports --version"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:all-binaries-no-args-contract")
|
||||
&& ecosystem.contains("Test-ToolboxNoArgsContracts"),
|
||||
"ecosystem gate should prove every toolbox binary has bounded no-args behavior"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:all-binaries-invalid-flag-contract")
|
||||
&& ecosystem.contains("Test-ToolboxInvalidFlagContracts"),
|
||||
"ecosystem gate should prove every toolbox binary has bounded invalid-flag diagnostics"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:all-binaries-structured-output-help")
|
||||
&& ecosystem.contains("Test-ToolboxStructuredOutputHelpContracts"),
|
||||
"ecosystem gate should prove every toolbox binary exposes structured output help"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:malformed-jsonl-stdin-contract")
|
||||
&& ecosystem.contains("Test-ToolboxMalformedJsonlStdinContracts"),
|
||||
"ecosystem gate should prove malformed JSONL stdin is bounded for input-format commands"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:valid-jsonl-path-stream-smokes"),
|
||||
"ecosystem gate should prove representative positive JSONL path-stream behavior"
|
||||
);
|
||||
assert!(
|
||||
ecosystem.contains("toolbox:functional-toon-smokes"),
|
||||
"ecosystem gate should prove representative functional TOON output smokes"
|
||||
);
|
||||
|
||||
let check_hardening = read_workspace_text(
|
||||
&["scripts", "check-jade-hardening.ps1"],
|
||||
"scripts/check-jade-hardening.ps1",
|
||||
);
|
||||
for required_gate in [
|
||||
"cargo miri setup",
|
||||
"NightlyToolchain",
|
||||
"'fuzz'",
|
||||
"'run'",
|
||||
"json_family_decode",
|
||||
"-Zsanitizer=address",
|
||||
"check-no-panic.ps1",
|
||||
"loom_capture",
|
||||
"Mode 'hardening'",
|
||||
"ValidateRange(1, 3600)",
|
||||
"Only = 'All'",
|
||||
] {
|
||||
assert!(
|
||||
check_hardening.contains(required_gate),
|
||||
"hardening script should contain {required_gate:?}"
|
||||
);
|
||||
}
|
||||
assert!(check_hardening.contains("exemption requires a non-empty reason"));
|
||||
|
||||
let jade_install = read_workspace_text(
|
||||
&["scripts", "install-jade-tooling.ps1"],
|
||||
"scripts/install-jade-tooling.ps1",
|
||||
);
|
||||
assert!(jade_install.contains("PSScriptAnalyzer"));
|
||||
assert!(jade_install.contains("cargo-binstall"));
|
||||
assert!(jade_install.contains("\"just\", \"bacon\""));
|
||||
assert!(jade_install.contains("\"component\", \"add\", \"miri\""));
|
||||
assert!(jade_install.contains("\"cargo-udeps\", \"cargo-llvm-cov\""));
|
||||
assert!(jade_install.contains("\"install\", \"cargo-fuzz\""));
|
||||
|
||||
let docs = read_workspace_text(&["docs", "jade-discipline.md"], "jade discipline docs");
|
||||
assert!(docs.contains("PowerShell Gate"));
|
||||
assert!(docs.contains("check-powershell.ps1"));
|
||||
assert!(docs.contains("check-ai-skill.ps1"));
|
||||
assert!(docs.contains("PSScriptAnalyzer"));
|
||||
assert!(docs.contains("cargo-flamegraph-windows.ps1"));
|
||||
|
||||
let readme = read_workspace_text(&["README.md"], "README.md");
|
||||
assert!(readme.contains("cargo-flamegraph-windows.ps1"));
|
||||
}
|
||||
|
||||
fn assert_justfile_test_recipes(root: &std::path::Path) {
|
||||
let justfile = fs::read_to_string(root.join("justfile")).expect("justfile");
|
||||
assert!(
|
||||
justfile.contains("coverage:\n cargo llvm-cov nextest --all-features --summary-only"),
|
||||
"just coverage should keep a fast local coverage path without forcing Jade's serial coverage gate"
|
||||
);
|
||||
assert!(
|
||||
!justfile.contains("coverage:\n cargo llvm-cov clean --workspace"),
|
||||
"just coverage should not pre-clean coverage artifacts on every local iteration"
|
||||
);
|
||||
assert!(
|
||||
justfile.contains("test:\n cargo nextest run --all-features"),
|
||||
"just test should keep the fast incremental nextest path for local iteration"
|
||||
);
|
||||
assert!(
|
||||
justfile.contains("stable-test:")
|
||||
&& justfile.contains(
|
||||
"CARGO_INCREMENTAL = '0'; cargo nextest run --all-features --run-ignored all",
|
||||
),
|
||||
"stable-test should keep the non-incremental Windows cleanup-race path and slow integration coverage"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn repo_temp_paths_are_audited_and_use_exclusive_writes() {
|
||||
let root = workspace_root();
|
||||
let production_temp_dir_hits = production_source_hits(
|
||||
&root,
|
||||
&[
|
||||
"std::env::temp_dir()",
|
||||
"env::temp_dir()",
|
||||
"tempfile::",
|
||||
"NamedTempFile",
|
||||
"TempDir::new",
|
||||
"tempdir()",
|
||||
],
|
||||
);
|
||||
assert_eq!(
|
||||
production_temp_dir_hits,
|
||||
[
|
||||
"crates\\argv\\src\\lib.rs:std::env::temp_dir().join(format!(",
|
||||
"crates\\envdiff\\src\\lib.rs:std::env::temp_dir().join(format!(",
|
||||
"crates\\msudo\\src\\lib.rs:let temp_dir = std::env::temp_dir();",
|
||||
"crates\\runtimekit\\src\\lib.rs:std::env::temp_dir().join(format!(\"{prefix}-{unique}.{extension}\"))",
|
||||
],
|
||||
"production temp root use must stay explicitly audited"
|
||||
);
|
||||
|
||||
for (path, required) in [
|
||||
(
|
||||
"crates/runtimekit/src/lib.rs",
|
||||
&[
|
||||
"fn write_shell_wrapper_file",
|
||||
".create_new(true)",
|
||||
"refusing to replace existing shell wrapper",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"crates/argv/src/lib.rs",
|
||||
&[
|
||||
"fn write_cmd_wrapper_file",
|
||||
".create_new(true)",
|
||||
"refusing to replace existing cmd inspect wrapper",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"crates/envdiff/src/lib.rs",
|
||||
&[
|
||||
"fn write_temp_file_exclusive",
|
||||
".create_new(true)",
|
||||
"fn create_temp_dir_exclusive",
|
||||
"fs::create_dir(path)",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"crates/msudo/src/lib.rs",
|
||||
&[
|
||||
"fn write_relay_exit_status",
|
||||
".create_new(true)",
|
||||
"failed to create relay exit status",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"crates/runprobe/src/lib.rs",
|
||||
&[
|
||||
"fn write_log_file_exclusive",
|
||||
".create_new(true)",
|
||||
"refusing to replace existing runprobe log",
|
||||
][..],
|
||||
),
|
||||
(
|
||||
"crates/windowsupport/src/sudo.rs",
|
||||
&[
|
||||
"fn create_relay_output_file",
|
||||
".create_new(true)",
|
||||
"FILE_FLAG_OPEN_REPARSE_POINT",
|
||||
][..],
|
||||
),
|
||||
] {
|
||||
let body = fs::read_to_string(root.join(path)).unwrap_or_else(|error| {
|
||||
panic!("failed to read {path}: {error}");
|
||||
});
|
||||
for needle in required {
|
||||
assert!(
|
||||
body.contains(needle),
|
||||
"{path} should keep temp/log output guard {needle:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn production_source_hits(root: &std::path::Path, needles: &[&str]) -> Vec<String> {
|
||||
let mut hits = Vec::new();
|
||||
collect_production_source_hits(&root.join("crates"), root, needles, &mut hits);
|
||||
hits.sort();
|
||||
hits
|
||||
}
|
||||
|
||||
fn collect_production_source_hits(
|
||||
directory: &std::path::Path,
|
||||
root: &std::path::Path,
|
||||
needles: &[&str],
|
||||
hits: &mut Vec<String>,
|
||||
) {
|
||||
for entry in fs::read_dir(directory).unwrap_or_else(|error| {
|
||||
panic!("failed to read {}: {error}", directory.display());
|
||||
}) {
|
||||
let path = entry.expect("directory entry").path();
|
||||
if path.is_dir() {
|
||||
if path.file_name().and_then(|name| name.to_str()) != Some("tests") {
|
||||
collect_production_source_hits(&path, root, needles, hits);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if path.extension().and_then(|extension| extension.to_str()) != Some("rs") {
|
||||
continue;
|
||||
}
|
||||
collect_file_hits(&path, root, needles, hits);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_file_hits(
|
||||
path: &std::path::Path,
|
||||
root: &std::path::Path,
|
||||
needles: &[&str],
|
||||
hits: &mut Vec<String>,
|
||||
) {
|
||||
let body = fs::read_to_string(path).unwrap_or_else(|error| {
|
||||
panic!("failed to read {}: {error}", path.display());
|
||||
});
|
||||
let mut in_test_region = path.components().any(|component| {
|
||||
component
|
||||
.as_os_str()
|
||||
.to_string_lossy()
|
||||
.eq_ignore_ascii_case("tests")
|
||||
});
|
||||
for line in body.lines() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed == "#[cfg(test)]" || trimmed.starts_with("#[test]") {
|
||||
in_test_region = true;
|
||||
}
|
||||
if !in_test_region && needles.iter().any(|needle| trimmed.contains(needle)) {
|
||||
let relative = path.strip_prefix(root).unwrap_or(path);
|
||||
hits.push(format!("{}:{}", relative.display(), trimmed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deny_advisory_ignores_carry_review_evidence() {
|
||||
let deny = read_workspace_text(&["deny.toml"], "deny.toml");
|
||||
let advisory = "RUSTSEC-2024-0436";
|
||||
let offset = deny
|
||||
.find(advisory)
|
||||
.unwrap_or_else(|| panic!("deny.toml should mention {advisory}"));
|
||||
let context_start = deny[..offset]
|
||||
.rfind("[advisories]")
|
||||
.expect("advisories section");
|
||||
let context = &deny[context_start..offset];
|
||||
|
||||
for required in [
|
||||
"Package:",
|
||||
"Reachability:",
|
||||
"Reviewed:",
|
||||
"Upgrade/follow-up:",
|
||||
] {
|
||||
assert!(
|
||||
context.contains(required),
|
||||
"advisory ignore {advisory} should document {required}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ai_asset_checks_self_heal_generated_drift_before_failing() {
|
||||
for script_name in ["check-ai-prompt.ps1", "check-ai-skill.ps1"] {
|
||||
let script = read_workspace_text(&["scripts", script_name], script_name);
|
||||
assert!(
|
||||
script.contains("Invoke-GeneratorCheck"),
|
||||
"{script_name} should use the shared check/regenerate/recheck helper"
|
||||
);
|
||||
assert!(
|
||||
script.contains("Invoke-GeneratorWrite"),
|
||||
"{script_name} should regenerate stale generated assets automatically"
|
||||
);
|
||||
assert!(
|
||||
script.contains("still out of date after regeneration"),
|
||||
"{script_name} should only ask for manual intervention after regeneration fails"
|
||||
);
|
||||
}
|
||||
|
||||
let docs = read_workspace_text(&["docs", "jade-discipline.md"], "jade docs");
|
||||
assert!(
|
||||
docs.contains("self-heal generated asset drift"),
|
||||
"Jade docs should describe the AI asset gate's self-healing behavior"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user