Skip to content

FR: events emit projections — resolve the ADR-0007 vs ADR-0028 contradiction (a stream is a channel, not a source) #212

Description

@dmealing

Summary

There is a live contradiction between two accepted decisions, and it should be resolved before a streaming/CDC backend lands:

  • ADR-0007's source catalog includes source.event @topic @role:publish (CDC / outbox) — a stream as a source.
  • ADR-0028 rules that "message topics/queues are channels, not sources — they live at the surface layer as binding.* on operations (AsyncAPI's model), never in source.*."

Both are currently on the books.

Resolution — toward ADR-0028: a stream is a channel, not a source

A source.* answers "where can this object's data be READ from" — it must be addressable state the tool can get-by-id against and that a verify --db-style drift check can inspect as a schema. A topic is transport: you cannot get-by-id against it, and no drift check can inspect "its contents." So:

  1. Amend ADR-0007's catalog: drop event as a source paradigm (and remove the publish role's source-side home).
  2. Model emission at the surface layer FR-024 §9 already reserved: an event/streaming api sibling (api.eventing / operation.event / binding.messaging) whose payload references a projection.

This lands a clean CQRS + events symmetry: queries return projections, commands take values, events emit projections. A CDC event's shape is a projection (passthrough/computed origins evaluated at emit time); only its exposure is a channel binding instead of a source — the projection concept still does all the shape work.

Two edge cases, pre-decided

  1. Windowed / stateful stream aggregation (Kafka-Streams-style folds over history) violates the meta migrate: aggregate/monitoring read-model views can't be modeled as projections — 4 missing origin/field capabilities #195 determinism contract (a pure derivation over the current entity graph). It is stream processing, not projection — stays out permanently.
  2. A compacted changelog treated as a state store (KTable) is functionally addressable. If ever needed, it enters as an ordinary read-only-@kind paradigm source — because the doctrine has a principled escape: a stream becomes a source exactly when it is treated as addressable state. Record this clause in the ADR so the door is principled, not ad hoc.

Scope

Amend ADR-0007 (remove the event paradigm + the publish source role); design the reserved api eventing sibling (operation.event + binding.messaging + a payload→projection reference); record the "stream becomes a source when addressable" escape clause. No change to the projection/entity/value taxonomy — this is purely about where event exposure lives (surface layer, not source layer).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:metamodelMetamodel vocabulary / loaderenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions