Skip to content
CAI
Software that uses CAICheck a score

parody/chronik

47.9

Weak · 21 September 2026

2.1k

lines of production code

Elixir

primary language

7

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

Chronik is an event sourcing library for Elixir that manages aggregate state, projections, and domain event persistence. It provides a GenServer-based architecture for handling commands and events, with configurable storage adapters (Ecto, ETS) and pub/sub capabilities. The system supports multi-entity commands, event compression, and strict/consistent projection modes.

Features

Introduce core Chronik modules for aggregates, projections, and event storage

The library now provides foundational modules for building event-sourced applications. \Chronik.Aggregate\ replaces previous macro-based definitions with a GenServer-based approach for managing aggregate state and commands. \Chronik.Projection\ enables read models to subscribe to domain events, supporting both eventual and strict consistency modes. \Chronik.Store\ defines the interface for persisting and retrieving domain events, while \Chronik.PubSub\ handles event broadcasting. The refactoring removes the \Chronik.Macros\ and \Chronik.Supervisor\ modules, simplifying the API and configuration.

lib/chronik · high confidence

Removals

Removed Store and Supervisor modules from the Chronik library

The Chronik.Store and Chronik.Store.Supervisor modules have been removed from the codebase. This change eliminates the previous implementation of the event store and its associated supervisor, likely as part of a larger refactoring of the Chronik library's internal architecture.

lib/chronik/store · high confidence

Behavioural changes

Added CI, formatter, and documentation badges

The project now includes a Travis CI configuration for automated testing across multiple Elixir and OTP versions, a .formatter.exs file to standardize code formatting, and build, documentation, and Hex.pm version/download badges in the README.

(repo-wide) · high confidence

Added multi-entity command support and refactored aggregate lifecycle

Chronik now supports generating a single command that affects multiple entities via the new \Chronik.Aggregate.Multi\ module, which allows defining transaction-like updates across several aggregates. Additionally, the \Chronik.Aggregate\ module has been refactored to use modern Elixir child specs for process supervision, and the supervisor has been updated to use the new \start\_link\ signature, improving how aggregate processes are started and managed.

lib/chronik/aggregate · medium confidence

Database schema updates for versioning and binary storage

The database schema was updated to support larger version numbers and binary data storage. Specifically, the \version\ and \aggregate\_version\ fields in the \domain\_events\ table, as well as the \snapshot\_version\ field in the \aggregates\ table, were changed from integer to bigint types to accommodate larger values. Additionally, the \snapshot\ column in the \aggregates\ table and the \domain\_event\ and \domain\_event\_json\ columns in the \domain\_events\ table were modified to use a MEDIUMBLOB type, allowing for larger binary payloads. The migration files were also reorganized under the \priv/chronik\_repo/migrations\ directory.

priv · medium confidence

Ecto adapter supports configurable compression, custom JSON library, and streaming

The Ecto adapter now supports configurable compression for aggregate snapshots and domain events, with defaults at 0 (disabled). It allows specifying a custom JSON library (defaulting to Jason) and can disable JSON serialization entirely. The adapter also introduces streaming capabilities for domain events and a new \current\_version/1\ function for projections that do not require replay. Additionally, the \Blob\ type handles binary storage, and the \DomainEvents\ schema includes a \version\ field.

lib/chronik/store/adapters/ecto · medium confidence

Projection API renamed and restructured

The Projection module and its associated supervisor have been removed, and the public API for implementing projections has changed. The \next\_state\ callback has been renamed to \handle\_event\, and the signature has changed to receive an \EventRecord\ containing the \domain\_event\ rather than the event directly. Additionally, the \use Chronik.Projection\ macro has been replaced with \@behaviour Chronik.Projection\, and the \start\_link\ function is now explicitly defined in the implementing module rather than generated by the macro.

lib/chronik/projection · high confidence

Refactor ETS store adapter with new public API and internal structure

The ETS store adapter has been refactored to expose a cleaner public API for interacting with the event store. New methods such as \append\, \fetch\, \snapshot\, \get\_snapshot\, \remove\_events\, \fetch\_by\_aggregate\, \current\_version\, \stream\_by\_aggregate\, and \stream\ are now explicitly defined, replacing the previous implicit GenServer call patterns. Internally, the \start\_link\ function has been moved to the \Store/PubSub\ module, and the module's documentation has been removed. The implementation also introduces a \compare\_version\ function to handle version comparisons, including string-based versions, and updates logging to use \Utils.debug\ instead of the standard \Logger\. These changes streamline how clients interact with the ETS adapter while maintaining the underlying ETS table management.

lib/chronik/store/adapters/ets · medium confidence

Refactor Ecto repository configuration and add compression settings

