Skip to content

Implement correlation ID stamping for multi-packet responses#371

Merged
leynos merged 11 commits intomainfrom
codex/implement-multi-packet-streaming-responses
Sep 28, 2025
Merged

Implement correlation ID stamping for multi-packet responses#371
leynos merged 11 commits intomainfrom
codex/implement-multi-packet-streaming-responses

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Sep 27, 2025

Summary

  • add a CorrelatableFrame trait and implement it for the built-in Envelope
  • ensure the connection actor stamps multi-packet frames with the originating correlation id and asserts the invariant
  • extend unit/behavioural coverage and update the design notes and roadmap entry

Testing

  • make fmt
  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_68d6d2f14f388322a3d51b04a3b6347d

Summary by Sourcery

Implement and enforce correlation ID stamping on multi-packet responses by introducing a CorrelatableFrame trait, refactoring multi-packet state into a structured context, and augmenting ConnectionActor to apply and assert the correct identifiers.

New Features:

  • Introduce CorrelatableFrame trait for generic frame correlation access and implement it for Envelope
  • Enable stamping of request correlation IDs onto multi-packet frames and end-of-stream terminators via ConnectionActor

Enhancements:

  • Refactor multi-packet channel state into a dedicated MultiPacketContext with built-in stamping configuration and invariants
  • Add debug assertions to enforce correlation ID invariants during multi-packet dispatch

Documentation:

  • Update roadmap and design documents to reflect completed correlation ID stamping feature

Tests:

  • Extend unit tests for CorrelatableFrame and multi-packet stamping behavior
  • Add behavioural and cucumber scenarios to verify correlation propagation and clearing across multi-packet channels

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 27, 2025

Warning

Rate limit exceeded

@leynos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 9 seconds before requesting another review.

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

📥 Commits

Reviewing files that changed from the base of the PR and between f2f115c and c41c403.

📒 Files selected for processing (1)
  • src/connection.rs (15 hunks)

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • New Features
    • Streaming multi-packet responses now propagate the correct correlation ID from the originating request.
    • Supports multi-packet flows without a request correlation ID (IDs are cleared as expected).
    • Terminator/end-of-stream frames correctly apply the expected correlation.
  • Documentation
    • Updated design notes for multi-packet and streaming responses.
    • Roadmap updated to mark Phase 6 correlation handling steps as completed.
  • Tests
    • Added unit, integration, and feature tests covering normal streaming, early receiver closure, no-correlation cases, and error paths.
  • Refactor
    • Internal multi-packet correlation handling simplified and made more robust with debug-time guards.

Walkthrough

Introduce a new CorrelatableFrame trait and implement it for Envelope; wire multi‑packet correlation state into ConnectionActor with set_multi_packet_with_correlation, stamp correlation IDs on multi‑packet frames (with debug assertions), update docs/roadmap, and add tests and BDD/world helpers for multi‑packet scenarios.

Changes

Cohort / File(s) Summary of Changes
Design docs
docs/multi-packet-and-streaming-responses-design.md, docs/roadmap.md
Add design refinement for multi‑packet stamping, mark several Phase 6 correlation checklist items as implemented, and document examples, tests and edge cases (early close, errors).
Correlation trait & exports
src/correlation.rs, src/lib.rs
Add public CorrelatableFrame trait with correlation_id / set_correlation_id; noop impls for u8 and Vec<u8>; add unit tests; re-export trait in lib.rs.
Envelope impl
src/app/envelope.rs
Implement CorrelatableFrame for Envelope (getter/setter for correlation_id) and import trait.
Connection actor wiring
src/connection.rs
Replace prior optional receiver with a MultiPacketContext including stamping mode; tighten generics to F: FrameLike + CorrelatableFrame; add set_multi_packet_with_correlation, install/clear helpers, emit_multi_packet_frame/apply_multi_packet_correlation, debug_assert invariants, and ensure stamping on emit/close/shutdown paths.
Test support changes
src/connection/test_support.rs
Change multi‑packet availability checks from is_some() to is_active() and add unit tests for install/clear behaviour.
Unit & integration tests
tests/correlation_id.rs, tests/features/correlation_id.feature
Add multi‑packet tests and BDD scenarios validating correlation propagation, absent correlation cases, and terminator stamping.
BDD steps & world helpers
tests/steps/correlation_steps.rs, tests/world.rs
Refactor CorrelationWorld to use Option<u64> expected; add process_multi for multi‑packet channels; add steps for no‑correlation and multi processing; update verify to handle Some/None.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant Conn as ConnectionActor
  participant MP as Multi-packet Channel
  participant Frame as Frame (CorrelatableFrame)
  participant Out as Outbound Queue

  Client->>Conn: set_multi_packet_with_correlation(rx, correlation_id?)
  Note over Conn: install_multi_packet(rx) and store optional expected correlation

  loop Drain multi-packet frames
    MP-->>Conn: next Frame
    Conn->>Frame: apply_multi_packet_correlation(frame)
    alt correlation present
      Note right of Conn #dff2d8: set correlation_id on frame\ndebug_assert stamped id == expected
    else no correlation
      Note right of Conn #f7f0f0: leave frame unchanged
    end
    Conn->>Out: enqueue Frame
  end

  Conn->>Conn: on channel close or shutdown -> clear_multi_packet()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A little id rides each packet’s song,
Stamped and tracked as streams roll along.
Debug asserts hum to guard what’s known,
Channels close tidy when seeds are sown.
Tests applaud; the queues march on.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed Recognise that the title clearly summarises the main change by stating “Implement correlation ID stamping for multi-packet responses”, which concisely and accurately reflects the feature introduced without extraneous detail.
Description Check ✅ Passed Confirm that the description thoroughly outlines the introduction of the CorrelatableFrame trait, the stamping behaviour in ConnectionActor, design and roadmap updates, and the extended testing, making it directly relevant to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Sep 27, 2025

Reviewer's Guide

This PR extends the connection actor to propagate request-level correlation IDs onto multi-packet response frames by introducing a generic stamping trait, encapsulating channel state and stamping config, adding a dedicated API and stamping logic with debug invariants, and covering the behavior with new tests and updated docs.

File-Level Changes

Change Details Files
Abstract correlation stamping via a new trait
  • Define CorrelatableFrame trait with accessors
  • Implement it for Envelope and noop for basic types
  • Expose the trait in the public API
src/correlation.rs
src/app/envelope.rs
src/lib.rs
Encapsulate multi-packet channel and stamping state
  • Replace multi_packet Option with MultiPacketContext struct
  • Add methods to install, clear, and query channel and correlation state
