Table of Contents

Dynamic Consistency Boundary in Chronicle

Chronicle was designed to support decision-scoped consistency long before DCB was named. You can append events independently, project read models from disparate streams, and still enforce consistency for the specific facts used to decide.

Mapping DCB to Chronicle

  • Decision facts are read from projections or other read models.
  • Constraints validate that the decision is still valid when appending events.
  • Concurrency scopes let you define which streams or partitions must be checked together.
  • Projections update read models asynchronously after the append.
flowchart LR
    A[Client command] --> B[Read models]
    B --> C[Decide and build constraints]
    C --> D[Append events]
    D --> E[Event store]
    D --> F[Projections]
    F --> B
    C --> G[Concurrency scopes]
    G --> D

Constraints and concurrency scopes

Constraints are the primary way to express decision correctness. They are evaluated at append time, so the decision is validated against the most recent events. Concurrency scopes complement this by defining which streams must be checked together to keep the decision consistent without forcing a single aggregate boundary.

Metadata tags

Chronicle uses formalized metadata tags to scope concurrency control. These tags are indexed and used by Chronicle when evaluating concurrency scopes:

  • EventSourceId: Unique identifier for the event source
  • EventSourceType: Overarching, binding concept (e.g., Account)
  • EventStreamType: A concrete process related to event source type (e.g., Onboarding, Transactions)
  • EventStreamId: A marker to separate independent streams for a stream type (e.g., Monthly, Yearly)
  • EventTypes: Specific event types to scope concurrency to

For more details, see Formalized metadata tags for concurrency.

You can also attach custom tags to events when appending for categorization and filtering purposes.

Aggregate roots

If you prefer an aggregate root style, Chronicle supports it through Cratis.Arc. See aggregate roots support.

Arc command validation flow

When using Arc, command validation runs before decision evaluation. See Arc validation for details.

flowchart LR
    A[Client command] --> B[Arc command validation]
    B --> C[Read models]
    C --> D[Decide and build constraints]
    D --> E[Append events]
    E --> F[Event store]
    E --> G[Projections]
    G --> C
    D --> H[Concurrency scopes]
    H --> E

Practical flow

  1. Read the projections needed to decide.
  2. Build constraints that capture the decision rule.
  3. Choose concurrency scopes that match the decision boundary.
  4. Append events and let projections update.

Next steps