Architecture Decision Record

ADR-0035: Message Lineage Uses Correlation and Causation in the Envelope

Status: Accepted · Date: 2026-03-06

Status: Accepted

Date: 2026-03-06

Context

BSFG already separates envelope from fact. In messaging patterns, a correlation identifier is used to link a message to the conversation or request it belongs to, and message-history style metadata belongs in headers rather than the body because it is system-level control information, not application content. :contentReference[oaicite:0]{index=0}

BSFG needs a stable way to express lineage without turning the fact body into transport history. Two distinct questions must remain separate:

Options Considered

Option Description Benefits Drawbacks
No lineage fields Omit both correlation and causation; infer lineage from payloads or external systems.

|

| | Correlation only | Carry a single workflow or conversation identifier in the envelope. |

|

| | Causation only | Carry only the immediate predecessor message ID. |

|

| | Correlation and causation in the envelope (Selected) | Carry both a broader correlation identifier and an immediate causation identifier as first-class envelope fields. |

|

|

Decision

BSFG uses both correlation_id and causation_id in the envelope.

correlation_id = broader conversation / workflow / batch interaction
causation_id   = immediate prior message that caused this message

These are envelope fields, not fact fields.

Example:

message_id     = msg-9007
correlation_id = batch-B1042-release-flow
causation_id   = msg-9006

This keeps lineage explicit while preserving the rule that the fact body carries domain meaning, not transport history. Header-level lineage is consistent with established messaging patterns. :contentReference[oaicite:1]{index=1}

Consequences

Benefits:

Tradeoffs: