Skip to content

EnvelopeRegistryService

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Bounded context BC-42 Data & Event Foundations
Platform / plane Data & Event Platform / Data & Event
Deployment granularity module of host · host DataEventFoundations
Status target · ConnectSoft.Factory.DataEvent.Envelopes
Built from connectsoft-microservice · libraries: connectsoft-extensions-messaging-model, connectsoft-extensions-messaging-model-orleans, connectsoft-extensions-persistence-model-nhibernate, connectsoft-extensions-saas-abstractions
Decisions ADR-0012, ADR-0014
Traceability FR-10 FUX-11 NFR-05 NFR-14 XL-02

Purpose and responsibilities

EnvelopeRegistryService makes the event architecture (original design §55, ADR-0012, ADR-0014) enforceable. Every integration event in the model has a topic context.area.vN.event-name with exactly one producer and listed consumers; the registry holds the same facts at runtime with the payload schema versions and their compatibility (backward, forward, full, breaking), and refuses to activate a breaking version until every registered consumer has acknowledged it. It also holds the envelope profile: the port-level envelope fields are identical on every messaging profile (Orleans outbox/inbox, MassTransit on Azure Service Bus, NServiceBus); what differs is the carriage — mirrored transport properties, outbox and inbox table contracts, deduplication window — and that is what the profile records.

Hosts call ResolveTopic at publish time (cached) and, in non-production profiles, ValidateEnvelope before an outbox write.

Context and boundaries

flowchart LR
    S["EnvelopeRegistryService"]
    ControlPlaneApi["ControlPlaneApi"] -->|grpc| S
    StudioBff["StudioBff"] -->|sync-http| S
    S -->|grpc| ArtifactService["ArtifactService"]
    S -. "TopicRegistered" .-> E_TopicRegistered(("event"))
    S -. "SchemaVersionPublished" .-> E_SchemaVersionPublished(("event"))
    S -. "TopicDeprecated" .-> E_TopicDeprecated(("event"))
    S -. "EnvelopeProfileActivated" .-> E_EnvelopeProfileActivated(("event"))
Hold "Alt" / "Option" to enable pan & zoom

The registry is downstream of the architecture model: ModelSync applies the generated topic catalog at release time and reports drift, so the model stays the source of truth and the registry the runtime mirror. Replay is not promised and exactly-once external effects are not promised (ADR-0014); consumers deduplicate on eventId within the profile's window.

Domain model

TopicDefinition — One integration topic: context (the producing bounded context slug), area, version, event name, producing service, registered consumers, the current payload schema version and the envelope profile; mirrors the architecture model and is the runtime truth for publish-time validation. (catalog entry)

Field Type Required Description
topic string yes context.area.vN.event-name
context string yes
area string yes
version int yes
eventName string yes
producer string yes Service id.
consumers list:string yes
currentSchemaVersion string yes
state enum:TopicState yes
registeredAt datetime yes

Invariants:

  • Exactly one producer per topic; the context segment equals the producer's bounded-context slug.
  • A new schema version is Active only if it is backward compatible with the current one or every registered consumer has acknowledged the breaking version.
  • Deprecated topics keep delivering for the deprecation window; Retired topics reject publication.
stateDiagram-v2
    Draft --> Active : Activate
    Active --> Deprecated : Deprecate
    Deprecated --> Retired : WindowElapsed
Hold "Alt" / "Option" to enable pan & zoom

Events: TopicRegistered, SchemaVersionPublished, TopicDeprecated · Tables: Topics, SchemaVersions, TopicConsumers · Repository: TopicDefinitionRepository

EnvelopeProfile — How the port-level envelope (eventId, schemaVersion, occurredAt, tenantId, projectId, runId, stepId, attemptId, correlationId, causationId, producer, type; ADR-0014) is carried on each messaging profile: body fields, mirrored transport properties, outbox and inbox table contracts, deduplication window. (catalog entry)

