Skip to main content

lean_ctx/core/value_gate/
outcome_evaluator.rs

1//! Deterministic task-outcome acceptance evaluation.
2
3/// Observable outcome signals from one execution.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum OutcomeSignal {
6    BuildSucceeded,
7    TestsPassed,
8    LintClean,
9    UserAccepted,
10    UserRejected,
11    CompileError,
12    TestFailed,
13}
14
15/// Outcome observation associated with one task.
16#[derive(Debug, Clone, Default, PartialEq, Eq)]
17pub struct TaskOutcome {
18    pub task_id: String,
19    pub completed: bool,
20    pub signals: Vec<OutcomeSignal>,
21}
22
23/// Accept only completed outcomes without an explicit negative signal.
24pub fn evaluate(outcome: &TaskOutcome) -> bool {
25    outcome.completed
26        && !outcome.signals.iter().any(|signal| {
27            matches!(
28                signal,
29                OutcomeSignal::UserRejected
30                    | OutcomeSignal::CompileError
31                    | OutcomeSignal::TestFailed
32            )
33        })
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn outcome_accepted_all_positive() {
42        let outcome = TaskOutcome {
43            task_id: "task".into(),
44            completed: true,
45            signals: vec![
46                OutcomeSignal::BuildSucceeded,
47                OutcomeSignal::TestsPassed,
48                OutcomeSignal::LintClean,
49                OutcomeSignal::UserAccepted,
50            ],
51        };
52        assert!(evaluate(&outcome));
53    }
54
55    #[test]
56    fn outcome_rejected_on_failure() {
57        let outcome = TaskOutcome {
58            task_id: "task".into(),
59            completed: true,
60            signals: vec![OutcomeSignal::TestsPassed, OutcomeSignal::TestFailed],
61        };
62        assert!(!evaluate(&outcome));
63    }
64
65    #[test]
66    fn outcome_rejected_not_completed() {
67        let outcome = TaskOutcome {
68            task_id: "task".into(),
69            completed: false,
70            signals: vec![OutcomeSignal::BuildSucceeded],
71        };
72        assert!(!evaluate(&outcome));
73    }
74}