1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//! SagaShield — ACID transactional Saga runtime, Step-0 security guardrail,
//! and MCP server for autonomous AI agents.
//!
//! Every tool call runs inside a saga: it is authorized by a deterministic
//! [`StateMachine`], logged to a SQLite write-ahead log ([`Wal`]), executed
//! through a [`TransactionalTool`], and — on failure — compensated in reverse
//! order (Saga rollback). A [`SecurityGuard`] screens requests *before* the
//! FSM check, the WAL write, or any side effect.
//!
//! ## Architecture
//!
//! - [`AgentKernel`] — single entry point: FSM + WAL + [`ToolRegistry`] +
//! optional security guard, with automatic LIFO rollback.
//! - [`Wal`] — `sessions`/`actions` tables, idempotency lookups, dangling
//! session recovery, OTel-ready tracing spans.
//! - [`SessionReplay`] — deterministic dry-run replay of a past saga with
//! formal FSM re-validation (no side effects).
//! - [`AuditExporter`] — session export as OpenTelemetry `resourceSpans` JSON.
//! - [`McpServer`] — JSON-RPC 2.0 stdio server (`sagashield-mcp` binary).
//!
//! ## Quickstart
//!
//! ```rust
//! use std::sync::Arc;
//! use sagashield::{
//! AgentKernel, KernelError, ToolContext, ToolOutput, ToolRegistry,
//! TransactionalTool, Wal,
//! };
//! use serde_json::{Value, json};
//!
//! struct GreetTool;
//!
//! #[async_trait::async_trait]
//! impl TransactionalTool for GreetTool {
//! fn id(&self) -> &'static str { "greet" }
//!
//! async fn execute(
//! &self,
//! _ctx: &ToolContext,
//! args: Value,
//! ) -> Result<ToolOutput, KernelError> {
//! let name = args.get("name").and_then(Value::as_str).unwrap_or("world");
//! Ok(ToolOutput::new(json!({ "greeting": format!("hello {name}") })))
//! }
//!
//! async fn compensate(
//! &self,
//! _ctx: &ToolContext,
//! _args: Value,
//! _output: ToolOutput,
//! ) -> Result<(), KernelError> {
//! Ok(())
//! }
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let wal = Arc::new(Wal::open_in_memory()?);
//! let registry = ToolRegistry::new();
//! registry.register(Arc::new(GreetTool))?;
//!
//! let mut kernel = AgentKernel::new(wal, registry);
//! let session = uuid::Uuid::new_v4();
//! kernel.begin_planning()?;
//! kernel.begin_tool("greet")?;
//! let out = kernel.execute_tool(&session, "greet", json!({ "name": "ada" }), None).await?;
//! assert!(out.data["greeting"] == "hello ada");
//! Ok(())
//! }
//! ```
pub use AuditExporter;
pub use ;
pub use ;
pub use ;
pub use McpServer;
pub use ;
pub use ;
pub use TransactionalTool;
pub use ;
pub use Wal;
/// Modulo nativo Python `_core` (solo con `--features python`, maturin).