myc

Self-custodial remote signer for Radroots apps
git clone https://radroots.dev/git/myc.git
Log | Files | Refs | README | LICENSE

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:
Mcontracts/rshr-202-step-300-gates.v1.json | 2+-
Mflake.lock | 22+++++++++++++++++-----
Mflake.nix | 108++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Mradroots.service.source-lock.v3.toml | 2+-
Mtools/xtask/src/rshr_202_step_300_gate.rs | 6+++---
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", ), ];