use super::*;
mod caller;
mod deliver;
mod envelope;
mod ledger;
mod marker;
mod paths;
mod policy;
mod reach;
mod reconcile;
mod records;
mod send;
mod slots;
mod types;
use std::path::{Path, PathBuf};
const SESSION: &str = "00000000-0000-4000-8000-000000000001";
const RECEIVER: &str = "00000000-0000-4000-8000-000000000002";
const AGENT: &str = "a0123456789abcdef";
const TEAMMATE: &str = "aRelay-0123456789abcdef";
const MSG_ID: &str = "0123456789abcdef";
struct Fixture {
root: PathBuf,
}
impl Fixture {
fn new() -> Self {
static SEQ: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
let seq = SEQ.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_nanos());
let root = std::env::temp_dir().join(format!(
"csift-channel-test-{}-{nanos}-{seq}",
std::process::id()
));
std::fs::create_dir_all(&root).unwrap();
Fixture {
root: channel_dir(&root),
}
}
fn scratch(&self) -> &Path {
self.root.parent().unwrap_or(&self.root)
}
}
impl Drop for Fixture {
fn drop(&mut self) {
if let Some(parent) = self.root.parent() {
let _ = std::fs::remove_dir_all(parent);
}
}
}
const LANE_TRANSCRIPT: &str = concat!(
r#"{"type":"user","uuid":"r1","timestamp":"2026-06-07T05:00:00.000Z","version":"2.1.258","message":{"role":"user","content":"go"}}"#,
"\n",
r#"{"type":"assistant","uuid":"r2","timestamp":"2026-06-07T05:00:05.000Z","version":"2.1.258","message":{"role":"assistant","stop_reason":null,"content":[{"type":"text","text":"working"}]}}"#,
"\n",
);
const PARENT_LANE: &str = "a0123456789abcde1";
const CHILD_LANE: &str = "a0123456789abcde2";
const OTHER_LANE: &str = "a0123456789abcde3";
fn spawn_tree(f: &Fixture) -> PathBuf {
let session_path = f.scratch().join(format!("{SESSION}.jsonl"));
let subagents = f.scratch().join(SESSION).join("subagents");
std::fs::create_dir_all(&subagents).unwrap();
std::fs::write(&session_path, LANE_TRANSCRIPT).unwrap();
for (id, parent) in [
(PARENT_LANE, None),
(CHILD_LANE, Some(PARENT_LANE)),
(OTHER_LANE, None),
] {
std::fs::write(subagents.join(format!("agent-{id}.jsonl")), LANE_TRANSCRIPT).unwrap();
let link = parent.map_or_else(String::new, |p| format!(r#","parentAgentId":"{p}""#));
std::fs::write(
subagents.join(format!("agent-{id}.meta.json")),
format!(r#"{{"agentType":"general-purpose"{link}}}"#),
)
.unwrap();
}
session_path
}
fn tree_caller(lane: &str) -> crate::live::channel::caller::Caller {
crate::live::channel::caller::Caller {
kind: SenderKind::Lane,
session: Some(SESSION.to_string()),
lane: Some(lane.to_string()),
label: None,
lane_exact: true,
}
}
fn tree_receiver(session_path: &Path, lane: &str) -> crate::live::channel::caller::Receiver {
crate::live::channel::caller::Receiver {
lane: lane.to_string(),
session: SESSION.to_string(),
session_path: session_path.to_path_buf(),
kind: crate::live::channel::policy::ReceiverKind::UnnamedSubagent,
state: crate::live::channel::policy::ReceiverState::Running,
version: Some("2.1.258".to_string()),
cwd: None,
routing_id: None,
socket_present: false,
headless: false,
teammate_lanes: 0,
}
}
fn message(body: &str) -> Message {
Message {
id: MSG_ID.to_string(),
ts_utc: "2026-06-07T05:00:05Z".to_string(),
from: MessageFrom {
kind: SenderKind::Lane,
session: Some(SESSION.to_string()),
lane: Some(TEAMMATE.to_string()),
label: None,
cwd: Some("/Users/dev/relay".to_string()),
},
to: MessageTo {
session: RECEIVER.to_string(),
lane: RECEIVER.to_string(),
form: TargetForm::Transcript,
routing_id: None,
},
mode: Mode::Steer,
ttl_secs: 43200,
relation: Relation::Child,
cross_project: false,
body: body.to_string(),
}
}
fn emit(part: u32, parts: u32, vehicle: Vehicle) -> LedgerLine {
LedgerLine::Emit {
id: MSG_ID.to_string(),
event: "Stop".to_string(),
slot: part,
part,
parts,
vehicle,
ts_utc: "2026-06-07T05:00:05Z".to_string(),
hook_session: Some(SESSION.to_string()),
hook_agent_id: Some(AGENT.to_string()),
block_count: (vehicle == Vehicle::Exit2).then_some(1),
}
}