Skip to content

Release v0.51.235 — Release HC (stage-q5): no duplicate transcript replay on repeated questions after compression - #3490

Merged
nesquena-hermes merged 1 commit into
masterfrom
release/stage-q5
Jun 3, 2026
Merged

nesquena-hermes merged 1 commit into
masterfrom
release/stage-q5

Conversation

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Release v0.51.235 — Release HC (stage-q5)

Single fix in the data-sensitive transcript-merge path, with a Codex-found MUST-FIX applied.

Fix

PR Author Fix
#3468 @jasonjcwu _find_current_user_turn returns the last matching user turn instead of the first, so post-compression result_messages (which carries the full history) no longer replays the entire conversation when the user repeats a similar question (137-msg session → 89 duplicate replays).

Pre-release review caught a CORE issue (fixed before ship)

Codex's regression gate found that a naive last-match could be overridden by a synthetic role:"user" continuation prompt (the agent loop injects "Continue"/empty-recovery nudges — verified at conversation_loop.py:1763/4183/4356) that only substring-matches the user text — anchoring the merge past the real turn and dropping the assistant/tool output in between. Applied the fix: track strong (exact _looks_like_current_user_turn) and weak (substring) matches separately and return last_strong → last_weak → fallback. The real turn (strong) always wins over a later synthetic continuation (weak).

Opus reviewed the original and said ship; the applied fix is strictly safer than what it reviewed.

Gate results

  • Full pytest suite: 7465 passed, 8 skipped, 3 xpassed, 0 failed
  • ruff forward gate: CLEAN
  • browser-smoke gate: CLEAN
  • Codex (regression): SHIP ONLY WITH FIXES → fix applied → re-reviewed SAFE TO SHIP
  • Opus (correctness): SHIP IT (on the pre-fix code; applied fix is strictly safer)
  • Regression test (tests/test_issue3468_duplicate_after_compression.py, 7 cases): pins the last-match behavior, the strong-beats-later-weak invariant, and the end-to-end no-duplicate-replay invariant — each verified to fail against the pre-fix logic.

Co-authored-by: jasonjcwu jasonjcwu@users.noreply.github.com

No duplicate transcript replay on repeated questions after compression.

- #3468 _find_current_user_turn returns the LAST matching user turn (not first),
  so post-compression result_messages carrying full history no longer replays the
  whole conversation when the user repeats a similar question (@jasonjcwu).
  + regression test (fails against the pre-fix first-match logic).

Co-authored-by: jasonjcwu <jasonjcwu@users.noreply.github.com>
@nesquena-hermes
nesquena-hermes merged commit aae584b into master Jun 3, 2026
11 checks passed
@nesquena-hermes
nesquena-hermes deleted the release/stage-q5 branch June 3, 2026 17:12
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
## Release v0.51.235 — Release HC (stage-q5)

Single fix in the data-sensitive transcript-merge path, with a Codex-found MUST-FIX applied.

### Fix
| PR | Author | Fix |
|----|--------|-----|
| nesquena#3468 | @jasonjcwu | `_find_current_user_turn` returns the **last** matching user turn instead of the first, so post-compression `result_messages` (which carries the full history) no longer replays the entire conversation when the user repeats a similar question (137-msg session → 89 duplicate replays). |

### Pre-release review caught a CORE issue (fixed before ship)
Codex's regression gate found that a naive last-match could be overridden by a **synthetic `role:"user"` continuation prompt** (the agent loop injects "Continue"/empty-recovery nudges — verified at `conversation_loop.py:1763/4183/4356`) that only *substring*-matches the user text — anchoring the merge **past** the real turn and dropping the assistant/tool output in between. Applied the fix: track **strong** (exact `_looks_like_current_user_turn`) and **weak** (substring) matches separately and return `last_strong → last_weak → fallback`. The real turn (strong) always wins over a later synthetic continuation (weak).

Opus reviewed the original and said ship; the applied fix is strictly safer than what it reviewed.

### Gate results
- **Full pytest suite**: 7465 passed, 8 skipped, 3 xpassed, **0 failed**
- **ruff forward gate**: CLEAN
- **browser-smoke gate**: CLEAN
- **Codex (regression)**: SHIP ONLY WITH FIXES → fix applied → re-reviewed **SAFE TO SHIP**
- **Opus (correctness)**: SHIP IT (on the pre-fix code; applied fix is strictly safer)
- **Regression test** (`tests/test_issue3468_duplicate_after_compression.py`, 7 cases): pins the last-match behavior, the strong-beats-later-weak invariant, and the end-to-end no-duplicate-replay invariant — each **verified to fail against the pre-fix logic**.

Co-authored-by: jasonjcwu <jasonjcwu@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant