Add rulespec extensions: new predicate rules, when conditions, null handling, solon agent
Features: - New predicate rules: NotContains, AnyOf, NoneOf - Conditional predicates via when clauses (WhenCondition/CompiledWhenCondition) - Null handling: YAML null treated as absent for exists/not_exists - Solon agent for rulespec authoring (agents/solon.md) - Rulespec schema documentation (prompts/schemas/rulespec.schema.md) Bugfix: - Fixed when condition evaluation in datalog path: catch-all branch did naive string contains instead of delegating to evaluate_predicate_datalog(). Rules like matches (regex) were silently ignored, causing vacuous pass and letting violations through. Now delegates to evaluate_predicate_datalog() which handles all 12 rule types correctly. Tests: 34 new tests covering all new rules, null handling, when conditions, and the when+matches bugfix (butler rulespec pattern).
This commit is contained in:
@@ -98,7 +98,7 @@ pub async fn run_agent_mode(
|
||||
// Load agent prompt: workspace agents/<name>.md first, then embedded fallback
|
||||
let (agent_prompt, from_disk) = load_agent_prompt(agent_name, &workspace_dir).ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"Agent '{}' not found.\nAvailable embedded agents: breaker, carmack, euler, fowler, hopper, lamport, scout\nOr create agents/{}.md in your workspace.",
|
||||
"Agent '{}' not found.\nAvailable embedded agents: breaker, carmack, euler, fowler, hopper, lamport, scout, solon\nOr create agents/{}.md in your workspace.",
|
||||
agent_name,
|
||||
agent_name
|
||||
)
|
||||
|
||||
@@ -22,6 +22,7 @@ static EMBEDDED_AGENTS: &[(&str, &str)] = &[
|
||||
("huffman", include_str!("../../../agents/huffman.md")),
|
||||
("lamport", include_str!("../../../agents/lamport.md")),
|
||||
("scout", include_str!("../../../agents/scout.md")),
|
||||
("solon", include_str!("../../../agents/solon.md")),
|
||||
];
|
||||
|
||||
/// Get an embedded agent prompt by name.
|
||||
@@ -89,7 +90,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_embedded_agents_exist() {
|
||||
// Verify all expected agents are embedded
|
||||
let expected = ["breaker", "carmack", "euler", "fowler", "hopper", "huffman", "lamport", "scout"];
|
||||
let expected = ["breaker", "carmack", "euler", "fowler", "hopper", "huffman", "lamport", "scout", "solon"];
|
||||
for name in expected {
|
||||
assert!(
|
||||
get_embedded_agent(name).is_some(),
|
||||
@@ -102,7 +103,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_list_embedded_agents() {
|
||||
let agents = list_embedded_agents();
|
||||
assert!(agents.len() >= 8, "Should have at least 8 embedded agents");
|
||||
assert!(agents.len() >= 9, "Should have at least 9 embedded agents");
|
||||
assert!(agents.contains(&"carmack"));
|
||||
assert!(agents.contains(&"hopper"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user