Field Type Required Description
profile enum:MessagingProfile yes
envelopeSchemaVersion string yes
transportProperties json yes Mirrored properties, e.g. cs-event-type, cs-tenant-id, cs-schema-version
outboxContract json yes Outbox table columns and dispatcher semantics.
inboxContract json yes Inbox table columns and deduplication window.
dedupWindowHours int yes
active bool yes

Invariants:

  • The envelope fields are identical across profiles; only their carriage differs.
  • No profile promises exactly-once external effects or replay (ADR-0014); consumers deduplicate on eventId within the window.

Events: EnvelopeProfileActivated · Tables: EnvelopeProfiles · Repository: EnvelopeProfileRepository

erDiagram
    TopicDefinition {
        string topic PK
        string context
        string area
        int version
        string eventName
        string producer
        list_string consumers
        string currentSchemaVersion
        enum_TopicState state
        datetime registeredAt
    }
    EnvelopeProfile {
        enum_MessagingProfile profile PK
        string envelopeSchemaVersion
        json transportProperties
        json outboxContract
        json inboxContract
        int dedupWindowHours
        bool active
    }
    SchemaVersion {
        string version

        string schemaRef

        enum_Compatibility compatibility

        datetime publishedAt

        datetime deprecatedAt

    }
    TopicDefinition ||--o{ SchemaVersion : contains
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

SchemaVersion (entity, in TopicDefinition) — One payload schema version with its JSON Schema reference and compatibility against the previous.

Field Type Required Description
version string yes
schemaRef string yes
compatibility enum:Compatibility yes
publishedAt datetime yes
deprecatedAt datetime no

Data model and storage

Store Role Engine / profile Tables
Data & Event foundations store primary azure-sql / nhibernate-sqlserver Topics, SchemaVersions, TopicConsumers, EnvelopeProfiles
Table Owner Columns Indexes
dbo.Topics TopicDefinition 10 2
dbo.SchemaVersions SchemaVersion 7 0
dbo.TopicConsumers TopicDefinition 4 0
dbo.EnvelopeProfiles EnvelopeProfile 8 0

Full DDL: appendix.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
GET /factory/data/topics ListTopics factory.data.read read natural GW-03 Topics with producer, consumers, current schema version and state; filter by context or producer.
GET /factory/data/topics/{topic} GetTopic factory.data.read read natural GW-03 One topic with its schema versions and compatibility history.
PUT /factory/data/topics/{topic} RegisterTopic factory.data.admin production natural GW-03 Register or update a topic (Platform admin; normally applied from the architecture model by the release pipeline).
POST /factory/data/topics/{topic}/schema-versions PublishSchemaVersion factory.data.admin production key-header GW-03 Publish a payload schema version; breaking versions need every consumer's acknowledgement first.
GET /factory/data/envelope-profiles ListEnvelopeProfiles factory.data.read read natural GW-03 Envelope carriage per messaging profile with outbox and inbox contracts.
gRPC service Method Streaming Visibility Side effects Summary
Envelopes ResolveTopic none internal read Resolve an event name to its topic, current schema version and state at publish time.
Envelopes ValidateEnvelope none internal read Validate an envelope and payload against the registered schema version before it enters the outbox (optional strict mode).

Messages

Event Topic Scope / v Aggregate Consumers Summary
TopicRegistered data-foundations.topics.v1.topic-registered integration / 1 TopicDefinition StudioBff, AuditService A topic was registered or its producer or consumers changed.
SchemaVersionPublished data-foundations.topics.v1.schema-version-published integration / 1 TopicDefinition StudioBff, AuditService A payload schema version is active.
TopicDeprecated data-foundations.topics.v1.topic-deprecated integration / 1 TopicDefinition StudioBff, AuditService A topic entered its deprecation window.
EnvelopeProfileActivated data-foundations.envelopes.v1.envelope-profile-activated integration / 1 EnvelopeProfile StudioBff, AuditService The installation's envelope profile (or its contracts) changed.

TopicRegistered payload:

Field Type Required Description
topic string yes
producer string yes
currentSchemaVersion string yes
state enum:TopicState yes

SchemaVersionPublished payload:

Field Type Required Description
topic string yes
version string yes
compatibility enum:Compatibility yes

TopicDeprecated payload:

Field Type Required Description
topic string yes
retiresAt datetime yes

EnvelopeProfileActivated payload:

Field Type Required Description
profile enum:MessagingProfile yes
envelopeSchemaVersion string yes
Command Handled by Result events Summary
RegisterTopic TopicDefinition TopicRegistered
PublishSchemaVersion TopicDefinition SchemaVersionPublished

None modelled

No consumed events are modelled for this item yet.

Workers and jobs

Worker Trigger Output events Retry Idempotency key Summary
ModelSync manual on release of the architecture model TopicRegistered, SchemaVersionPublished fixed topic + schemaVersion Applies the topics, producers, consumers and schema references of the architecture model (the generated catalogs) to the registry at release time and reports drift.
DeprecationSweeper schedule 0 2 * * * — none topic + day Retires topics whose deprecation window elapsed.

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

None modelled

No sagas are modelled for this item yet.

sequenceDiagram
    participant REL as Release pipeline
    participant E as EnvelopeRegistryService
    participant C as Consumer service
    participant P as Producer host (outbox writer)
    REL->>E: ModelSync (topics, producers, consumers, schema refs)
    E->>E: compatibility check per schema version
    alt breaking
        E-->>REL: refused until consumers acknowledge
        C->>E: acknowledge schema version
    end
    E-)C: SchemaVersionPublished
    P->>E: ResolveTopic(eventName) → topic, schema version, state
    P->>P: write envelope + payload to outbox (profile contract)
