Skip to main content

forge_engine/cea/
store.rs

1use crate::cea::graph::CausalGraph;
2use crate::cea::instrumentation::AttributedRunResult;
3use crate::config::ForgeConfig;
4use crate::error::ForgeResult;
5use crate::store::ForgeStore;
6use rusqlite::Transaction;
7
8pub use cea_store::UpdateResult;
9
10/// Update the causal graph from an attributed run result.
11///
12/// Invariant I10: Idempotent — same run_hash produces no graph change on replay.
13pub fn update_graph(
14    store: &ForgeStore,
15    result: &AttributedRunResult,
16    eval_id: &str,
17    version_id: &str,
18    config: &ForgeConfig,
19) -> ForgeResult<UpdateResult> {
20    store.with_transaction_conn(|tx| update_graph_with_tx(tx, result, eval_id, version_id, config))
21}
22
23/// Update the causal graph using an already-open transaction handle.
24///
25/// This avoids nested write transactions and keeps CEA writes inside the
26/// owning store transaction boundary.
27pub fn update_graph_with_tx(
28    tx: &Transaction,
29    result: &AttributedRunResult,
30    eval_id: &str,
31    version_id: &str,
32    config: &ForgeConfig,
33) -> ForgeResult<UpdateResult> {
34    let sqlite = cea_sqlite::SqliteCeaStoreTx::new(tx);
35    Ok(cea_store::update_graph(
36        &sqlite,
37        result,
38        eval_id,
39        version_id,
40        config.cea.attribution_decay_factor,
41    )?)
42}
43
44/// Load the causal graph from the store into memory.
45///
46/// Reconstructs the in-memory `CausalGraph` from persisted `cea_nodes` and `cea_edges`.
47/// If `version_id` is `Some`, only edges for that version are loaded; otherwise all edges.
48pub fn load_graph(store: &ForgeStore, version_id: Option<&str>) -> ForgeResult<CausalGraph> {
49    store.with_conn(|conn| {
50        let sqlite = cea_sqlite::SqliteCeaStoreConn::new(conn);
51        Ok(cea_store::load_graph(&sqlite, version_id)?)
52    })
53}
54
55/// Load the causal graph from an already-open transaction handle.
56///
57/// Reuses the caller-provided transaction for transaction-local graph reads.
58pub fn load_graph_with_tx(tx: &Transaction, version_id: Option<&str>) -> ForgeResult<CausalGraph> {
59    let sqlite = cea_sqlite::SqliteCeaStoreTx::new(tx);
60    Ok(cea_store::load_graph(&sqlite, version_id)?)
61}