From 347edec79ee47d6b7f1b7d1c3b895b5946e38012 Mon Sep 17 00:00:00 2001 From: Florious95 <281215401+Florious95@users.noreply.github.com> Date: Mon, 31 Aug 2026 01:04:56 +0800 Subject: [PATCH 1/2] test(mcp): isolate unknown status ingress from tmux --- .../lifecycle/tests/harvest2_a_batch_red.rs | 2 +- .../tests/support/mcp_sim_harness.rs | 81 ++++++++++++++----- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs b/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs index 21f7af01..734d47f7 100644 --- a/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +++ b/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs @@ -229,7 +229,7 @@ got {status:?}" #[test] #[serial(t3_event)] fn t3_unknown_business_status_is_preserved_without_normalized_event() { - let harness = McpSimHarness::new(); + let harness = McpSimHarness::new_without_tmux(); let mut worker = harness.spawn_mcp_client("worker_a", "teamA"); let status = "garbage-status-xyz"; let call = worker.call_tool( diff --git a/crates/team-agent/tests/support/mcp_sim_harness.rs b/crates/team-agent/tests/support/mcp_sim_harness.rs index 65a58b0d..b28a6a24 100644 --- a/crates/team-agent/tests/support/mcp_sim_harness.rs +++ b/crates/team-agent/tests/support/mcp_sim_harness.rs @@ -60,27 +60,8 @@ pub struct McpSimHarness { impl McpSimHarness { pub fn new() -> Self { - static N: AtomicU64 = AtomicU64::new(0); - let run_tag = format!( - "{}-{}", - std::process::id(), - SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("system clock after unix epoch") - .as_nanos() - ); - let workspace = std::env::temp_dir().join(format!( - "ta-rs-mcp-sim-{run_tag}-{}", - N.fetch_add(1, Ordering::Relaxed) - )); - let _ = std::fs::remove_dir_all(&workspace); - std::fs::create_dir_all(&workspace).unwrap(); - let workspace = std::fs::canonicalize(workspace).unwrap(); + let (workspace, session) = fresh_mcp_workspace(); let backend = TmuxBackend::for_workspace(&workspace); - let session = SessionName::new(format!( - "team-mcp-sim-{run_tag}-{}", - N.fetch_add(1, Ordering::Relaxed) - )); let mut harness = Self { workspace, backend, @@ -97,6 +78,23 @@ impl McpSimHarness { harness } + /// Build an MCP-only fixture for contracts whose assertion does not exercise + /// pane delivery. This keeps the stdio ingress test runnable on hosts without + /// a tmux binary (for example, the Grok full-test image). + pub fn new_without_tmux() -> Self { + let (workspace, session) = fresh_mcp_workspace(); + let backend = TmuxBackend::for_workspace(&workspace); + let harness = Self { + workspace, + backend, + session, + panes: BTreeMap::new(), + }; + harness.seed_mcp_report_state(); + let _ = MessageStore::open(&harness.workspace).unwrap(); + harness + } + pub fn spawn_mcp_client(&self, worker_id: &str, owner_team_id: &str) -> McpClient { spawn_mcp_client(&self.workspace, worker_id, owner_team_id) } @@ -316,7 +314,7 @@ impl McpSimHarness { "worker_c": {"status": "running"} }, "tasks": [ - {"id": "task_mcp", "assignee": "worker_a", "status": "pending"} + {"id": "task_mcp", "assignee": "worker_a", "status": "pending", "result_route": "pipeline"} ] }, "teamB": { @@ -332,6 +330,47 @@ impl McpSimHarness { ) .unwrap(); } + + fn seed_mcp_report_state(&self) { + team_agent::state::persist::save_runtime_state( + &self.workspace, + &json!({ + "active_team_key": "teamA", + "teams": { + "teamA": { + "tasks": [ + {"id": "task_mcp", "assignee": "worker_a", "status": "pending"} + ] + } + } + }), + ) + .unwrap(); + } +} + +fn fresh_mcp_workspace() -> (PathBuf, SessionName) { + static N: AtomicU64 = AtomicU64::new(0); + let run_tag = format!( + "{}-{}", + std::process::id(), + SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("system clock after unix epoch") + .as_nanos() + ); + let workspace = std::env::temp_dir().join(format!( + "ta-rs-mcp-sim-{run_tag}-{}", + N.fetch_add(1, Ordering::Relaxed) + )); + let _ = std::fs::remove_dir_all(&workspace); + std::fs::create_dir_all(&workspace).unwrap(); + let workspace = std::fs::canonicalize(workspace).unwrap(); + let session = SessionName::new(format!( + "team-mcp-sim-{run_tag}-{}", + N.fetch_add(1, Ordering::Relaxed) + )); + (workspace, session) } impl Drop for McpSimHarness { From a5605ca844d056d8d37f6952d1ae89dd9699b811 Mon Sep 17 00:00:00 2001 From: Florious95 <281215401+Florious95@users.noreply.github.com> Date: Mon, 31 Aug 2026 02:20:12 +0800 Subject: [PATCH 2/2] test(mcp): preserve default leader result route --- crates/team-agent/tests/support/mcp_sim_harness.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/team-agent/tests/support/mcp_sim_harness.rs b/crates/team-agent/tests/support/mcp_sim_harness.rs index b28a6a24..d7e287bf 100644 --- a/crates/team-agent/tests/support/mcp_sim_harness.rs +++ b/crates/team-agent/tests/support/mcp_sim_harness.rs @@ -314,7 +314,7 @@ impl McpSimHarness { "worker_c": {"status": "running"} }, "tasks": [ - {"id": "task_mcp", "assignee": "worker_a", "status": "pending", "result_route": "pipeline"} + {"id": "task_mcp", "assignee": "worker_a", "status": "pending"} ] }, "teamB": {