//! Allocation-count bounds on one agent turn (`SMH-SPEC-SPEC0001`, memory //! accounting). Bounds only tighten. use smith_alloc::{Counting, Scope, measure}; use smith_harness::{RuntimeConfig, build_agent, mock_text_reply}; #[global_allocator] static ALLOC: Counting = Counting; /// One mock text turn on a fresh session: request build (one decode of the /// user message), stream consumption, two recorded entries encoded once into /// the arena, one single-buffer frame write each. const MOCK_TURN_ALLOCATIONS: u64 = 42; fn mock_turn(tag: &str) -> (u64, u64) { let dir = std::env::temp_dir().join(format!("smith_alloc_{tag}_{}", std::process::id())); let _ = std::fs::remove_dir_all(&dir); std::fs::create_dir_all(&dir).unwrap(); let mut agent = build_agent(&RuntimeConfig::mock(&dir, vec![mock_text_reply("hi")])).unwrap(); let (outcome, cost) = measure(Scope::Turn, || agent.run_turn("hello")); assert_eq!(outcome.unwrap().text, "hi"); let _ = std::fs::remove_dir_all(&dir); (cost.allocations, cost.bytes) } #[test] fn mock_turn_is_bounded_and_reproducible() { // Process-wide lazy state initializes on the first turn only. let _warmup = mock_turn("warmup"); let first = mock_turn("a"); let second = mock_turn("b"); assert_eq!(first, second); assert_eq!( first.0, MOCK_TURN_ALLOCATIONS, "turn allocated {} times, bound is {MOCK_TURN_ALLOCATIONS}", first.0 ); }