//! Abstraction over how execution logs are recorded. //! //! Lives in `shared` so the orchestrator can append logs without //! depending on `manager-core`. In single-process MVP mode, the //! manager's Postgres sink is plugged in directly. In cluster mode //! (v1.3+) the orchestrator's impl will post over HTTP to the manager. use async_trait::async_trait; use thiserror::Error; use crate::execution_log::ExecutionLog; #[derive(Debug, Error)] pub enum LogSinkError { #[error("sink backend error: {0}")] Backend(String), } #[async_trait] pub trait ExecutionLogSink: Send + Sync { async fn record(&self, log: ExecutionLog) -> Result<(), LogSinkError>; }