Skip to content
CAI
Software that uses CAICheck a score

get-eventually/go-eventually

68.9

Adequate · 21 September 2026

3.8k

lines of production code

Go

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Go library implementing Event Sourcing and CQRS patterns, providing core abstractions for aggregates, commands, queries, and domain events. It supports persistence via PostgreSQL and in-memory stores, with built-in instrumentation for OpenTelemetry and generic serialization for JSON and Protobuf. The library facilitates domain-driven design through typed envelopes, optimistic concurrency control, and iterator-based event streaming.

How it got here

2021 — Initial scaffolding and generic refactoring

8 changes.

The project was established with initial scaffolding, including CI configuration and documentation, followed by a comprehensive refactoring of the core packages to leverage Go generics. Legacy interfaces and implementations were removed to simplify the API, while new packages for commands and queries were introduced to support CQRS patterns.

2022–2026 — core event sourcing infrastructure

8 changes.

This period focused on establishing the foundational components of the go-eventually library, including the core event package with iterator-based streaming, serialization frameworks, and versioning for optimistic concurrency. It introduced robust storage backends with PostgreSQL integration and comprehensive observability through OpenTelemetry instrumentation. The work was validated by complete domain examples, such as User and TodoList, demonstrating end-to-end event sourcing and DDD patterns.

Features

Added internal User domain example with event-sourcing and query capabilities

The internal/user package now provides a complete domain example for modeling an Aggregate using go-eventually. This includes the User aggregate definition with Create and UpdateEmail commands, domain events (UserWasCreated, UserEmailWasUpdated), and Protobuf-based serialization (serde) for both aggregates and events. It also introduces a query capability via a GetByEmail handler that maintains a read-model view indexed by email, updated through event processing. Additionally, test suites are provided to validate aggregate repository persistence (including optimistic locking) and event store append operations.

internal · high confidence

Initial project scaffolding and repository structure

This change establishes the foundational structure of the project, introducing the MIT license, a comprehensive README with usage examples for the Event Sourcing and CQRS patterns, and a Makefile to manage linting, testing, and building across Go workspace modules. It also configures the development and CI environment by adding Nix flake definitions for reproducible tooling, GitHub Actions workflows, and configuration files for golangci-lint v2, Codecov, release-please, and Renovate. Additionally, it removes legacy internal interfaces (EventApplier, Event) that are no longer part of the public API.

(repo-wide) · high confidence

Introduces generic serialization and deserialization interfaces with JSON, Protobuf, and chaining support

The \serde\ package now provides a generic framework for serializing and deserializing data, featuring core interfaces (\Serializer\, \Deserializer\, \Serde\) and a \Fused\ type to combine them. Users can immediately use built-in implementations for JSON (\NewJSON\) and Protobuf (\NewProto\, \NewProtoJSON\) to convert data to and from byte arrays. Additionally, a \Chained\ type allows composing multiple serialization steps, enabling complex data transformations by linking separate serde instances together.

serde · high confidence

Introduction of the event package with iterator-based streaming and in-memory store

This change introduces the \event\ package, providing the core types and interfaces for Domain Events, including \Event\, \Envelope\, \Persisted\, and the \Store\ interface. A key behavioral shift is the adoption of Go 1.23+ iterators for event streaming via the \Stream\ type, replacing previous channel-based approaches to allow for more flexible and cancellable event consumption. The package includes a thread-safe \InMemoryStore\ implementation that supports optimistic concurrency checks during event appending and version-based filtering during streaming, along with a \TrackingStore\ wrapper for testing purposes.

event · high confidence

Introduction of versioning and optimistic concurrency types

The version package now provides core types for managing Event Stream versions and handling optimistic concurrency. It introduces the Version type (uint32) to represent stream length, a Selector struct for specifying event stream slices, and Check interfaces (CheckAny and CheckExact) to control concurrency validation during event appending. Additionally, a ConflictError type is included to report mismatches between expected and actual stream versions.

version · high confidence

New TodoList example demonstrating Connect, DDD, and Event Sourcing

