use std::path::{Path, PathBuf};
use supercode_harness::{
DiscoveryQuery, HarnessCatalog, HarnessHomes, HarnessId, Role, Session, SessionSource,
};
fn openclaw_home() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/openclaw_home")
}
fn sessions_dir() -> PathBuf {
openclaw_home().join("agents/main/sessions")
}
#[test]
fn discovery_lists_real_sessions_and_skips_trajectory_files() {
let query = DiscoveryQuery {
harnesses: vec![HarnessId::new(HarnessId::OPENCLAW)],
homes: HarnessHomes {
openclaw: openclaw_home(),
..HarnessHomes::default()
},
..DiscoveryQuery::default()
};
let found = HarnessCatalog::new().discover(&query).unwrap();
assert_eq!(found.len(), 4, "{found:#?}");
for descriptor in &found {
assert_eq!(descriptor.locator.harness.as_str(), HarnessId::OPENCLAW);
assert_eq!(
descriptor.cwd.as_deref(),
Some(Path::new("/workspace/project"))
);
}
assert!(found
.iter()
.any(|descriptor| descriptor.locator.session_id == "3dd577ae-a0a3-4b5b-8063-f402be4f5fd4"));
}
#[test]
fn real_session_loads_with_openclaw_provenance_and_vendor_metadata() {
let path = sessions_dir().join("3dd577ae-a0a3-4b5b-8063-f402be4f5fd4.jsonl");
let session = Session::load(&path).unwrap();
assert_eq!(session.meta.source, SessionSource::OpenClaw);
assert_eq!(session.parse_error_lines, 0);
let users: Vec<&str> = session
.messages
.iter()
.filter(|message| message.role == Role::User)
.filter_map(|message| message.content.as_deref())
.collect();
assert!(!users.is_empty());
let stamped = session
.messages
.iter()
.find(|message| message.metadata.contains_key("openclaw_senderIsOwner"))
.expect("real acp-authored user messages carry __openclaw metadata");
assert_eq!(
stamped
.metadata
.get("openclaw_senderIsOwner")
.map(String::as_str),
Some("true")
);
assert!(session.raw_is_verbatim);
}
#[test]
fn leaf_entry_redirects_the_active_path_away_from_the_abandoned_branch() {
let path = sessions_dir().join("aaaa1111-2222-3333-4444-555566667777.jsonl");
let session = Session::load(&path).unwrap();
assert_eq!(session.meta.source, SessionSource::OpenClaw);
let texts: Vec<String> = session
.messages
.iter()
.filter_map(|message| message.content.clone())
.collect();
assert!(texts.iter().any(|text| text.contains("first question")));
assert!(texts.iter().any(|text| text.contains("first answer")));
assert!(
!texts.iter().any(|text| text.contains("abandoned branch")),
"leaf redirect must exclude the abandoned branch: {texts:?}"
);
assert!(session
.raw
.iter()
.any(|line| line.contains("abandoned branch answer")));
}
#[test]
fn side_append_entries_never_anchor_and_foreign_refs_stay_inert() {
let path = sessions_dir().join("bbbb1111-2222-3333-4444-555566667777.jsonl");
let session = Session::load(&path).unwrap();
assert_eq!(session.meta.source, SessionSource::OpenClaw);
let texts: Vec<String> = session
.messages
.iter()
.filter_map(|message| message.content.clone())
.collect();
assert!(texts.iter().any(|text| text.contains("main answer")));
assert!(
!texts
.iter()
.any(|text| text.contains("side-channel annotation")),
"a side-append entry anchored the walk: {texts:?}"
);
let stamped = session
.messages
.iter()
.find(|message| message.metadata.contains_key("openclaw_sessionKey"))
.expect("sessionKey vendor metadata must be stamped");
assert!(stamped
.metadata
.get("openclaw_sessionKey")
.unwrap()
.contains("acp-bridge"));
assert!(session
.raw
.iter()
.any(|line| line.contains("delegateSession")));
assert_eq!(session.parse_error_lines, 0);
}
#[test]
fn plain_pi_sessions_are_not_misdetected_as_openclaw() {
let jsonl = concat!(
"{\"type\":\"session\",\"version\":3,\"id\":\"p1\",\"timestamp\":\"2026-08-31T02:20:00.000Z\",\"cwd\":\"/w\"}\n",
"{\"type\":\"message\",\"id\":\"x1\",\"parentId\":null,\"timestamp\":\"2026-08-31T02:20:01.000Z\",\"message\":{\"role\":\"user\",\"content\":\"tell me about __openclaw and type leaf entries\"}}\n",
);
let session = Session::from_pi_str(jsonl).unwrap();
assert_eq!(session.meta.source, SessionSource::Pi);
let dir = std::env::temp_dir().join(format!(
"supercode-uni16-detect-{}-{}",
std::process::id(),
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos()
));
std::fs::create_dir_all(&dir).unwrap();
let file = dir.join("p1.jsonl");
std::fs::write(&file, jsonl).unwrap();
let detected = Session::load(&file).unwrap();
assert_eq!(detected.meta.source, SessionSource::Pi);
}