From dbaaa05b546d6ca13bfb283bc20eef8b3f48674d Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sat, 17 Oct 2026 00:53:37 +0000 Subject: [PATCH 1/2] test(daemon): drop wall bounds from source-body and admission tests source_body reads with the Engine requirement and never waits on the held catalog, so its 1 s caller deadline only measured CPU share. The admission test awaited admission under a 10 s timeout; it now awaits admission and then the convergence gate, so an admission that waited on convergence hangs instead of racing a wall clock. --- .../source_body_readiness_journey_test.rs | 8 +++--- .../src/daemon/store_runtime_tests.rs | 25 ++++++------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/crates/tracedecay/src/daemon/production_harness/source_body_readiness_journey_test.rs b/crates/tracedecay/src/daemon/production_harness/source_body_readiness_journey_test.rs index 864b9a9377..f3665c2213 100644 --- a/crates/tracedecay/src/daemon/production_harness/source_body_readiness_journey_test.rs +++ b/crates/tracedecay/src/daemon/production_harness/source_body_readiness_journey_test.rs @@ -5,7 +5,7 @@ use tempfile::TempDir; use tracedecay_code_index::graph_projection::{ CodeGraphCatalogReleaseV1, CodeGraphReadinessRequirement, }; -use tracedecay_domain::{ProjectId, SymbolOccurrenceId, UtcMicros}; +use tracedecay_domain::{ProjectId, SymbolOccurrenceId}; use tracedecay_graph_db::NeverCancelled; use super::ProductionProjectCompositionHarnessV1; @@ -82,13 +82,13 @@ async fn source_body_serves_while_the_released_catalog_cannot_rewarm() { // These point reads prove that the retained engine and occurrence are ready. let point = reader.symbol_summary(&occurrence, Arc::new(NeverCancelled)); let catalog_pending = store.await_rewarm(Duration::ZERO); - let deadline = UtcMicros(tracedecay_contracts::now_micros().0 + 1_000_000); + // A read that waited on the held catalog would spend its re-warm budget + // and answer unavailable instead of evidence. let response = harness - .call_tool_with_deadline( + .call_tool( &project, "tracedecay_source_body", serde_json::json!({"node_id": node_id, "format": "json"}), - deadline, ) .await; let still_pending = store.await_rewarm(Duration::ZERO); diff --git a/crates/tracedecay/src/daemon/store_runtime_tests.rs b/crates/tracedecay/src/daemon/store_runtime_tests.rs index ae6975a853..5d39dbf782 100644 --- a/crates/tracedecay/src/daemon/store_runtime_tests.rs +++ b/crates/tracedecay/src/daemon/store_runtime_tests.rs @@ -1160,24 +1160,13 @@ async fn daemon_admission_remains_ready_while_lcm_indexes_converge_in_background .expect("session runtime registry"); let convergence_gate = registry.block_registered_schema_convergence_for_test(); - let admission = registry.project_sessions(project_id, [project_root]); - tokio::pin!(admission); - let convergence_blocked = convergence_gate.wait_until_blocked(); - tokio::pin!(convergence_blocked); - let database = tokio::time::timeout(std::time::Duration::from_secs(10), async { - tokio::select! { - result = &mut admission => { - let database = result.expect("registered project sessions"); - convergence_blocked.await; - database - } - () = &mut convergence_blocked => { - admission.await.expect("registered project sessions") - } - } - }) - .await - .expect("daemon admission and convergence scheduling must not stall"); + // The gate holds convergence until the assertions below, so an admission + // that waited on convergence never returns. + let database = registry + .project_sessions(project_id, [project_root]) + .await + .expect("registered project sessions"); + convergence_gate.wait_until_blocked().await; assert_eq!( registry.registered_schema_convergence_status(&shard_id), From c49608de04eb2c12942ef466b7ccf3873d2bf05f Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Sat, 17 Oct 2026 02:24:34 +0000 Subject: [PATCH 2/2] test(daemon): retry every retryable hook refusal, not only mounting settled_session_ingest retried only application.runtime.mounting. Under load the reopened composition answered temporal_refresh_unavailable, which is retryable after 250 ms, and the helper returned it as settled. It now retries any problem marked retryable and drops its 30 s wall, so a server that never settles fails at the harness timeout. --- .../project_server_capacity_journey_test.rs | 41 ++++++------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/crates/tracedecay/src/daemon/production_harness/project_server_capacity_journey_test.rs b/crates/tracedecay/src/daemon/production_harness/project_server_capacity_journey_test.rs index 984bb348ca..54377ae806 100644 --- a/crates/tracedecay/src/daemon/production_harness/project_server_capacity_journey_test.rs +++ b/crates/tracedecay/src/daemon/production_harness/project_server_capacity_journey_test.rs @@ -498,18 +498,17 @@ async fn twelve_project_journey_retires_idle_owners_without_empty_graphs() { harness.shutdown().await; } -/// Ingest through the session stores until the full server has mounted them, -/// returning the first settled answer, or `None` once the bound expires. +/// Ingest through the session stores, retrying each retryable refusal, and +/// return the first settled answer. A server that never settles fails at the +/// harness timeout. async fn settled_session_ingest( harness: &ProductionProjectCompositionHarnessV1, project: &Path, -) -> Option { +) -> serde_json::Value { settled_server_session_ingest(&harness.server(project).expect("mounted project")).await } -async fn settled_server_session_ingest( - server: &crate::mcp::McpServer, -) -> Option { +async fn settled_server_session_ingest(server: &crate::mcp::McpServer) -> serde_json::Value { let request = serde_json::from_value::(serde_json::json!({ "jsonrpc": "2.0", "id": 1, @@ -524,7 +523,6 @@ async fn settled_server_session_ingest( }, })) .expect("hook runtime request"); - let deadline = std::time::Instant::now() + std::time::Duration::from_secs(30); loop { let response = server .handle_request(&request) @@ -535,11 +533,10 @@ async fn settled_server_session_ingest( "hook runtime failed: {response:?}" ); let answer = response.result.expect("hook runtime result"); - if !answer.to_string().contains("application.runtime.mounting") { - return Some(answer); - } - if std::time::Instant::now() >= deadline { - return None; + // Mounting is one retryable refusal; a refresh that missed its + // publish deadline under load is another. + if answer["structuredContent"]["problem"]["retryable"] != true { + return answer; } tokio::time::sleep(std::time::Duration::from_millis(250)).await; } @@ -559,11 +556,7 @@ async fn shut_down_composition_releases_its_session_stores_for_an_immediate_reop let harness = ProductionProjectCompositionHarnessV1::open(isolation.path(), [project.clone()]) .await .expect("first production composition"); - let first = settled_session_ingest(&harness, &project).await; - assert!( - first.is_some(), - "the first composition mounts its session stores" - ); + settled_session_ingest(&harness, &project).await; let project_data_root = harness .project_data_root(&project) .await @@ -600,11 +593,8 @@ async fn shut_down_composition_releases_its_session_stores_for_an_immediate_reop .await .expect("reopened production composition"); let reopened = settled_session_ingest(&harness, &project).await; - assert_eq!( - reopened - .as_ref() - .map(|answer| answer.to_string().contains("accepted_for_replay")), - Some(true), + assert!( + reopened.to_string().contains("accepted_for_replay"), "the reopened composition must remount the session stores: {reopened:?}" ); harness.shutdown().await; @@ -651,12 +641,7 @@ async fn capacity_retirement_releases_session_stores_its_owner_used_on_the_first .unwrap_or_else(|error| { panic!("project {ordinal} must open over released capacity: {error}") }); - assert!( - settled_server_session_ingest(&opened.server) - .await - .is_some(), - "project {ordinal} mounts its session stores" - ); + settled_server_session_ingest(&opened.server).await; drop(opened); opened_projects += 1; }