Skip to content

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.

  • 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.

Client command

Read models

Decide and build constraints

Append events

Event store

Projections

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.

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.

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

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

Client command

Arc command validation

Read models

Decide and build constraints

Append events

Event store

Projections

Concurrency scopes

  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.