{"record":{"id":"b8b34e27e2512de7","repo":"jdx/mise","slug":"packslip-project-this-release-if-the-vendo","errorCode":null,"errorMessage":"packslip:{project}: this release {}.\n\nIf the vendor announced the change, run `mise packslip forget {project}` and install again; the next release accepted sets the pin.","messagePattern":"packslip:(.+?): this release (.+?)\\.\n\nIf the vendor announced the change, run `mise packslip forget (.+?)` and install again; the next release accepted sets the pin\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packslip_pins.rs","lineNumber":151,"sourceCode":"}\n\nfn check_against(pin: &Pin, project: &str, observed: Observed<'_>) -> Result<()> {\n    let signer = signer_of(observed.scheme, observed.key_id);\n    let mut problems = Vec::new();\n    if pin.scheme != observed.scheme || pin.signer != signer {\n        problems.push(format!(\n            \"is signed by {signer} ({}), but {} ({}) signed what mise accepted before\",\n            observed.scheme, pin.signer, pin.scheme\n        ));\n    }\n    if pin.attested_by == \"vendor\" && observed.attested_by == \"repackager\" {\n        problems.push(\n            \"is attested by a repackager, but the vendor's own packslip was accepted before\".into(),\n        );\n    }\n    if pin.provenance && !observed.provenance {\n        problems.push(\"drops the build provenance every artifact linked before\".into());\n    }\n    if !problems.is_empty() {\n        bail!(\n            \"packslip:{project}: this release {}.\\n\\nIf the vendor announced the change, run `mise packslip forget {project}` and install again; the next release accepted sets the pin.\",\n            problems.join(\", and \")\n        );\n    }\n    Ok(())\n}\n\n/// Set the project's pin from an accepted release, or strengthen it: what\n/// got stronger is remembered, what stayed the same is left alone. Checks\n/// again under the lock, since the file may have changed since [`check`].\npub(crate) fn record(project: &str, observed: Observed<'_>) -> Result<Pin> {\n    record_at(&pins_file(), project, observed)\n}\n\npub(crate) fn record_at(path: &Path, project: &str, observed: Observed<'_>) -> Result<Pin> {\n    let _lock = locked(path)?;","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/packslip_pins.rs#L133-L169","documentation":"Packslip pins record properties of the first accepted release of a project (signer set, repackager attestation, build provenance). `check_against` compares the new release against that pin and bails listing every property the release changed. This is a supply-chain guard: a vendor-side change to signing or provenance silently differing from what you accepted before is blocked until you explicitly acknowledge it.","triggerScenarios":"Installing or updating a packslip tool where the new release's signer list shrinks/changes, provenance metadata disappears, or attestation flips relative to the pinned state recorded in the pins file.","commonSituations":"Vendor rotated signing keys or switched CI and dropped provenance; a repackager replaced the official distribution; pins file carried over from an old install while upstream changed its release process.","solutions":["Confirm the vendor publicly announced the signing/provenance change","Run `mise packslip forget <project>` to clear the pin, then reinstall — the next accepted release sets a new pin","If the change was NOT announced, do not forget the pin; treat it as a possible supply-chain compromise and verify artifacts out-of-band","Inspect the error's problem list (joined by ', and ') to see exactly which property changed before deciding"],"exampleFix":"// before: update blocked by pin\nmise install packslip:example-cli   # error: this release drops the build provenance...\n// after: acknowledge the announced change\nmise packslip forget example-cli && mise install packslip:example-cli","handlingStrategy":"validation","validationCode":"mise packslip show <project>  # inspect pinned signers/provenance before updating","typeGuard":null,"tryCatchPattern":"match packslip_pins::check_against(&pin, &observed) {\n    Ok(()) => proceed_install(),\n    Err(e) if vendor_announced_change() => { packslip_forget(project)?; proceed_install(); }\n    Err(e) => halt_and_alert_user(e),\n}","preventionTips":["Subscribe to vendor announcements for signing-key rotations","Review the pins file when migrating machines so stale pins are intentional","Never blindly `packslip forget` when the problem list mentions dropped provenance or signer changes","Treat unexplained pin violations as potential supply-chain incidents"],"tags":["security","supply-chain","packslip","signing"],"backgroundTag":"checksum-mismatch","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}