commit 9c74385661e5fbdf0489eae876e27a90cef56ec2
parent 23f7a63df9bd9c7bc59c69c95ed3f32406d024ee
Author: triesap <tyson@radroots.org>
Date: Mon, 7 Sep 2026 01:11:02 +0000
fix(nix): make Myc package builds reproducible
- Pin Crane to the immutable compatible v0.22.0 revision.
- Preserve embedded JSON contracts and README in the Nix source.
- Exercise a real repository-local release-acceptance command.
- Refresh the source lock and governed Step 300 verifier digests.
Diffstat:
5 files changed, 110 insertions(+), 30 deletions(-)
diff --git a/contracts/rshr-202-step-300-gates.v1.json b/contracts/rshr-202-step-300-gates.v1.json
@@ -1 +1 @@
-{"gate_command_contract":[{"argv_template":["cargo","extbuild","run","--","cargo","run","--offline","--locked","-q","-p","myc_xtask","--","rshr-step-300-gate","--step={step}","--check-id={check_id}","--source-revision={source_revision}","--source-tree={source_tree}","--candidate-digest={candidate_digest}","--platform=macos_aarch64","--execution-request-sha256={execution_request_sha256}"],"assertion_id":["step_300_gate_01_0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5"],"check_id":"gate-01-0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5","environment_authority":{"cache_policy_id":"rshr-200-step-287-cache-policy.v1","cache_policy_sha256":"3e81d178bce97b6c349dfbb00c68fd6f620ac00b1a1c8d37b12e9998f3c9eaaa","cadence_policy_id":"rshr-200-step-287-cadence-policy.v1","cadence_policy_sha256":"d24903df8659ee3772297c84994911efe7d21cb8b988320ddc6ddce0431892a1","isolation":"extbuild_host_constrained","network":"disabled","network_policy_id":"none","network_policy_sha256":"none","resource_policy_id":"rshr-200-step-287-resource-policy.v1","resource_policy_sha256":"05d3c7a89185d3c55678d97955193fce2ed92b1eee5af99083d77ea64c98d14e"},"environment_names":["EXT_BUILD_CONFIG","EXT_BUILD_MACHINE_CONFIG","EXT_BUILD_ROOT","HOME","PATH","RUSTUP_TOOLCHAIN","TMPDIR"],"gate_definition_sha256":"0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5","required_platforms":["macos_aarch64"],"required_tools":["rustc"],"result_schema":"radroots.services-hardening.rshr-200-step-check-result.v1","schema":"radroots.services-hardening.rshr-200-step-check-command.v1","step":300,"verifier_path":"tools/xtask/src/rshr_202_step_300_gate.rs","verifier_sha256":"c6b54d4fe93f539fce6427c43de4ef7a6313bdec31e659aa0cc7f5870670048f"}],"schema":"radroots.myc.rshr-202-step-300-gates.v1","step":[300]}
+{"gate_command_contract":[{"argv_template":["cargo","extbuild","run","--","cargo","run","--offline","--locked","-q","-p","myc_xtask","--","rshr-step-300-gate","--step={step}","--check-id={check_id}","--source-revision={source_revision}","--source-tree={source_tree}","--candidate-digest={candidate_digest}","--platform=macos_aarch64","--execution-request-sha256={execution_request_sha256}"],"assertion_id":["step_300_gate_01_0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5"],"check_id":"gate-01-0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5","environment_authority":{"cache_policy_id":"rshr-200-step-287-cache-policy.v1","cache_policy_sha256":"3e81d178bce97b6c349dfbb00c68fd6f620ac00b1a1c8d37b12e9998f3c9eaaa","cadence_policy_id":"rshr-200-step-287-cadence-policy.v1","cadence_policy_sha256":"d24903df8659ee3772297c84994911efe7d21cb8b988320ddc6ddce0431892a1","isolation":"extbuild_host_constrained","network":"disabled","network_policy_id":"none","network_policy_sha256":"none","resource_policy_id":"rshr-200-step-287-resource-policy.v1","resource_policy_sha256":"05d3c7a89185d3c55678d97955193fce2ed92b1eee5af99083d77ea64c98d14e"},"environment_names":["EXT_BUILD_CONFIG","EXT_BUILD_MACHINE_CONFIG","EXT_BUILD_ROOT","HOME","PATH","RUSTUP_TOOLCHAIN","TMPDIR"],"gate_definition_sha256":"0293aa6fc55f8e03e0eddf11bb8d28a89272cca330854aa3fd7a68633c2850f5","required_platforms":["macos_aarch64"],"required_tools":["rustc"],"result_schema":"radroots.services-hardening.rshr-200-step-check-result.v1","schema":"radroots.services-hardening.rshr-200-step-check-command.v1","step":300,"verifier_path":"tools/xtask/src/rshr_202_step_300_gate.rs","verifier_sha256":"5e42647050621b3e6d80e9fb5192d70cd7729af4be863d9dfea5438ce5a5e057"}],"schema":"radroots.myc.rshr-202-step-300-gates.v1","step":[300]}
diff --git a/flake.lock b/flake.lock
@@ -2,16 +2,17 @@
"nodes": {
"crane": {
"locked": {
- "lastModified": 1773189535,
- "narHash": "sha256-E1G/Or6MWeP+L6mpQ0iTFLpzSzlpGrITfU2220Gq47g=",
+ "lastModified": 1766774972,
+ "narHash": "sha256-8qxEFpj4dVmIuPn9j9z6NTbU+hrcGjBOvaxTzre5HmM=",
"owner": "ipetkov",
"repo": "crane",
- "rev": "6fa2fb4cf4a89ba49fc9dd5a3eb6cde99d388269",
+ "rev": "01bc1d404a51a0a07e9d8759cd50a7903e218c82",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
+ "rev": "01bc1d404a51a0a07e9d8759cd50a7903e218c82",
"type": "github"
}
},
@@ -35,7 +36,9 @@
},
"lib": {
"inputs": {
- "crane": "crane",
+ "crane": [
+ "crane"
+ ],
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay",
@@ -89,7 +92,16 @@
},
"root": {
"inputs": {
- "lib": "lib"
+ "crane": "crane",
+ "lib": "lib",
+ "nixpkgs": [
+ "lib",
+ "nixpkgs"
+ ],
+ "rust-overlay": [
+ "lib",
+ "rust-overlay"
+ ]
}
},
"rust-overlay": {
diff --git a/flake.nix b/flake.nix
@@ -1,10 +1,29 @@
{
description = "Myc Nostr remote signer";
- inputs.lib.url = "github:radrootslabs/lib/055096853fca95e15d0f813d33a14aca13be3881";
+ inputs = {
+ # Crane 0.23+ currently asks nixpkgs' Cargo vendor helper to fetch
+ # semver-build-metadata crate versions through the crates.io API. That
+ # endpoint rejects the literal `+`; the immutable v0.22.0 input avoids
+ # that upstream fetch defect while preserving the same locked sources.
+ crane.url = "github:ipetkov/crane/01bc1d404a51a0a07e9d8759cd50a7903e218c82";
+ lib = {
+ url = "github:radrootslabs/lib/055096853fca95e15d0f813d33a14aca13be3881";
+ inputs.crane.follows = "crane";
+ };
+ nixpkgs.follows = "lib/nixpkgs";
+ rust-overlay.follows = "lib/rust-overlay";
+ };
outputs =
- { self, lib }:
+ {
+ self,
+ crane,
+ lib,
+ nixpkgs,
+ rust-overlay,
+ ...
+ }:
let
systems = lib.lib.supportedSystems;
forAllSystems = function:
@@ -17,40 +36,89 @@
serviceOutputs =
system:
let
+ pkgs = import nixpkgs {
+ inherit system;
+ overlays = [ rust-overlay.overlays.default ];
+ };
helpers = lib.lib.mkServiceHelpers system;
toolchain = helpers.mkToolchain {
rustToolchainFile = ./rust-toolchain.toml;
};
nativeInputs = helpers.mkNativeInputs { };
- package = helpers.mkServicePackage {
- inherit nativeInputs toolchain;
- source = ./.;
+ craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
+ source = pkgs.lib.cleanSourceWith {
+ src = ./.;
+ filter =
+ path: type:
+ craneLib.filterCargoSources path type
+ || pkgs.lib.hasSuffix ".json" (baseNameOf path)
+ || baseNameOf path == "README";
+ name = "myc-source";
+ };
+ commonArgs = {
+ src = source;
cargoLock = ./Cargo.lock;
- servicePackage = "myc";
- binaryName = "myc";
+ strictDeps = true;
+ nativeBuildInputs = nativeInputs.nativeBuildInputs;
+ buildInputs = nativeInputs.buildInputs;
+ env = nativeInputs.environment;
+ doCheck = false;
};
- hooks = {
+ cargoArtifacts = craneLib.buildDepsOnly commonArgs;
+ package = craneLib.buildPackage (
+ commonArgs
+ // {
+ inherit cargoArtifacts;
+ pname = "myc";
+ version = "0.1.0";
+ CARGO_PROFILE = "release";
+ cargoExtraArgs = "--locked --package myc --bin myc";
+ }
+ );
+ mkCargoCheck =
+ name: command: extraArgs:
+ craneLib.mkCargoDerivation (
+ commonArgs
+ // extraArgs
+ // {
+ inherit cargoArtifacts;
+ pname = "myc-${name}";
+ version = "1";
+ buildPhaseCargoCommand = command;
+ installPhaseCommand = "mkdir -p $out";
+ }
+ );
+ checks = {
+ fmt = craneLib.cargoFmt (
+ commonArgs
+ // {
+ pname = "myc-fmt";
+ version = "1";
+ }
+ );
+ check = mkCargoCheck "check" "cargo check --workspace --all-targets --locked" { };
+ test = mkCargoCheck "test" "cargo test --workspace --all-targets --locked" { };
+ clippy = mkCargoCheck "clippy" "cargo clippy --workspace --all-targets --locked -- -D warnings" { };
+ docs = mkCargoCheck "docs" "cargo doc --workspace --no-deps --locked" {
+ RUSTDOCFLAGS = "-D warnings";
+ };
config = package;
integration = package;
+ package = package;
source-lock = package;
sqlx = package;
};
- checks = helpers.mkServiceChecks {
- serviceName = "myc";
- inherit
- hooks
- nativeInputs
- package
- toolchain
- ;
- source = ./.;
- cargoLock = ./Cargo.lock;
- };
apps = helpers.mkServiceApps {
serviceName = "myc";
binaryName = "myc";
inherit nativeInputs package toolchain;
- releaseAcceptanceCommand = "${package}/bin/myc --help >/dev/null";
+ releaseAcceptanceCommand = ''
+ ${package}/bin/myc \
+ --profile repo-local \
+ --instance nix-release-acceptance \
+ --repo-local-root "$PWD" \
+ config schema >/dev/null
+ '';
};
devShells.default = helpers.mkServiceDevShell {
serviceName = "myc";
diff --git a/radroots.service.source-lock.v3.toml b/radroots.service.source-lock.v3.toml
@@ -38,7 +38,7 @@ supported_systems = ["aarch64-darwin", "x86_64-linux"]
[nix.public_input_lock]
path = "flake.lock"
-sha256 = "df48d334292ea79f1156757279b0cfc01008be1b8a50f013b381b6fe31ff8f56"
+sha256 = "5d5b11622c341292f429a5f93e55f38a3506431b139720ff62f983b35bf7d55f"
binding = "exact_regular_file_bytes"
mutable_reference = "forbidden"
lib_input = "lib"
diff --git a/tools/xtask/src/rshr_202_step_300_gate.rs b/tools/xtask/src/rshr_202_step_300_gate.rs
@@ -28,15 +28,15 @@ const EXACT_SOURCES: &[(&str, &str)] = &[
),
(
"flake.lock",
- "df48d334292ea79f1156757279b0cfc01008be1b8a50f013b381b6fe31ff8f56",
+ "5d5b11622c341292f429a5f93e55f38a3506431b139720ff62f983b35bf7d55f",
),
(
"flake.nix",
- "13d3acf9a25e8403dc03fa770b6ccb8bdc2ff2fea1c483395128b622f2703393",
+ "906b1cb7176e421d6bf067e76d6da2860a4863468651e9d768bc0933a1635eb4",
),
(
"radroots.service.source-lock.v3.toml",
- "fab0e089bd81c707f59a2428789555337fb0ef56d3d0cb195b59b257010bead7",
+ "32064c24438615895e0ebdef2de5f55b93c32400280e87452a4dc6077ddbaf72",
),
];