# enact-core
`enact-core` is the core graph-first agent runtime crate for the Enact
platform. It provides the execution kernel, graph engine, and streaming
infrastructure for deterministic, auditable agent execution.
## Key Features
### Execution Kernel
- **Reducer-based state machine** - Pure function state transitions for determinism
- **Tenant isolation** - `TenantContext` required for all executions
- **Agentic DAG** - Dynamic step discovery with policy-bounded execution
- **Parallel step execution** - Independent steps execute concurrently via `tokio::join!`
- **Circular graph detection** - Topological sort validation at compile time
### Mid-Execution Control
- **Inbox integration** - Inject guidance, evidence, and control signals mid-execution
- **Async cancellation** - Cooperative cancellation via `CancellationToken`
- **Checkpointing** - Save and restore execution state
### Content Protection
- **ProtectedEventEmitter** - Optional content protection pipeline
- **PII detection** - Via `enact-guardrails` integration
- **Context-aware masking** - Different protection based on destination
### Tool Execution
- **ToolExecutor** - Policy-aware tool execution
- **Policy decision events** - All tool policy decisions emitted for audit trail
- **Trust levels** - Untrusted, Low, Medium, High, System
### Observability
- **StreamEvent** - AI SDK compatible wire format with `data-*` prefix
- **EventStore** - Append-only event persistence
- **Artifact lifecycle** - First-class artifacts with deterministic IDs
## Module Structure
```
src/
├── kernel/ # Execution kernel (state machine, reducer, events)
│ ├── kernel.rs # ExecutionKernel entry point
│ ├── reducer.rs # Pure state transitions
│ ├── event.rs # ExecutionEvent types
│ ├── error.rs # Error taxonomy with retry policies
│ ├── execution_state.rs # ExecutionState, WaitReason
│ ├── interrupt.rs # Interrupt handling for HITL
│ └── artifact/ # Artifact lifecycle (feat-04)
├── context/ # TenantContext, RuntimeContext
├── flow/ # Execution semantics (sequential, parallel, conditional)
├── callable/ # Callable trait, LlmCallable
├── policy/ # ExecutionPolicy, ToolPolicy, TenantPolicy
├── streaming/ # SSE streaming, EventStore, ProtectedEventEmitter
├── graph/ # StateGraph, CompiledGraph, Node
├── tool/ # Tool trait, ToolExecutor, policy enforcement
├── inbox/ # Mid-execution guidance (INV-INBOX-*)
├── providers/ # ModelProvider trait
├── telemetry/ # OpenTelemetry integration
└── runner/ # Thin wiring shell
```
## Usage
```rust
use enact_core::prelude::*;
use enact_core::context::TenantContext;
// Create kernel with required tenant context
let tenant = TenantContext::new(TenantId::from("tenant_123"));
let kernel = ExecutionKernel::new(tenant)
.with_inbox(Arc::new(InMemoryInboxStore::new()))
.with_artifact_store(Arc::new(InMemoryArtifactStore::new()));
// Compile and execute graph
let graph = StateGraph::new("my_agent")
.add_node("step1", my_callable)
.add_edge("start", "step1");
let compiled = graph.compile()?;
let result = kernel.execute_graph(&compiled, input).await?;
```
## Invariants
See [04-KERNEL_INVARIANTS.md](../../docs/TECHNICAL/04-KERNEL_INVARIANTS.md) for:
- Execution invariants (determinism, replay, tenant isolation)
- Graph execution invariants (parallel execution, cycle detection)
- Inbox invariants (INV-INBOX-001 through INV-INBOX-004)
- Cancellation invariants (cooperative, propagating, observable)
- Artifact lifecycle invariants (first-class, deterministic IDs, immutable)
- Content protection invariants (protected emission, bypass for control)
- Tool policy invariants (auditable decisions, ToolExecutor enforcement)
## Related Documentation
- [02-ENACT-CORE-ARCHITECTURE.md](../../docs/TECHNICAL/02-ENACT-CORE-ARCHITECTURE.md) - Full architecture
- [07-EXECUTION_LIFECYCLE.md](../../docs/TECHNICAL/07-EXECUTION_LIFECYCLE.md) - Execution lifecycle
- [31-MID-EXECUTION-GUIDANCE.md](../../docs/TECHNICAL/31-MID-EXECUTION-GUIDANCE.md) - Inbox system
- [17-GUARDRAILS-PROTECTION.md](../../docs/TECHNICAL/17-GUARDRAILS-PROTECTION.md) - PII protection