ainl_context_freshness/
lib.rs1use ainl_contracts::{ContextFreshness, ImpactDecision};
9
10#[derive(Debug, Clone, Default)]
12pub struct FreshnessInputs {
13 pub index_stale_vs_head: Option<bool>,
15 pub unknown: bool,
17}
18
19#[must_use]
21pub fn evaluate_freshness(i: &FreshnessInputs) -> ContextFreshness {
22 if i.unknown {
23 return ContextFreshness::Unknown;
24 }
25 match i.index_stale_vs_head {
26 Some(true) => ContextFreshness::Stale,
27 Some(false) => ContextFreshness::Fresh,
28 None => ContextFreshness::Unknown,
29 }
30}
31
32#[must_use]
34pub fn impact_decision_strict(f: ContextFreshness, repo_intel_ready: bool) -> ImpactDecision {
35 match f {
36 ContextFreshness::Stale => {
37 if repo_intel_ready {
38 ImpactDecision::RequireImpactFirst
39 } else {
40 ImpactDecision::BlockUntilFresh
41 }
42 }
43 ContextFreshness::Unknown => {
44 let _ = repo_intel_ready;
47 ImpactDecision::RequireImpactFirst
48 }
49 ContextFreshness::Fresh => ImpactDecision::AllowExecute,
50 }
51}
52
53#[must_use]
55pub fn impact_decision_balanced(f: ContextFreshness, repo_intel_ready: bool) -> ImpactDecision {
56 match f {
57 ContextFreshness::Fresh => ImpactDecision::AllowExecute,
58 ContextFreshness::Stale | ContextFreshness::Unknown => {
59 if repo_intel_ready {
60 ImpactDecision::RequireImpactFirst
61 } else {
62 ImpactDecision::AllowExecute
63 }
64 }
65 }
66}
67
68#[must_use]
70pub fn can_execute_with_context(f: ContextFreshness, strict: bool, repo_intel_ready: bool) -> bool {
71 let d = if strict {
72 impact_decision_strict(f, repo_intel_ready)
73 } else {
74 impact_decision_balanced(f, repo_intel_ready)
75 };
76 matches!(d, ImpactDecision::AllowExecute)
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn fresh_allows() {
85 assert!(can_execute_with_context(
86 ContextFreshness::Fresh,
87 true,
88 false
89 ));
90 }
91}