src/connection.rs
Add stamping API and integrate stamping logic
  • Introduce set_multi_packet_with_correlation, clear_multi_packet, apply_multi_packet_correlation
  • Adjust set_response to use new context
  • Embed stamping calls and debug_asserts in poll loop, frame processing, and termination
src/connection.rs
Expand test coverage for correlation stamping
  • Add unit and behavioral tests in tests/correlation_id.rs
  • Update world.rs and cucumber steps for multi-packet scenarios
  • Add new feature scenarios in tests/features/correlation_id.feature
tests/correlation_id.rs
tests/world.rs
tests/steps/correlation_steps.rs
tests/features/correlation_id.feature
Update design and roadmap documentation
  • Mark correlation stamping tasks as completed in roadmap
  • Add implementation notes and invariant assertions in design doc
docs/roadmap.md
docs/multi-packet-and-streaming-responses-design.md
Adjust test support for multi-packet queue
  • Change has_multi_queue to use is_active on new context
src/connection/test_support.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and found some issues that need to be addressed.

  • Consider replacing the boxed closure stamper with a simple stored Option and stamping directly in apply_multi_packet_correlation to eliminate dynamic dispatch and simplify the code.
  • The reset of multi_packet_stamper and multi_packet_correlation is scattered across several branches – consolidate the teardown into install_multi_packet (or a dedicated clear method) to avoid potential cleanup gaps.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider replacing the boxed closure stamper with a simple stored Option<u64> and stamping directly in apply_multi_packet_correlation to eliminate dynamic dispatch and simplify the code.
- The reset of multi_packet_stamper and multi_packet_correlation is scattered across several branches – consolidate the teardown into install_multi_packet (or a dedicated clear method) to avoid potential cleanup gaps.

## Individual Comments

### Comment 1
<location> `tests/correlation_id.rs:33-42` </location>
<code_context>
+#[tokio::test]
</code_context>

<issue_to_address>
**suggestion (testing):** Consider adding negative and edge case tests for correlation ID stamping.

Please add tests for cases where the correlation ID is None or pre-set to a different value to ensure robust handling of all scenarios.

Suggested implementation:

```rust
#[tokio::test]
async fn multi_packet_frames_carry_request_correlation_id() {
    let cid = 7u64;
    let (tx, rx) = mpsc::channel(4);
    tx.send(Envelope::new(1, None, vec![1]))
        .await
        .expect("send frame");
    tx.send(Envelope::new(1, Some(99), vec![2]))
        .await
        .expect("send frame");
    drop(tx);
}

// Negative test: correlation ID is None
#[tokio::test]
async fn packet_with_none_correlation_id_is_handled() {
    let (tx, mut rx) = mpsc::channel(1);
    tx.send(Envelope::new(1, None, vec![42]))
        .await
        .expect("send frame");
    drop(tx);

    let mut out = Vec::new();
    // Replace with actual actor invocation as in your codebase
    actor_run(&mut out, &mut rx).await.expect("actor run failed");
    // Expect correlation_id to be None
    assert!(out.iter().all(|e| e.correlation_id().is_none()));
}

// Edge case: correlation ID is pre-set to a different value
#[tokio::test]
async fn packet_with_pre_set_correlation_id_is_preserved() {
    let preset_cid = 12345u64;
    let (tx, mut rx) = mpsc::channel(1);
    tx.send(Envelope::new(1, Some(preset_cid), vec![99]))
        .await
        .expect("send frame");
    drop(tx);

    let mut out = Vec::new();
    // Replace with actual actor invocation as in your codebase
    actor_run(&mut out, &mut rx).await.expect("actor run failed");
    // Expect correlation_id to be the preset value
    assert!(out.iter().all(|e| e.correlation_id() == Some(preset_cid)));
}

```

- Replace `actor_run(&mut out, &mut rx)` with the actual function or method that processes the envelopes and populates `out`, matching your codebase's conventions.
- If your test harness or actor invocation differs, adjust the test body accordingly.
- Ensure that the `Envelope` and `correlation_id()` methods are available and behave as expected.
</issue_to_address>

### Comment 2
<location> `src/connection.rs:124` </location>
<code_context>
     /// This preserves fairness with queued sources.
     /// The actor emits the protocol terminator when the sender closes the channel.
     multi_packet: Option<mpsc::Receiver<F>>,
+    multi_packet_stamper: Option<MultiPacketStamper<F>>,
+    multi_packet_correlation: Option<u64>,
</code_context>

<issue_to_address>
**issue (complexity):** Consider refactoring the three multi_packet-related fields and their helper methods into a single MultiPacketContext struct to centralize logic and simplify state management.

```markdown
You can collapse the three `multi_packet`‐related fields and their helper methods into a single `MultiPacketContext` struct. This centralizes setup/teardown and removes all of the `Option` juggling and manual clears.

1. Define the context in your module:

```rust
type MultiPacketStamper<F> = Box<dyn FnMut(&mut F) + Send + 'static>;

struct MultiPacketContext<F> {
    channel: Option<mpsc::Receiver<F>>,
    stamper: Option<MultiPacketStamper<F>>,
    correlation_id: Option<u64>,
}

impl<F> MultiPacketContext<F> {
    fn set(
        &mut self,
        channel: Option<mpsc::Receiver<F>>,
        stamper: Option<MultiPacketStamper<F>>,
        correlation_id: Option<u64>,
    ) {
        self.channel = channel;
        self.stamper = stamper;
        self.correlation_id = correlation_id;
    }

    fn apply(&mut self, frame: &mut F)
    where
        F: CorrelatableFrame,
    {
        if let Some(stamper) = &mut self.stamper {
            stamper(frame);
        }
    }

    fn clear(&mut self) {
        self.stamper = None;
        self.correlation_id = None;
    }

