use klieo_provenance::{
ProvenanceError, ProvenanceEvent, ProvenanceEventKind, ProvenanceRepository,
};
use serde_json::{json, Value};
use std::sync::Arc;
pub(crate) const STATUS_SUCCEEDED: &str = "succeeded";
pub(crate) const STATUS_FAILED: &str = "failed";
pub(crate) const STATUS_ABORTED: &str = "aborted";
const METADATA_STATUS_KEY: &str = "status";
const METADATA_REASON_KEY: &str = "reason";
#[derive(Clone)]
pub(crate) struct RunProvenance {
pub repo: Arc<dyn ProvenanceRepository>,
pub run_id: String,
pub author: String,
pub workflow_id: String,
pub content_hash: String,
}
impl RunProvenance {
pub async fn record_started(&self) -> Result<(), ProvenanceError> {
let event = self.event(ProvenanceEventKind::AgentRunStarted, Value::Null);
self.repo.append(&self.run_id, event).await.map(|_| ())
}
pub async fn record_terminal(
&self,
status: &str,
reason: Option<String>,
) -> Result<(), ProvenanceError> {
let mut metadata = json!({ METADATA_STATUS_KEY: status });
if let Some(reason) = reason {
metadata[METADATA_REASON_KEY] = Value::String(reason);
}
let event = self.event(ProvenanceEventKind::AgentRunCompleted, metadata);
self.repo.append(&self.run_id, event).await.map(|_| ())
}
fn event(&self, kind: ProvenanceEventKind, metadata: Value) -> ProvenanceEvent {
ProvenanceEvent {
kind,
actor: self.author.clone(),
resource_ref: self.workflow_id.clone(),
payload_hash_hex: self.content_hash.clone(),
metadata,
}
}
}