Added a new \todolist\ example in the \examples/todolist\ directory that exercises the \go-eventually\ library's DDD and Event Sourcing primitives end-to-end. The example includes a Connect-based service exposing CRUD operations for a TodoList aggregate (create list, add/delete items, mark as done/pending, get list) over unencrypted HTTP/2, complete with gRPC health and reflection. It demonstrates key patterns such as client-generated IDs for idempotency, in-memory event sourcing via \event.NewInMemoryStore\, BDD-style command and aggregate scenarios, and error mapping to Connect codes. The example also includes the necessary \buf\ configuration for protobuf generation and generated Go code for the service and messages.

examples · high confidence

New message envelope and iterator-backed stream types

The message package now exposes a generic Message interface and an Envelope type that bundles messages with optional metadata, allowing users to route and carry context with their events or commands. Additionally, a new Stream type provides a single-use, iterator-backed sequence for consuming message streams, replacing previous channel-based approaches with Go's standard range-loop iteration pattern while handling producer errors and consumer abandonment gracefully.

message · high confidence

New query package with handler interfaces and testing scenarios

The 'query' package has been introduced to support Domain Queries within the application. It defines the core types for queries (Query, Envelope) and the Handler interface that query handlers must implement. Additionally, it provides a Scenario API for testing query handlers, allowing developers to set up preconditions using persisted events and verify query results or errors in a structured way.

query · high confidence

OpenTelemetry instrumentation for event store and aggregate repository

The opentelemetry package now provides \InstrumentedEventStore\ and \InstrumentedRepository\ wrappers that automatically emit OpenTelemetry traces and metrics for event store operations (Stream, Append) and aggregate repository operations (Get, Save). Users can configure custom Tracer and Meter providers via \WithTracerProvider\ and \WithMeterProvider\ options, or rely on the global defaults. The instrumentation records duration histograms in milliseconds, spans with specific names (e.g., \event.Store.Stream\, \aggregate.Repository.Get\), and attributes such as stream ID, aggregate type, and error status.

opentelemetry · high confidence

PostgreSQL integration for event sourcing and aggregate storage

This release introduces the PostgreSQL backend for the go-eventually library, providing an \AggregateRepository\ and an \EventStore\ to persist domain events and aggregate states. The implementation uses \pgx/v5\ connection pooling and enforces \SERIALIZABLE\ transaction isolation levels to ensure data consistency during concurrent updates. It includes database migrations for \event\_streams\, \events\, and \aggregates\ tables, with support for custom table names via functional options.

postgres · high confidence

Removals

Removal of in-memory event store implementation

The in-memory event store implementation and its associated tracking utilities have been removed from the codebase. This deletes the \inmemory\ package, including the \EventStore\ struct that provided an in-memory backend for the event store interface, along with its test suite and the \TrackingEventStore\ helper used for recording events during testing.

inmemory · high confidence

Removal of legacy EventStore interface definitions

The file defining the core \EventStore\ API contract, including the \Store\, \Streamer\, \Subscriber\, \Typed\, and \Instanced\ interfaces, has been removed from the codebase. This deletion eliminates the previous interface structure that relied on a custom \Event\ struct wrapping \eventually.Event\ and a channel-based \EventStream\ type, indicating a shift in how the event store API is structured or exposed to consumers.

eventstore · high confidence

Removal of subscription package

The subscription package has been removed from the codebase, eliminating the CatchUp subscription implementation and its associated interfaces (Subscription, CheckpointGetter, CheckpointStorer). Users relying on this specific subscription mechanism will need to adopt alternative approaches provided by other parts of the library.

subscription · high confidence

Behavioural changes

Aggregate package refactored to use Go generics and new event stream APIs

The aggregate package has been rewritten to leverage Go generics, replacing the previous non-generic interfaces (such as the old \Root\ and \Type\ structs) with generic definitions like \Root\[I ID\]\ and \Type\[I ID, T Root\[I\]\]\. This change introduces a new \EventSourcedRepository\ implementation that utilizes the updated \event.Stream\ iterator for rehydrating state, replacing the older channel-based streaming and \eventstore.Typed\ dependencies. The public API has shifted from the previous \Record\ and \RecordWithMetadata\ functions to a new \RecordThat\ function that accepts variadic \event.Envelope\ arguments, and the repository interface is now split into composable \Getter\ and \Saver\ components.

aggregate · high confidence

Command package refactored to use generics and typed envelopes

The command package has been refactored to replace the previous non-generic \Command\ interface and \SimpleBus\ with a generic \Envelope\[T\]\ type and a generic \Handler\[T\]\ interface. This change introduces strong typing for command handlers, allowing them to receive specific command types rather than a generic interface, and updates the scenario testing API to work with these generic types and \event.Persisted\ structures instead of raw event slices. The old \bus.go\ and \handler.go\ implementations have been removed in favor of this new generic approach.

command · high confidence

Dependencies

Add Go 1.26-based todolist example and update core dependencies

The repository now includes a new Go 1.26-based todolist example application, establishing a modern baseline for users. The core library has been upgraded to Go 1.26 and updated to version v0.4.0, with a retract directive added for the premature v0.4.0 release. Key dependencies have been bumped to their latest versions, including the PostgreSQL driver (github.com/jackc/pgx/v5 to v5.11.0), OpenTelemetry components (v1.46.0), and testcontainers (v0.44.0), while the module path has been updated to github.com/get-eventually/go-eventually.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 66 → 69 (+3.2)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 100 → 100 (+0.1)
  • Architecture 100 → 97 (-3.1)
  • Maturity 62 → 64 (+1.5)
  • Readiness 59 → 71 (+11.9)
  • Security 89 → 95 (+6.3)
  • Domain Modelling 100 → 100 (+0.0)
  • Event-Driven 100 → 100 (+0.0)
  • Event Sourcing 61 → 61 (+0.0)

Resolved (14)

  • Coverage not included — suite not readable by the collector
  • Critical CVE: [GHSA redacted] (go.mod)
  • Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
  • Duplicated block (11 lines × 2) (aggregate/scenario.go)
  • High CVE: [GHSA redacted] (go.mod)
  • High CVE: [GHSA redacted] (go.mod)
  • Medium CVE: GO-2026-4599 (go.mod)
  • Medium CVE: GO-2026-5004 (go.mod)
  • Medium CVE: GO-2026-5970 (go.mod)
  • Medium vulnerability: GO-2026-5841 (go.mod)
  • No exposed public API
  • Off-boarding risk: anonymized user #1
  • Test reliability not included
  • The 'How to Use' section is cut off mid-sentence inside the Aggregate Root pattern description ('It ... reuses the same repository's Get'), so the outline promises a Persistence with Aggregate Repository interface and CQRS sections are not flagged as missing. (README.md)

New (11)

  • Duplicated block (11 lines × 2) (aggregate/scenario.go)
  • High CVE: [GHSA redacted] (go.mod)
  • High CVE: [GHSA redacted] (go.mod)
  • Low cohesion: ConnectServiceHandler (LCOM4 6) (examples/todolist/internal/todolist/connect_handler.go)
  • Medium CVE: GO-2026-4599 (go.mod)
  • Medium CVE: GO-2026-5004 (go.mod)
  • Medium vulnerability: GO-2026-5932 (go.mod)
  • Outdated: connectrpc.com/connect
  • Outdated: connectrpc.com/grpchealth
  • Outdated: github.com/get-eventually/go-eventually
  • Outdated: github.com/golang-migrate/migrate/v4

Changes since last survey

  • 13 commits — 3 feature/other, 10 fixes

By area

  • (root) — 12 commits
  • .github/workflows — 1 commit

Notable commits

  • fix: fix(deps): update all non-major dependencies (#355)
  • fix: fix(deps): update all non-major dependencies to v0.44.0 (#353)
  • fix: fix(deps): update all non-major dependencies to v1.45.0 (#351)
  • fix: fix(deps): update all non-major dependencies to v1.46.0 (#361)
  • fix: fix(deps): update google.golang.org/genproto digest to 1b09341 (#356)
  • fix: fix(deps): update google.golang.org/genproto digest to c8921c7 (#348)
  • fix: fix(deps): update google.golang.org/genproto digest to ec0a776 (#354)
  • fix: fix(deps): update google.golang.org/genproto digest to f8649dd (#358)
  • fix: fix(deps): update module github.com/jackc/pgx/v5 to v5.11.0 (#362)
  • fix: fix(deps): update module github.com/stretchr/testify to v1.12.1 (#359)
  • change: chore(deps): bump github.com/moby/go-archive from 0.2.0 to 0.3.0 (#357)
  • change: chore(deps): update actions/checkout digest to 3d3c42e (#350)
  • change: chore: release main (#352)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

get-eventually/go-eventually was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 09cfa5e7553897127ce3261791e9f0529a32713b — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-fa71c66cabd8.