{"record":{"id":"7cb35c65d8cdafc8","repo":"astrid-runtime/astrid","slug":"invalid-capsule-authority-migration-receipt","errorCode":null,"errorMessage":"invalid capsule authority migration receipt: {}","messagePattern":"invalid capsule authority migration receipt: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/legacy_migration_barrier/ledger.rs","lineNumber":95,"sourceCode":"                    \"verified-system-env-v1:source-digest={}:markers=blake3:{}\",\n                    host_source.digest,\n                    blake3::hash(&receipt).to_hex()\n                ))?\n            } else {\n                DestinationProof::absent()\n            },\n        );\n    }\n    if let Some(authority_source) = sources.get(\"system:capsule-authority\") {\n        let proof = if authority_source.present {\n            let path = home.migrations_dir().join(CAPSULE_AUTHORITY_RECEIPT_NAME);\n            let proof = DestinationProof::from_stored(\n                fs::read_to_string(&path).map_err(io::Error::other)?,\n            )?;\n            if !proof.starts_with(\"verified-capsule-authority-v1:\")\n                || !proof.contains(&format!(\"source-digest={}\", authority_source.digest))\n            {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    format!(\n                        \"invalid capsule authority migration receipt: {}\",\n                        path.display()\n                    ),\n                ));\n            }\n            proof\n        } else {\n            DestinationProof::absent()\n        };\n        proofs.insert(\"system:capsule-authority\".to_owned(), proof);\n    }\n\n    let audit = store.system_control_kv(\"audit\").map_err(storage_io)?;\n    let audit_proof = audit\n        .get(\"audit:migrations:legacy-principal-home-v1\")\n        .await","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/legacy_migration_barrier/ledger.rs#L77-L113","documentation":"`collect_destination_proofs` reads a stored DestinationProof from the migrations ledger and validates its shape: it must start with the `verified-capsule-authority-v1:` prefix and embed the current authority source digest. If either check fails, the receipt is rejected as invalid. This is fail-closed validation to ensure migration receipts genuinely attest to the same capsule authority source.","triggerScenarios":"The receipt file at the given path was hand-edited, truncated, written by an older/other version, or its embedded source-digest no longer matches the current authority_source.digest (e.g. the authority source changed after receipts were recorded).","commonSituations":"Manual tampering with receipts in migrations_dir; migrating after upgrading the code so the authority digest changed while old receipts persist; restoring a partial backup of the migrations directory.","solutions":["Inspect the receipt file named in the message; confirm the `verified-capsule-authority-v1:` prefix and `source-digest=...` field.","If the authority source legitimately changed, re-run the full migration (e.g. migrate_legacy_layout / initialize_fresh_layout) so receipts are regenerated for the new digest.","If receipts are corrupt or from an unknown source, restore them from a trusted backup or re-migrate from scratch; never hand-edit receipts."],"exampleFix":"// before: hand-edited receipt missing the digest\nverified-capsule-authority-v1:manual-ok\n// after: delete and regenerate via migration\n$ rm <migrations-dir>/<receipt>.json && astrid migrate","handlingStrategy":"try-catch","validationCode":"let raw = std::fs::read_to_string(&receipt_path)?;\nlet digest_ok = raw.starts_with(\"verified-capsule-authority-v1:\")\n    && raw.contains(&format!(\"source-digest={digest}\"));\nif !digest_ok { eprintln!(\"receipt stale or corrupt; re-migrate\"); }","typeGuard":null,"tryCatchPattern":"match migrate_legacy_layout(...) {\n    Err(e) if e.to_string().contains(\"invalid capsule authority migration receipt\") => {\n        eprintln!(\"receipts do not match current authority; re-run full migration\");\n    }\n    r => r?,\n}","preventionTips":["Never hand-edit receipt files under migrations_dir.","Back up the whole migrations directory atomically (ledger + receipts together).","Re-migrate from scratch after any change that alters the capsule authority source digest."],"tags":["security","validation","ledger","tampering"],"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"}