Skip to content

fix(context): to_compress built from HashSet iteration — non-deterministic LLM summarization order #4558

@bug-ops

Description

@bug-ops

Description

In crates/zeph-core/src/agent/tool_execution/focus.rs, select_messages_for_compression builds to_compress by iterating over a HashSet<usize> (line 323):

```rust
let to_compress: Vec<zeph_llm::provider::Message> = to_remove_indices
.iter()
.map(|&i| self.msg.messages[i].clone())
.collect();
```

HashSet does not guarantee iteration order, so the messages passed to build_compression_prompt arrive in a random chronological order on each run. This produces variable summarization quality and makes results non-reproducible across identical sessions.

Note: apply_compression_removals already handles this correctly by sorting the to_remove_indices before deletion — the fix needed is only in the to_compress construction.

Reproduction Steps

  1. Enable compress_context or request_compaction in a session.
  2. Observe that the bullet list in the compression prompt has messages in non-chronological order across multiple runs with identical input.

Expected Behavior

Messages passed to the compression LLM prompt should be in the same chronological order as they appear in self.msg.messages (ascending index order).

Actual Behavior

Messages are ordered by HashSet iteration, which is non-deterministic.

Fix

Replace the HashSet iteration with a sorted iteration:

```rust
let mut sorted_indices: Vec = to_remove_indices.iter().copied().collect();
sorted_indices.sort_unstable();
let to_compress: Vec<zeph_llm::provider::Message> = sorted_indices
.iter()
.map(|&i| self.msg.messages[i].clone())
.collect();
```

Environment

  • Commit: 08021ee
  • Feature: compress_context / ARC request_compaction

Logs / Evidence

Code review of crates/zeph-core/src/agent/tool_execution/focus.rs:317-328 (CI-889 arch audit).

Metadata

Metadata

Assignees

Labels

P3Research — medium-high complexitybugSomething isn't workingllmzeph-llm crate (Ollama, Claude)

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions