Skip to content

fix(dispatcher): honor caller-supplied :causation_id on persisted events - #103

Merged
yordis merged 4 commits into
mainfrom
yordis/fix-dispatcher-causation-id
May 14, 2026
Merged

yordis merged 4 commits into
mainfrom
yordis/fix-dispatcher-causation-id

Conversation

@yordis

@yordis yordis commented May 14, 2026

Copy link
Copy Markdown
Member
  • Without this, the persisted causation_id always points at the dispatched command's command_uuid, which is not stored in the event store — so a chain of causation cannot be reconstructed from events alone for any flow where a process manager or event handler dispatches follow-up commands.
  • Mirrors the spirit of upstream commanded/commanded#652, which is still open; we apply it now rather than wait.

The execution context dropped pipeline.causation_id and used command_uuid,
breaking chain-of-causation reconstruction from events alone for any
multi-event flow where a process manager or event handler dispatches
follow-up commands.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@cursor

cursor Bot commented May 14, 2026 •

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes how causation_id is derived in the command execution context, which affects persisted event metadata and traceability across the system. Risk is moderate because it can alter causation chains relied on by downstream consumers and observability tooling.

Overview
Event causation_id now honors the caller-supplied dispatch option. The dispatcher’s execution context uses pipeline.causation_id when present, falling back to command_uuid only when it isn’t provided, so persisted events reflect the intended causation chain (e.g., event-handler/process-manager follow-up commands).

Tests are updated/expanded to cover both fallback and explicit :causation_id behavior, including event-handler dispatched commands. CI workflow actions are also pinned to specific commit SHAs (e.g., actions/checkout, actions/cache, erlef/setup-beam) for supply-chain hardening.

Reviewed by Cursor Bugbot for commit efb195f. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented May 14, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Rate limit exceeded

@yordis has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 26 minutes and 49 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 019795a5-bca4-41dc-a849-7dafde962da1

📥 Commits

Reviewing files that changed from the base of the PR and between ad6cd9d and efb195f.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • lib/commanded/opentelemetry/aggregate.ex
  • lib/commanded/opentelemetry/event_handler.ex

Walkthrough

This PR enhances command dispatch to support explicit causation_id propagation. The dispatcher's execution context construction now examines the command payload for an optional causation_id and applies it, defaulting to the command_uuid when absent. Tests verify both behaviors and confirm causation_id chains through event handler dispatch.

Changes

Causation ID Propagation

Layer / File(s) Summary
Dispatcher causation_id handling and tests
lib/commanded/commands/dispatcher.ex, test/commands/correlation_causation_test.exs
The dispatcher's to_execution_context/2 function now extracts causation_id from command payloads and applies it in ExecutionContext, falling back to command_uuid when absent. Tests split into two cases: fallback behavior when causation_id is not provided, and explicit override when it is. Event handler dispatch tests verify that causation_id chains through handled events using the prior event's event_id.

Sequence Diagram

sequenceDiagram
  participant Client
  participant Dispatcher
  participant ExecutionContext
  participant EventHandler
  participant Event

  Client->>Dispatcher: dispatch(command with optional causation_id)
  Dispatcher->>Dispatcher: extract command from Pipeline
  Dispatcher->>ExecutionContext: build with causation_id from payload || command_uuid
  ExecutionContext->>EventHandler: pass causation_id in context
  EventHandler->>Event: create with causation_id from context
  Event-->>Client: event persisted with causation_id
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A causation sprout, both explicit and true,
Commands now carry what caused them through,
From payload to context, from context to event—
A chain of identity, perfectly sent!
Tests split the cases with care and delight,
Fallback or chosen, the causation's just right! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: honoring caller-supplied :causation_id on persisted events in the dispatcher.
Description check ✅ Passed The description is directly related to the changeset, explaining the issue being fixed and the impact on event causation tracking.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yordis/fix-dispatcher-causation-id

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The org policy blocks the conventional-commits action and any tag-pinned
reference, so CI has been failing at startup on every PR since the
policy landed.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/commands/correlation_causation_test.exs (1)

1-1: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in module name.

The module name has a typo: CorrelationCasuationTest should be CorrelationCausationTest (missing 'a' in "Causation").

📝 Proposed fix
-defmodule Commanded.Commands.CorrelationCasuationTest do
+defmodule Commanded.Commands.CorrelationCausationTest do
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/commands/correlation_causation_test.exs` at line 1, Rename the
misspelled module identifier Commanded.Commands.CorrelationCasuationTest to
Commanded.Commands.CorrelationCausationTest in the test file so the module name
matches the intended spelling; update the module declaration (defmodule
Commanded.Commands.CorrelationCasuationTest -> defmodule
Commanded.Commands.CorrelationCausationTest) and any references to that module
in the file or tests to use the corrected name.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@test/commands/correlation_causation_test.exs`:
- Line 1: Rename the misspelled module identifier
Commanded.Commands.CorrelationCasuationTest to
Commanded.Commands.CorrelationCausationTest in the test file so the module name
matches the intended spelling; update the module declaration (defmodule
Commanded.Commands.CorrelationCasuationTest -> defmodule
Commanded.Commands.CorrelationCausationTest) and any references to that module
in the file or tests to use the corrected name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 370b76ab-6dda-4b57-b8f9-00cd173dbc25

📥 Commits

Reviewing files that changed from the base of the PR and between 3761509 and ad6cd9d.

📒 Files selected for processing (2)
  • lib/commanded/commands/dispatcher.ex
  • test/commands/correlation_causation_test.exs

yordis added 2 commits May 14, 2026 14:31
…sted

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Pre-existing drift surfaced by the first CI run since the action allowlist
was unblocked; unrelated to the dispatcher fix on this branch.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis merged commit 13f88f3 into main May 14, 2026
4 of 5 checks passed
@yordis
yordis deleted the yordis/fix-dispatcher-causation-id branch May 14, 2026 19:06
This was referenced Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant