{"record":{"id":"c69a7b104c5cb0d6","repo":"astrid-runtime/astrid","slug":"legacy-principal-layout","errorCode":null,"errorMessage":"legacy principal layout","messagePattern":"legacy principal layout","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/audit_retirement_tests.rs","lineNumber":12,"sourceCode":"use super::{preflight_legacy_audit_sources, require_audit_integrity, retire_legacy_audit_dir};\nuse astrid_audit::ChainVerificationResult;\nuse astrid_core::SessionId;\nuse astrid_core::dirs::AstridHome;\n\n#[test]\nfn audit_retirement_validates_tree_and_removes_only_verified_source() {\n    let directory = tempfile::tempdir().expect(\"temporary home\");\n    let home = AstridHome::from_path(directory.path().join(\".astrid\"));\n    home.ensure().expect(\"home layout\");\n    let principal_home = home.principal_home(&astrid_core::PrincipalId::default());\n    principal_home.ensure().expect(\"legacy principal layout\");\n    std::fs::write(principal_home.audit_dir().join(\"entry\"), b\"audit\").expect(\"audit fixture\");\n\n    retire_legacy_audit_dir(&home, &principal_home.audit_dir()).expect(\"retire audit source\");\n    assert!(!principal_home.audit_dir().exists());\n    assert!(\n        !home\n            .migrations_dir()\n            .join(\"audit-principal-home.retired\")\n            .exists()\n    );\n}\n\n#[cfg(unix)]\n#[test]\nfn audit_retirement_rejects_redirects_before_removal() {\n    let directory = tempfile::tempdir().expect(\"temporary home\");\n    let home = AstridHome::from_path(directory.path().join(\".astrid\"));\n    home.ensure().expect(\"home layout\");","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/audit_retirement_tests.rs#L1-L30","documentation":"The panic message \"legacy principal layout\" comes from calling .expect() on the Result returned by principal_home.ensure() in the test audit_retirement_validates_tree_and_removes_only_verified_source (crates/astrid-kernel/src/audit_retirement_tests.rs:12). AstridHome::principal_home() returns a handle for a per-principal directory; ensure() creates the full on-disk layout (including the audit directory) or fails with an io::Error. The library throws it when the per-principal directory tree cannot be created or verified under the home root. In this test the panic indicates the per-principal scaffolding step broke, which would invalidate everything the retirement test does afterwards.","triggerScenarios":"Calling principal_home(&PrincipalId::default()).ensure() when the parent .astrid home exists but the per-principal subdirectory cannot be created — e.g. create_dir_all fails due to permissions, a non-directory file already occupies the principal path, the path exceeds filesystem limits, or ensure() contains a layout validation that rejects the produced tree.","commonSituations":"Running the test suite on a filesystem where the tempdir root is not writable (read-only /tmp, restricted CI sandboxes, some container runtimes), a stale tempdir entry where a file named after the principal id already exists, or a regression in AstridHome/PrincipalHome path construction that builds an invalid path (e.g. empty id segment).","solutions":["Re-run the test in a writable temp location to rule out an environmental (permissions/disk) cause.","Check that the principal path does not collide with an existing non-directory file; delete the stale tempdir and retry.","Inspect PrincipalHome::ensure() for recent changes to layout creation or validation that could reject the default-principal tree.","Ensure AstridHome::ensure() succeeded first (home layout) since ensure() on the principal home may depend on the parent structure existing."],"exampleFix":"// before\nprincipal_home.ensure().expect(\"legacy principal layout\");\n// after\nif let Err(e) = principal_home.ensure() {\n    panic!(\"legacy principal layout: failed to ensure {}: {e}\", principal_home.path().display());\n}","handlingStrategy":"validation","validationCode":"fn assert_ensureable(home: &PrincipalHome) -> Result<(), String> {\n    let path = home.path();\n    if path.exists() && !path.is_dir() {\n        return Err(format!(\"{} exists and is not a directory\", path.display()));\n    }\n    std::fs::create_dir_all(path).map_err(|e| format!(\"{}: {e}\", path.display()))\n}\n// call assert_ensureable(&principal_home)?; before the real ensure()","typeGuard":"fn is_dir_writable(p: &std::path::Path) -> bool {\n    p.is_dir() && std::fs::metadata(p).map(|m| !m.permissions().readonly()).unwrap_or(false)\n}","tryCatchPattern":"match principal_home.ensure() {\n    Ok(()) => {}\n    Err(e) => panic!(\"legacy principal layout: {e} at {}\", principal_home.path().display()),\n}","preventionTips":["Always call home.ensure() before principal_home().ensure() so parents exist.","Run the test suite with a writable TMPDIR and sufficient disk space.","Include the failing path and io::Error in panic messages instead of bare expect strings.","Watch for regular files colliding with principal directory paths after refactors."],"tags":["rust","filesystem","test-panic","directory-creation"],"backgroundTag":"mkdir-permission-denied","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"}