use std::path::PathBuf;
use supercode_harness::reduce::stub::{self, Kind};
use supercode_harness::reduce::{
content_hash, make_id, reduction_id, set_reduction_id, MessageAddr, ReadLogEntry, Reduction,
ReductionKind, ReductionLog, SidecarPtr, REDUCTION_METADATA_KEY, REDUCTION_SENTINEL,
};
use supercode_harness::{ChatMessage, Role};
fn sample_ptr(seed: &str) -> SidecarPtr {
SidecarPtr {
addr: MessageAddr {
index: 3,
role: Role::Tool,
},
span: None,
content_hash: content_hash(seed.as_bytes()),
}
}
fn one_of_each_kind() -> Vec<Reduction> {
let read_log = ReadLogEntry {
path: PathBuf::from("/workspace/src/lib.rs"),
addr: MessageAddr {
index: 1,
role: Role::Tool,
},
content_hash: content_hash(b"file contents at read time"),
mtime: Some(1_700_000_000),
};
vec![
Reduction {
id: make_id(0, &content_hash(b"tool output original")),
kind: ReductionKind::ToolOutputTruncated {
original_bytes: 100_000,
kept_bytes: 4096,
},
ptr: sample_ptr("tool output original"),
placeholder: stub::format(
Kind::ToolOutput,
&make_id(0, &content_hash(b"tool output original")),
"100000 bytes total, showing first 4096",
),
},
Reduction {
id: make_id(1, &content_hash(b"file read original")),
kind: ReductionKind::FileReadElided {
path: PathBuf::from("/workspace/src/lib.rs"),
read_log: read_log.clone(),
},
ptr: sample_ptr("file read original"),
placeholder: stub::format(
Kind::FileRead,
&make_id(1, &content_hash(b"file read original")),
"read /workspace/src/lib.rs elided — file unchanged on disk, re-read on demand",
),
},
Reduction {
id: make_id(2, &content_hash(b"image bytes")),
kind: ReductionKind::ImageRedacted { part_index: 1 },
ptr: sample_ptr("image bytes"),
placeholder: stub::format(
Kind::Image,
&make_id(2, &content_hash(b"image bytes")),
"image redacted",
),
},
Reduction {
id: make_id(3, &content_hash(b"cleared turns")),
kind: ReductionKind::TurnsCleared {
first: 4,
last: 9,
summary: None,
},
ptr: sample_ptr("cleared turns"),
placeholder: stub::format(
Kind::TurnsCleared,
&make_id(3, &content_hash(b"cleared turns")),
"turns 4-9 cleared",
),
},
Reduction {
id: make_id(4, &content_hash(b"re-read original")),
kind: ReductionKind::FileReadDiffed {
path: PathBuf::from("/workspace/src/lib.rs"),
base: MessageAddr {
index: 1,
role: Role::Tool,
},
base_hash: content_hash(b"file contents at read time"),
new_hash: content_hash(b"re-read original"),
original_bytes: 2048,
diff_bytes: 64,
},
ptr: sample_ptr("re-read original"),
placeholder: stub::format(
Kind::FileReadDiffed,
&make_id(4, &content_hash(b"re-read original")),
"read /workspace/src/lib.rs diffed vs prior read at msg #1 — 64B diff, 2048B full (3%)",
),
},
Reduction {
id: make_id(5, &content_hash(b"duplicate output original")),
kind: ReductionKind::DuplicateOutput {
canonical: MessageAddr {
index: 0,
role: Role::Tool,
},
original_bytes: 2_411,
},
ptr: sample_ptr("duplicate output original"),
placeholder: stub::format(
Kind::Duplicate,
&make_id(5, &content_hash(b"duplicate output original")),
"bash output duplicates msg #0 (2,411B)",
),
},
]
}
#[test]
fn reduction_log_serde_and_wire_hygiene() {
let log = ReductionLog {
reductions: one_of_each_kind(),
expanded: vec![],
read_log: vec![ReadLogEntry {
path: PathBuf::from("/workspace/src/lib.rs"),
addr: MessageAddr {
index: 1,
role: Role::Tool,
},
content_hash: content_hash(b"file contents at read time"),
mtime: Some(1_700_000_000),
}],
attribution: None,
};
let json = serde_json::to_string(&log).expect("serialize ReductionLog");
let round_tripped: ReductionLog = serde_json::from_str(&json).expect("deserialize");
assert_eq!(log, round_tripped);
let mut msg = ChatMessage::tool_result("call-1", "read_file", "elided");
set_reduction_id(&mut msg, &log.reductions[0].id);
assert_eq!(reduction_id(&msg), Some(log.reductions[0].id.as_str()));
assert_eq!(
msg.metadata.get(REDUCTION_METADATA_KEY),
Some(&log.reductions[0].id)
);
let wire = serde_json::to_string(&msg).expect("serialize ChatMessage");
assert!(
!wire.contains("sc.reduction"),
"wire form leaked the reduction metadata key: {wire}"
);
assert!(
!wire.contains("metadata"),
"wire form leaked the metadata field name: {wire}"
);
}
#[test]
fn content_hash_is_deterministic() {
let a = content_hash(b"the quick brown fox");
let b = content_hash(b"the quick brown fox");
assert_eq!(a, b);
assert_ne!(a, content_hash(b"the quick brown fox "));
}
#[test]
fn ptr_verify_rejects_tampered_content() {
let ptr = SidecarPtr {
addr: MessageAddr {
index: 0,
role: Role::Tool,
},
span: None,
content_hash: content_hash(b"the original content"),
};
assert!(ptr.verify(b"the original content").is_ok());
assert!(ptr.verify(b"tampered content").is_err());
}
#[test]
fn stub_format_matches_grammar_for_every_kind() {
let re = regex::Regex::new(
r"^\[sc-reduced (tool-output|file-read|image|turns-cleared|file-read-diffed|duplicate) r\d{4}-[0-9a-f]{4}: [^\]]+\]$",
)
.unwrap();
for (i, kind) in [
Kind::ToolOutput,
Kind::FileRead,
Kind::Image,
Kind::TurnsCleared,
Kind::FileReadDiffed,
Kind::Duplicate,
]
.into_iter()
.enumerate()
{
let id = make_id(i, &content_hash(format!("seed-{i}").as_bytes()));
let summary = format!("summary for kind {i}");
let line = stub::format(kind, &id, &summary);
assert!(re.is_match(&line), "{line:?} did not match the C2 grammar");
assert_eq!(
stub::parse(&line),
Some((kind, id, summary)),
"parse(format(x)) != x for {line:?}"
);
assert!(
line.starts_with(REDUCTION_SENTINEL),
"stub must start with the reduction sentinel"
);
}
}
#[test]
fn stub_parse_rejects_malformed_input() {
let ok_id = make_id(1, &content_hash(b"seed"));
assert_eq!(
stub::parse("sc-reduced tool-output r0001-aaaa: no bracket"),
None
);
assert_eq!(
stub::parse(&format!("[sc-reduced tool-output {ok_id}: unterminated")),
None
);
assert_eq!(
stub::parse(&format!("[sc-reduced not-a-kind {ok_id}: summary]")),
None
);
assert_eq!(
stub::parse("[sc-reduced tool-output not-an-id: summary]"),
None
);
assert_eq!(
stub::parse("[sc-reduced tool-output r1-aaaa: summary]"),
None
);
assert_eq!(
stub::parse("[sc-reduced tool-output r0001-AAAA: summary]"),
None
);
assert_eq!(
stub::parse(&format!("[sc-reduced tool-output {ok_id}: has ] inside]")),
None
);
}