diff --git a/crates/tracedecay/src/daemon/production_harness.rs b/crates/tracedecay/src/daemon/production_harness.rs index c0e2b21fb1..cdae3b7619 100644 --- a/crates/tracedecay/src/daemon/production_harness.rs +++ b/crates/tracedecay/src/daemon/production_harness.rs @@ -852,6 +852,42 @@ impl ProductionProjectCompositionHarnessV1 { }) } + /// Await optional attribution for the exact current publication without + /// making it a prerequisite for ordinary composition or graph readiness. + pub async fn await_test_attribution( + &self, + project_root: impl AsRef, + cancellation: &tracedecay_runtime_core::cancellation::CancellationToken, + ) -> Result { + let graph = self.server(project_root)?.cg().await; + let target = graph.configuration_runtime().configuration_target(); + let scope = tracedecay_code_index_runtime::resolved_scope_for_project( + graph.project_root(), + &target.project_id, + ) + .map_err(|error| TraceDecayError::Config { + message: format!("production-composition code-index scope is invalid: {error:?}"), + })?; + let resources = self + .resources + .as_ref() + .ok_or_else(|| TraceDecayError::Config { + message: "production-composition harness is shut down".to_owned(), + })?; + let schedulers = &resources.invocation.code_index_schedulers; + let Some(current) = schedulers.latest_text_serving_for_scope(&scope).await else { + return Ok(tracedecay_domain::ProviderEvaluationStateV1::Unavailable); + }; + Ok(schedulers + .await_test_attribution_for_scope( + graph.project_root(), + &scope, + ¤t.metadata().manifest().generation_id, + cancellation, + ) + .await) + } + pub async fn project_data_root(&self, project_root: impl AsRef) -> Result { Ok(self .server(project_root)? diff --git a/crates/tracedecay/tests/mcp_suite/mcp_handler_test/affected_tests_test.rs b/crates/tracedecay/tests/mcp_suite/mcp_handler_test/affected_tests_test.rs index 146ca4b274..a353053947 100644 --- a/crates/tracedecay/tests/mcp_suite/mcp_handler_test/affected_tests_test.rs +++ b/crates/tracedecay/tests/mcp_suite/mcp_handler_test/affected_tests_test.rs @@ -181,6 +181,21 @@ fn assert_unknown_handle_markdown(response: &JsonRpcResponse) { async fn published_cycle(fixture: &ProductionCompositionFixture, document_uri: &str) -> Value { let deadline = Instant::now() + Duration::from_secs(60); + let cancellation = tracedecay_runtime_core::cancellation::CancellationToken::new(); + let attribution = tokio::time::timeout_at( + deadline.into(), + fixture + .harness + .await_test_attribution(&fixture.project_root, &cancellation), + ) + .await + .expect("current generation attribution must settle before the cycle deadline") + .expect("production attribution readiness"); + assert_eq!( + attribution, + tracedecay_domain::ProviderEvaluationStateV1::Partial, + "the current generation must expose conservative test attribution" + ); loop { let response = call( fixture,