use super::*;
use std::sync::{Arc, Mutex};
fn a_row(session_id: &str) -> SavingsRow {
SavingsRow {
ts: "2026-09-10T21:08:49Z".to_string(),
session_id: session_id.to_string(),
technique: crate::core::savings::TECHNIQUE_INSTRUCTION_COMPRESSION.to_string(),
tokens_saved: 6_699,
tokens_before: 6_702,
cost_saved_usd: 0.020_097,
basis: "hand-built".to_string(),
model_source: crate::core::session_model::MODEL_SOURCE_LAUNCH_CONFIG.to_string(),
}
}
fn project_with_compiled_prompt(under: &Path, name: &str, scope: &str) -> PathBuf {
let project = under.join(name);
let compiled = crate::core::instruction_pipeline::compiled_prompt_path(&project, scope);
std::fs::create_dir_all(compiled.parent().expect("session dir")).expect("session dir");
let body = "x".repeat(
crate::core::savings_instructions::min_plausible_compiled_bytes(
crate::core::savings_instructions::SectionBytes::of(
crate::core::content_source::test_support::rc(),
),
)
.max(1),
);
std::fs::write(&compiled, &body).expect("compiled prompt");
compiled
}
fn rows_in(ledger: &Path) -> usize {
std::fs::read_to_string(ledger)
.map(|text| text.lines().filter(|line| !line.trim().is_empty()).count())
.unwrap_or(0)
}
fn backdate(path: &Path, hours: u64) {
let when = SystemTime::now() - Duration::from_secs(hours * 60 * 60);
std::fs::File::options()
.write(true)
.open(path)
.expect("staged file")
.set_modified(when)
.expect("backdate the staged file");
}
#[test]
fn the_sweep_claims_a_row_staged_under_another_session_scope() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "managed-7411");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
stage_row(&root, &compiled, &a_row("managed-7411"));
assert!(
emit_staged_row_for_session_in(&root, &project, "claude-1"),
"a hook that resolves a different session scope must still claim the staged row"
);
assert!(
!crate::core::savings::fold_session(&ledger, "claude-1").is_zero(),
"the statusline fold under the Claude session id must find the row"
);
assert!(
!pending_row_path_in(&root, &compiled).exists(),
"a claimed row must not stay staged"
);
assert!(
!emit_staged_row_for_session_in(&root, &project, "claude-1"),
"a second SessionStart must append nothing"
);
assert_eq!(rows_in(&ledger), 1, "the row must land exactly once");
}
#[test]
fn n_hooks_sweeping_a_restaged_row_append_exactly_one() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "managed-7658");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
for _ in 0..26 {
stage_row(&root, &compiled, &a_row("managed-7658"));
emit_staged_row_for_session_in(&root, &project, "claude-7658");
}
assert_eq!(
rows_in(&ledger),
1,
"26 hooks over one re-staged measurement must leave one row, got:\n{}",
std::fs::read_to_string(&ledger).unwrap_or_default()
);
assert!(
!pending_row_path_in(&root, &compiled).exists(),
"a redundant staged row must be dropped, not left to be claimed again"
);
}
#[test]
fn an_unreadable_ledger_leaves_the_staged_row_alone() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "managed-7658b");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
std::fs::create_dir_all(&ledger).expect("occupy the ledger path");
stage_row(&root, &compiled, &a_row("managed-7658b"));
assert!(
!emit_staged_row_for_session_in(&root, &project, "claude-7658b"),
"no row can be reported against a ledger that cannot be read"
);
assert!(
pending_row_path_in(&root, &compiled).exists(),
"the measurement must stay staged for a hook that can read the ledger"
);
}
#[test]
fn a_stranded_row_stops_being_restaged_against_an_unreadable_ledger() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "managed-7658c");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
std::fs::create_dir_all(&ledger).expect("occupy the ledger path");
let staged = pending_row_path_in(&root, &compiled);
stage_row(&root, &compiled, &a_row("managed-7658c"));
backdate(&staged, STRANDED_AFTER.as_secs() / 3600 + 1);
assert!(!emit_staged_row_for_session_in(
&root,
&project,
"claude-7658c"
));
assert!(
!staged.exists(),
"a stranded row against an unreadable ledger must not be re-staged"
);
let leftovers: Vec<PathBuf> = std::fs::read_dir(root.join("usage").join(PENDING_DIR))
.expect("pending dir")
.flatten()
.map(|entry| entry.path())
.collect();
assert_eq!(leftovers.len(), 1, "the row's bytes must survive");
assert!(
leftovers[0]
.extension()
.is_none_or(|extension| extension != "json"),
"the leftover must not be swept again: {}",
leftovers[0].display()
);
assert!(!emit_staged_row_for_session_in(
&root,
&project,
"claude-7658c"
));
assert_eq!(
std::fs::read_dir(root.join("usage").join(PENDING_DIR))
.expect("pending dir")
.count(),
1,
"a second sweep must neither claim nor duplicate it"
);
}
#[test]
fn a_hook_with_nothing_staged_rederives_from_the_compiled_prompt() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
project_with_compiled_prompt(tmp.path(), "project", "local");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
assert!(
emit_staged_row_for_session_in(&root, &project, "claude-2"),
"with nothing staged the hook must re-measure the fold from the compiled prompt"
);
let folded = crate::core::savings::fold_session(&ledger, "claude-2");
assert!(
!folded.is_zero(),
"the re-derived row must be foldable under the Claude session id: {folded:?}"
);
}
#[test]
fn a_second_session_start_does_not_append_a_second_rederived_row() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
project_with_compiled_prompt(tmp.path(), "project", "local");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
emit_staged_row_for_session_in(&root, &project, "claude-3");
emit_staged_row_for_session_in(&root, &project, "claude-3");
assert_eq!(
rows_in(&ledger),
1,
"two SessionStart events for one session must leave one row"
);
}
#[test]
fn a_stranded_orphan_is_discarded_with_its_measurement_logged() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let project = tmp.path().join("project");
let vanished = project.join(".trusty-mpm/sessions/gone/INSTRUCTIONS-COMPILED.md");
let staged = pending_row_path_in(&root, &vanished);
let ledger = crate::core::savings::savings_log_in(&root);
stage_row(&root, &vanished, &a_row("gone"));
assert_eq!(
sweep_pending_rows(&ledger, &root, &project, "claude-4"),
0,
"a fresh orphan is not yet the sweep's to judge"
);
assert!(staged.exists(), "a fresh orphan must be left alone");
backdate(&staged, 13);
let capture = CaptureWriter::default();
let subscriber = tracing_subscriber::fmt()
.with_writer(capture.clone())
.with_max_level(tracing::Level::WARN)
.with_ansi(false)
.finish();
tracing::subscriber::with_default(subscriber, || {
sweep_pending_rows(&ledger, &root, &project, "claude-4");
});
assert!(
!staged.exists(),
"a stranded orphan must not survive the next hook"
);
assert_eq!(rows_in(&ledger), 0, "a discarded row is not a ledger row");
let logged = String::from_utf8(capture.0.lock().expect("capture lock").clone())
.expect("the captured log must be utf-8");
assert!(
logged.contains("compiled prompt no longer exists"),
"the discard must state its reason: {logged}"
);
assert!(
logged.contains("6699"),
"the discard must preserve the measurement: {logged}"
);
}
#[test]
fn a_fresh_row_for_another_project_is_left_for_its_own_hook() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let theirs = project_with_compiled_prompt(tmp.path(), "theirs", "local");
let ours = tmp.path().join("ours");
std::fs::create_dir_all(&ours).expect("our project");
let ledger = crate::core::savings::savings_log_in(&root);
stage_row(&root, &theirs, &a_row("local"));
assert_eq!(
sweep_pending_rows(&ledger, &root, &ours, "claude-5"),
0,
"another project's fresh row is not ours to claim"
);
assert!(
pending_row_path_in(&root, &theirs).exists(),
"it must still be there for its own hook"
);
assert_eq!(
sweep_pending_rows(&ledger, &root, &tmp.path().join("theirs"), "claude-6"),
1,
"its own project's hook must claim it"
);
}
#[test]
fn a_stranded_row_for_another_project_is_adopted_rather_than_stranded() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let theirs = project_with_compiled_prompt(tmp.path(), "theirs", "local");
let ours = tmp.path().join("ours");
std::fs::create_dir_all(&ours).expect("our project");
let ledger = crate::core::savings::savings_log_in(&root);
stage_row(&root, &theirs, &a_row("local"));
backdate(&pending_row_path_in(&root, &theirs), 13);
assert_eq!(
sweep_pending_rows(&ledger, &root, &ours, "claude-7"),
1,
"a row nobody has claimed in half a day must be adopted, not stranded"
);
assert!(
!crate::core::savings::fold_session(&ledger, "claude-7").is_zero(),
"the adopted row must reach the ledger"
);
}
#[test]
fn a_row_staged_without_a_path_is_still_claimed_by_digest() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "local");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
let staged = pending_row_path_in(&root, &compiled);
std::fs::create_dir_all(staged.parent().expect("pending dir")).expect("pending dir");
std::fs::write(
&staged,
serde_json::to_string(&a_row("local")).expect("serialise"),
)
.expect("write the pre-#7411 staged row");
assert_eq!(
sweep_pending_rows(&ledger, &root, &project, "claude-8"),
1,
"a row staged by an older tm must still be claimed"
);
assert!(!crate::core::savings::fold_session(&ledger, "claude-8").is_zero());
}
#[test]
fn two_racing_sweeps_append_exactly_one_row() {
let tmp = tempfile::tempdir().expect("temp dir");
let root = tmp.path().join("framework");
let compiled = project_with_compiled_prompt(tmp.path(), "project", "local");
let project = tmp.path().join("project");
let ledger = crate::core::savings::savings_log_in(&root);
stage_row(&root, &compiled, &a_row("local"));
let claimed: usize = std::thread::scope(|scope| {
let racers: Vec<_> = (0..2)
.map(|_| scope.spawn(|| sweep_pending_rows(&ledger, &root, &project, "claude-9")))
.collect();
racers
.into_iter()
.map(|racer| racer.join().expect("racer"))
.sum()
});
assert_eq!(claimed, 1, "exactly one racer may claim the staged row");
assert_eq!(rows_in(&ledger), 1, "the ledger must hold exactly one row");
}
#[derive(Clone, Default)]
struct CaptureWriter(Arc<Mutex<Vec<u8>>>);
impl std::io::Write for CaptureWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.lock().expect("capture lock").extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for CaptureWriter {
type Writer = CaptureWriter;
fn make_writer(&'a self) -> Self::Writer {
self.clone()
}
}