use super::*;
use crate::opslog::YOG_CONTROL;
use serde_json::json;
mod ceiling;
mod world;
use world::{Closed, World, request};
#[test]
fn the_request_parse_requires_every_field_and_ignores_the_rest() {
let r = Request::parse(&request("bash", json!({"command": "ls"}))).unwrap();
assert_eq!(r.id, "toolu_01");
assert_eq!(r.name, "bash");
assert_eq!(r.role, "worker");
assert_eq!(r.agent_id, "amber");
assert_eq!(r.field("command"), "ls");
assert_eq!(r.field("path"), "");
let extra = json!({"id":"i","name":"n","input":{},"role":"r","agent_id":"a","sandbox":true});
assert!(Request::parse(&extra.to_string()).is_some());
for key in ["id", "name", "input", "role", "agent_id"] {
let mut value = json!({"id":"i","name":"n","input":{},"role":"r","agent_id":"a"});
value.as_object_mut().unwrap().remove(key);
assert!(Request::parse(&value.to_string()).is_none(), "{key}");
}
assert!(Request::parse("not json").is_none());
}
#[test]
fn a_pass_carries_no_reason_and_the_other_two_require_one() {
assert_eq!(Verdict::Pass.json(), r#"{"verdict":"pass"}"#);
assert_eq!(
Verdict::Hold("why".to_owned()).json(),
r#"{"reason":"why","verdict":"hold"}"#
);
assert_eq!(
Verdict::Refuse("why".to_owned()).json(),
r#"{"reason":"why","verdict":"refuse"}"#
);
}
#[test]
fn the_writable_root_is_the_agent_worktree_plus_the_claim_this_workspace_made() {
let w = World::new();
w.claim("/dev/proj", "bl-1a2b", "cobalt-gecko");
let entries = opslog::tail(&w.state(), usize::MAX);
let root = w.consult().root("amber", &entries);
assert_eq!(root.cwd, w.workspace().join("agents").join("amber"));
assert!(root.holds(&w.workspace().join("agents/amber/src/x")));
assert!(
root.holds(
&w.balls()
.join("plugins/bl-delivery/dev/proj/bl-1a2b/README.md")
)
);
assert!(!root.holds(Path::new("/etc/hosts")));
w.claim("/dev/proj", "bl-9999", "other-name");
let entries = opslog::tail(&w.state(), usize::MAX);
let root = w.consult().root("amber", &entries);
assert!(!root.holds(&w.balls().join("plugins/bl-delivery/dev/proj/bl-9999/x")));
}
#[test]
fn the_default_table_decides_an_unanswered_invocation() {
let w = World::new();
let c = w.consult();
let verdict = |name: &str, input: serde_json::Value| {
adjudicate(&c, &Request::parse(&request(name, input)).unwrap())
};
assert_eq!(
verdict("bash", json!({"command": "cargo test"})),
Verdict::Pass
);
assert_eq!(verdict("read_file", json!({"path": "x"})), Verdict::Pass);
assert_eq!(
verdict("dispatch", json!({"role": "worker", "goal": "g"})),
Verdict::Pass
);
assert_eq!(
verdict("bash", json!({"command": "curl https://x"})),
Verdict::Pass
);
let Verdict::Refuse(reason) = verdict("bash", json!({"command": "rm -rf /etc"})) else {
panic!("loss is declined in band");
};
assert!(reason.contains("destructive"), "{reason}");
assert!(reason.contains("bash"), "{reason}");
}
#[test]
fn the_operator_s_answers_fold_over_the_table() {
let w = World::new();
w.answer(&[YOG_CONTROL, "answer", "toolu_01", "pass"]);
assert_eq!(
adjudicate(
&w.consult(),
&Request::parse(&request("bash", json!({"command": "rm -rf /etc"}))).unwrap()
),
Verdict::Pass
);
w.answer(&[YOG_CONTROL, "floor", "amber", "raise"]);
let held = adjudicate(
&w.consult(),
&Request::parse(
&json!({"id":"toolu_02","name":"bash","input":{"command":"cargo test"},
"role":"worker","agent_id":"amber"})
.to_string(),
)
.unwrap(),
);
assert!(matches!(held, Verdict::Hold(_)), "{held:?}");
}
#[test]
fn a_floor_parks_by_what_the_call_reaches_not_by_which_tool_it_is() {
let w = World::new();
w.answer(&[YOG_CONTROL, "floor", "amber", "raise"]);
let verdict = |id: &str, command: &str| {
adjudicate(
&w.consult(),
&Request::parse(
&json!({"id": id, "name": "bash", "input": {"command": command},
"role": "worker", "agent_id": "amber"})
.to_string(),
)
.unwrap(),
)
};
for read in ["echo ADJUDICATED", "ls -la", "cat Cargo.toml"] {
assert_eq!(verdict("toolu_r", read), Verdict::Pass, "{read}");
}
for parked in ["mkdir -p /tmp/elsewhere", "curl https://x", "touch /etc/x"] {
assert!(
matches!(verdict("toolu_h", parked), Verdict::Hold(_)),
"{parked}"
);
}
}
#[test]
fn a_reason_never_hands_the_reader_a_section_number() {
let w = World::new();
let verdict = adjudicate(
&w.consult(),
&Request::parse(&request("bash", json!({"command": "rm -rf /etc"}))).unwrap(),
);
let Verdict::Refuse(reason) = verdict else {
panic!("loss is declined in band");
};
assert!(!reason.contains('§'), "{reason}");
}
mod policy;
mod shim;
#[test]
fn the_workspace_is_litany_s_own_env_var_else_the_cwd_it_runs_in() {
let env = crate::xdg::Env::from_pairs([("LITANY_CONV_REPO", "/w/ws")]);
assert_eq!(workspace_of(&env), PathBuf::from("/w/ws"));
let env = crate::xdg::Env::from_pairs([("LITANY_CONV_REPO", "")]);
assert_eq!(workspace_of(&env), std::env::current_dir().unwrap());
}