docs(event-broker): module design + SDK#4083
Conversation
|
Important Review skippedToo many files! This PR contains 217 files, which is 117 over the limit of 100. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (217)
You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR registers the Event Broker SDK and stable-hash toolkit in the Cargo workspace, expands cargo-shear test exclusions, and adds GEARS.md documentation describing the Event Broker design, implementation status, and reference links. ChangesEvent Broker SDK registration and docs
Estimated code review effort: 1 (Trivial) | ~3 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
modules/system/event-broker/scenarios/INDEX.md (1)
1-183:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd the required TOC blocks across the scenario docs.
The same guideline violation appears in
modules/system/event-broker/scenarios/INDEX.md,modules/system/event-broker/scenarios/consumer-groups/README.md,modules/system/event-broker/scenarios/consumer-groups/negative-1.5-delete-group-with-active-members.md, andmodules/system/event-broker/scenarios/consumer-groups/negative-1.6-invalid-client-agent.md: each markdown artifact is missing the generated table of contents required by the repo conventions.As per coding guidelines, "Generate Table of Contents (TOC) for artifact documentation".
🤖 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 `@modules/system/event-broker/scenarios/INDEX.md` around lines 1 - 183, The listed markdown artifacts (document titled "Event Broker — API Scenario Guide" and the consumer-groups scenario pages including "negative-1.5 — Delete group with active members" and "negative-1.6 — Invalid (non-ASCII) field") are missing the repo-required generated Table of Contents; update each file to include the TOC block per project convention (insert the generated TOC shortcode/block at the top of the scenario artifact, matching how other scenarios render their TOC), regenerate or commit the produced TOC content so each of INDEX.md, consumer-groups/README.md, consumer-groups/negative-1.5-delete-group-with-active-members.md and consumer-groups/negative-1.6-invalid-client-agent.md contains the required TOC block.Source: Coding guidelines
modules/system/event-broker/scenarios/subscriptions/negative-2.8-leave-unknown-subscription.md (1)
1-28:⚠️ Potential issue | 🔴 CriticalCritical build failure: missing
modkit*workspace dependency declarations
modules/system/event-broker/event-broker-sdk/Cargo.tomldeclaresmodkit-security = { workspace = true },modkit = { workspace = true }, andmodkit-db = { workspace = true, optional = true, features = ["preview-outbox"] }, but the rootCargo.tomlhas no corresponding entries under[workspace.dependencies], so Cargo cannot resolveworkspace = truedependencies (e.g.,dependency.modkitnot found inworkspace.dependencies).Action required: Add
modkit,modkit-security, andmodkit-dbto the root[workspace.dependencies]with the correctversion/path(and ensuremodkit-dbincludes the requiredpreview-outboxfeature).🤖 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 `@modules/system/event-broker/scenarios/subscriptions/negative-2.8-leave-unknown-subscription.md` around lines 1 - 28, The root workspace is missing entries for the workspace dependencies referenced by event-broker-sdk; open the root Cargo.toml and under [workspace.dependencies] add entries for modkit, modkit-security, and modkit-db matching their package names (provide correct version or path as used by the repo), and for modkit-db include the features = ["preview-outbox"] entry so Cargo can resolve dependency.modkit/modkit-security/modkit-db when event-broker-sdk declares workspace = true; ensure names exactly match the dependency keys used in modules/system/event-broker/event-broker-sdk/Cargo.toml.Source: Pipeline failures
🟡 Minor comments (16)
modules/system/event-broker/event-broker-sdk/README.md-15-17 (1)
15-17:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSpecify a language for the fenced block.
Line 15 trips MD040. Use a concrete lexer like
textso the README stays lint-clean.🤖 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 `@modules/system/event-broker/event-broker-sdk/README.md` around lines 15 - 17, The fenced code block containing the DESIGN_PIN value currently lacks a language identifier and triggers MD040; update the block delimiter from ``` to a concrete lexer such as ```text (e.g., change ```\nDESIGN_PIN = bb8e169ee04eb40bdda18ff3a01da980c86fa546\n``` to ```text\nDESIGN_PIN = bb8e169ee04eb40bdda18ff3a01da980c86fa546\n```), so the README's code block for the DESIGN_PIN constant is lint-clean.Source: Linters/SAST tools
modules/system/event-broker/event-broker-sdk/src/mock/tests/schema.rs-47-52 (1)
47-52:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMatch typed error variants instead of
Debugsubstrings.These assertions can pass on the wrong failure as long as the formatted message happens to contain
"invalid", the topic name, or"EventTypeUnknown". For contract coverage, match the concreteEventBrokerErrorvariants and assert the relevant fields.Also applies to: 70-73, 94-98
🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/schema.rs` around lines 47 - 52, Replace fragile string-based assertions with direct matching against the concrete EventBrokerError variants returned by broker.publish in this test: bind the unwrap_err() result (err) and use pattern matching (e.g., match or if let) to assert it is EventBrokerError::EventDataInvalid { .. } or EventBrokerError::EventTypeUnknown { topic, .. } as appropriate, and assert on relevant fields (payload, topic, validation details) rather than inspecting Debug-formatted msg; apply the same replacement for the other similar assertions in this test file that currently check msg substrings.modules/system/event-broker/event-broker-sdk/src/mock/tests/standby.rs-25-32 (1)
25-32:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winThis failover test still allows false positives.
If Line 26 sees no active assignment, the ack path is skipped and the test keeps going. Then Lines 47-49 only assert that some cursor exists, not that the inherited cursor reflects the acked offset
3. Please make the active assignment mandatory and assert the carried cursor value.Also applies to: 46-49
🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/standby.rs` around lines 25 - 32, The test currently skips the ack path when active_partition.first() is None, allowing false positives; make the active assignment mandatory by failing the test if no slot exists (e.g., replace the if-let with an unwrap/expect on active_partition.first() or assert_some) and always call broker.ack with the constructed map (using the slot from active_partition.first()). Then update the later assertion that inspects the inherited cursor (the block that checks for a cursor after failover) to assert the exact carried offset equals 3 (compare the cursor value for slot.topic/slot.partition to 3) so the test verifies the acked offset is inherited. Apply this same change pattern to the other similar block around lines 46-49.modules/system/event-broker/event-broker-sdk/src/mock/tests/offsets.rs-162-171 (1)
162-171:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFail when the reassigned slot is missing.
This test currently passes if the rejoined subscription does not get
TOPIC/partition0, because the assertion is guarded byif let Some(...). That hides exactly the regression this test is meant to catch.Suggested change
- let slot = sub_second - .assigned - .iter() - .find(|s| s.topic == TOPIC && s.partition == 0); - if let Some(slot) = slot { - assert_eq!( - slot.offset, 99, - "cursor must survive subscription churn (M8)" - ); - } + let slot = sub_second + .assigned + .iter() + .find(|s| s.topic == TOPIC && s.partition == 0) + .expect("rejoined subscription must retain an assignment for TOPIC partition 0"); + assert_eq!(slot.offset, 99, "cursor must survive subscription churn (M8)");🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/offsets.rs` around lines 162 - 171, The test silently succeeds when the reassigned slot is missing because the check uses `if let Some(slot) = slot { ... }`; change this to explicitly fail when the slot isn't present (e.g., assert that the found `slot` is Some with a clear message) and then perform the `assert_eq!(slot.offset, 99, ...)` on the unwrapped value; target the `slot` variable from `sub_second.assigned.iter().find(|s| s.topic == TOPIC && s.partition == 0)` so the test fails if the rejoined subscription does not receive TOPIC/partition 0.modules/system/event-broker/event-broker-sdk/src/mock/tests/offsets.rs-175-217 (1)
175-217:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win
seek_earliest_starts_from_zeronever verifies offset0.The test name claims stream delivery restarts from offset
0, but the body only callsseek()and exits. As written, it will pass even if the broker ignoresResolvedPosition::Earliest.Suggested change
#[tokio::test] async fn seek_earliest_starts_from_zero() { let (broker, _h) = broker_with_topic(TOPIC, 1).await; let c = ctx(); @@ broker .seek( &c, subscription.subscription_id, &[SeekPosition { topic: TOPIC.to_owned(), partition: 0, value: ResolvedPosition::Earliest, }], ) .await .unwrap(); - // After seek Earliest, stream should deliver from offset 0. - // (Full stream traversal is covered by mock_backfill.rs) + use crate::consumer::backend::WireFrame; + use futures_util::StreamExt; + + let mut stream = broker.stream(&c, subscription.subscription_id).await.unwrap(); + let _ = stream.next().await; // topology + match stream.next().await { + Some(Ok(WireFrame::Event(event))) => assert_eq!(event.offset, 0), + other => panic!("expected first delivered event at offset 0, got {other:?}"), + } }🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/offsets.rs` around lines 175 - 217, The test seek_earliest_starts_from_zero currently only calls broker.seek(...) but never asserts that the stream actually starts at offset 0; update the test to subscribe/consume after the seek and assert the first delivered event has offset 0. Specifically, after broker.seek(...) use the existing subscription (subscription.subscription_id) to pull or await the next delivered message from the broker (same ctx c and TOPIC), then assert the returned record's offset (from the delivery metadata or record position field) equals 0 and its payload matches the earlier published wire_event(TOPIC, EVT, ...); this guarantees ResolvedPosition::Earliest behavior is verified.modules/system/event-broker/event-broker-sdk/src/mock/tests/producer_flow.rs-78-88 (1)
78-88:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFail fast if the alternate key doesn't land on a different partition.
This negative test currently does nothing when
otherhashes back top0, so it can pass without asserting the rejection path at all. Assert that precondition first so the test remains meaningful if the hash implementation changes.Suggested change
let p0 = partition_for(&c.subject_tenant_id().to_string(), 2); let other = if p0 == 0 { "other-one" } else { "other-zero" }; - if partition_for(other, 2) != p0 { - let mut ev2 = wire_event(TOPIC, EVT, c.subject_tenant_id()); - ev2.partition_key = Some(other.to_owned()); - let err = broker - .publish_batch(&c, &[wire_event(TOPIC, EVT, c.subject_tenant_id()), ev2]) - .await - .unwrap_err(); - assert!(format!("{err:?}").contains("mixed") || format!("{err:?}").contains("partition")); - } + assert_ne!(partition_for(other, 2), p0, "test key must hit the other partition"); + let mut ev2 = wire_event(TOPIC, EVT, c.subject_tenant_id()); + ev2.partition_key = Some(other.to_owned()); + let err = broker + .publish_batch(&c, &[wire_event(TOPIC, EVT, c.subject_tenant_id()), ev2]) + .await + .unwrap_err(); + assert!(format!("{err:?}").contains("mixed") || format!("{err:?}").contains("partition"));🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/producer_flow.rs` around lines 78 - 88, The test currently skips the negative-path assertions when the computed `other` key hashes to the same partition `p0`; add a precondition check (e.g., `assert_ne!(partition_for(other, 2), p0, "alternate key landed on same partition; test invalid")`) right after computing `other` so the test fails fast if the alternate key does not land on a different partition, then keep the existing branch that constructs `ev2` and asserts the `publish_batch` error; reference `partition_for`, `other`, `p0`, `ev2`, `wire_event`, and `publish_batch` to locate where to insert the assertion.modules/system/event-broker/event-broker-sdk/src/mock/tests/rebalance.rs-121-130 (1)
121-130:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFail the test if the handoff assignment is missing.
If rebalance regresses and
sub_secondnever receives partition0, this branch is skipped and the test still passes. Assert the slot exists before checking its offset.Suggested fix
- if let Some(slot) = slot { - assert_eq!( - slot.offset, 0, - "sub_second must start from sub_first's cursor.acked=0" - ); - } + let slot = slot.expect("sub_second must receive partition 0 after handoff"); + assert_eq!( + slot.offset, 0, + "sub_second must start from sub_first's cursor.acked=0" + );🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/rebalance.rs` around lines 121 - 130, The test currently searches for a slot in sub_second.assigned for TOPIC partition 0 and only asserts its offset if found, which lets the test pass silently if the slot is missing; change this to first assert that the slot exists (e.g., assert!(slot.is_some(), "expected sub_second to be assigned partition 0")) and then unwrap or match the slot to assert slot.offset == 0 so the test fails if the handoff assignment is missing; reference the variables/functions: sub_second, assigned, TOPIC, partition, slot, and offset when applying the check.modules/system/event-broker/event-broker-sdk/src/mock/ingest.rs-209-212 (1)
209-212:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove the leaked fallback key.
first.tenant_id.to_string().leak()permanently leaks memory on every batch call, and the resultingfirst_partition_keyis never used. The laterfirst_partition_inputblock already computes the fallback you need.Suggested fix
- let first_partition_key = first - .partition_key - .as_deref() - .unwrap_or_else(|| first.tenant_id.to_string().leak()); // only for comparison let partitions = core .topics .get(&first.topic) .map(|t| t.partitions) .unwrap_or(1);🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/ingest.rs` around lines 209 - 212, The code creates a leaked fallback key via first.tenant_id.to_string().leak() when computing first_partition_key; remove that leaked fallback and instead only call as_deref() / unwrap_or(...) without leaking, relying on the existing first_partition_input computation for the fallback value (refer to the variables first_partition_key and first_partition_input in ingest.rs) so no memory is leaked and the unused leaked value is eliminated.modules/system/event-broker/docs/ADR/0004-subscription-filter-typing.md-117-123 (1)
117-123:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winLabel the grammar fence.
Markdownlint already flags this block; adding a language tag (
ebnfortext) keeps the docs check green and makes the syntax intent clearer.🤖 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 `@modules/system/event-broker/docs/ADR/0004-subscription-filter-typing.md` around lines 117 - 123, The fenced grammar block defining type_pattern, exact_pattern, wildcard_pattern and gts_prefix needs a language label to satisfy markdownlint and clarify intent; update the triple-backtick fence that surrounds that grammar (the block starting with "type_pattern = exact_pattern | wildcard_pattern") to include an appropriate language tag such as ebnf or text (e.g., change ``` to ```ebnf) so the docs check passes and the grammar is explicitly labeled.Source: Linters/SAST tools
modules/system/event-broker/docs/PRD.md-543-567 (1)
543-567:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the remaining markdownlint hits here.
The API-surface fence is unlabeled, and the following heading skips a level. Add a fence language and normalize the heading hierarchy so the docs checks pass.
Also applies to: 579-579
🤖 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 `@modules/system/event-broker/docs/PRD.md` around lines 543 - 567, The fenced API-surface block is missing a language label and the following heading skips a level; update the fenced code block (the triple-backtick block containing the POST/GET routes) to include a language (e.g., ```http or ```text) and then adjust the subsequent heading so it does not jump levels (make it the correct Hn that follows the previous heading) to satisfy markdownlint heading-order rules; locate the unlabelled fence and the heading immediately after it in PRD.md and change the fence label and the heading level accordingly.Source: Linters/SAST tools
modules/system/event-broker/scenarios/INDEX.md-13-53 (1)
13-53:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the heading level jump in the journey steps.
The section goes from
## 1. Integration Journeyto#### Step 1, which triggers MD001 and makes the outline harder to navigate. These step headings should be###.🤖 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 `@modules/system/event-broker/scenarios/INDEX.md` around lines 13 - 53, The step subheadings under "1. Integration Journey" use level-4 headings (e.g., "#### Step 1 — Establish a consumer group", "#### Step 2 — Publish events", etc.) causing a heading level jump and MD001; change each "#### Step X ..." heading to a level-3 heading "### Step X ..." (update the headings for Step 1 through Step 6 and the inline link titles like "Step 1 — Establish a consumer group", "Step 2 — Publish events", "Step 3 — JOIN a subscription", "Step 4 — SEEK the starting position", "Step 5 — Stream events", and "Step 6 — Acknowledge progress") so the outline is hierarchical and MD001 is resolved.Source: Linters/SAST tools
modules/system/event-broker/scenarios/consumer-groups/negative-1.6-invalid-client-agent.md-1-17 (1)
1-17:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign the scenario identity with the field it actually tests.
The file name and intro frame this as an invalid
client_agentcase, but the request and Problem Details payload exercisedescriptioninstead. That makes the catalog misleading when someone looks for theclient_agentvalidation scenario or tries to trace failures back to this file.Also applies to: 30-32
🤖 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 `@modules/system/event-broker/scenarios/consumer-groups/negative-1.6-invalid-client-agent.md` around lines 1 - 17, The scenario identity is inconsistent: the title and filename reference client_agent but the request and Problem Details exercise description; update the scenario so both identity and payload match by either (A) renaming the scenario title/header (“# Reject a non-ASCII / over-length field on group create”) and the file name to indicate description (e.g., mention description) and leaving the request body as-is, or (B) changing the JSON request and any Problem Details examples to use the client_agent field with a non-ASCII/over-length value; ensure any references to client_agent or description inside the scenario text and the example block are updated consistently (search for the strings "client_agent" and "description" and the header line) and fix the duplicated mentions around lines 30-32 accordingly.modules/system/event-broker/scenarios/flows/flow-7.2-two-consumer-rebalance.md-122-134 (1)
122-134:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSpecify language for fenced code block.
Line 122 contains a bare fenced code block (
```) without a language specifier. Since this contains JSON, it should be tagged as```jsonor the appropriate language to enable syntax highlighting and parsing.🐛 Proposed fix to add language tag
## Exchange 4 — A's open stream receives a topology frame On A's stream from Exchange 2, the next part is a `topology` frame (the stream is not closed): -``` +```json --evbkA1 Content-Type: application/json🤖 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 `@modules/system/event-broker/scenarios/flows/flow-7.2-two-consumer-rebalance.md` around lines 122 - 134, Add a language tag to the fenced code block containing the JSON payload so Markdown renders and highlights it correctly: update the opening fence from ``` to ```json for the block that begins with the marker `--evbkA1` and the `Content-Type: application/json` header in the file `flow-7.2-two-consumer-rebalance.md` (look for the fenced block around the JSON topology payload).Source: Linters/SAST tools
modules/system/event-broker/event-broker-sdk/src/mock/tests/consumer_flow.rs-113-119 (1)
113-119:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFail this test when the expected assignment is missing.
If
find(...)returnsNone, the test exits without any assertion and still passes. That makes assignment regressions invisible. Replace theif letwithexpect(...)so the test fails when partition0is not assigned.Possible fix
- let slot = sub_second + let slot = sub_second .assigned .iter() .find(|s| s.topic == TOPIC && s.partition == 0); - if let Some(slot) = slot { - assert_eq!(slot.offset, 1, "re-JOIN should start from cursor.acked=1"); - } + let slot = slot.expect("partition 0 should be assigned after re-JOIN"); + assert_eq!(slot.offset, 1, "re-JOIN should start from cursor.acked=1");🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/consumer_flow.rs` around lines 113 - 119, The test currently silently passes when the expected slot assignment is missing because it uses `if let Some(slot) = slot { ... }`; change this to assert presence by replacing the `find(...)` + conditional with a direct unwrap/assert, e.g. call `expect(...)` on the result of `sub_second.assigned.iter().find(|s| s.topic == TOPIC && s.partition == 0)` so the test fails if the slot for partition 0 is not assigned, then assert `slot.offset == 1` as before.modules/system/event-broker/event-broker-sdk/src/mock/tests/fanout.rs-67-72 (1)
67-72:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAssert the untouched cursor precisely.
unwrap_or(0) < 5still passes if group 2 is accidentally advanced to1..=4. Since this test never ACKs for group 2, the stronger contract is the exact untouched value (Nonein the current mock behavior). Tightening the assertion will catch partial cursor leakage across groups.Possible fix
- let g2_cursor = h.cursor(&group2, TOPIC, 0).await; - assert!( - g2_cursor.unwrap_or(0) < 5, - "g2 cursor must not be affected by g1 ack" - ); + assert_eq!( + h.cursor(&group2, TOPIC, 0).await, + None, + "g2 cursor must not be affected by g1 ack" + );🤖 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 `@modules/system/event-broker/event-broker-sdk/src/mock/tests/fanout.rs` around lines 67 - 72, The test currently checks g2_cursor.unwrap_or(0) < 5 which allows accidental partial advancement; change the assertion to require the exact untouched cursor value (None) for group2. Locate the test using h.cursor(&group2, TOPIC, 0).await and replace the loose assert with an equality check asserting g2_cursor == None (or assert!(g2_cursor.is_none())) so the mock guarantees no cursor leakage from group1's ack to group2.modules/system/event-broker/docs/features/0002-consumer-subscription-lifecycle.md-14-18 (1)
14-18:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix the stale TOC fragment for section 2.2.
The TOC entry points at
#22-seek-offset-override, but the actual heading slug comes from### 2.2 SEEK (set cursor; pre-stream or forward-ack). That link will not resolve.As per coding guidelines,
**/*.{md,markdown,adoc,asciidoc}: Generate Table of Contents (TOC) for artifact documentation.🤖 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 `@modules/system/event-broker/docs/features/0002-consumer-subscription-lifecycle.md` around lines 14 - 18, The TOC entry for section 2.2 points to the wrong slug (`#22-seek-offset-override`) which doesn’t match the actual heading "### 2.2 SEEK (set cursor; pre-stream or forward-ack)"; either update the TOC line under "2. Actor Flows (CDSL)" to use the correct slug (e.g. `#22-seek-set-cursor-pre-stream-or-forward-ack`) or rename the heading to match the existing TOC slug; adjust the link text in the TOC (the list item referencing 2.2) so it exactly matches the generated heading slug for "2.2 SEEK (set cursor; pre-stream or forward-ack)".Sources: Coding guidelines, Linters/SAST tools
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 095c512a-e137-4ebc-99a5-02840372aeba
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (147)
Cargo.tomldocs/GEARS.mdmodules/system/event-broker/docs/ADR/0001-partition-selection.mdmodules/system/event-broker/docs/ADR/0002-event-schema.mdmodules/system/event-broker/docs/ADR/0003-idempotent-producer-protocol.mdmodules/system/event-broker/docs/ADR/0004-subscription-filter-typing.mdmodules/system/event-broker/docs/DESIGN.mdmodules/system/event-broker/docs/PRD.mdmodules/system/event-broker/docs/USE_CASES.mdmodules/system/event-broker/docs/features/0001-idempotent-producers.mdmodules/system/event-broker/docs/features/0002-consumer-subscription-lifecycle.mdmodules/system/event-broker/docs/features/0003-topic-segment-introspection.mdmodules/system/event-broker/docs/features/0004-consumption-transport.mdmodules/system/event-broker/docs/migration.sqlmodules/system/event-broker/docs/openapi.yamlmodules/system/event-broker/docs/schemas/consumer_group.v1.schema.jsonmodules/system/event-broker/docs/schemas/event.v1.schema.jsonmodules/system/event-broker/docs/schemas/event_type.v1.schema.jsonmodules/system/event-broker/docs/schemas/subscription.v1.schema.jsonmodules/system/event-broker/docs/schemas/topic.v1.schema.jsonmodules/system/event-broker/event-broker-sdk/Cargo.tomlmodules/system/event-broker/event-broker-sdk/README.mdmodules/system/event-broker/event-broker-sdk/src/api.rsmodules/system/event-broker/event-broker-sdk/src/consumer/ack.rsmodules/system/event-broker/event-broker-sdk/src/consumer/backend.rsmodules/system/event-broker/event-broker-sdk/src/consumer/builder.rsmodules/system/event-broker/event-broker-sdk/src/consumer/consumer.rsmodules/system/event-broker/event-broker-sdk/src/consumer/dispatcher.rsmodules/system/event-broker/event-broker-sdk/src/consumer/mod.rsmodules/system/event-broker/event-broker-sdk/src/consumer/offset_manager.rsmodules/system/event-broker/event-broker-sdk/src/error.rsmodules/system/event-broker/event-broker-sdk/src/ids.rsmodules/system/event-broker/event-broker-sdk/src/internal/chain_state.rsmodules/system/event-broker/event-broker-sdk/src/internal/envelope.rsmodules/system/event-broker/event-broker-sdk/src/internal/mod.rsmodules/system/event-broker/event-broker-sdk/src/internal/outbox.rsmodules/system/event-broker/event-broker-sdk/src/internal/partitioning.rsmodules/system/event-broker/event-broker-sdk/src/internal/schema_cache.rsmodules/system/event-broker/event-broker-sdk/src/lib.rsmodules/system/event-broker/event-broker-sdk/src/mock/control.rsmodules/system/event-broker/event-broker-sdk/src/mock/core.rsmodules/system/event-broker/event-broker-sdk/src/mock/ingest.rsmodules/system/event-broker/event-broker-sdk/src/mock/mod.rsmodules/system/event-broker/event-broker-sdk/src/mock/rebalance.rsmodules/system/event-broker/event-broker-sdk/src/mock/storage.rsmodules/system/event-broker/event-broker-sdk/src/mock/stream.rsmodules/system/event-broker/event-broker-sdk/src/mock/stubs.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/backfill.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/consumer_flow.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/contracts.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/fanout.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/helpers.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/idempotency.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/mod.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/offsets.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/partitioning.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/producer_flow.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/rebalance.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/recovery.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/rolling_deploy.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/schema.rsmodules/system/event-broker/event-broker-sdk/src/mock/tests/standby.rsmodules/system/event-broker/event-broker-sdk/src/mock/transport.rsmodules/system/event-broker/event-broker-sdk/src/models.rsmodules/system/event-broker/event-broker-sdk/src/producer/async_producer.rsmodules/system/event-broker/event-broker-sdk/src/producer/backend.rsmodules/system/event-broker/event-broker-sdk/src/producer/mod.rsmodules/system/event-broker/event-broker-sdk/src/producer/sync_producer.rsmodules/system/event-broker/event-broker-sdk/src/typed_event.rsmodules/system/event-broker/event-broker-sdk/tests/contract.rsmodules/system/event-broker/event-broker-sdk/tests/integration_async_producer.rsmodules/system/event-broker/event-broker-sdk/tests/integration_consumer.rsmodules/system/event-broker/event-broker-sdk/tests/integration_producer.rsmodules/system/event-broker/event-broker-sdk/tests/unit_chain_state.rsmodules/system/event-broker/event-broker-sdk/tests/unit_errors.rsmodules/system/event-broker/event-broker-sdk/tests/unit_offset_manager.rsmodules/system/event-broker/event-broker-sdk/tests/unit_producer_builder.rsmodules/system/event-broker/event-broker-sdk/tests/unit_schema_cache.rsmodules/system/event-broker/event-broker-sdk/tests/unit_typed_event.rsmodules/system/event-broker/scenarios/INDEX.mdmodules/system/event-broker/scenarios/consumer-groups/README.mdmodules/system/event-broker/scenarios/consumer-groups/negative-1.5-delete-group-with-active-members.mdmodules/system/event-broker/scenarios/consumer-groups/negative-1.6-invalid-client-agent.mdmodules/system/event-broker/scenarios/consumer-groups/negative-1.7-get-unknown-group.mdmodules/system/event-broker/scenarios/consumer-groups/positive-1.1-create-anonymous-group.mdmodules/system/event-broker/scenarios/consumer-groups/positive-1.2-get-group-by-id.mdmodules/system/event-broker/scenarios/consumer-groups/positive-1.3-list-groups.mdmodules/system/event-broker/scenarios/consumer-groups/positive-1.4-delete-empty-group.mdmodules/system/event-broker/scenarios/errors/README.mdmodules/system/event-broker/scenarios/errors/errors-8.1-problem-details-envelope.mdmodules/system/event-broker/scenarios/errors/errors-8.2-401-unauthenticated.mdmodules/system/event-broker/scenarios/errors/errors-8.3-403-unauthorized.mdmodules/system/event-broker/scenarios/errors/errors-8.4-404-not-found.mdmodules/system/event-broker/scenarios/errors/errors-8.5-409-conflict.mdmodules/system/event-broker/scenarios/errors/errors-8.6-412-sequence-violation.mdmodules/system/event-broker/scenarios/errors/errors-8.7-429-rate-limited.mdmodules/system/event-broker/scenarios/errors/errors-8.8-500-internal.mdmodules/system/event-broker/scenarios/events/README.mdmodules/system/event-broker/scenarios/events/negative-4.10-rate-limited.mdmodules/system/event-broker/scenarios/events/negative-4.6-chained-sequence-violation.mdmodules/system/event-broker/scenarios/events/negative-4.7-schema-validation-failure.mdmodules/system/event-broker/scenarios/events/negative-4.8-mixed-partition-batch.mdmodules/system/event-broker/scenarios/events/negative-4.9-batch-too-large.mdmodules/system/event-broker/scenarios/events/positive-4.1-publish-single-async.mdmodules/system/event-broker/scenarios/events/positive-4.2-publish-sync-wait-persisted.mdmodules/system/event-broker/scenarios/events/positive-4.3-publish-batch.mdmodules/system/event-broker/scenarios/events/positive-4.4-chained-mode-sequence.mdmodules/system/event-broker/scenarios/events/positive-4.5-idempotency-key-dedup.mdmodules/system/event-broker/scenarios/flows/README.mdmodules/system/event-broker/scenarios/flows/flow-7.1-publish-subscribe-consume-ack.mdmodules/system/event-broker/scenarios/flows/flow-7.2-two-consumer-rebalance.mdmodules/system/event-broker/scenarios/flows/flow-7.3-positions-not-set-recovery.mdmodules/system/event-broker/scenarios/positions/README.mdmodules/system/event-broker/scenarios/positions/negative-3.5-out-of-range-offset.mdmodules/system/event-broker/scenarios/positions/negative-3.6-offset-above-hwm.mdmodules/system/event-broker/scenarios/positions/negative-3.7-mid-stream-backward-seek.mdmodules/system/event-broker/scenarios/positions/negative-3.9-seek-unassigned-partition.mdmodules/system/event-broker/scenarios/positions/positive-3.1-pre-stream-seek-earliest.mdmodules/system/event-broker/scenarios/positions/positive-3.10-pre-stream-any-value-in-range.mdmodules/system/event-broker/scenarios/positions/positive-3.2-pre-stream-seek-latest.mdmodules/system/event-broker/scenarios/positions/positive-3.3-pre-stream-seek-exact-offset.mdmodules/system/event-broker/scenarios/positions/positive-3.4-mixed-int-and-sentinels.mdmodules/system/event-broker/scenarios/positions/positive-3.8-mid-stream-forward-ack.mdmodules/system/event-broker/scenarios/subscriptions/README.mdmodules/system/event-broker/scenarios/subscriptions/negative-2.6-join-unauthorized-topic.mdmodules/system/event-broker/scenarios/subscriptions/negative-2.7-join-too-many-interests.mdmodules/system/event-broker/scenarios/subscriptions/negative-2.8-leave-unknown-subscription.mdmodules/system/event-broker/scenarios/subscriptions/positive-2.1-cold-join-fresh-group.mdmodules/system/event-broker/scenarios/subscriptions/positive-2.2-join-multi-topic-interests.mdmodules/system/event-broker/scenarios/subscriptions/positive-2.3-join-with-typed-filter.mdmodules/system/event-broker/scenarios/subscriptions/positive-2.4-parallelism-multiple-subscriptions.mdmodules/system/event-broker/scenarios/subscriptions/positive-2.5-leave-subscription.mdmodules/system/event-broker/scenarios/topics/README.mdmodules/system/event-broker/scenarios/topics/negative-5.3-segments-unknown-topic.mdmodules/system/event-broker/scenarios/topics/positive-5.1-list-topics.mdmodules/system/event-broker/scenarios/topics/positive-5.2-list-topic-segments.mdmodules/system/event-broker/scenarios/transports/README.mdmodules/system/event-broker/scenarios/transports/guardrail-6.7-stream-accept-json-rejected.mdmodules/system/event-broker/scenarios/transports/guardrail-6.8-sse-from-stream-endpoint.mdmodules/system/event-broker/scenarios/transports/negative-6.10-stream-rejects-timeout-collect-params.mdmodules/system/event-broker/scenarios/transports/negative-6.4-stream-positions-not-set.mdmodules/system/event-broker/scenarios/transports/negative-6.5-stream-unknown-subscription.mdmodules/system/event-broker/scenarios/transports/negative-6.6-stream-terminated-subscription.mdmodules/system/event-broker/scenarios/transports/positive-6.1-stream-multipart-frames.mdmodules/system/event-broker/scenarios/transports/positive-6.2-stream-heartbeat-cadence.mdmodules/system/event-broker/scenarios/transports/positive-6.3-stream-topology-frame-on-rebalance.mdmodules/system/event-broker/scenarios/transports/positive-6.9-sse-event-stream.md
c89c54c to
3cf3180
Compare
bd6d5b3 to
7bc6cd4
Compare
2f202d6 to
ac31e47
Compare
954494f to
a0e28de
Compare
e125899 to
a7a0492
Compare
dc1326f to
98b2491
Compare
f4570fe to
fbc2fb0
Compare
Signed-off-by: Striped Zebra <striped.zebra.dev@gmail.com>
fbc2fb0 to
8fcc371
Compare
Summary by CodeRabbit
Documentation
Chores