Eventplane is an event-native, controller-driven orchestration system that treats every change as an event. It draws inspiration from Kubernetes reconciliation, event sourcing, and AI-assistive operations: agents (human or LLM) express intent, controllers reconcile that intent deterministically, and projections rebuild read models from fact events. There are no workflows or CRUD engines—only events, decisions, and replayable projections.
- Intent First – Specs describe user intent up front; controllers reconcile desired vs. actual state.
- Deterministic Controllers – Idempotent, pure Python classes return
ControllerDecisionobjects; runtime mutates events and handles I/O. - Audit by Default – Every state change is an append-only event, backed by PostgreSQL and broadcast over NATS.
- LLM-Friendly – Documentation (
AGENTS.md,llms.txt) codifies how agents interact with the system safely.
[ CLI / Agent / Chatbot ]
↓
Intent Event (EventFactory.from_intent)
↓
Controller Runtime (mutate_event + EventStore)
↓
Controllers (deterministic reconcile)
↓
Decision → New Event (internal/fact)
↓
Event Store (append-only PostgreSQL)
↓
Event Bus (NATS subjects)
↓
Projections (replayable read models)
apps/ # Domain modules (e.g., organization)
└─ <domain>/
├─ specs/ # ResourceSpec definitions (intent schema)
├─ controllers/ # Deterministic reconciliation logic
├─ projections/ # Read-model builders fed by fact events
└─ models/, runtime/ (supporting DTOs or helpers)
eventplane/
├─ event/ # Event model, factory, mutation helpers
├─ controller/ # Controller base classes + runtime
├─ store/ # Append-only EventStore (SQLModel/PostgreSQL)
├─ bus/ # NATS producer utilities
├─ registry.py # Spec/projection discovery
├─ spec.py # Spec prompting/validation for CLI
└─ utils.py # Time, UUID, publishing helpers
evtctl/ & cli/ # Intent-publishing CLI (Click commands)
resources/, sqls/ # Deployment assets, SQL scripts, migrations
- Python 3.14
- Poetry 1.7+
- Access to PostgreSQL + NATS (local Docker compose available)
git clone https://github.com/dotlabshq/eventplane.git
cd eventplane
poetry installSpin up dependencies:
docker compose up -d postgres natsCustomize .eventplane.toml if needed (see eventplane/config/ for schema). Tenants/secrets for local development belong in environment variables or .env files—not in specs or events.
Generate and publish an intent event:
poetry run evtctl apply Organization -f examples/org.yaml
# or interactively:
poetry run evtctl apply Organizationapply loads the relevant ResourceSpec from apps/<domain>/specs, prompts for missing fields, and calls EventFactory.from_intent. When --dry-run is omitted it publishes to NATS (eventplane.<kind>.intent).
- Controllers inherit from
eventplane/controller/base.pyand declareWATCHfilters. ControllerRuntime(seeeventplane/controller/runtime.py) invokes controllers, useseventplane/event/mutate.pyto maintain status/finalizers, persists viaeventplane/store/event_store.py, then publishes on the bus.- Controllers must stay pure (no network, DB, or filesystem I/O) and only return
ControllerDecision.
- Read
AGENTS.mdfor the behavioral contract andllms.txtfor agent navigation tips. - Specs are public contracts—version bumps or field changes must be documented in
ARCHITECTURE.md. - New capabilities must touch specs → events → controllers → projections, and include replay-safe projections/tests (
CONTRIBUTING.mdexplains expectations). - Use
poetry run pytestfor controller/projection tests; avoid mocking the EventStore—replay with realEventinstances.
SECURITY.md describes the multi-tenant, zero-trust model: tenant IDs on every event, authorization at the edge, subject-level ACLs in NATS, and replay-first incident response. Never embed secrets inside event payloads; use opaque handles instead.
- Issues / feature discussions: GitHub Issues (public topics only; see
SECURITY.mdfor vulnerability reporting). - Contact:
teams@dotlabs.dev
Eventplane agents assist the system in deciding, never in executing side effects directly.