The Ecto repository configuration has been moved from the main :chronik key to the specific :Chronik.Store.Adapters.Ecto.ChronikRepo key, and the database connection now uses a CHRONIK\_REPO\_URL environment variable instead of hardcoded credentials. Additionally, new configuration keys have been added for Chronik.Store.Adapters.Ecto to control aggregate and domain event compression levels, and to specify the JSON library (Jason) for serialization.

config · high confidence

Refactor PubSub adapter to use conditional logging and handle strict projection failures

The PubSub adapter has been refactored to replace direct Logger calls with a conditional logging mechanism via Chronik.Utils, meaning debug output is now controlled by configuration rather than being always-on. Additionally, the broadcast method now explicitly handles non-:ok results from strict projections by logging a warning, ensuring that failed projections are acknowledged rather than silently ignored or causing unhandled errors.

_lib/chronik/pub\sub · high confidence

Refactored Aggregate and Projection APIs to remove macros and support custom supervision trees

The example application's aggregate and projection modules have been refactored to remove the \Chronik.Macros\ and \use\ declarations in favor of explicit behaviors (\@behaviour\). Specifically, the \Cart\ aggregate now uses \Aggregate.command\ and \handle\_event\/\handle\_command\ functions instead of macro-generated methods. Projections like \CartsState\ and \Echo\ now implement the \Chronik.Projection\ behavior and include a \child\_spec/1\ function, allowing client code to insert them into their own supervision trees rather than relying on the library's default supervision. Additionally, the example's configuration has been updated to use an environment variable for the database URL.

example · high confidence

Updated module documentation and type specifications

The Chronik module's documentation has been restructured to clearly list the four core components (Store, PubSub, Aggregate, Projection) and added a section on configuring debug mode. Additionally, the \id\, \command\, and \domain\_event\ type specifications have been updated to improve clarity and accuracy.

lib · medium confidence

Test coverage

Added tests for the Chronik Store module; Updated test helper to use new Chronik.Store and Chronik.PubSub modules; Updated test suite for Chronik aggregates and projections.

Dependencies

Update Elixir version requirement and dependencies

The project now requires Elixir 1.6 or higher (previously 1.5-rc). Several dependencies have been updated or added: \ex\_doc\ to 0.19, \dialyxir\ to 1.0.0-rc.3, \excoveralls\ to 0.10, \credo\ to 0.10, \jason\ to 1.1, and \confex\ to 3.2.3. Additionally, the \inch\_ex\ package was added for documentation badges, and the \poison\ dependency was replaced by \jason\ for JSON handling.

(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 51 → 48 (-3.3)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 99 → 99 (-0.1)
  • Architecture 100 → 76 (-24.5)
  • Maturity 31 → 31 (+0.0)
  • Readiness 40 → 46 (+5.8)
  • Security 97 → 78 (-18.9)

Resolved (13)

  • Coverage not included — suite not readable by the collector
  • Dependency hygiene not measured — no supported dependency manifest was read
  • Duplicated block (10 lines × 2) (lib/chronik/projection.ex)
  • Duplicated block (13 lines × 2) (lib/chronik/store/adapters/ecto/ecto.ex)
  • Duplicated block (15 lines × 2) (lib/chronik/store/adapters/ecto/ecto.ex)
  • Duplicated block (15 lines × 2) (lib/chronik/store/adapters/ets/ets.ex)
  • High CVE: [GHSA redacted] (mix.lock)
  • Installation instructions point to mix.exs but do not show how to run a simple example. (README.md)
  • Medium CVE: EEF-[CVE redacted] (mix.lock)
  • No exposed public API
  • Test reliability not included
  • The README states 'A lightweight event sourcing micro framework for Elixir' but never explains what event sourcing means for the project and what features Chronik provides. (README.md)
  • dormant codebase — no living knowledge left to concentrate

New (20)

  • Documentation: no usage examples (README.md)
  • Duplicated block (12–17 lines × 2) (lib/chronik/projection.ex)
  • Duplicated block (16 lines × 2) (lib/chronik/store/adapters/ecto/ecto.ex)
  • Duplicated block (18 lines × 2) (lib/chronik/store/adapters/ets/ets.ex)
  • Duplicated block (21 lines × 2) (lib/chronik/store/adapters/ecto/ecto.ex)
  • FixmeComment (test/chronik/projection/projection_test.exs)
  • High CVE: [GHSA redacted] (mix.lock)
  • Medium CVE: EEF-[CVE redacted] (mix.lock)
  • No SBOM
  • No artifact signing
  • No build provenance
  • No dependency advisory monitoring
  • Outdated: credo
  • Outdated: dialyxir
  • Outdated: ex_doc
  • Outdated: excoveralls
  • Outdated: excoveralls
  • Outdated: jason
  • TodoComment (lib/chronik/aggregate.ex)
  • TodoComment (test/chronik/pub_sub/pub_sub_test.exs)

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

Survey your own repository

parody/chronik 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 ec2dbc5b415433d8732575db6ce24b02ebaf5da3 — 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-b84573e22831.