{"record":{"id":"56118d1e40bee2eb","repo":"astrid-runtime/astrid","slug":"legacy-audit-retirement-source-is-outside-the-defa-56118d","errorCode":null,"errorMessage":"legacy audit retirement source is outside the default principal audit path","messagePattern":"legacy audit retirement source is outside the default principal audit path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":4251,"sourceCode":"        tracing::info!(\n            total_sessions = results.len(),\n            \"Audit chain verification passed for all sessions\"\n        );\n    }\n    Ok(())\n}\n\n#[cfg(unix)]\npub(crate) fn retire_legacy_audit_dir(\n    home: &astrid_core::dirs::AstridHome,\n    source: &Path,\n) -> std::io::Result<()> {\n    let retired = home.migrations_dir().join(\"audit-principal-home.retired\");\n    let expected = home\n        .principal_home(&astrid_core::PrincipalId::default())\n        .audit_dir();\n    if source != expected {\n        return Err(std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            \"legacy audit retirement source is outside the default principal audit path\",\n        ));\n    }\n    astrid_core::platform_fs::verify_no_redirects(source.parent().ok_or_else(|| {\n        std::io::Error::new(\n            std::io::ErrorKind::InvalidInput,\n            \"legacy audit source has no parent\",\n        )\n    })?)?;\n    astrid_core::platform_fs::ensure_private_directory(&home.migrations_dir())?;\n    astrid_core::platform_fs::verify_no_redirects(&home.migrations_dir())?;\n    match std::fs::symlink_metadata(source) {\n        Ok(metadata) if metadata.file_type().is_symlink() || !metadata.is_dir() => {\n            return Err(std::io::Error::new(\n                std::io::ErrorKind::InvalidData,\n                format!(\n                    \"legacy audit source is not a regular directory: {}\",","sourceCodeStart":4233,"sourceCodeEnd":4269,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L4233-L4269","documentation":"The legacy audit retirement routine only accepts a source path equal to the default principal's audit_dir; any other path is refused with InvalidInput. This guard prevents callers from renaming arbitrary directories into the migrations area under the guise of a legacy audit migration.","triggerScenarios":"Calling retire_legacy_audit (or the migration that uses it) with a source path that differs from home.principal_home(PrincipalId::default()).audit_dir().","commonSituations":"Passing a custom or relative audit path; migrating a non-default principal; hard-coding the audit path instead of building it via the home API so it no longer matches byte-for-byte.","solutions":["Construct the source path via home.principal_home(PrincipalId::default()).audit_dir() instead of hard-coding it","Use canonicalized paths on both sides so path formatting differences do not cause a mismatch","If you truly need to retire a non-default audit tree, do it manually rather than through this API"],"exampleFix":"// before\nretire_legacy_audit(&home, &Path::new(\"~/.app/audit\"))?;\n// after\nlet source = home.principal_home(astrid_core::PrincipalId::default()).audit_dir();\nretire_legacy_audit(&home, &source)?;","handlingStrategy":"validation","validationCode":"let expected = home.principal_home(astrid_core::PrincipalId::default()).audit_dir();\nassert_eq!(source, expected, \"source must be the default principal audit_dir\");","typeGuard":"fn is_expected_source(source: &std::path::Path, home: &Home) -> bool {\n    source == home.principal_home(astrid_core::PrincipalId::default()).audit_dir()\n}","tryCatchPattern":"if let Err(e) = retire_legacy_audit(&home, &source) {\n    if e.kind() == std::io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"outside the default principal audit path\") {\n        // rebuild source via the home API and retry\n    } else { return Err(e.into()); }\n}","preventionTips":["Always derive the audit path from the home API, never hard-code it","Canonicalize both paths before comparing","Only use this routine for the default principal"],"tags":["audit","migration","path-validation","rust"],"backgroundTag":"invalid-argument-value","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"}