    fn take_channel(&mut self) -> Option<mpsc::Receiver<F>> {
        self.channel.take()
    }
}
```

2. Collapse your three fields in `ConnectionActor`:

```rust
pub struct ConnectionActor<F, E> {
    //
    multi_ctx: MultiPacketContext<F>,
    //
}
```

3. Update constructors and setters to delegate into the context:

```rust
impl<F, E> ConnectionActor<F, E>
where
    F: CorrelatableFrame,
    E: std::fmt::Debug,
{
    pub fn set_multi_packet(&mut self, channel: Option<mpsc::Receiver<F>>) {
        self.multi_ctx.set(channel, None, None);
    }

    pub fn set_multi_packet_with_correlation(
        &mut self,
        channel: Option<mpsc::Receiver<F>>,
        correlation_id: Option<u64>,
    ) {
        let expected = correlation_id;
        let stamper: MultiPacketStamper<F> = Box::new(move |frame: &mut F| {
            frame.set_correlation_id(expected);
            debug_assert_eq!(
                frame.correlation_id(),
                expected,
                "mismatch…"
            );
        });
        self.multi_ctx.set(channel, Some(stamper), correlation_id);
    }
}
```

4. In your queue‐processing and shutdown paths, replace the manual clears with:

```rust
// in process_queue:
if matches!(kind, QueueKind::Multi) {
    self.multi_ctx.apply(&mut frame);
}

// in handle_closed_receiver / start_shutdown:
if let Some(rx) = self.multi_ctx.take_channel() {
    rx.close();
    state.mark_closed();
}
self.multi_ctx.clear();
```

This collapses all the scattered `multi_packet_*` logic into a single struct with three methods (.set, .apply, .clear), removing repeated assertions and manual clears while preserving behavior.
</issue_to_address>

### Comment 3
<location> `src/connection.rs:254` </location>
<code_context>
+    }
+
+    /// Set or replace the current multi-packet response channel and stamp correlation identifiers.
+    pub fn set_multi_packet_with_correlation(
+        &mut self,
+        channel: Option<mpsc::Receiver<F>>,
</code_context>

<issue_to_address>
**issue (review_instructions):** Add behavioural and unit tests for set_multi_packet_with_correlation and correlation stamping logic.

The new set_multi_packet_with_correlation method and related correlation stamping logic require both behavioural and unit tests to verify correct operation and guard against regressions. Please add targeted tests that exercise this functionality, including debug assertion coverage.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*`

**Instructions:**
For any new feature or change to an existing feature, both behavioural *and* unit tests are required.

</details>
</issue_to_address>

