Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions crates/freshell-freshagent/src/session_handoff/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6291,20 +6291,29 @@ async fn the_claude_handoff_target_binding_carries_the_handoff_generation() {

// The target resume's sidecar init adoption writes the binding row
// (async to the runner's commit) — bounded-poll until it lands.
// DEFLAKE (wait-depth): the loop previously broke on ANY matching row,
// but an interim unfenced row (observed pair None) can land FIRST —
// the runner's under-ticket adoption (the row this test asserts on)
// follows it. Poll for the SETTLED row — one stamped with the supplied
// handoff pair — so the assertions below never read an interim row.
// The r27 regression shape (the adoption writing None and never the
// pair) still fails here at the deadline, with the full dump.
let deadline = tokio::time::Instant::now() + Duration::from_secs(15);
loop {
if fake
.bindings
.lock()
.unwrap()
.iter()
.any(|b| b.provider == "claude" && b.session_id == sid && b.mode == "freshclaude")
{
if fake.bindings.lock().unwrap().iter().any(|b| {
b.provider == "claude"
&& b.session_id == sid
&& b.mode == "freshclaude"
&& b.observed_epoch == Some(rig.ownership.boot_epoch())
&& b.observed_generation == Some(committed_generation)
}) {
break;
}
assert!(
tokio::time::Instant::now() < deadline,
"the target resume's session-init adoption never wrote its binding row"
"the under-ticket adoption never stamped its binding row with the supplied \
handoff pair — bindings: {:?}",
fake.bindings.lock().unwrap()
);
tokio::time::sleep(Duration::from_millis(25)).await;
}
Expand Down
14 changes: 13 additions & 1 deletion crates/freshell-platform/src/mcp_inject_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,19 @@ fn live_wslpath_timeout_falls_back_and_reaps_the_child() {
"timed-out conversion should return promptly"
);

let pid = std::fs::read_to_string(&pid_file).expect("timeout script wrote its pid");
// The child writes its pid as the script's FIRST statement, so when the
// file is absent at read time the shell NEVER STARTED: under heavy
// parallel load (the workspace gate; WSL fork latency) the conversion's
// 3s deadline can kill the child before its fork+exec ever runs. A
// pre-start kill+wait IS the reap — the property under test holds by
// construction, and the leak this test guards against (a started
// `sleep` surviving the timeout) always leaves the pid file behind for
// the kill -0 assertion below. (Base-gate flake: the old unconditional
// read panicked here on the pre-start-kill outcome.)
let pid = match std::fs::read_to_string(&pid_file) {
Ok(pid) => pid,
Err(_) => return,
};
let status = std::process::Command::new("kill")
.arg("-0")
.arg(pid.trim())
Expand Down
Loading