MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / populate_session_tables

Method populate_session_tables

atomic-core/src/pristine/txn/write/mod.rs:77–290  ·  view source on GitHub ↗

Populate the session tables from a provenance graph. Called during `save_provenance_graph` for provenance produced by any** agent — Sherpa, Claude Code, OpenCode, the generic `atomic-agent`, etc. Sherpa graphs (`profile == "sherpa-trace/1.0.0"`) carry richer structured `detail` JSON (intent/todo/phase/verification), so they populate the intent and phase tables more fully; graphs from other agents

(
        &mut self,
        provenance_id: u64,
        graph: &crate::change::ProvenanceGraph,
    )

Source from the content-addressed store, hash-verified

75 ///
76 /// Best-effort: parse errors on individual nodes are logged and skipped.
77 pub fn populate_session_tables(
78 &mut self,
79 provenance_id: u64,
80 graph: &crate::change::ProvenanceGraph,
81 ) -> PristineResult<()> {
82 use crate::change::provenance_graph::ProvenanceNodeKind;
83 use crate::change::session::*;
84
85 // No profile gate: provenance from any agent is indexed into the
86 // session tables. The per-node extraction below is profile-agnostic
87 // and falls back to node summary / kind labels when the richer
88 // Sherpa-specific `detail` keys are absent.
89
90 // Open all four tables.
91 let mut events_table = self.txn.open_table(SESSION_EVENTS)?;
92 let mut todos_table = self.txn.open_table(SESSION_TODOS)?;
93 let mut phases_table = self.txn.open_table(SESSION_PHASES)?;
94 let mut intents_table = self.txn.open_table(SESSION_INTENTS)?;
95
96 for (seq, node) in graph.nodes.iter().enumerate() {
97 let seq = seq as u64;
98 let detail: Option<serde_json::Value> = if let Some(s) = node.detail.as_deref() {
99 match serde_json::from_str(s) {
100 Ok(v) => Some(v),
101 Err(e) => {
102 log::warn!(
103 "Warning: failed to parse provenance node detail JSON (node id={}, kind={}): {}",
104 node.id,
105 node.kind.label(),
106 e
107 );
108 None
109 }
110 }
111 } else {
112 None
113 };
114
115 // Write every node as a SessionEvent regardless of kind.
116 //
117 // `event_kind` and `record_type` are populated from the original
118 // Sherpa/agent-trace `record_type` field stored in the detail JSON
119 // (e.g. "intent", "todo_status", "phase_transition"). We fall back
120 // to `node.kind.label()` only when no such field is present so that
121 // non-Sherpa nodes still get a meaningful discriminant.
122 let sherpa_record_type = detail
123 .as_ref()
124 .and_then(|d| d["record_type"].as_str())
125 .map(|s| s.to_string());
126 let event_kind = sherpa_record_type
127 .clone()
128 .unwrap_or_else(|| node.kind.label().to_string());
129 let event = SessionEvent {
130 seq,
131 timestamp: format_timestamp_ms(node.timestamp),
132 event_kind,
133 place: None,
134 transition: None,

Calls 14

format_timestamp_msFunction · 0.85
encode_session_event_keyFunction · 0.85
encode_session_phase_keyFunction · 0.85
encode_session_todo_keyFunction · 0.85
as_refMethod · 0.80
as_u64Method · 0.80
getMethod · 0.65
iterMethod · 0.45
as_strMethod · 0.45
cloneMethod · 0.45
labelMethod · 0.45
to_bytesMethod · 0.45