use crate::agent::Session;
use crate::declarations::{self, Declaration};
use crate::git;
use crate::report;
use crate::runner;
use crate::trailer::Verdict;
fn reaches(declaration: &Declaration) -> Result<bool, String> {
Ok(!git::tracked(&declaration.paths)?.is_empty())
}
fn sweep(
declaration: &Declaration,
agent: &crate::agent::Agent,
ceiling: std::time::Duration,
) -> Result<(Vec<Verdict>, String), String> {
let system = crate::brief::system(declaration, crate::brief::Reach::Whole)?;
let session = Session::opened();
report::reviewing(&declaration.gate, session.id());
let answer = agent.run(
crate::agent::Role::Review,
&system,
&crate::brief::sweeping(),
&session,
declaration.model.as_deref(),
ceiling,
)?;
let verdicts = runner::verdicts(&answer, declaration.brief.simple)?;
Ok((verdicts, runner::findings(&answer.text)))
}
pub fn run(ceiling: std::time::Duration) -> Result<bool, String> {
let hook = declarations::read()?;
let agent = runner::configured()?;
report::auditing(&hook.path);
let mut blocked = false;
let mut reviewed = 0;
for declaration in &hook.gates {
if !reaches(declaration)? {
report::skipped(&declaration.gate, &declaration.paths);
continue;
}
let (verdicts, findings) = sweep(declaration, &agent, ceiling)?;
blocked |= verdicts.iter().any(Verdict::blocks);
reviewed += 1;
report::audited(&declaration.gate, &verdicts, &findings);
}
if reviewed == 0 {
return Err(format!("{} declared no gate this tree reaches", hook.path));
}
report::audit_done(reviewed, blocked);
Ok(!blocked)
}