converge-core 0.5.0

Converge Agent OS - correctness-first, context-driven multi-agent runtime
Documentation

Converge Core

A correctness-first, context-driven multi-agent runtime library.

converge-core is the foundational semantic engine for the Converge workspace. It contains the pure mechanisms for convergence, context management, and abstraction traits. It is designed to be agnostic of specific domain logic or LLM provider implementations.

Workspace Role

Converge is organized into several specialized crates:

Crate Responsibility
converge-core Foundational engine, context, and traits (Pure)
converge-provider LLM provider implementations (Anthropic, etc.)
converge-domain Domain-specific agents and business logic (Growth, etc.)
converge-tool Developer tools, Gherkin validation, and contracts
converge-runtime HTTP/gRPC server and CLI/TUI interfaces

Overview

Converge Core provides the foundational runtime for building systems where:

  • Context is the API — Agents collaborate through shared data, not direct calls
  • Convergence is mandatory — Execution proceeds until a fixed point is reached
  • Correctness over availability — Wrong answers are worse than no answers

Core Concepts

Context

The shared, typed, evolving state of a job. Context is append-only in meaning and provides the only communication channel between agents. It is fully serializable for persistence and cross-crate usage.

Agents

Capabilities that read context and emit effects. Agents never call each other directly—all communication happens through context. The Agent trait is defined here but implemented in converge-domain.

Engine

The convergence loop that coordinates agents, merges effects, and detects when execution has reached a fixed point. It supports parallel agent execution with serial, deterministic commit.

Convergence

Execution halts when the context reaches a stable state (no new facts are added in a cycle).

Agent Idempotency Contract

This is a formal rule that all agents must follow.

An agent has contributed if any artifact it emitted exists in the context — regardless of whether that artifact was accepted, validated, or promoted.

Why This Matters

The engine has no concept of "pending", "validated", or "proposal lifecycle". It only knows:

  • Which keys are dirty (changed since last cycle)
  • Which agents have dependencies on those keys
  • Whether accepts() returns true

If an agent uses hidden state (like has_run: bool) to track whether it ran, it breaks convergence guarantees. The engine cannot reason about hidden state.

The Correct Pattern

impl Agent for MyAgent {
    fn dependencies(&self) -> &[ContextKey] {
        // MUST include both input keys AND output key (for idempotency check)
        &[ContextKey::Seeds, ContextKey::Hypotheses]  // Seeds=input, Hypotheses=output
    }

    fn accepts(&self, ctx: &Context) -> bool {
        // 1. Precondition: input exists
        if !ctx.has(ContextKey::Seeds) {
            return false;
        }

        // 2. Idempotency: check if we already contributed (CONTEXT-BASED!)
        let my_prefix = format!("{}-", self.name());
        let already_contributed = ctx.get(ContextKey::Hypotheses)
            .iter()
            .any(|f| f.id.starts_with(&my_prefix));

        !already_contributed  // Only run if we haven't contributed
    }

    fn execute(&self, _ctx: &Context) -> AgentEffect {
        // Emit fact with stable ID prefix
        AgentEffect::with_fact(Fact::new(
            ContextKey::Hypotheses,
            "myagent-result-1",  // ID starts with agent's prefix
            "derived content",
        ))
    }
}

What This Includes

Artifacts that count as "contributed":

  • Facts — Trusted data added to context
  • Proposals — LLM suggestions (even if later rejected)
  • Diagnostics — Error/warning messages
  • Authority requests — Permission escalations

Common Mistakes

Mistake Why It Breaks
has_run: AtomicBool Hidden state — engine can't see it
Checking only if output key exists Another agent might have contributed
Not declaring output key in dependencies() Agent won't be reconsidered when output changes

Proof Tests

Run the axiom proof tests to verify these guarantees:

cargo test -p converge-core --test engine_convergence_axioms -- --nocapture
cargo test -p converge-core --test engine_convergence_bones -- --nocapture

See CONVERGENCE_PROOFS.md for detailed documentation.

Quick Start

use converge_core::{Engine, Context, ContextKey};
use converge_core::agents::{SeedAgent, ReactOnceAgent};

// Create engine and register agents
let mut engine = Engine::new();
engine.register(SeedAgent::new("seed-1", "initial data"));
engine.register(ReactOnceAgent::new("hyp-1", "derived insight"));

// Run until convergence
let result = engine.run(Context::new()).expect("should converge");

// Inspect results
assert!(result.converged);
assert!(result.context.has(ContextKey::Seeds));
println!("Converged in {} cycles", result.cycles);

Public API

Core Types

  • [Engine] — The convergence runtime
  • [Context] — Shared job state
  • [Agent] — Agent trait for implementing capabilities
  • [AgentEffect] — Buffered output from agents
  • [Fact] — Typed facts added to context
  • [ProposedFact] — LLM suggestions requiring validation
  • [LlmProvider] — Abstraction for external LLM backends

Guarantees

  • Determinism: Same input → same output
  • Termination: Budgets prevent infinite loops
  • Isolation: Agents never call each other
  • Auditability: All changes are traceable

Documentation

For detailed API documentation, run cargo doc -p converge-core --open.

For high-level architecture and design principles, see the public documentation.

License

MIT