{"record":{"id":"ddf6d0286d4d0cc7","repo":"astrid-runtime/astrid","slug":"capsule-expected-signed-ref-expected-ref-did","errorCode":null,"errorMessage":"capsule '{expected}' signed ref {expected_ref} did not match installed ref {:?}","messagePattern":"capsule '(.+?)' signed ref (.+?) did not match installed ref (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/init.rs","lineNumber":875,"sourceCode":"        .into_iter()\n        .next()\n        .expect(\"length checked\");\n    if installed.id != *expected {\n        bail!(\n            \"distro declared capsule '{expected}', but the checked installer reported '{}'\",\n            installed.id\n        );\n    }\n    if !declared_version.is_empty() && installed.version != declared_version {\n        bail!(\n            \"capsule '{expected}' release selector declared version {declared_version}, but the installed manifest reports {}\",\n            installed.version\n        );\n    }\n    if let Some(expected_ref) = expected_ref\n        && outcome.resolved_ref.as_deref() != Some(expected_ref)\n    {\n        bail!(\n            \"capsule '{expected}' signed ref {expected_ref} did not match installed ref {:?}\",\n            outcome.resolved_ref\n        );\n    }\n    Ok(VerifiedBatchInstall {\n        version: installed.version,\n        wasm_hash: installed.wasm_hash,\n        resolved_ref: outcome.resolved_ref,\n        skipped: installed.skipped,\n    })\n}\n\n/// Persist distro variable templates through the daemon's typed env API.\n///\n/// Init may run before a capsule has been installed, so this deliberately\n/// does not require a capsule manifest to classify fields. Variable metadata\n/// from `Distro.toml` carries the secret bit; unresolved literal fields are\n/// ordinary text. The daemon remains the only writer for durable env state.","sourceCodeStart":857,"sourceCodeEnd":893,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/init.rs#L857-L893","documentation":"After a batch install, validate_batch_install checks that the resolved git ref recorded by the installer matches the signed ref the distro expected. If outcome.resolved_ref differs from expected_ref, it bails. This ensures the capsule was installed from the exact signed commit/ref, protecting supply-chain integrity.","triggerScenarios":"install_capsules_with_resume passes an expected_ref (signed ref from the distro) and the install outcome's resolved_ref is None or points to a different ref/commit.","commonSituations":"The upstream repository was force-pushed or the signed ref was rotated; a mirror checked out a different branch/commit; the distro lockfile is stale relative to the published signed ref.","solutions":["Refresh the distro/lock data so the signed ref matches the currently published ref, then rerun the install.","Inspect the installer log to see which ref was actually resolved; if it is the legitimate new ref, update the signed ref expectation.","Verify the capsule source repository for force-pushes or tag moves before trusting either ref.","Pin to a commit hash instead of a mutable ref to avoid drift."],"exampleFix":"// before\nexpected_ref = \"refs/tags/v1.0.0\"   // upstream moved tag to a new commit\n// after\nexpected_ref = \"refs/tags/v1.0.1\"   // refreshed signed ref after verifying upstream","handlingStrategy":"validation","validationCode":"if let Some(expected_ref) = expected_ref {\n    let resolved = fetch_resolved_ref(capsule)?; // before install\n    if resolved.as_deref() != Some(expected_ref) {\n        return Err(anyhow!(\"signed ref drift for {capsule}: {resolved:?} != {expected_ref}\"));\n    }\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"signed ref\") => eprintln!(\"upstream ref moved; refresh signed ref after verifying\"),\n    Err(e) => return Err(e),\n    Ok(v) => Ok(v),\n}","preventionTips":["Pin immutable commit hashes rather than movable tags/branches.","Verify upstream repos for force-pushes before trusting signed refs.","Refresh distro lock/signed refs through a verified update flow.","Alert on signed-ref mismatch instead of silently re-resolving."],"tags":["ref-mismatch","supply-chain","capsule-install"],"backgroundTag":"checksum-mismatch","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}