Skip to main content

rto_graph/
provenance.rs

1//! Edge provenance classes.
2
3use serde::{Deserialize, Serialize};
4
5/// How an edge or node in the graph was produced.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum Provenance {
9    /// Deterministically extracted from source ASTs (tree-sitter). The default:
10    /// the overwhelmingly common node/edge, and the correct value when a legacy
11    /// cached fact set (serialized before nodes carried provenance) omits it.
12    #[default]
13    Derived,
14    /// Authored by a human or agent in an ADR, blueprint, or annotation.
15    Authored,
16    /// Heuristically inferred (docs, embeddings); carries a confidence score.
17    Inferred,
18}
19
20impl Provenance {
21    /// Parse a provenance from its stable string token, returning `None` for an
22    /// unrecognised value (e.g. a corrupt database row).
23    #[must_use]
24    pub fn from_token(s: &str) -> Option<Self> {
25        match s {
26            "derived" => Some(Self::Derived),
27            "authored" => Some(Self::Authored),
28            "inferred" => Some(Self::Inferred),
29            _ => None,
30        }
31    }
32
33    /// Stable string form used in the `SQLite` store.
34    #[must_use]
35    pub fn as_str(self) -> &'static str {
36        match self {
37            Self::Derived => "derived",
38            Self::Authored => "authored",
39            Self::Inferred => "inferred",
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::Provenance;
47
48    #[test]
49    fn stable_string_forms() {
50        assert_eq!(Provenance::Derived.as_str(), "derived");
51        assert_eq!(Provenance::Authored.as_str(), "authored");
52        assert_eq!(Provenance::Inferred.as_str(), "inferred");
53    }
54
55    #[test]
56    fn from_token_round_trips_and_rejects_unknown() {
57        for p in [
58            Provenance::Derived,
59            Provenance::Authored,
60            Provenance::Inferred,
61        ] {
62            assert_eq!(Provenance::from_token(p.as_str()), Some(p));
63        }
64        assert_eq!(Provenance::from_token("bogus"), None);
65    }
66}