{"record":{"id":"4fc8d3f15cf13d44","repo":"astrid-runtime/astrid","slug":"distro-lock-identity-does-not-match-the-signed-dis","errorCode":null,"errorMessage":"Distro.lock identity does not match the signed Distro.toml","messagePattern":"Distro\\.lock identity does not match the signed Distro\\.toml","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init_signed_source.rs","lineNumber":337,"sourceCode":"    Ok(lock\n        .capsules\n        .iter()\n        .filter_map(|capsule| {\n            capsule\n                .resolved_ref\n                .clone()\n                .map(|resolved_ref| (capsule.name.clone(), resolved_ref))\n        })\n        .collect())\n}\n\n/// Require the signed lock to describe exactly the authenticated TOML members.\nfn validate_signed_member_sets(manifest: &DistroManifest, lock: &DistroLock) -> anyhow::Result<()> {\n    if lock.schema_version != manifest.schema_version\n        || lock.distro.id != manifest.distro.id\n        || lock.distro.version != manifest.distro.version\n    {\n        bail!(\"Distro.lock identity does not match the signed Distro.toml\");\n    }\n\n    let declared: HashMap<&str, &DistroCapsule> = manifest\n        .capsules\n        .iter()\n        .map(|capsule| (capsule.name.as_str(), capsule))\n        .collect();\n    anyhow::ensure!(\n        declared.len() == manifest.capsules.len() && lock.capsules.len() == declared.len(),\n        \"signed Distro.lock members do not match Distro.toml declarations\"\n    );\n    for capsule in &lock.capsules {\n        let declared_capsule = declared\n            .get(capsule.name.as_str())\n            .copied()\n            .ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"signed Distro.lock contains undeclared capsule '{}'\",","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init_signed_source.rs#L319-L355","documentation":"validate_signed_member_sets enforces that the Distro.lock describes exactly the same distribution as the signed Distro.toml before any capsule is resolved. It first compares schema_version, distro.id, and distro.version; any difference means the lock belongs to a different distribution identity than the authenticated manifest, so it bails rather than resolving members. This prevents mixing members across distro versions or entirely different distros.","triggerScenarios":"verify_signed_manifest calls validate_signed_member_sets with the signed DistroManifest and DistroLock; lock.schema_version != manifest.schema_version, or lock.distro.id != manifest.distro.id, or lock.distro.version != manifest.distro.version.","commonSituations":"Upstream released distro version 1.3.0 but the lock still records 1.2.0; lock file copied from a different distro project (id mismatch); manifest or lock schema upgraded by a tooling version bump; user checked out an old branch whose lock predates the signed manifest's version bump.","solutions":["Align versions: regenerate Distro.lock from the current signed Distro.toml so schema_version, distro.id, and distro.version all match.","If you meant the older version, fetch the signed Distro.toml for the distro version recorded in your lock instead.","Check for a schema-version upgrade requiring a tooling update — upgrade the CLI and re-lock.","Ensure the lock file actually belongs to this distro (matching id); if copied from another project, delete it and re-init."],"exampleFix":"// before (Distro.lock)\ndistro = { id = \"mydistro\", version = \"1.2.0\" }\n// after (regenerated to match signed Distro.toml)\ndistro = { id = \"mydistro\", version = \"1.3.0\" }","handlingStrategy":"validation","validationCode":"let identity_matches = lock.schema_version == manifest.schema_version\n    && lock.distro.id == manifest.distro.id\n    && lock.distro.version == manifest.distro.version;\nif !identity_matches {\n    eprintln!(\"Distro.lock was generated for a different distro/version; re-lock\");\n}","typeGuard":null,"tryCatchPattern":"match verify_signed_manifest(&client, &url, &manifest_hash, &lock, accept_new_key).await {\n    Err(e) if e.to_string().contains(\"identity does not match\") => {\n        eprintln!(\"Lock belongs to {} {}, manifest is {} {} — regenerate the lock\",\n            lock.distro.id, lock.distro.version, manifest.distro.id, manifest.distro.version);\n        Err(e)\n    }\n    other => other,\n}","preventionTips":["Keep one Distro.lock per distro id/version; never copy locks between projects","Bump/re-lock in the same change as any distro version upgrade","Ensure the manifest URL you fetch corresponds to the distro version in your lock","Track schema-version changes in the tooling changelog and upgrade before re-locking"],"tags":["integrity","lockfile","version-mismatch","signature","rust"],"backgroundTag":"checksum-mismatch","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}