BUG-HUNT: [domain-model-invariant] Session._validate_message_ordering silently accepts duplicate sequence numbers #7722

Open
opened 2026-04-12 03:21:00 +00:00 by HAL9000 · 3 comments
Owner

Bug Report: Domain Model Invariant — Session Accepts Duplicate Sequence Numbers

Severity Assessment

  • Impact: Multiple messages with the same sequence number can coexist in a Session, breaking ordering guarantees and causing silent data corruption in export/import round-trips.
  • Likelihood: High — any code path that appends messages with duplicate sequence numbers (or reconstructs a session from storage with duplicates) bypasses this check.
  • Priority: High

Location

  • File: src/cleveragents/domain/models/core/session.py
  • Class: Session
  • Method: _validate_message_ordering
  • Lines: ~230–240

Description

The _validate_message_ordering model validator only checks that sequence numbers are in sorted order. It does NOT reject duplicate sequence numbers. Two or more messages with the same sequence value will pass validation as long as the list is non-decreasing.

Additionally, append_message() sets next_sequence = self.messages[-1].sequence + 1, which is correct for normal appends, but if the messages list is mutated externally (e.g. via Session(messages=[...]) constructor with pre-populated, possibly duplicated sequences), duplicates are silently accepted.

Evidence

# From session.py ~line 232
@model_validator(mode="after")
def _validate_message_ordering(self) -> Session:
    """Ensure messages are ordered by sequence."""
    if len(self.messages) > 1:
        sequences = [m.sequence for m in self.messages]
        if sequences != sorted(sequences):   # BUG: allows duplicates!
            raise ValueError("Messages must be ordered by sequence")
    return self

A sequence list like [0, 0, 1, 2] or [0, 1, 1, 2] would pass because sorted([0, 0, 1, 2]) == [0, 0, 1, 2].

Expected Behavior

The validator should reject duplicate sequence numbers. A valid message list must have strictly increasing (not just non-decreasing) sequence numbers.

Actual Behavior

Duplicate sequence numbers are silently accepted, violating the ordering invariant.

Suggested Fix

@model_validator(mode="after")
def _validate_message_ordering(self) -> Session:
    if len(self.messages) > 1:
        sequences = [m.sequence for m in self.messages]
        if sequences != sorted(set(sequences)):  # ensure unique AND sorted
            raise ValueError(
                "Messages must be ordered by sequence with no duplicates"
            )
        if len(sequences) != len(set(sequences)):
            raise ValueError("Messages must have unique sequence numbers")
    return self

Category

domain-model-invariant

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: bug-hunter

## Bug Report: Domain Model Invariant — Session Accepts Duplicate Sequence Numbers ### Severity Assessment - **Impact**: Multiple messages with the same sequence number can coexist in a Session, breaking ordering guarantees and causing silent data corruption in export/import round-trips. - **Likelihood**: High — any code path that appends messages with duplicate sequence numbers (or reconstructs a session from storage with duplicates) bypasses this check. - **Priority**: High ### Location - **File**: `src/cleveragents/domain/models/core/session.py` - **Class**: `Session` - **Method**: `_validate_message_ordering` - **Lines**: ~230–240 ### Description The `_validate_message_ordering` model validator only checks that sequence numbers are in **sorted order**. It does NOT reject duplicate sequence numbers. Two or more messages with the same `sequence` value will pass validation as long as the list is non-decreasing. Additionally, `append_message()` sets `next_sequence = self.messages[-1].sequence + 1`, which is correct for normal appends, but if the `messages` list is mutated externally (e.g. via `Session(messages=[...])` constructor with pre-populated, possibly duplicated sequences), duplicates are silently accepted. ### Evidence ```python # From session.py ~line 232 @model_validator(mode="after") def _validate_message_ordering(self) -> Session: """Ensure messages are ordered by sequence.""" if len(self.messages) > 1: sequences = [m.sequence for m in self.messages] if sequences != sorted(sequences): # BUG: allows duplicates! raise ValueError("Messages must be ordered by sequence") return self ``` A sequence list like `[0, 0, 1, 2]` or `[0, 1, 1, 2]` would pass because `sorted([0, 0, 1, 2]) == [0, 0, 1, 2]`. ### Expected Behavior The validator should reject duplicate sequence numbers. A valid message list must have strictly increasing (not just non-decreasing) sequence numbers. ### Actual Behavior Duplicate sequence numbers are silently accepted, violating the ordering invariant. ### Suggested Fix ```python @model_validator(mode="after") def _validate_message_ordering(self) -> Session: if len(self.messages) > 1: sequences = [m.sequence for m in self.messages] if sequences != sorted(set(sequences)): # ensure unique AND sorted raise ValueError( "Messages must be ordered by sequence with no duplicates" ) if len(sequences) != len(set(sequences)): raise ValueError("Messages must have unique sequence numbers") return self ``` ### Category domain-model-invariant ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-12 03:46:42 +00:00
Author
Owner

Verified — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Domain model bug: Session accepts duplicate sequence numbers silently. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#7722
No description provided.