mod interop_common;
use std::path::{Path, PathBuf};
use interop_common::{core, msg_eq_multimodal, replay_eligible};
use supercode::reduce::{
export_session, invert, project, reduce_to_fit, reduction_id, verify_log, ReductionKind,
ReductionLog, ReductionPolicy, REDUCTION_METADATA_KEY, REDUCTION_SENTINEL,
};
use supercode::session::{Session, SessionFormat};
use supercode::sidecar::SidecarWriter;
use supercode::tokens::estimate_view_tokens;
use supercode::{ChatMessage, FunctionCall, Role, ToolCall};
fn fixture(name: &str) -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures")
.join(name)
}
fn fixture_file_for(f: SessionFormat) -> &'static str {
match f {
SessionFormat::ClaudeCode => "claude_code_session.jsonl",
SessionFormat::Codex => "codex_session.jsonl",
SessionFormat::OpenCode => "opencode_session.jsonl",
SessionFormat::Pi => "pi_session.jsonl",
SessionFormat::Grok => "grok_session/chat_history.jsonl",
}
}
fn fname(f: SessionFormat) -> &'static str {
match f {
SessionFormat::ClaudeCode => "claude",
SessionFormat::Codex => "codex",
SessionFormat::OpenCode => "opencode",
SessionFormat::Pi => "pi",
SessionFormat::Grok => "grok",
}
}
fn load_fixture(f: SessionFormat) -> Session {
let path = fixture(fixture_file_for(f));
match f {
SessionFormat::ClaudeCode => Session::from_claude_code(path).unwrap(),
SessionFormat::Codex => Session::from_codex(path).unwrap(),
SessionFormat::OpenCode => Session::from_opencode(path).unwrap(),
SessionFormat::Pi => Session::from_pi(path).unwrap(),
SessionFormat::Grok => Session::from_grok(path).unwrap(),
}
}
fn production_policy() -> ReductionPolicy {
ReductionPolicy::default()
}
fn big(label: &str, target_len: usize) -> String {
let mut s = format!("[{label}] ");
while s.len() < target_len {
s.push_str("the quick brown fox jumps over the lazy dog; ");
}
s.truncate(target_len);
s
}
fn tool_call(id: &str, name: &str, args: serde_json::Value) -> ChatMessage {
ChatMessage {
role: Role::Assistant,
content: None,
content_parts: None,
tool_calls: Some(vec![ToolCall {
id: id.to_string(),
kind: "function".to_string(),
function: FunctionCall {
name: name.to_string(),
arguments: args.to_string(),
},
}]),
tool_call_id: None,
name: None,
metadata: Default::default(),
}
}
fn heavy_continuation() -> Vec<ChatMessage> {
vec![
tool_call(
"ir4-call-1",
"bash",
serde_json::json!({"command": "cat build.log"}),
),
ChatMessage::tool_result("ir4-call-1", "bash", big("BUILD-LOG-CONTENTS", 12_000)),
tool_call(
"ir4-call-2",
"bash",
serde_json::json!({"command": "cat build.log"}),
),
ChatMessage::tool_result("ir4-call-2", "bash", big("BUILD-LOG-CONTENTS", 12_000)),
tool_call(
"ir4-call-3",
"bash",
serde_json::json!({"command": "cargo test"}),
),
ChatMessage::tool_result("ir4-call-3", "bash", big("CARGO-TEST-FAIL-RUN-1", 12_000)),
tool_call(
"ir4-call-4",
"bash",
serde_json::json!({"command": "cargo test"}),
),
ChatMessage::tool_result("ir4-call-4", "bash", big("CARGO-TEST-FAIL-RUN-2", 12_000)),
tool_call(
"ir4-call-5",
"write_file",
serde_json::json!({"path": "output.log", "content": big("WRITE-FILE-PAYLOAD", 12_000)}),
),
ChatMessage::tool_result(
"ir4-call-5",
"write_file",
"wrote 12000 bytes to output.log",
),
tool_call(
"ir4-call-6",
"bash",
serde_json::json!({"command": "cargo test"}),
),
ChatMessage::tool_result("ir4-call-6", "bash", big("CARGO-TEST-PASS-RUN-3", 12_000)),
]
}
fn kind_name(kind: &supercode::reduce::ReductionKind) -> String {
let dbg = format!("{kind:?}");
dbg.split(['{', ' ']).next().unwrap_or(&dbg).to_string()
}
fn measure_and_verify(format: SessionFormat) {
let imported = load_fixture(format);
let continuation = heavy_continuation();
let mut full = imported.clone();
full.messages.extend(continuation.iter().cloned());
let replay = replay_eligible(&full.messages);
let before = estimate_view_tokens(&replay);
let sidecar_path = std::env::temp_dir().join(format!(
"sc-reduction-metric-{}-{}.jsonl",
std::process::id(),
fname(format)
));
{
let mut writer = SidecarWriter::create(&sidecar_path, &imported).unwrap();
for msg in &continuation {
writer.append(msg).unwrap();
}
}
let sidecar_text = std::fs::read_to_string(&sidecar_path).unwrap();
let sidecar_session = Session::from_sidecar_str(&sidecar_text).unwrap();
std::fs::remove_file(&sidecar_path).ok();
assert_eq!(
sidecar_session.messages.len(),
full.messages.len(),
"{format:?}: the sidecar must record every message of the continued session \
(imported prefix + heavy continuation), positionally, before any reduction \
is even minted"
);
let policy = production_policy();
let (view, log) = project(&full, &policy, &ReductionLog::default());
assert!(
!log.reductions.is_empty(),
"{format:?}: the heavy continuation produced ZERO reductions at production \
defaults — this is exactly the vacuous-truth failure mode this fix exists to \
close; if this genuinely can't be built for this harness, that is a STOP-and-\
report condition, not a silently-passing test"
);
let mut kinds: Vec<String> = log.reductions.iter().map(|r| kind_name(&r.kind)).collect();
kinds.sort();
let distinct_kinds: std::collections::BTreeSet<&String> = kinds.iter().collect();
assert!(
distinct_kinds.len() > 1,
"{format:?}: the heavy continuation must exercise more than one reduction kind \
(got only {kinds:?}) — a single-kind result is weaker evidence than the \
continuation is built to provide"
);
let after = estimate_view_tokens(&replay_eligible(&view));
let ratio = if before == 0 {
1.0
} else {
after as f64 / before as f64
};
let pct_reduced = (1.0 - ratio) * 100.0;
println!(
"reduction[{}] = {} -> {} tokens ({:.1}% reduced, {} reduction(s): {})",
fname(format),
before,
after,
pct_reduced,
log.reductions.len(),
kinds.join(", "),
);
let full_reconstructed = invert(&view, &log, &sidecar_session)
.unwrap_or_else(|e| panic!("{format:?}: invert failed: {e}"));
let before_core = core(&full.messages);
let after_core = core(&full_reconstructed);
assert_eq!(
before_core.len(),
after_core.len(),
"{format:?}: invert changed message count"
);
for (i, (a, b)) in before_core.iter().zip(&after_core).enumerate() {
assert!(
msg_eq_multimodal(a, b),
"{format:?}: invert lost/changed message {i}:\n before: {a:?}\n after: {b:?}"
);
}
verify_log(&log, &sidecar_session)
.unwrap_or_else(|e| panic!("{format:?}: verify_log failed: {e}"));
let stub_count = view.iter().filter(|m| reduction_id(m).is_some()).count();
assert_eq!(
stub_count,
log.reductions.len(),
"{format:?}: stub count must equal reduction count (no silent reduction)"
);
assert!(
after <= before,
"{format:?}: reduction must never INCREASE the estimated token count ({before} -> {after})"
);
}
const REDUCTION_RATIO_FLOOR: [(&str, u64, u64); 4] = [
("claude", 18528, 7691),
("codex", 20254, 9417),
("opencode", 18463, 7627),
("pi", 18511, 7675),
];
#[test]
fn reduction_ratio_regression_floor() {
for &format in &[
SessionFormat::ClaudeCode,
SessionFormat::Codex,
SessionFormat::OpenCode,
SessionFormat::Pi,
] {
let (harness, before_pin, after_ceiling) = REDUCTION_RATIO_FLOOR
.iter()
.find(|(h, _, _)| *h == fname(format))
.copied()
.unwrap_or_else(|| panic!("{format:?}: no pinned floor row — add one"));
let imported = load_fixture(format);
let continuation = heavy_continuation();
let mut full = imported.clone();
full.messages.extend(continuation.iter().cloned());
let replay = replay_eligible(&full.messages);
let before = estimate_view_tokens(&replay);
assert_eq!(
before, before_pin,
"{harness}: pre-reduction token count drifted from the pinned {before_pin} (got \
{before}) — the fixture or heavy_continuation() input changed; re-measure and \
re-pin deliberately (this is a sanity check on the INPUT, not the reducer)"
);
let policy = production_policy();
let (view, _log) = project(&full, &policy, &ReductionLog::default());
let after = estimate_view_tokens(&replay_eligible(&view));
assert!(
after <= after_ceiling,
"{harness}: reduction-ratio regression — post-reduction token count {after} exceeds \
the pinned ceiling of {after_ceiling} (before={before}). At production defaults, \
the reducer is now LESS effective on this exact, deterministic fixture than it was \
at pin time — token reduction is priority #1 (the rate-limit-rescue flagship); this \
is a high-severity regression, not a rounding blip."
);
let pct_reduced_at_pin = (1.0 - after_ceiling as f64 / before_pin as f64) * 100.0;
let pct_reduced_now = (1.0 - after as f64 / before as f64) * 100.0;
println!(
"reduction_ratio_floor[{harness}]: pinned {before_pin}->{after_ceiling} \
({pct_reduced_at_pin:.1}% reduced) | measured now {before}->{after} \
({pct_reduced_now:.1}% reduced)"
);
}
}
#[test]
fn reduction_metric_per_harness() {
println!("\n=== §4.3 CONTINUE-WITH-REDUCTION (measured ratio + reversibility) ===");
for &format in &[
SessionFormat::ClaudeCode,
SessionFormat::Codex,
SessionFormat::OpenCode,
SessionFormat::Pi,
] {
measure_and_verify(format);
}
}
#[test]
#[ignore = "requires a large real harness session; set SUPERCODE_CORPUS=1 and \
SUPERCODE_CORPUS_SESSION=<path to a real session file>"]
fn corpus_gated_flagship_reduction_ratio() {
if std::env::var("SUPERCODE_CORPUS").is_err() {
panic!(
"SUPERCODE_CORPUS not set — this corpus test asserts nothing without a real, \
large harness session; set SUPERCODE_CORPUS=1 and SUPERCODE_CORPUS_SESSION=<path>."
);
}
let path = std::env::var("SUPERCODE_CORPUS_SESSION")
.expect("set SUPERCODE_CORPUS_SESSION=<path to a real harness session file>");
let s = Session::load(&path).unwrap();
let replay = replay_eligible(&s.messages);
let before = estimate_view_tokens(&replay);
let sidecar_path = std::env::temp_dir().join(format!(
"sc-reduction-metric-corpus-{}.jsonl",
std::process::id()
));
{
let _writer = SidecarWriter::create(&sidecar_path, &s).unwrap();
}
let sidecar_text = std::fs::read_to_string(&sidecar_path).unwrap();
let sidecar_session = Session::from_sidecar_str(&sidecar_text).unwrap();
std::fs::remove_file(&sidecar_path).ok();
let policy = ReductionPolicy::default();
let (view, log) = project(&s, &policy, &ReductionLog::default());
let after = estimate_view_tokens(&replay_eligible(&view));
let ratio = if before == 0 {
1.0
} else {
after as f64 / before as f64
};
println!(
"corpus flagship: {} -> {} tokens ({:.1}% reduced, ratio={:.4}, {} reductions) — {}",
before,
after,
(1.0 - ratio) * 100.0,
ratio,
log.reductions.len(),
path
);
let target = before.saturating_mul(35).div_ceil(100);
let (target_view, target_log, target_policy) =
reduce_to_fit(&s.messages, &policy, &ReductionLog::default(), |view| {
estimate_view_tokens(&replay_eligible(view)) <= target
});
let target_after = estimate_view_tokens(&replay_eligible(&target_view));
let mut kinds = std::collections::BTreeMap::<&'static str, usize>::new();
for reduction in &target_log.reductions {
let name = match reduction.kind {
ReductionKind::ToolOutputTruncated { .. } => "ToolOutputTruncated",
ReductionKind::FileReadElided { .. } => "FileReadElided",
ReductionKind::ImageRedacted { .. } => "ImageRedacted",
ReductionKind::TurnsCleared { .. } => "TurnsCleared",
ReductionKind::ToolInputElided { .. } => "ToolInputElided",
ReductionKind::OutputNormalized { .. } => "OutputNormalized",
ReductionKind::FileReadDiffed { .. } => "FileReadDiffed",
ReductionKind::DuplicateOutput { .. } => "DuplicateOutput",
ReductionKind::Superseded { .. } => "Superseded",
};
*kinds.entry(name).or_default() += 1;
}
println!(
"corpus 35%-target: {} -> {} tokens (ratio={:.4}, {} reductions, kinds={:?})",
before,
target_after,
target_after as f64 / before as f64,
target_log.reductions.len(),
kinds
);
assert!(
target_after <= target,
"35% target missed: {target_after} retained tokens > {target} target tokens"
);
let mut before_clear_policy = target_policy.clone();
before_clear_policy.clear_turns_older_than = None;
let (_, before_clear_log) = project(&s, &before_clear_policy, &ReductionLog::default());
let clear_range = target_log.reductions.iter().find_map(|reduction| {
if let ReductionKind::TurnsCleared { first, last, .. } = reduction.kind {
Some((first, last))
} else {
None
}
});
let swallowed_by_clear = clear_range.map_or(0, |(first, last)| {
before_clear_log
.reductions
.iter()
.filter(|reduction| {
reduction.ptr.addr.index >= first && reduction.ptr.addr.index <= last
})
.count()
});
println!(
"corpus pass-order: {} pre-A10 claims; {} swallowed by A10 and removed from the final log (no double count)",
before_clear_log.reductions.len(),
swallowed_by_clear,
);
let target_log_path = std::env::temp_dir().join(format!(
"sc-reduction-metric-corpus-{}.reduction.json",
std::process::id()
));
std::fs::write(
&target_log_path,
serde_json::to_vec_pretty(&target_log).unwrap(),
)
.unwrap();
let reloaded_target_log: ReductionLog =
serde_json::from_slice(&std::fs::read(&target_log_path).unwrap()).unwrap();
std::fs::remove_file(&target_log_path).ok();
verify_log(&reloaded_target_log, &sidecar_session).unwrap();
let target_full = invert(&target_view, &reloaded_target_log, &sidecar_session).unwrap();
assert_eq!(
sidecar_session.messages, target_full,
"disk-reloaded target log must restore every canonical message byte-exact"
);
let claude_export = export_session(&sidecar_text, SessionFormat::ClaudeCode).unwrap();
assert_eq!(claude_export.matches(REDUCTION_SENTINEL).count(), 0);
assert_eq!(claude_export.matches(REDUCTION_METADATA_KEY).count(), 0);
let full = invert(&view, &log, &sidecar_session).unwrap();
let before_core = core(&s.messages);
let after_core = core(&full);
assert_eq!(before_core.len(), after_core.len());
for (a, b) in before_core.iter().zip(&after_core) {
assert!(msg_eq_multimodal(a, b));
}
verify_log(&log, &sidecar_session).unwrap();
}