use crate::harness::*;
const ENC_R: &str = "-Users-dev-Projects-relay";
const SESS_R: &str = "00000000-0000-4000-8000-000000000001";
const RELAY_ID: &str = "aRelay-0123456789abcdef";
const TWIN_ID: &str = "aRelay-fedcba9876543210";
fn relay_home(twin: bool) -> Home {
let h = Home::new();
h.write(
&format!("{ENC_R}/{SESS_R}.jsonl"),
concat!(
r#"{"type":"user","uuid":"u0","timestamp":"2026-06-07T05:00:00.000Z","message":{"role":"user","content":"start the relay"}}"#, "\n",
r#"{"type":"assistant","uuid":"a0","timestamp":"2026-06-07T05:00:01.000Z","message":{"role":"assistant","content":[{"type":"tool_use","id":"toolu_relay","name":"Agent","input":{"description":"relay work","subagent_type":"general-purpose","name":"Relay"}}]}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{RELAY_ID}.jsonl"),
concat!(
r#"{"type":"user","isSidechain":true,"agentId":"aRelay-0123456789abcdef","timestamp":"2026-06-07T05:00:02.000Z","message":{"role":"user","content":"ROUTINGPROBE relay the throttle beacon"}}"#, "\n",
r#"{"type":"assistant","timestamp":"2026-06-07T05:00:03.000Z","message":{"role":"assistant","content":[{"type":"text","text":"beacon relayed"}]}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{RELAY_ID}.meta.json"),
r#"{"agentType":"Relay","description":"relay work","name":"Relay","taskKind":"in_process_teammate","teamName":"harbor"}"#,
);
if twin {
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{TWIN_ID}.jsonl"),
concat!(
r#"{"type":"user","isSidechain":true,"agentId":"aRelay-fedcba9876543210","timestamp":"2026-06-07T05:00:04.000Z","message":{"role":"user","content":"ROUTINGTWIN the second relay"}}"#, "\n",
r#"{"type":"assistant","timestamp":"2026-06-07T05:00:05.000Z","message":{"role":"assistant","content":[{"type":"text","text":"second beacon relayed"}]}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{TWIN_ID}.meta.json"),
r#"{"agentType":"Relay","description":"relay work","name":"Relay","taskKind":"in_process_teammate","teamName":"harbor"}"#,
);
}
h
}
#[test]
fn routing_form_targets_the_teammate_transcript() {
let h = relay_home(false);
let s = h.run(&["search", "ROUTINGPROBE", "@Relay@harbor"]);
assert!(s.success, "search @Relay@harbor: {}", s.stderr);
assert!(
s.stdout.contains("ROUTINGPROBE"),
"search did not reach the teammate transcript: {}",
s.stdout
);
let sh = h.run(&["show", "@Relay@harbor", "--line", "1"]);
assert!(sh.success, "show @Relay@harbor: {}", sh.stderr);
assert!(
sh.stdout.contains("ROUTINGPROBE"),
"show fetched the wrong transcript: {}",
sh.stdout
);
let l = h.run(&["list", "@Relay@harbor"]);
assert!(l.success, "list @Relay@harbor: {}", l.stderr);
assert!(
l.stdout.contains(RELAY_ID),
"list did not name the transcript id: {}",
l.stdout
);
}
#[test]
fn routing_form_matches_name_and_team_exactly() {
let h = relay_home(false);
for token in ["@relay@harbor", "@Relay@Harbor", "@Relay@region"] {
let out = h.run(&["show", token, "--line", "1"]);
assert!(!out.success, "{token} must not resolve");
assert!(
out.stderr.contains("no teammate") && out.stderr.contains("ROUTING form"),
"{token} error must name the grammar; stderr: {}",
out.stderr
);
assert!(
out.stderr.contains("--shape teammate"),
"{token} error must name the discovery command; stderr: {}",
out.stderr
);
}
}
#[test]
fn routing_form_ignores_a_non_teammate_agent_of_the_same_name() {
let h = Home::new();
h.write(
&format!("{ENC_R}/{SESS_R}.jsonl"),
concat!(
r#"{"type":"user","uuid":"u0","timestamp":"2026-06-07T05:00:00.000Z","message":{"role":"user","content":"start"}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{RELAY_ID}.jsonl"),
concat!(
r#"{"type":"user","isSidechain":true,"agentId":"aRelay-0123456789abcdef","timestamp":"2026-06-07T05:00:02.000Z","message":{"role":"user","content":"ROUTINGPROBE plain task subagent"}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{RELAY_ID}.meta.json"),
r#"{"agentType":"general-purpose","name":"Relay","teamName":"harbor","toolUseId":"toolu_relay"}"#,
);
let out = h.run(&["show", "@Relay@harbor", "--line", "1"]);
assert!(
!out.success,
"a non-teammate must not answer a routing form"
);
assert!(out.stderr.contains("no teammate"), "stderr: {}", out.stderr);
let byid = h.run(&["show", &at(RELAY_ID), "--line", "1"]);
assert!(byid.success, "show @<agent-id>: {}", byid.stderr);
assert!(byid.stdout.contains("ROUTINGPROBE"), "{}", byid.stdout);
}
#[test]
fn routing_form_collision_bails_listing_every_transcript_id() {
let h = relay_home(true);
let out = h.run(&["show", "@Relay@harbor", "--line", "1"]);
assert!(!out.success, "an ambiguous routing form must bail");
assert!(
out.stderr.contains("AMBIGUOUS")
&& out.stderr.contains(RELAY_ID)
&& out.stderr.contains(TWIN_ID),
"the ambiguity must list every matching transcript id; stderr: {}",
out.stderr
);
let one = h.run(&["show", &at(TWIN_ID), "--line", "1"]);
assert!(one.success, "show @<twin id>: {}", one.stderr);
assert!(one.stdout.contains("ROUTINGTWIN"), "{}", one.stdout);
}
#[test]
fn a_routing_form_shared_across_two_sessions_is_ambiguous_too() {
let h = relay_home(false);
let second = "00000000-0000-4000-8000-000000000002";
let other_id = "aRelay-00112233445566aa";
h.write(
&format!("{ENC_R}/{second}.jsonl"),
concat!(
r#"{"type":"user","uuid":"u0","timestamp":"2026-06-07T06:00:00.000Z","message":{"role":"user","content":"start the second relay"}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{second}/subagents/agent-{other_id}.jsonl"),
concat!(
r#"{"type":"user","isSidechain":true,"agentId":"aRelay-00112233445566aa","timestamp":"2026-06-07T06:00:02.000Z","message":{"role":"user","content":"ROUTINGOTHER the other session's relay"}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{second}/subagents/agent-{other_id}.meta.json"),
r#"{"agentType":"Relay","description":"relay work","name":"Relay","taskKind":"in_process_teammate","teamName":"harbor"}"#,
);
let out = h.run(&["show", "@Relay@harbor", "--line", "1"]);
assert!(!out.success, "two sessions, one routing id: {}", out.stdout);
assert!(
out.stderr.contains("AMBIGUOUS")
&& out.stderr.contains(RELAY_ID)
&& out.stderr.contains(other_id),
"both sessions' transcript ids are listed; stderr: {}",
out.stderr
);
let still = h.run(&["search", "ROUTINGPROBE", &at(SESS_R), "@Relay@harbor"]);
assert!(!still.success, "a sibling target narrows nothing");
assert!(still.stderr.contains("AMBIGUOUS"), "{}", still.stderr);
let byid = h.run(&["search", "ROUTINGOTHER", &at(other_id)]);
assert!(byid.success, "stderr: {}", byid.stderr);
assert!(byid.stdout.contains("ROUTINGOTHER"), "{}", byid.stdout);
}
#[test]
fn a_teammate_meta_with_no_transcript_is_not_a_teammate_in_scope() {
let h = Home::new();
h.write(
&format!("{ENC_R}/{SESS_R}.jsonl"),
concat!(
r#"{"type":"user","uuid":"u0","timestamp":"2026-06-07T05:00:00.000Z","message":{"role":"user","content":"start"}}"#, "\n",
),
);
h.write(
&format!("{ENC_R}/{SESS_R}/subagents/agent-{RELAY_ID}.meta.json"),
r#"{"agentType":"Relay","description":"relay work","name":"Relay","taskKind":"in_process_teammate","teamName":"harbor"}"#,
);
let out = h.run(&["show", "@Relay@harbor", "--line", "1"]);
assert!(!out.success, "a meta alone is not a lane: {}", out.stdout);
assert!(
out.stderr.contains("no teammate `Relay@harbor`") && out.stderr.contains("ROUTING form"),
"the miss is the zero-match error, not a read failure; stderr: {}",
out.stderr
);
let byid = h.run(&["show", &at(RELAY_ID), "--line", "1"]);
assert!(!byid.success, "{}", byid.stdout);
}
#[test]
fn the_sessions_from_id_list_takes_transcript_ids_only() {
let h = relay_home(false);
let list = h.root.join("ids.txt");
std::fs::write(&list, "@Relay@harbor\n").unwrap();
let out = h.run(&["list", "--sessions-from", list.to_str().unwrap()]);
assert!(!out.success, "stdout: {}", out.stdout);
assert!(
out.stderr.contains("--sessions-from")
&& out.stderr.contains("not a session id")
&& out.stderr.contains("agent id"),
"the refusal names the accepted shapes; stderr: {}",
out.stderr
);
std::fs::write(&list, format!("{RELAY_ID}\n")).unwrap();
let ok = h.run(&["list", "--sessions-from", list.to_str().unwrap()]);
assert!(ok.success, "stderr: {}", ok.stderr);
assert!(ok.stdout.contains(RELAY_ID), "{}", ok.stdout);
let positional = h.run(&["list", "@Relay@harbor"]);
assert!(positional.success, "stderr: {}", positional.stderr);
assert!(
positional.stdout.contains(RELAY_ID),
"{}",
positional.stdout
);
}
#[test]
fn malformed_routing_shapes_stay_with_the_at_grammar_error() {
let h = relay_home(false);
for token in ["@Relay@har@bor", "@Relay@", "@Relay@har.bor"] {
let out = h.run(&["show", token, "--line", "1"]);
assert!(!out.success, "{token} must not resolve");
assert!(
out.stderr.contains("not a recognized @-target")
&& out.stderr.contains("@<name>@<team>"),
"{token} must hit the @-grammar error naming the routing form; stderr: {}",
out.stderr
);
}
let bare = h.run(&["show", "Relay@harbor", "--line", "1"]);
assert!(!bare.success, "a bare routing form must not be a path");
assert!(
bare.stderr.contains("looks like a session/agent id")
&& bare.stderr.contains("@<name>@<team>"),
"stderr: {}",
bare.stderr
);
}