# Architecture > Event sourcing, CQRS, workspace isolation, and the internals of Syntropic137 ## Event Sourcing Syntropic137 uses **event sourcing** as its core persistence pattern. Instead of storing current state, every state change is recorded as an immutable event. The current state is derived by replaying events. ### Two Event Types Syntropic137 distinguishes between two kinds of events, each optimized for its use case: | | Domain Events | Observability Events | |---|---|---| | **Purpose** | Business logic, state transitions | Telemetry, metrics, audit logs | | **Storage** | TimescaleDB (append-only, replay-safe) | TimescaleDB (hypertable, time-series optimized) | | **Pipeline** | Command → Aggregate → Event → Projection | Agent stdout → Collector → EventBuffer → TimescaleDB | | **Validation** | Aggregate invariants, can be rejected | Schema validation only, append-only | | **Examples** | `WorkflowCreated`, `ExecutionStarted` | `ToolExecuted`, `TokensUsed` | ## CQRS Commands and queries are strictly separated. Commands modify state through aggregates; queries read from pre-built projections cached in Redis. **Commands (12):** `CreateWorkflow`, `StartExecution`, `PauseExecution`, `ResumeExecution`, `CancelExecution`, `RegisterTrigger`, `UpdateTrigger`, `DeleteTrigger`, and more. **Events (31):** Every command produces one or more events: `WorkflowCreated`, `ExecutionStarted`, `ExecutionPaused`, `ExecutionResumed`, `ExecutionCompleted`, `TriggerRegistered`, etc. **Projections (14):** Pre-computed read models updated by event processors, cached in Redis or PostgreSQL for sub-millisecond query response times. Includes a `repo_correlation` projection that maps repositories to workflow executions for cross-context insight queries. ## Domain Model Syntropic137 is organized into five bounded contexts with nine aggregates: ## Real-Time Communication Syntropic137 uses **Server-Sent Events (SSE)** for real-time monitoring of executions — progress updates, tool events, token metrics, and state changes all stream over a single connection: ``` GET /api/executions/{execution_id}/stream ``` Control commands (pause, resume, cancel) are sent via standard REST API calls rather than a persistent connection. ### Execution State Machine
NOT_STARTED → start → RUNNING → finish → COMPLETED
RUNNING → error → FAILED
RUNNING → pause → PAUSED → resume → RUNNING
RUNNING → interrupt → INTERRUPTED → retry → RUNNING
PAUSED → cancel → CANCELLED
**Yield Points** — The agent can only be paused at safe points: before each workflow phase, after each tool execution, and after each LLM call. ## Performance Both event pipelines are optimized for their access patterns. Domain events use append-only writes with aggregate-level consistency. Observability events use TimescaleDB hypertables with automatic partitioning for high-throughput ingestion. Read models are cached in Redis for fast dashboard and API queries.