From 3e79aaa8e70bd5d189355d9c42b0aa55e4eb9388 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 27 Aug 2026 07:09:16 +0000 Subject: [PATCH 1/4] style(storage): apply rustfmt to resolver tests Fixes the Format check: tests/storage_suite/storage_resolver_test.rs was merged with two rustfmt violations (lines 1902 and 2033). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01A2BarcJk3iuv77aJQwHvnx --- tests/storage_suite/storage_resolver_test.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/storage_suite/storage_resolver_test.rs b/tests/storage_suite/storage_resolver_test.rs index 5e38771ace..d72b387c58 100644 --- a/tests/storage_suite/storage_resolver_test.rs +++ b/tests/storage_suite/storage_resolver_test.rs @@ -1902,9 +1902,7 @@ async fn linked_worktree_exact_registry_alias_ignores_duplicate_shared_legacy_ma store_kind: "code_project".to_string(), storage_mode: "profile_sharded".to_string(), store_relpath: format!("projects/{project_id}"), - manifest_relpath: Some(format!( - "projects/{project_id}/{STORE_MANIFEST_FILENAME}" - )), + manifest_relpath: Some(format!("projects/{project_id}/{STORE_MANIFEST_FILENAME}")), last_verified_at: None, last_write_at: None, }) @@ -2033,7 +2031,12 @@ async fn linked_worktree_exact_manifest_overrides_canonical_exact_registry_alias let canonical = TraceDecay::init(&project).await.unwrap(); canonical.index_all().await.unwrap(); - let canonical_project_id = canonical.store_layout().identity.project_id.clone().unwrap(); + let canonical_project_id = canonical + .store_layout() + .identity + .project_id + .clone() + .unwrap(); canonical.close(); git( From 55cfba7ea1b54ae3e6ad7daae8cd6e0c35ee445f Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 27 Aug 2026 07:09:16 +0000 Subject: [PATCH 2/4] fix(db): deduplicate identical branch arms in profile_project_root Fixes the Clippy check: clippy::if-same-then-else fired on two arms that both return parent.parent()?. Merging the conditions with || is semantically identical. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01A2BarcJk3iuv77aJQwHvnx --- .../src/db/access/path_layout.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/tracedecay-runtime-core/src/db/access/path_layout.rs b/crates/tracedecay-runtime-core/src/db/access/path_layout.rs index 0f6d0b68c7..2d3d2e98b4 100644 --- a/crates/tracedecay-runtime-core/src/db/access/path_layout.rs +++ b/crates/tracedecay-runtime-core/src/db/access/path_layout.rs @@ -46,14 +46,13 @@ pub(super) fn database_lock_root(database_path: &Path, fallback_parent: &Path) - fn profile_project_root(database_path: &Path) -> Option<&Path> { let parent = database_path.parent()?; - let data_root = if parent.file_name().is_some_and(|name| name == "branches") { - parent.parent()? - } else if parent - .file_name() - .is_some_and(|name| name == ".consolidation-input") - && database_path + let data_root = if parent.file_name().is_some_and(|name| name == "branches") + || (parent .file_name() - .is_some_and(|name| name == "source-sessions.db" || name == "target-sessions.db") + .is_some_and(|name| name == ".consolidation-input") + && database_path + .file_name() + .is_some_and(|name| name == "source-sessions.db" || name == "target-sessions.db")) { parent.parent()? } else { From 776c779b0964e85ee624fb31371e81c0dd5b6df3 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 27 Aug 2026 07:09:17 +0000 Subject: [PATCH 3/4] fix(storage): fail closed on populated exact-root duplicate stores Fixes the two tests failing on Linux, macOS, and Windows shards 2/5: doctor::tests::current_project_store_surfaces_split_identity_conflict and cli_non_interactive_test::status_surfaces_split_identity_conflict_without_suggesting_init. Commit 133ca5c48b made a populated exact-root selected store outrank legacy duplicates without probing them, so a genuine identity cutover (two populated shards whose manifests both name this exact root) resolved silently to the marker-selected shard instead of failing closed with the consolidation guidance. Keep the bounded-presence fast path, but probe exact-root candidates first: junk or empty duplicates are still ignored (registered_healthy_exact_root_ignores_duplicate_exact_manifests keeps passing), while a populated exact-root duplicate falls through to the identity-cutover conflict diagnostics. Also applies the pending rustfmt fix in this file (Format check flagged line 229). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01A2BarcJk3iuv77aJQwHvnx --- src/tracedecay/lifecycle.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/tracedecay/lifecycle.rs b/src/tracedecay/lifecycle.rs index 5d650b3724..5addbfbf1c 100644 --- a/src/tracedecay/lifecycle.rs +++ b/src/tracedecay/lifecycle.rs @@ -229,11 +229,7 @@ impl TraceDecay { // stay behind the rare paths that actually compare stores. Resolving a // layout is on every open, including fail-closed clients that must not // touch the store at all. - let ( - candidates, - selected_manifest_matches_exact_root, - candidates_match_exact_root, - ) = + let (candidates, selected_manifest_matches_exact_root, candidates_match_exact_root) = storage::matching_legacy_profile_layouts(project_root, &profile_root, selected_id)?; if selected.is_some() && !candidates.is_empty() @@ -280,14 +276,27 @@ impl TraceDecay { // This resolver uses bounded presence probes only; the subsequent // serving open performs full integrity validation and fails closed. // Legacy duplicates stay untouched, while an empty or unreadable - // selected store still reaches the fail-closed diagnostics. + // selected store still reaches the fail-closed diagnostics. An + // exact-root candidate with real content is a genuine identity + // cutover: it keeps the fail-closed conflict diagnostics instead of + // being silently outranked. if (selected_manifest_matches_exact_root || (selected_via_exact_registry_alias && !candidates_match_exact_root)) && !candidates.is_empty() - && let Some(selected) = selected.as_ref() + && let Some(selected_layout) = selected.as_ref() + && store_identity_has_bounded_population_evidence(selected_layout).await { - if store_identity_has_bounded_population_evidence(selected).await { - return Ok(Some(selected.clone())); + let mut exact_candidate_is_populated = false; + if candidates_match_exact_root { + for candidate in &candidates { + if store_identity_has_bounded_population_evidence(candidate).await { + exact_candidate_is_populated = true; + break; + } + } + } + if !exact_candidate_is_populated { + return Ok(Some(selected_layout.clone())); } } if candidates.len() > 1 { From b4d068682d9607d64ad3772689e266099b974b5b Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 27 Aug 2026 07:12:31 +0000 Subject: [PATCH 4/4] fix(lint): clear pedantic clippy debt unmasked by the runtime-core fix CI clippy aborted at the tracedecay-runtime-core error, so the root crate was never linted. With that fixed, five pre-existing pedantic violations surface: single_match_else in the scheduler shutdown, manual let-else and match_same_arms in the store-identity probes, fn_params_excessive_bools on choose_identity_layout (allowed: the flags mirror resolver evidence from the sole caller), and items_after_statements in a consolidate test. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01A2BarcJk3iuv77aJQwHvnx --- src/daemon/scheduler.rs | 16 ++++++++-------- src/migrate/consolidate/tests.rs | 3 ++- src/tracedecay/lifecycle.rs | 11 ++++++----- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/daemon/scheduler.rs b/src/daemon/scheduler.rs index 1e6e62c03d..998c5e83d4 100644 --- a/src/daemon/scheduler.rs +++ b/src/daemon/scheduler.rs @@ -321,7 +321,7 @@ impl DaemonEngine { } pub(super) async fn shutdown_automation_schedulers_with_deadline(&self, deadline: Duration) { - let scheduler_handles: Vec> = match timeout( + let Ok(scheduler_handles) = timeout( deadline, self.store_administration.with_writer(|| async { let mut schedulers = self @@ -329,16 +329,16 @@ impl DaemonEngine { .automation_schedulers() .lock() .await; - schedulers.drain().map(|(_, handle)| handle.task).collect() + schedulers + .drain() + .map(|(_, handle)| handle.task) + .collect::>>() }), ) .await - { - Ok(handles) => handles, - Err(_) => { - log_daemon_event("daemon_shutdown", &[("outcome", "timeout".to_string())]); - return; - } + else { + log_daemon_event("daemon_shutdown", &[("outcome", "timeout".to_string())]); + return; }; let _child_shutdown = crate::sessions::codex_app_server::begin_codex_app_server_shutdown(); for handle in &scheduler_handles { diff --git a/src/migrate/consolidate/tests.rs b/src/migrate/consolidate/tests.rs index 0191624606..d3326fca26 100644 --- a/src/migrate/consolidate/tests.rs +++ b/src/migrate/consolidate/tests.rs @@ -402,6 +402,8 @@ async fn synthesized_branch_metadata_change_invalidates_confirmation_token() { #[tokio::test] async fn hook_analytics_append_after_plan_preserves_bytes_without_invalidating_confirmation() { + use std::io::Write; + let fixture = fixture().await; let source = layout_for_id(&fixture.project, &fixture.profile, &fixture.source_id).unwrap(); let telemetry_path = source.data_root.join("hook_analytics.jsonl"); @@ -411,7 +413,6 @@ async fn hook_analytics_append_after_plan_preserves_bytes_without_invalidating_c let options = fixture.options(); let planned = plan(&options).await.unwrap(); - use std::io::Write; fs::OpenOptions::new() .append(true) .open(&telemetry_path) diff --git a/src/tracedecay/lifecycle.rs b/src/tracedecay/lifecycle.rs index 5addbfbf1c..b3342782d2 100644 --- a/src/tracedecay/lifecycle.rs +++ b/src/tracedecay/lifecycle.rs @@ -261,6 +261,9 @@ impl TraceDecay { ) } + // The four flags mirror the resolver evidence computed by the sole + // caller; a params struct would outlive this soon-to-move code. + #[allow(clippy::fn_params_excessive_bools)] async fn choose_identity_layout( project_root: &Path, selected: Option, @@ -1576,9 +1579,8 @@ async fn store_identity_has_bounded_population_evidence(layout: &StoreLayout) -> tree_has_files(&layout.lcm_payload_root), tree_has_files(&layout.response_handle_root), ); - let (automation_files, payload_files, response_files) = match tree_presence { - (Ok(automation), Ok(payloads), Ok(responses)) => (automation, payloads, responses), - _ => return false, + let (Ok(automation_files), Ok(payload_files), Ok(response_files)) = tree_presence else { + return false; }; graph_is_populated @@ -1600,11 +1602,10 @@ fn branch_inventory(data_root: &Path) -> std::result::Result { let path = data_root.join(storage::BRANCH_META_FILENAME); match std::fs::symlink_metadata(&path) { Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(0), - Err(_) => Err(()), Ok(metadata) if metadata.file_type().is_file() => branch_meta::load_branch_meta(data_root) .map(|meta| meta.branches.len()) .ok_or(()), - Ok(_) => Err(()), + Err(_) | Ok(_) => Err(()), } }