use super::world::{World, request};
use crate::control::wire::{Request, Verdict};
use crate::control::{Consult, adjudicate, ceiling};
use crate::opslog::YOG_CONTROL;
use crate::xdg::Env;
use serde_json::json;
use std::path::PathBuf;
use tempfile::{TempDir, tempdir};
const HEAD: &str = "spend ceiling reached:";
const CONV: &str = "20260803T120000Z-root";
const TABLE: &str = r#""prices":{"anthropic":{"opus":{"input":1}}}"#;
struct Priced {
dir: TempDir,
}
impl Priced {
fn new(keys: &str) -> Priced {
let it = Priced {
dir: tempdir().unwrap(),
};
std::fs::create_dir_all(it.state_root()).unwrap();
std::fs::write(
it.state_root().join("ui.json"),
format!(r#"{{"v":1,{keys}}}"#),
)
.unwrap();
std::fs::create_dir_all(it.workspace().join("repo.git")).unwrap();
it
}
fn state_root(&self) -> PathBuf {
self.dir.path().join("state").join("yog")
}
fn workspace(&self) -> PathBuf {
self.dir
.path()
.join("data")
.join("yog")
.join("workspaces")
.join("cobalt-gecko")
}
fn env(&self) -> Env {
let at = |leaf: &str| self.dir.path().join(leaf).to_string_lossy().into_owned();
Env::from_pairs([
("HOME", at("home")),
("XDG_STATE_HOME", at("state")),
("XDG_DATA_HOME", at("data")),
])
}
fn spent(&self, input: u64) {
let step = self.workspace().join("steps").join(CONV).join("001");
std::fs::create_dir_all(&step).unwrap();
std::fs::write(
step.join("response.json"),
format!(r#"{{"type":"usage","input_tokens":{input}}}"#),
)
.unwrap();
std::fs::write(step.join("request.json"), r#"{"model":"opus"}"#).unwrap();
}
fn unwalkable(&self) {
std::fs::create_dir_all(self.workspace()).unwrap();
std::fs::write(self.workspace().join("steps"), "not a tree").unwrap();
}
}
fn parked_consult(w: &World, sentence: &str) -> Consult {
Consult {
ceiling: Some(sentence.to_owned()),
..w.consult()
}
}
fn verdict(consult: &Consult, tool: &str, input: serde_json::Value) -> Verdict {
adjudicate(consult, &Request::parse(&request(tool, input)).unwrap())
}
#[test]
fn under_the_number_leaves_every_verdict_unchanged() {
let w = Priced::new(&format!(r#"{TABLE},"ceiling":5"#));
w.spent(3_000_000);
assert_eq!(ceiling::parked(&w.env()), None, "$3 under a $5 ceiling");
let shipped = World::new();
let ordinary = verdict(&shipped.consult(), "bash", json!({"command": "ls"}));
assert_eq!(ordinary, Verdict::Pass);
}
#[test]
fn at_the_number_every_class_holds_with_the_ceiling_s_own_sentence() {
let w = Priced::new(&format!(r#"{TABLE},"ceiling":2"#));
w.spent(3_000_000);
let sentence = ceiling::parked(&w.env()).expect("$3 is at or over a $2 ceiling");
assert!(sentence.starts_with(HEAD), "{sentence}");
assert!(sentence.contains("$3.00"), "{sentence}");
let shipped = World::new();
let consult = parked_consult(&shipped, &sentence);
for input in [
json!({"command": "ls"}),
json!({"command": "curl https://x"}),
json!({"command": "rm -rf /tmp/x"}),
] {
assert_eq!(
verdict(&consult, "bash", input.clone()),
Verdict::Hold(sentence.clone()),
"{input}"
);
}
assert_eq!(
verdict(&consult, "box2_fetch", json!({"url": "https://x"})),
Verdict::Hold(sentence.clone())
);
}
#[test]
fn an_answer_pass_for_this_tool_use_id_still_walks_through() {
let shipped = World::new();
let consult = parked_consult(&shipped, "spend ceiling reached: …");
assert!(matches!(
verdict(&consult, "bash", json!({"command": "ls"})),
Verdict::Hold(_)
));
shipped.answer(&[YOG_CONTROL, "answer", "toolu_01", "pass"]);
assert_eq!(
verdict(&consult, "bash", json!({"command": "ls"})),
Verdict::Pass,
"the operator answered this id"
);
}
#[test]
fn an_absent_key_or_an_empty_table_costs_one_read_and_no_walk() {
for (keys, why) in [
(TABLE, "no `ceiling` key"),
(r#""ceiling":1"#, "no `prices` table"),
] {
let world = Priced::new(keys);
world.unwalkable();
assert_eq!(ceiling::parked(&world.env()), None, "{why}");
}
}
#[test]
fn the_overshoot_is_one_step_per_live_conversation_because_the_park_is_a_hold() {
let shipped = World::new();
let consult = parked_consult(&shipped, "spend ceiling reached: …");
let answered = verdict(&consult, "bash", json!({"command": "rm -rf /tmp/x"}));
assert!(
matches!(answered, Verdict::Hold(_)),
"a loss the table refuses still parks: {answered:?}"
);
assert!(
!shipped.state().join("ops.jsonl").exists(),
"the consult writes nothing"
);
}