Hold "Alt" / "Option" to enable pan & zoom

Options and configuration

Section Key Type Default Reloadable Secret Summary
DataEvent:Envelopes StrictValidation bool false yes no Validate every outbox write against the schema (on in non-production profiles).
DataEvent:Envelopes DeprecationWindowDays int 90 yes no Days a deprecated topic keeps delivering.

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.data_event.topics updown {topic} state Topics by state.
connectsoft.factory.data_event.envelope_validation_failures counter {event} producer, topic Envelopes rejected by validation.

Security

Authentication client-credentials
Scopes factory.data.read (Read the registry.); factory.data.admin (Register topics and schema versions (Platform admin, release pipeline).)
Roles PlatformAdmin, Operator, Observer
Tenant isolation row-filter
Data classification internal
Max side-effect class production
Secrets —

Dependencies

Outbound

Target Kind Purpose Failure mode Required
ArtifactService grpc JSON Schema documents of payload versions. degrade no

Inbound

Target Kind Purpose Failure mode Required
ControlPlaneApi grpc ResolveTopic and ValidateEnvelope from every host's outbox writer. — yes
StudioBff sync-http Registry views. — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Breaking schema published without acknowledgement compatibility check the publish is refused with the list of unacknowledged consumers none 0

NFR targets

Target Class value (pilot-interactive) Override
latency_p95_ms 2000 —
availability_pct 99.5 —
throughput_rps 50 —
rpo_minutes 15 —
rto_minutes 240 —
cost_class low —

Deployment

Granularity module of host · host DataEventFoundations
Topologies saas-default, hybrid, on-prem, hybrid-compute
Runtime —; replicas —–—
Ports —

Current implementation

Topic naming and the envelope are documented (event envelope, ADR-0014) and typed as run-event-envelope.schema.json; AgentEventEnvelope in code carries a different, older dialect. No registry exists; the generated events catalog is the design-time registry.

Later capabilities

CloudEvents as an optional carriage profile over the port (ADR-0012 note, technology radar); consumer-driven contract tests generated from the registry; topic-level access control for partner subscriptions through A2A.

Decisions and traceability

Family Ids
FR FR-10
FUX FUX-11
NFR NFR-05, NFR-14
XL XL-02