### Comment 4
<location> `src/correlation.rs:9` </location>
<code_context>
+//! representation.
+
+/// Access and mutate correlation identifiers on frames.
+pub trait CorrelatableFrame {
+    /// Return the correlation identifier associated with this frame, if any.
+    fn correlation_id(&self) -> Option<u64>;
</code_context>

<issue_to_address>
**issue (review_instructions):** Add behavioural and unit tests for CorrelatableFrame trait and its implementations.

The new CorrelatableFrame trait and its usage should be covered by both behavioural and unit tests to ensure correct integration and trait contract adherence. Please add tests for this trait and its Envelope implementation.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*`

**Instructions:**
For any new feature or change to an existing feature, both behavioural *and* unit tests are required.

</details>
</issue_to_address>

### Comment 5
<location> `src/app/envelope.rs:104` </location>
<code_context>
     fn from_parts(parts: PacketParts) -> Self { parts.into() }
 }

+impl CorrelatableFrame for Envelope {
+    fn correlation_id(&self) -> Option<u64> { self.correlation_id }
+
</code_context>

<issue_to_address>
**issue (review_instructions):** Add behavioural and unit tests for Envelope's CorrelatableFrame implementation.

Envelope's implementation of CorrelatableFrame should be verified with both behavioural and unit tests to ensure correct handling of correlation_id. Please add these tests.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*`

**Instructions:**
For any new feature or change to an existing feature, both behavioural *and* unit tests are required.

</details>
</issue_to_address>

### Comment 6
<location> `docs/multi-packet-and-streaming-responses-design.md:278` </location>
<code_context>
   channel and stamps it onto every serialised frame. This preserves protocol
   invariants without requiring handlers to mutate frames post-creation and
   mirrors the message attribution strategy outlined in the capability roadmap.
+  - Implementation stores the expected identifier alongside a closure built
+    from the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+    generic actor without constraining other protocols. Debug builds assert the
</code_context>

<issue_to_address>
**issue (review_instructions):** This bullet point exceeds the 80 column wrapping limit for paragraphs and bullets.

Please wrap this bullet point so that no line exceeds 80 columns, in accordance with the documentation style guide.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

### Comment 7
<location> `docs/multi-packet-and-streaming-responses-design.md:279` </location>
<code_context>
   invariants without requiring handlers to mutate frames post-creation and
   mirrors the message attribution strategy outlined in the capability roadmap.
+  - Implementation stores the expected identifier alongside a closure built
+    from the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+    generic actor without constraining other protocols. Debug builds assert the
+    stamped frame exposes the expected identifier so regressions fail fast.
</code_context>

<issue_to_address>
**issue (review_instructions):** This line in the bullet point exceeds the 80 column wrapping limit for paragraphs and bullets.

Please wrap this line so that it does not exceed 80 columns, as per the documentation requirements.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

### Comment 8
<location> `docs/multi-packet-and-streaming-responses-design.md:280` </location>
<code_context>
   mirrors the message attribution strategy outlined in the capability roadmap.
+  - Implementation stores the expected identifier alongside a closure built
+    from the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+    generic actor without constraining other protocols. Debug builds assert the
+    stamped frame exposes the expected identifier so regressions fail fast.

</code_context>

<issue_to_address>
**issue (review_instructions):** This line in the bullet point exceeds the 80 column wrapping limit for paragraphs and bullets.

Please wrap this line to 80 columns to comply with the documentation formatting rules.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

### Comment 9
<location> `docs/multi-packet-and-streaming-responses-design.md:281` </location>
<code_context>
+  - Implementation stores the expected identifier alongside a closure built
+    from the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+    generic actor without constraining other protocols. Debug builds assert the
+    stamped frame exposes the expected identifier so regressions fail fast.

 Debug-mode assertions must guard this stamping by checking
</code_context>

<issue_to_address>
**issue (review_instructions):** This line in the bullet point exceeds the 80 column wrapping limit for paragraphs and bullets.

Please wrap this line to 80 columns as required by the documentation standards.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread tests/correlation_id.rs Outdated
Comment thread src/connection.rs Outdated
Comment thread src/app/envelope.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cbab48 and a39e0b5.

📒 Files selected for processing (10)
  • docs/multi-packet-and-streaming-responses-design.md (1 hunks)
  • docs/roadmap.md (1 hunks)
  • src/app/envelope.rs (2 hunks)
  • src/connection.rs (9 hunks)
  • src/correlation.rs (1 hunks)
  • src/lib.rs (2 hunks)
  • tests/correlation_id.rs (2 hunks)
  • tests/features/correlation_id.feature (1 hunks)
  • tests/steps/correlation_steps.rs (1 hunks)
  • tests/world.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • src/lib.rs
  • src/app/envelope.rs
  • src/correlation.rs
  • src/connection.rs
  • tests/world.rs
  • tests/correlation_id.rs
  • tests/steps/correlation_steps.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in...

Files:

  • src/lib.rs
  • src/app/envelope.rs
  • src/correlation.rs
  • src/connection.rs
  • tests/world.rs
  • tests/correlation_id.rs
  • tests/steps/correlation_steps.rs
{src,tests}/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • src/lib.rs
  • src/app/envelope.rs
  • src/correlation.rs
  • src/connection.rs
  • tests/world.rs
  • tests/correlation_id.rs
  • tests/steps/correlation_steps.rs
src/lib.rs

📄 CodeRabbit inference engine (AGENTS.md)

Never export eyre::Report from a library; convert to domain error enums at API boundaries

Files:

  • src/lib.rs
docs/**/*.md

📄 CodeRabbit inference engine (docs/documentation-style-guide.md)

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation text.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for example color.
Use the Oxford comma in documentation text.
Treat company names as collective nouns in documentation (e.g., "Lille Industries are expanding").
Write headings in sentence case in documentation.
Use Markdown headings (#, ##, ###, etc.) in order without skipping levels.
Follow markdownlint recommendations for Markdown files.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; use plaintext for non-code text.
Use - as the first level bullet and renumber lists when items change.
Prefer inline links using [text](url) or angle brackets around the URL; avoid reference-style links like [foo][bar].
Ensure blank lines before and after bulleted lists and fenced blocks in Markdown.
Ensure tables have a delimiter line below the header row in Markdown.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns in documentation.
Wrap code at 120 columns in documentation.
Do not wrap tables in documentation.
Use sequentially numbered footnotes referenced with [^1] and place definitions at the end of the file.
Where it adds clarity, include Mermaid diagrams in documentation.
When embedding figures, use ![alt text](path/to/image) and provide concise alt text describing the content.
Add a brief description before each Mermaid diagram in documentation for screen readers.

Document examples showing how to deprecate old message versions gracefully

docs/**/*.md: Use docs/ markdown as the source of truth for requirements and decisions
Proactively update docs/ when requirements, dependencies, or architecture change
Documentation must use en-GB-oxendict spelling and grammar (LICENSE name exempt)

When long lines are warranted in ...

Files:

  • docs/multi-packet-and-streaming-responses-design.md
  • docs/roadmap.md
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

**/*.md: Markdown paragraphs and bullet points must be wrapped at 80 columns
Markdown code blocks must be wrapped at 120 columns
Do not wrap tables and headings in Markdown
Use dashes (-) for list bullets in Markdown
Use GitHub-flavoured Markdown footnotes ([^1])

Files:

  • docs/multi-packet-and-streaming-responses-design.md
  • docs/roadmap.md

⚙️ CodeRabbit configuration file

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -yse / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/multi-packet-and-streaming-responses-design.md
  • docs/roadmap.md
docs/**

📄 CodeRabbit inference engine (docs/wireframe-1-0-detailed-development-roadmap.md)

docs/**: Document async-stream as the canonical way to create streams imperatively
Write comprehensive user guides for Duplex Messaging & Pushes, Streaming Responses, and Message Fragmentation with runnable examples

Files:

  • docs/multi-packet-and-streaming-responses-design.md
  • docs/roadmap.md
tests/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.rs: Use rstest fixtures for shared setup
Replace duplicated tests with #[rstest(...)] parameterised cases
Prefer mockall for mocks/stubs

Files:

  • tests/world.rs
  • tests/correlation_id.rs
  • tests/steps/correlation_steps.rs
🧬 Code graph analysis (5)
src/app/envelope.rs (1)
src/correlation.rs (2)
  • correlation_id (11-11)
  • set_correlation_id (14-14)
src/correlation.rs (1)
src/app/envelope.rs (5)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
  • set_correlation_id (107-109)
src/connection.rs (2)
src/app/envelope.rs (6)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
  • new (83-89)
  • new (115-121)
src/correlation.rs (1)
  • correlation_id (11-11)
tests/world.rs (2)
src/app/envelope.rs (2)
  • new (83-89)
  • new (115-121)
src/connection.rs (3)
  • new (30-34)
  • new (176-189)
  • new (772-785)
tests/correlation_id.rs (4)
src/app/envelope.rs (6)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/connection.rs (4)
  • new (30-34)
  • new (176-189)
  • new (772-785)
  • drop (38-41)
src/push/queues/mod.rs (2)
  • new (92-109)
  • builder (115-115)
tests/support.rs (1)
  • builder (8-10)
🔍 Remote MCP Ref

Additional Context for PR #371: Correlation ID Stamping for Multi-Packet Streaming Responses

  1. Design Rationale & Protocol Changes

    • Introduces stamping of frames via a CorrelatableFrame trait, allowing generic actors to set and read an optional correlation_id on frames for multi-packet responses (docs/multi-packet-and-streaming-responses-design.md).
      [Design doc]
  2. New Trait & Envelope Implementation

    • CorrelatableFrame trait added with fn correlation_id(&self) -> Option<u64> and fn set_correlation_id(&mut self, Option<u64>).
    • Implemented for Envelope in src/app/envelope.rs, enabling correlation_id propagation on the default packet type.
      [src/app/envelope.rs]
  3. ConnectionActor Enhancements

    • ConnectionActor extended with a MultiPacketStamper closure and optional correlation_id state.
    • New API:
      pub fn set_multi_packet_with_correlation<F, E>(
          &mut self, 
          channel: Option<mpsc::Receiver<F>>, 
          correlation_id: Option<u64>
      )
      where F: CorrelatableFrame;
    • Internally applies stamping to each frame drained from the multi-packet channel, with debug assertions to validate stamping invariants.
      [src/connection.rs]
  4. Trait & API Re-exports

    • Public module correlation and re-export pub use correlation::CorrelatableFrame in src/lib.rs.
      [src/lib.rs]
  5. Testing Coverage

    • Unit test multi_packet_frames_carry_request_correlation_id in tests/correlation_id.rs verifies that all frames from a multi-packet channel carry the specified correlation_id.
    • Behavioural test scenario “Multi-packet responses reuse the request correlation id” added in tests/features/correlation_id.feature with a new Cucumber step when a multi-packet channel emits frames implemented in tests/steps/correlation_steps.rs.
    • Supporting async helper CorrelationWorld::process_multi added in tests/world.rs.
      [tests/correlation_id.rs], [tests/features/correlation_id.feature], [tests/steps/correlation_steps.rs], [tests/world.rs]
  6. Documentation & Roadmap Updates

    • Design doc docs/multi-packet-and-streaming-responses-design.md updated to reflect stamping mechanism.
    • Roadmap docs/roadmap.md checklist items under Phase 6: Multi-Packet Streaming Responses flipped to implemented.
      [docs/roadmap.md]
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (5)
src/lib.rs (1)

14-32: Maintain this public surface alignment
Expose CorrelatableFrame from the root to keep the API cohesive with the new correlation module.

tests/features/correlation_id.feature (1)

7-10: Exercise the multi-packet scenario
Drive this scenario to assert that the multi-packet channel reuses the originating correlation identifier across frames.

tests/world.rs (1)

169-190: Drive the actor via the multi-packet path
Drive the actor through a live channel and capture stamped frames; this mirrors production behaviour in the world helper.

tests/steps/correlation_steps.rs (1)

12-13: Bind the multi-packet When-step
Expose this step so the new feature scenario can activate the world helper.

tests/correlation_id.rs (1)

33-60: Verify multi-packet stamping in unit coverage
Assert the stamped correlation identifier in this unit test to complement the behavioural coverage.

Comment thread src/connection.rs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting

Comment thread src/connection.rs Outdated
codescene-delta-analysis[bot]

This comment was marked as outdated.

* drop the boxed stamper in favour of storing the correlation id and stamping frames directly\n* centralise the multi-packet teardown logic via clear_multi_packet and ensure shutdown clears correlation state\n* implement CorrelatableFrame for u8 and Vec<u8> so ConnectionActor can require the trait
- cover multi-packet stamping with rstest cases including absent correlations

- extend cucumber scenarios and world state to support missing correlation ids

- add CorrelatableFrame unit tests for Envelope and no-op types
Track whether multi-packet correlation stamping is active by storing an outer option, only applying stamps when configured, and documenting the Clippy allowances required by the review guidance.
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

Apply the configured correlation id to hook-provided stream end frames before they are emitted so multi-packet pipelines keep the request context on terminators. Extend the async tests to cover stamped and cleared terminators by wiring a custom hook through the helper.
codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 372af8d and 4171794.

📒 Files selected for processing (6)
  • src/connection.rs (9 hunks)
  • src/correlation.rs (1 hunks)
  • tests/correlation_id.rs (2 hunks)
  • tests/features/correlation_id.feature (1 hunks)
  • tests/steps/correlation_steps.rs (1 hunks)
  • tests/world.rs (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • tests/steps/correlation_steps.rs
  • tests/world.rs
  • src/correlation.rs
  • tests/correlation_id.rs
  • src/connection.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in...

Files:

  • tests/steps/correlation_steps.rs
  • tests/world.rs
  • src/correlation.rs
  • tests/correlation_id.rs
  • src/connection.rs
{src,tests}/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • tests/steps/correlation_steps.rs
  • tests/world.rs
  • src/correlation.rs
  • tests/correlation_id.rs
  • src/connection.rs
tests/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.rs: Use rstest fixtures for shared setup
Replace duplicated tests with #[rstest(...)] parameterised cases
Prefer mockall for mocks/stubs

Files:

  • tests/steps/correlation_steps.rs
  • tests/world.rs
  • tests/correlation_id.rs
🧬 Code graph analysis (5)
tests/steps/correlation_steps.rs (1)
tests/world.rs (1)
  • expected (151-151)
tests/world.rs (3)
src/connection.rs (4)
  • new (30-34)
  • new (174-187)
  • new (783-796)
  • drop (38-41)
src/app/envelope.rs (6)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/push/queues/mod.rs (1)
  • new (92-109)
src/correlation.rs (1)
src/app/envelope.rs (7)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
  • set_correlation_id (107-109)
  • new (83-89)
  • new (115-121)
tests/correlation_id.rs (4)
src/app/envelope.rs (7)
  • payload (130-130)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/connection.rs (5)
  • new (30-34)
  • new (174-187)
  • new (783-796)
  • with_hooks (191-221)
  • default (92-97)
src/push/queues/mod.rs (2)
  • new (92-109)
  • builder (115-115)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
src/connection.rs (5)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
src/app/envelope.rs (4)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
tests/lifecycle.rs (1)
  • correlation_id (122-122)
tests/routes.rs (1)
  • correlation_id (42-42)
tests/world.rs (1)
  • expected (151-151)
🔍 Remote MCP

Relevant Additional Context for PR #371: Implementing Correlation ID Stamping for Multi‐Packet Responses

  1. Design Rationale & Invariants

    • The new stamping logic follows the design in docs/multi-packet-and-streaming-responses-design.md, which mandates:
      • Storing the expected correlation ID alongside a closure (MultiPacketStamper) obtained from the CorrelatableFrame trait.
      • Debug builds assert that each stamped frame’s correlation_id() matches the expected value, enforcing the invariant before dispatch.
        Citation: design spec [raw docs/multi-packet-and-streaming-responses-design.md] (URL unavailable due to access limits).
  2. Roadmap Phase 6 Overview

    • Phase 6 (“Multi-Packet Streaming Responses”) was updated in docs/roadmap.md to mark correlation ID handling as implemented:
      • Sent frames carry the correct ID from the initial request.
      • Early receiver closures and error paths now covered by tests.
        Citation: Roadmap [::Deepwiki_read_wiki_contents::] (“Phase 6: Multi-Packet…” entries).
  3. FrameLike vs CorrelatableFrame

    • FrameLike is a marker trait (Send + 'static) for frames ([::Deepwiki_ask_question::]).
    • CorrelatableFrame extends FrameLike to expose/get and set an Option<u64> correlation ID (methods correlation_id(), set_correlation_id(…)).
      Citation: FrameLike & CorrelatableFrame definitions [::Deepwiki_ask_question::].
  4. ConnectionActor Changes

    • The ConnectionActor<F,E> now requires F: FrameLike + CorrelatableFrame enabling stamping in the multi-packet path.
    • New methods manage stamping lifecycle:
      • install_multi_packet stores the stamper closure and expected ID.
      • apply_multi_packet_correlation(&mut self, frame: &mut F) stamps each outgoing frame.
        Citation: ConnectionActor diff summary in PR context.
  5. Envelope Implementation

    • Envelope now implements CorrelatableFrame:
      impl CorrelatableFrame for Envelope {
          fn correlation_id(&self) -> Option<u64> { self.correlation_id }
          fn set_correlation_id(&mut self, cid: Option<u64>) { self.correlation_id = cid; }
      }
    • Enables stamping on the default envelope type without altering other protocols.
      Citation: Envelope impl diff in src/app/envelope.rs.
  6. Tests Covering Behavior

    • Unit tests in src/correlation.rs verify round-trip stamping and noop behavior on u8/Vec<u8>.
    • Integration tests in tests/correlation_id.rs and Cucumber scenarios in tests/features/correlation_id.feature confirm:
      • Multi-packet frames reuse the request’s correlation ID.
      • Cases with no initial ID produce None on subsequent frames.
        Citation: Test summaries in PR context.
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review

Comment thread src/connection.rs Outdated
Comment thread tests/correlation_id.rs Outdated
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 909089b and 5dfa373.

📒 Files selected for processing (2)
  • src/connection.rs (14 hunks)
  • tests/correlation_id.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • tests/correlation_id.rs
  • src/connection.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in...

Files:

  • tests/correlation_id.rs
  • src/connection.rs
{src,tests}/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • tests/correlation_id.rs
  • src/connection.rs
tests/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.rs: Use rstest fixtures for shared setup
Replace duplicated tests with #[rstest(...)] parameterised cases
Prefer mockall for mocks/stubs

Files:

  • tests/correlation_id.rs
🧬 Code graph analysis (2)
tests/correlation_id.rs (4)
src/connection.rs (8)
  • correlation (186-186)
  • new (30-34)
  • new (152-157)
  • new (222-235)
  • new (810-823)
  • drop (38-41)
  • with_hooks (239-268)
  • default (92-97)
src/app/envelope.rs (7)
  • payload (130-130)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/push/queues/mod.rs (2)
  • new (92-109)
  • builder (115-115)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
src/connection.rs (2)
src/app/envelope.rs (6)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
🔍 Remote MCP

Summary of additional facts relevant to reviewing PR #371

  • New public trait CorrelatableFrame (correlation_id / set_correlation_id) added and re-exported from crate root; trivial no-op impls exist for u8 and Vec. [::Deepwiki_read_wiki_contents::]
  • Envelope now implements CorrelatableFrame so Envelope frames can carry/set Option correlation IDs. [::Deepwiki_read_wiki_contents::]
  • ConnectionActor generic bound tightened to F: FrameLike + CorrelatableFrame; actor stores multi_packet_correlation: Option<Option> and exposes set_multi_packet_with_correlation(...) to install a multi-packet channel plus optional correlation id. Private helpers install_multi_packet, clear_multi_packet, apply_multi_packet_correlation added; debug_asserts enforce stamping invariants (only in debug builds). [::Deepwiki_read_wiki_contents::]
  • apply_multi_packet_correlation is applied along the multi-packet streaming path (queue processing and end-of-stream handling); correlation state is cleared on channel close/shutdown. [::Deepwiki_read_wiki_contents::]
  • Tests added/updated:
    • Unit tests for CorrelatableFrame behavior (Envelope round-trip; noop for primitives).
    • Integration/unit tests exercising multi-packet correlation propagation and terminator behavior (tests/correlation_id.rs).
    • BDD scenarios and step defs updated to use optional expected correlation (tests/features/correlation_id.feature, tests/steps/correlation_steps.rs, tests/world.rs). Test harness adjusted (ActorHarness.has_multi_queue uses is_active()). [::Deepwiki_read_wiki_contents::]
  • Docs updated: design doc describes storing an expected correlation id + stamper closure and debug assertions; roadmap marks Phase 6 correlation handling items as implemented. [::Deepwiki_read_wiki_contents::]
  • Runtime/testing notes: multi-packet flows in tests use tokio::sync::mpsc channels and rstest fixtures; developer/test commands remain make fmt / make lint / make test. [::Deepwiki_read_wiki_contents::]
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (22)
src/connection.rs (18)

49-49: Correlation import correctly added to support trait-bounded frames.

The import enables the trait constraint on ConnectionActor's generic type parameter F, providing correlation stamping capabilities.


124-124: Multi-packet state correctly refactored into context struct.

The previous scattered state fields have been appropriately consolidated into a single MultiPacketContext, reducing option juggling and centralising multi-packet logic.


140-189: Implement bounded correlation state tracking.

The MultiPacketContext correctly tracks stamping activation separately from the stored identifier using nested Option<Option<u64>>. The debug assertion ensures state consistency when channels are active.


201-201: Generic constraint correctly tightened for correlatable frames.

The trait bound F: FrameLike + CorrelatableFrame enables correlation stamping whilst maintaining frame serialisation capabilities.


252-252: Context initialisation correctly integrated.

The field initialisation uses the new context constructor, maintaining consistency with the refactored structure.


276-276: Invariant assertion correctly updated for new context.

The assertion uses the context's is_active() method to check multi-packet state consistency.


294-296: Correlation state correctly tracked for basic multi-packet setup.

When no correlation stamping is required, the code correctly maps channel presence to Some(None), indicating stamping is active but with no identifier.


298-313: Correlation API correctly implements optional stamping.

The set_multi_packet_with_correlation method correctly maps the channel to correlation state, using Some(correlation_id) to indicate active stamping with the provided identifier.


315-315: Context clearing correctly delegated.

The method delegates to the context's clear() method, maintaining encapsulation.


317-345: Correlation stamping logic correctly handles all stamping states.

The method appropriately handles three correlation states: explicit stamping with an identifier, explicit clearing with None, and misconfigured state with proper debug assertions.


376-380: Invariant assertions correctly updated for context usage.

The debug assertions now use the context's is_active() method and the state constructor correctly tracks multi-packet activity.


407-407: Multi-packet availability check correctly uses context.

The availability guard correctly queries the context's is_active() method whilst respecting shutdown state.


416-416: Channel polling correctly delegates to context.

The select branch correctly uses channel_mut() to access the receiver through the context.


472-475: Correlation stamping correctly applied to multi-packet frames.

The logic correctly mutates frames when correlation is configured and applies stamping only to multi-packet sources.


510-512: Channel extraction correctly delegated to context.

The method appropriately uses the context's take_channel() to extract the receiver whilst maintaining state consistency.


531-538: Terminator frame correlation correctly applied.

The terminator frame from hooks receives correlation stamping when configured, ensuring end-of-stream frames carry the expected correlation identifier. This addresses the requirement that all frames in multi-packet responses maintain consistent correlation.

Based on previous review comments.


588-592: Shutdown correctly handles multi-packet context.

The shutdown logic appropriately extracts and closes the channel, marks the state as closed, and clears the context to prevent resource leaks.


661-681: Opportunistic draining correctly applies correlation stamping.

The multi-packet draining logic correctly applies correlation to frames when configured, maintaining consistency with the primary event processing path.

tests/correlation_id.rs (4)

4-14: Test dependencies correctly imported for multi-packet correlation.

The imports provide necessary testing infrastructure including parameterised testing via rstest, channels for multi-packet scenarios, and correlation trait support.


36-66: Multi-packet test harness correctly implemented.

The run_multi_packet_channel helper appropriately constructs a test environment with configurable correlation settings and protocol hooks, enabling comprehensive multi-packet scenario testing.


68-84: Parameterised correlation tests comprehensively cover stamping scenarios.

The rstest cases appropriately verify stamping behaviour across three critical scenarios: applying request correlation to frames lacking identifiers, clearing correlation when the request has none, and preserving matching identifiers. This ensures robust correlation handling.

rstest generates independent test cases and the chosen scenarios align with the coding guidelines requiring comprehensive testing of new functionality.


86-105: Terminator correlation tests verify end-of-stream stamping.

The tests correctly verify that terminator frames from protocol hooks receive appropriate correlation stamping, ensuring complete consistency across multi-packet response flows including end-of-stream signalling.

This resolves the issue flagged in previous reviews regarding terminator frame correlation handling.

Comment thread tests/correlation_id.rs Outdated
Use a widening cast before serialising the marker bytes so the multi-packet correlation tests cannot panic on large indices.
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 28, 2025

@coderabbitai review

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Sep 28, 2025

@sourcery-ai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 28, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • Consider replacing the nested Option<Option<u64>> correlation field with a small enum (e.g. Disabled / Enabled(None) / Enabled(Some)) to make the stamping configuration more self‐documenting and avoid the double‐Option pattern.
  • The correlation‐stamping logic is repeated around multiple frame emission points; you could centralize calls to apply_multi_packet_correlation in a single emit path to reduce duplication and maintenance overhead.
  • Relying on debug_assert(false) for the undefined‐state branch means it will be optimized away in non-debug builds—consider using unreachable!() or an explicit panic to enforce invariants in all builds.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider replacing the nested `Option<Option<u64>>` correlation field with a small enum (e.g. Disabled / Enabled(None) / Enabled(Some)) to make the stamping configuration more self‐documenting and avoid the double‐Option pattern.
- The correlation‐stamping logic is repeated around multiple frame emission points; you could centralize calls to `apply_multi_packet_correlation` in a single emit path to reduce duplication and maintenance overhead.
- Relying on `debug_assert(false)` for the undefined‐state branch means it will be optimized away in non-debug builds—consider using `unreachable!()` or an explicit panic to enforce invariants in all builds.

## Individual Comments

### Comment 1
<location> `src/connection/test_support.rs:97-99` </location>
<code_context>

     /// Returns `true` when the multi-packet queue is still available.
     #[must_use]
-    pub fn has_multi_queue(&self) -> bool { self.actor.multi_packet.is_some() }
+    pub fn has_multi_queue(&self) -> bool { self.actor.multi_packet.is_active() }

     /// Process a multi-packet poll result.
</code_context>

<issue_to_address>
**suggestion (testing):** Consider adding tests for the test harness changes.

Please add or update tests to confirm that the harness accurately tracks the queue's state, including after clearing or installing the queue.

```suggestion
    /// Returns `true` when the multi-packet queue is still available.
    #[must_use]
    pub fn has_multi_queue(&self) -> bool { self.actor.multi_packet.is_active() }

    #[cfg(test)]
    mod tests {
        use super::*;

        struct DummyMultiPacket {
            active: bool,
        }

        impl DummyMultiPacket {
            fn new() -> Self {
                Self { active: false }
            }
            fn install(&mut self) {
                self.active = true;
            }
            fn clear(&mut self) {
                self.active = false;
            }
            fn is_active(&self) -> bool {
                self.active
            }
        }

        struct DummyActor {
            multi_packet: DummyMultiPacket,
        }

        struct TestHarness {
            actor: DummyActor,
        }

        impl TestHarness {
            fn new() -> Self {
                Self {
                    actor: DummyActor {
                        multi_packet: DummyMultiPacket::new(),
                    },
                }
            }
            pub fn has_multi_queue(&self) -> bool {
                self.actor.multi_packet.is_active()
            }
            pub fn install_multi_queue(&mut self) {
                self.actor.multi_packet.install();
            }
            pub fn clear_multi_queue(&mut self) {
                self.actor.multi_packet.clear();
            }
        }

        #[test]
        fn test_has_multi_queue_initially_false() {
            let harness = TestHarness::new();
            assert!(!harness.has_multi_queue(), "Queue should not be active initially");
        }

        #[test]
        fn test_has_multi_queue_after_install() {
            let mut harness = TestHarness::new();
            harness.install_multi_queue();
            assert!(harness.has_multi_queue(), "Queue should be active after install");
        }

        #[test]
        fn test_has_multi_queue_after_clear() {
            let mut harness = TestHarness::new();
            harness.install_multi_queue();
            harness.clear_multi_queue();
            assert!(!harness.has_multi_queue(), "Queue should not be active after clear");
        }
    }
```
</issue_to_address>

### Comment 2
<location> `docs/multi-packet-and-streaming-responses-design.md:279` </location>
<code_context>
   invariants without requiring handlers to mutate frames post-creation and
   mirrors the message attribution strategy outlined in the capability roadmap.
+- Implementation stores the expected identifier alongside a closure built from
+  the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+  generic actor without constraining other protocols. Debug builds assert the
+  stamped frame exposes the expected identifier so regressions fail fast.
</code_context>

<issue_to_address>
**suggestion (review_instructions):** This paragraph line exceeds 80 columns and should be wrapped for readability.

Please wrap this paragraph so that no line exceeds 80 columns, in accordance with the documentation style guide.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

### Comment 3
<location> `docs/multi-packet-and-streaming-responses-design.md:280` </location>
<code_context>
   mirrors the message attribution strategy outlined in the capability roadmap.
+- Implementation stores the expected identifier alongside a closure built from
+  the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+  generic actor without constraining other protocols. Debug builds assert the
+  stamped frame exposes the expected identifier so regressions fail fast.

</code_context>

<issue_to_address>
**suggestion (review_instructions):** This paragraph line exceeds 80 columns and should be wrapped for readability.

Please wrap this paragraph so that no line exceeds 80 columns, in accordance with the documentation style guide.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

### Comment 4
<location> `docs/multi-packet-and-streaming-responses-design.md:281` </location>
<code_context>
+- Implementation stores the expected identifier alongside a closure built from
+  the new `CorrelatableFrame` trait, ensuring frames can be stamped in a
+  generic actor without constraining other protocols. Debug builds assert the
+  stamped frame exposes the expected identifier so regressions fail fast.

 Debug-mode assertions must guard this stamping by checking
</code_context>

<issue_to_address>
**suggestion (review_instructions):** This paragraph line exceeds 80 columns and should be wrapped for readability.

Please wrap this paragraph so that no line exceeds 80 columns, in accordance with the documentation style guide.

<details>
<summary>Review instructions:</summary>

**Path patterns:** `**/*.md`

**Instructions:**
Paragraphs and bullets must be wrapped to 80 columns

</details>
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/connection/test_support.rs
codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dfa373 and f2f115c.

📒 Files selected for processing (3)
  • src/connection.rs (15 hunks)
  • src/connection/test_support.rs (2 hunks)
  • tests/correlation_id.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • tests/correlation_id.rs
  • src/connection/test_support.rs
  • src/connection.rs

⚙️ CodeRabbit configuration file

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.
  • Environment access (env::set_var and env::remove_var) are always unsafe in Rust 2024 and MUST be marked as such

    • For testing of functionality depending upon environment variables, dependency injection and the mockable crate are the preferred option.
    • If mockable cannot be used, env mutations in...

Files:

  • tests/correlation_id.rs
  • src/connection/test_support.rs
  • src/connection.rs
{src,tests}/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • tests/correlation_id.rs
  • src/connection/test_support.rs
  • src/connection.rs
tests/**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.rs: Use rstest fixtures for shared setup
Replace duplicated tests with #[rstest(...)] parameterised cases
Prefer mockall for mocks/stubs

Files:

  • tests/correlation_id.rs
🧬 Code graph analysis (3)
tests/correlation_id.rs (3)
src/app/envelope.rs (7)
  • payload (130-130)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/connection.rs (6)
  • new (30-34)
  • new (158-163)
  • new (220-233)
  • new (812-825)
  • with_hooks (237-266)
  • default (92-97)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
src/connection/test_support.rs (1)
src/connection.rs (4)
  • new (30-34)
  • new (158-163)
  • new (220-233)
  • new (812-825)
src/connection.rs (2)
src/app/envelope.rs (6)
  • new (83-89)
  • new (115-121)
  • correlation_id (52-52)
  • correlation_id (97-97)
  • correlation_id (105-105)
  • correlation_id (127-127)
src/correlation.rs (3)
  • correlation_id (11-11)
  • correlation_id (18-18)
  • correlation_id (24-24)
🔍 Remote MCP Deepwiki

Summary of additional context relevant to reviewing PR #371

  • New public trait CorrelatableFrame added and re-exported from crate root; provides correlation_id() -> Option and set_correlation_id(Option) and has noop impls for u8/Vec.
  • Envelope now implements CorrelatableFrame so Envelope-based frames carry/set Option correlation ids.
  • ConnectionActor generic bound tightened to F: FrameLike + CorrelatableFrame; new API set_multi_packet_with_correlation(channel, correlation_id: Option) installs multi-packet channel plus optional correlation id. apply_multi_packet_correlation logic stamps emitted multi-packet frames and terminators with the stored correlation id. Debug-only assertions enforce invariants (fail-fast in debug builds).
  • MultiPacketContext replaces prior optional receiver field; exposes is_active() and channel_mut/take_channel helpers; multi-packet state is cleared on channel close/shutdown.
  • Tests updated/added:
    • Unit tests for CorrelatableFrame behavior (Envelope round-trip; noop impls).
    • Connection-level tests exercising multi-packet correlation propagation and terminator stamping (tests/correlation_id.rs).
    • BDD feature scenarios and step defs updated to use optional expected correlation id (tests/features/, tests/steps/, tests/world.rs). Tests use tokio::sync::mpsc and rstest fixtures.
  • Docs updated: design doc documents storing expected correlation id + stamper closure and debug assertions; roadmap marks Phase 6 multi-packet correlation items as implemented.
  • Runtime/test notes / CI expectations unchanged: make fmt, make lint, make test remain the developer commands; tests rely on wireframe testing helpers and bincode/LengthPrefixed framing.
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (10)
src/connection/test_support.rs (2)

99-99: Use of is_active() aligns harness with new multi‑packet context.

Keep this; it correctly reflects the new API and avoids Option poking.


184-225: Good: added harness tests for multi‑packet availability.

These tests exercise install/clear transitions and match prior review asks.

tests/correlation_id.rs (3)

36-66: Solid channel driver for multi‑packet correlation tests.

The helper wires stamping through set_multi_packet_with_correlation and avoids payload overflows by using LE bytes.


68-85: Parametrized coverage of stamp/clear/preserve paths is complete.

Retain these cases; they verify overwrite, clear‑on‑None, and preserve semantics succinctly.


86-105: Terminators are correctly stamped/cleared.

This asserts the roadmap requirement that end‑of‑stream frames carry the originating correlation ID when configured.

src/connection.rs (5)

140-188: Lean stamping state machine is appropriate.

MultiPacketStamp and MultiPacketContext cleanly separate channel presence from stamping behaviour; keep this design.


283-299: Default multi‑packet enablement clears correlation IDs.

Enabling with Enabled(None) is a sensible default; it guarantees deterministic output for multi‑packet frames without leaking stale IDs.


321-347: Stamp frames via a single path.

emit_multi_packet_frame + apply_multi_packet_correlation ensures all multi‑packet frames pass through hooks/metrics with enforced invariants. Keep this.


535-549: Stamp the terminator before emission.

Routing the hook‑provided end frame through emit_multi_packet_frame fixes the earlier gap where terminators could lose correlation.


664-683: Handle disconnected multi‑packet receiver robustly.

Extract the receiver, emit a stamped terminator, and clear context; this prevents stale state and double‑close.

Comment thread src/connection.rs
Comment thread src/connection.rs
@leynos leynos merged commit a7b2b9c into main Sep 28, 2025
6 checks passed
@leynos leynos deleted the codex/implement-multi-packet-streaming-responses branch September 28, 2025 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant