# Converge Core
> **Context is the only shared state.**
> **The engine decides; agents propose.**
A correctness-first, context-driven multi-agent runtime library.
[](https://crates.io/crates/converge-core)
[](https://docs.rs/converge-core)
---
## What Is Converge Core?
Converge Core is the **foundational semantic engine** of the Converge ecosystem. It provides:
- **Context** — The single source of truth, append-only and typed
- **Engine** — The convergence loop that orchestrates agents to a fixed point
- **Agent Trait** — The contract for capabilities that observe and propose
- **Invariants** — Runtime constraints that guard correctness (Gherkin-style)
- **Capability Traits** — Interfaces that providers implement
### What Converge Core IS
| **The authority** | The engine decides what becomes a Fact |
| **Context owner** | Context is the API; all collaboration happens through it |
| **Convergence guarantor** | Execution proceeds until a fixed point is reached |
| **Invariant enforcer** | Constraints are checked continuously and at convergence |
| **Trait definer** | Defines `Agent`, `LlmProvider`, `Embedding`, etc. |
### What Converge Core is NOT
| **Not a workflow engine** | No predefined steps; agents react to context |
| **Not an event bus** | No pub/sub; context changes trigger eligibility |
| **Not an actor system** | Agents never call each other; no message passing |
| **Not eventual consistency** | Convergence is explicit and observable |
| **Not provider implementations** | Providers live in `converge-provider` |
---
## Core Axioms
These are the non-negotiable principles that define Converge.
### 1. Context Is the Only Shared State
Agents do not call each other. They read Context and emit effects.
Context is the API.
### 2. Agents Propose, Engine Decides
Agents return `AgentEffect` containing `Fact` or `ProposedFact`.
The engine validates, merges, and commits.
### 3. Convergence Is Mandatory
Execution proceeds until:
- `Context_{n+1} == Context_n` (fixed point), or
- Budget exhausted, or
- Invariant failed
### 4. Correctness Over Availability
Wrong answers are worse than no answers.
Invariants block invalid states.
### 5. Determinism Is Transparent
Same input → same output.
All decisions are traceable.
### 6. LLMs Suggest, Never Decide
LLM outputs become `ProposedFact`, not `Fact`.
Validators promote proposals after verification.
---
## Converging Flow Principles
Beyond the core axioms, Converge is built on a systems-level understanding of **converging flows**.
### What Is a Converging Flow?
A converging flow is a goal-directed, multi-agent process where:
- Multiple partial perspectives iteratively reduce uncertainty
- Progress is measured by **reduction of ambiguity**, not by speed or steps completed
- Execution continues until a stable decision, artifact, or state is reached
### Canonical Phases
All flows decompose into six structural phases:
```
Intent → Framing → Exploration → Tension → Convergence → Commitment
```
If any phase is missing, the system oscillates, over-optimizes locally, or produces brittle outcomes.
### Flow Truths
**Intent must be explicit.** Without declared intent, convergence must not begin.
**Constraints precede exploration.** Exploration without surfaced constraints produces invalid outcomes.
**Tension is mandatory.** If multiple perspectives immediately agree without conflict, force contradiction search.
**Commitment freezes state.** The system must commit or explicitly defer — no ambiguous endings.
### Flow Classification
Flows are classified by dominant uncertainty:
- **Epistemic** ("What is true?") — high exploration, late commitment
- **Pragmatic** ("What works?") — bounded exploration, early feasibility pruning
- **Normative** ("What should be done?") — explicit values, narrative convergence
- **Strategic** ("What matters most?") — reframing loops, ranking under uncertainty
See [converge-business/knowledgebase/core-CONVERGING_FLOWS.md](../../converge-business/knowledgebase/core-CONVERGING_FLOWS.md) for the complete flow theory.
---
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ converge-core │
│ The foundational layer. Depends on NOTHING in the ecosystem. │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Engine │ │ Context │ │ Invariant │ │
│ │ (decides) │───▶│ (shared) │◀───│ (guards) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ ▲ │
│ │ │ │
│ ▼ │ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Agent │───▶│ AgentEffect │ │
│ │ (proposes) │ │ (buffered) │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ Trait Definitions: │
│ • Agent • LlmProvider • Embedding │
│ • Invariant • VectorRecall • GraphRecall │
│ • Reranking • ModelSelector │
│ │
└─────────────────────────────────────────────────────────────────┘
│
│ implements traits
▼
┌─────────────────────────────────────────────────────────────────┐
│ converge-provider │
│ Capability adapters (Anthropic, OpenAI, Gemini, etc.) │
└─────────────────────────────────────────────────────────────────┘
│
│ uses providers in agents
▼
┌─────────────────────────────────────────────────────────────────┐
│ converge-domain │
│ Domain agents, use cases, business logic │
└─────────────────────────────────────────────────────────────────┘
```
### Dependency Rules
| `converge-core` | (nothing) | `converge-provider`, `converge-domain` |
| `converge-provider` | `converge-core` | `converge-domain` |
| `converge-domain` | `converge-core`, `converge-provider` | — |
---
## Installation
```toml
[dependencies]
converge-core = "0.6"
```
## Related Crates
| **converge-core** | 0.6.2 | Runtime engine, agent traits, capabilities |
| [converge-provider](https://crates.io/crates/converge-provider) | 0.2.4 | 14+ LLM providers, model selection |
| [converge-domain](https://crates.io/crates/converge-domain) | 0.2.4 | 12 business use cases |
---
## Quick Start
```rust
use converge_core::{Engine, Context, ContextKey, Fact, Agent, AgentEffect};
// Define a simple agent
struct GreetingAgent;
impl Agent for GreetingAgent {
fn name(&self) -> &str { "greeting" }
fn dependencies(&self) -> &[ContextKey] { &[ContextKey::Seeds, ContextKey::Signals] }
fn accepts(&self, ctx: &Context) -> bool {
ctx.has(ContextKey::Seeds) &&
!ctx.get(ContextKey::Signals).iter().any(|f| f.id.starts_with("greeting-"))
}
fn execute(&self, _ctx: &Context) -> AgentEffect {
AgentEffect::with_fact(Fact::new(
ContextKey::Signals,
"greeting-response",
"Hello from Converge!",
))
}
}
fn main() {
let mut engine = Engine::new();
engine.register(GreetingAgent);
let mut ctx = Context::new();
ctx.add_fact(Fact::new(ContextKey::Seeds, "input", "Start")).unwrap();
let result = engine.run(ctx).expect("should converge");
println!("Converged in {} cycles", result.cycles);
}
```
---
## Core Types
### Context
The shared, typed, evolving state of a job.
```rust
pub struct Context {
// Internally organized by ContextKey
// Seeds → Signals → Hypotheses → Strategies → Evaluations
}
pub enum ContextKey {
Seeds, // Initial input data
Signals, // Observations and discoveries
Hypotheses, // Tentative conclusions
Strategies, // Proposed solutions
Evaluations, // Quality assessments
Constraints, // Domain constraints
Proposals, // Pending LLM suggestions
Approvals, // Human-approved items
}
```
### Agent
A capability that reads context and emits effects.
```rust
pub trait Agent: Send + Sync {
/// Unique name for this agent
fn name(&self) -> &str;
/// Context keys this agent depends on
fn dependencies(&self) -> &[ContextKey];
/// Whether this agent should run given current context
fn accepts(&self, ctx: &Context) -> bool;
/// Execute and return effects (facts to add)
fn execute(&self, ctx: &Context) -> AgentEffect;
}
```
### AgentEffect
Buffered output from an agent. Never mutates context directly.
```rust
pub struct AgentEffect {
pub facts: Vec<Fact>,
pub proposed_facts: Vec<ProposedFact>,
pub trace: Option<String>,
}
```
### Fact vs ProposedFact
```
┌─────────────────────────────────────────────────────────────────┐
│ TRUST LEVELS │
├─────────────────────────────────────────────────────────────────┤
│ Fact (authoritative) │ ProposedFact (tentative) │
│ ───────────────────────── │ ───────────────────────────── │
│ Emitted by deterministic │ Emitted by LLM agents │
│ agents or promoted from │ Requires validation before │
│ validated proposals │ becoming a Fact │
│ Added directly to Context │ Held in Proposals key │
└─────────────────────────────────────────────────────────────────┘
```
### Engine
The convergence loop that orchestrates agents.
```rust
pub struct Engine {
agents: Vec<Box<dyn Agent>>,
invariants: Vec<Box<dyn Invariant>>,
budget: Budget,
}
impl Engine {
/// Run until convergence or budget exhaustion
pub fn run(&self, ctx: Context) -> Result<ConvergeResult, ConvergeError>;
}
```
---
## Agent Idempotency Contract
**All agents must follow this rule:**
> An agent has contributed if any artifact it emitted exists in the context — regardless of acceptance or validation.
```rust
impl Agent for MyAgent {
fn dependencies(&self) -> &[ContextKey] {
// Include BOTH input AND output keys
&[ContextKey::Seeds, ContextKey::Hypotheses]
}
fn accepts(&self, ctx: &Context) -> bool {
// 1. Check precondition
if !ctx.has(ContextKey::Seeds) { return false; }
// 2. Check idempotency (context-based, not hidden state)
let my_prefix = format!("{}-", self.name());
!ctx.get(ContextKey::Hypotheses)
.iter()
.any(|f| f.id.starts_with(&my_prefix))
}
fn execute(&self, _ctx: &Context) -> AgentEffect {
AgentEffect::with_fact(Fact::new(
ContextKey::Hypotheses,
"myagent-result-1",
"derived content",
))
}
}
```
---
## Invariants
Runtime constraints that guard correctness.
```rust
pub trait Invariant: Send + Sync {
/// Name of this invariant
fn name(&self) -> &str;
/// When to check: Structural, Semantic, or Acceptance
fn class(&self) -> InvariantClass;
/// Check the invariant against current context
fn check(&self, ctx: &Context) -> InvariantResult;
}
pub enum InvariantClass {
/// Checked on every merge (schema, types)
Structural,
/// Checked per-cycle (domain rules)
Semantic,
/// Checked at convergence (success criteria)
Acceptance,
}
```
---
## Capability Traits
Traits for providers to implement.
```rust
// LLM completion
pub trait LlmProvider: Send + Sync {
fn name(&self) -> &str;
fn model(&self) -> &str;
fn complete(&self, request: &LlmRequest) -> Result<LlmResponse, LlmError>;
}
// Embeddings
pub trait Embedding: Send + Sync {
fn embed(&self, request: &EmbedRequest) -> Result<EmbedResponse, CapabilityError>;
}
// Vector similarity search
pub trait VectorRecall: Send + Sync {
fn query(&self, query: &VectorQuery) -> Result<Vec<VectorMatch>, CapabilityError>;
}
// Graph pattern matching
pub trait GraphRecall: Send + Sync {
fn query(&self, query: &GraphQuery) -> Result<GraphResult, CapabilityError>;
}
// Re-ranking
pub trait Reranking: Send + Sync {
fn rerank(&self, request: &RerankRequest) -> Result<RerankResponse, CapabilityError>;
}
```
---
## Guarantees
| **Determinism** | Agents sorted by name; effects merged in order |
| **Termination** | Budget limits cycles, facts, and wall-clock time |
| **Isolation** | Agents read-only context; effects buffered |
| **Auditability** | Every fact has provenance |
| **Correctness** | Invariants block invalid states |
---
## Execution Model
```
repeat
1. Determine eligible agents (accepts() == true)
2. Execute eligible agents in parallel (read-only context)
3. Collect AgentEffects (buffered)
4. Merge effects into context (serialized, deterministic order)
5. Check structural invariants (immediate)
6. Check semantic invariants (per-cycle)
until
Context unchanged (convergence) OR
Budget exhausted OR
Invariant failed
finally
Check acceptance invariants (convergence gate)
```
---
## Testing
```bash
# Run all convergence axiom tests
cargo test -p converge-core --test engine_convergence_axioms -- --nocapture
# Run all tests
cargo test -p converge-core
# Run property-based tests
cargo test -p converge-core --test property_tests
```
### Test Categories
| `engine_convergence_axioms` | Core convergence guarantees |
| `convergence` | Basic convergence behavior |
| `parallel_execution` | Parallel agent execution |
| `transparent_determinism` | Determinism guarantees |
| `hitl_pause_resume_axioms` | Human-in-the-loop flows |
| `property_tests` | Property-based testing |
---
## Documentation
See [docs/](docs/) for detailed documentation:
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — Layering and contracts
- [docs/architecture/](docs/architecture/) — Core concepts and execution model
- [docs/agents/](docs/agents/) — Agent lifecycle and patterns
- [docs/governance/](docs/governance/) — Design tenets and terminology
- [docs/testing/](docs/testing/) — Invariant and validation testing
---
## Repository
This crate is part of the [Converge](https://github.com/kpernyer/converge) project.
**Standalone repo:** [github.com/kpernyer/converge-core](https://github.com/kpernyer/converge-core)
## License
Proprietary (Aprio One AB)