Skip to main content

bctx_conductor/spiral/
orient.rs

1use super::sense::HarvestedSignal;
2use crate::graph::SignalGraph;
3
4#[derive(Debug, Clone)]
5pub struct SituPicture {
6    pub active_signal_count: usize,
7    pub open_questions: Vec<OpenQuestion>,
8    pub has_recent_errors: bool,
9    pub vault_fact_count: usize,
10}
11
12#[derive(Debug, Clone)]
13pub struct OpenQuestion {
14    pub kind: QuestionKind,
15    pub detail: String,
16}
17
18#[derive(Debug, Clone, PartialEq)]
19pub enum QuestionKind {
20    InvestigateErrors,
21    RecallRelatedFacts,
22    DescribeProjectLayout,
23}
24
25pub fn contextualize(signals: &[HarvestedSignal], _graph: &SignalGraph) -> SituPicture {
26    let mut open_questions = Vec::new();
27    let mut has_errors = false;
28    let vault_facts = signals
29        .iter()
30        .filter(|s| s.source.starts_with("vault:"))
31        .count();
32
33    for sig in signals {
34        let content_lower = sig.content.to_lowercase();
35        if content_lower.contains("exit=1")
36            || content_lower.contains("exit=-1")
37            || content_lower.contains("error")
38            || content_lower.contains("failed")
39        {
40            has_errors = true;
41        }
42    }
43
44    if has_errors {
45        open_questions.push(OpenQuestion {
46            kind: QuestionKind::InvestigateErrors,
47            detail: "recent executions show errors or non-zero exits".into(),
48        });
49        // Recall any vault facts that might explain the errors
50        open_questions.push(OpenQuestion {
51            kind: QuestionKind::RecallRelatedFacts,
52            detail: "error".into(),
53        });
54    }
55
56    if signals.is_empty() {
57        open_questions.push(OpenQuestion {
58            kind: QuestionKind::DescribeProjectLayout,
59            detail: "no signals yet — describe project layout".into(),
60        });
61    }
62
63    SituPicture {
64        active_signal_count: signals.len(),
65        open_questions,
66        has_recent_errors: has_errors,
67        vault_fact_count: vault_facts,
68    }
69}