update shape of RuleMatch and Evaluation

This commit is contained in:
kevin zhao
2025-11-10 13:10:50 -08:00
parent 85edde08c1
commit 71ea7edca4
3 changed files with 92 additions and 31 deletions

View File

@@ -1,5 +1,6 @@
use codex_execpolicy2::Decision;
use codex_execpolicy2::PolicyParser;
use codex_execpolicy2::RuleMatch;
use codex_execpolicy2::tokenize_command;
#[test]
@@ -8,7 +9,14 @@ fn matches_default_git_status() {
let cmd = tokenize_command("git status").expect("tokenize");
let eval = policy.evaluate(&cmd).expect("match");
assert_eq!(eval.decision, Decision::Allow);
assert_eq!(eval.rule_id, "git_status");
assert_eq!(
eval.matched_rules,
vec![RuleMatch {
rule_id: "git_status".to_string(),
matched_prefix: vec!["git".to_string(), "status".to_string()],
decision: Decision::Allow,
}]
);
}
#[test]
@@ -25,7 +33,19 @@ prefix_rule(
for cmd in ["npm i", "npm install"] {
let tokens = tokenize_command(cmd).expect("tokenize");
let eval = policy.evaluate(&tokens).expect("match");
assert_eq!(eval.rule_id, "npm_install");
let matched_prefix = if cmd.ends_with(" i") {
vec!["npm".to_string(), "i".to_string()]
} else {
vec!["npm".to_string(), "install".to_string()]
};
assert_eq!(
eval.matched_rules,
vec![RuleMatch {
rule_id: "npm_install".to_string(),
matched_prefix,
decision: Decision::Allow,
}]
);
}
let no_match = tokenize_command("npmx install").expect("tokenize");
@@ -81,10 +101,61 @@ prefix_rule(
let status = tokenize_command("git status").expect("tokenize");
let status_eval = policy.evaluate(&status).expect("match");
assert_eq!(status_eval.decision, Decision::Prompt);
assert_eq!(status_eval.rule_id, "prompt_git");
assert_eq!(
status_eval.matched_rules,
vec![
RuleMatch {
rule_id: "allow_git_status".to_string(),
matched_prefix: vec!["git".to_string(), "status".to_string()],
decision: Decision::Allow,
},
RuleMatch {
rule_id: "prompt_git".to_string(),
matched_prefix: vec!["git".to_string()],
decision: Decision::Prompt,
}
]
);
let commit = tokenize_command("git commit -m hi").expect("tokenize");
let commit_eval = policy.evaluate(&commit).expect("match");
assert_eq!(commit_eval.decision, Decision::Forbidden);
assert_eq!(commit_eval.rule_id, "forbid_git_commit");
assert_eq!(
commit_eval.matched_rules,
vec![
RuleMatch {
rule_id: "prompt_git".to_string(),
matched_prefix: vec!["git".to_string()],
decision: Decision::Prompt,
},
RuleMatch {
rule_id: "forbid_git_commit".to_string(),
matched_prefix: vec!["git".to_string(), "commit".to_string()],
decision: Decision::Forbidden,
}
]
);
}
#[test]
fn unnamed_rule_uses_source_as_name() {
let policy_src = r#"
prefix_rule(
id = "unnamed_rule",
pattern = ["echo"],
)
"#;
let parser = PolicyParser::new("test.policy", policy_src);
let policy = parser.parse().expect("parse policy");
let eval = policy
.evaluate(&tokenize_command("echo hi").expect("tokenize"))
.expect("match");
assert_eq!(
eval.matched_rules,
vec![RuleMatch {
rule_id: "unnamed_rule".to_string(),
matched_prefix: vec!["echo".to_string()],
decision: Decision::Allow,
}]
);
}