Skip to content

fix: avoid false response-interrupted stale repair markers - #3046

Merged
4 commits merged into
nesquena:masterfrom
ai-ag2026:fix/compression-parent-stale-repair
May 28, 2026
Merged

4 commits merged into
nesquena:masterfrom
ai-ag2026:fix/compression-parent-stale-repair

Conversation

@ai-ag2026

@ai-ag2026 ai-ag2026 commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • skips stale-pending repair for archived pre-compression snapshot parent sessions
  • detects when a compression parent already has a continuation and avoids adding a false interrupted-turn marker
  • clears the runtime-only pre_compression_snapshot flag on the live continuation after preserving the archived snapshot
  • treats ACTIVE_RUNS worker bookkeeping as authoritative liveness in _clear_stale_stream_state() before writing an interrupted-turn marker
  • honors the pending-turn stale-repair grace window in _clear_stale_stream_state() so fresh turns are not marked interrupted just because the SSE channel is temporarily missing
  • trusts a terminal completed run journal before manufacturing an interrupted-turn marker, clearing stale pending runtime fields without altering a completed transcript
  • compares stale pending text against the latest user message, not only the last transcript message, so completed user→assistant turns are recognized as already checkpointed
  • adds regression coverage for parent/continuation repair guards, continuation runtime flag clearing, active-worker stale-stream deferral, fresh pending-turn grace deferral, and completed-journal late-pending cleanup

Why

A live auto-compression rotation can leave the archived parent with a pending/stale-looking runtime shape while the real response continues in the child session. The recovery pass should not repair that parent as an interrupted turn. Doing so creates a false "Response interrupted" marker and can hide or confuse the visible continuation.

A second observed path produced the same user-visible false marker without compression: _clear_stale_stream_state() checked only whether the SSE stream id was present in STREAMS. If that channel was gone or not visible while the worker was still alive in ACTIVE_RUNS, the route-level cleanup could call the core sync/error-marker repair path immediately and append a false "Response interrupted" marker even though the worker continued running API calls and tools.

A third observed path happened after a turn had already completed: the run journal contained a terminal completed event and the assistant answer was already in the transcript, but the sidecar still had stale pending_user_message / active_stream_id. A later stale cleanup saw no live stream/worker and appended a false marker. This PR now treats a completed journal as authoritative and clears the stale runtime fields without adding an interruption marker.

This is a concrete run-state consistency slice under #2361. It is adjacent to, but separate from, #2980: #2980 handles reload/sidebar continuation recovery, while this PR prevents backend stale-repair paths from manufacturing the bad interrupted state in the first place.

Refs #2361

Validation

  • python3 -m pytest tests/test_stale_stream_writeback.py::test_stale_stream_clear_trusts_completed_run_journal_instead_of_adding_marker -q → 1 passed
  • python3 -m pytest tests/test_stale_stream_writeback.py -q → 8 passed
  • python3 -m pytest tests/test_stale_stream_writeback.py tests/test_session_sidecar_repair.py tests/test_session_lost_response_regression.py tests/test_issue2157_sessions_list_stale_stream_state.py -q → 91 passed
  • GitHub Actions on 3469a2f: Python 3.11, 3.12, and 3.13 passed

@ai-ag2026 ai-ag2026 changed the title fix: skip stale repair for compression parents fix: avoid false response-interrupted stale repair markers May 28, 2026
@nesquena-hermes nesquena-hermes closed this pull request by merging all changes into nesquena:master in 6267716 May 28, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Shipped in v0.51.154 / Release DZ (stage-batch36, commit 6267716). Thanks for the contribution!

ai-ag2026 pushed a commit to ai-ag2026/hermes-webui that referenced this pull request May 28, 2026
# Conflicts:
#	CHANGELOG.md
ai-ag2026 pushed a commit to ai-ag2026/hermes-webui that referenced this pull request May 28, 2026
9-PR medium-risk cleanup:
- nesquena#3037 routes.py: argv-style prefill hook + env-var override for notes drawer
- nesquena#3046 models.py: compression parent not repaired as stale interrupted turn
- nesquena#3048 session_discoverability.py: --repair-safe CLI with default dry-run
- nesquena#3053 ui.js: streaming KaTeX guard for parser-owned equations
- nesquena#3059 models.py: empty partial activity rows excluded from sidebar recency
- nesquena#3060 profiles.py: API key writes to .env (chmod 600), not config.yaml
- nesquena#3064 routes.py: MEDIA: image tokens allow exact session-referenced paths
- nesquena#3069 models.py: cron sessions with project_id surface via Cron Jobs chip
- nesquena#3077 gateway_chat.py: HTTP 401 maps to gateway_auth_error event
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
# Conflicts:
#	CHANGELOG.md
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
9-PR medium-risk cleanup:
- nesquena#3037 routes.py: argv-style prefill hook + env-var override for notes drawer
- nesquena#3046 models.py: compression parent not repaired as stale interrupted turn
- nesquena#3048 session_discoverability.py: --repair-safe CLI with default dry-run
- nesquena#3053 ui.js: streaming KaTeX guard for parser-owned equations
- nesquena#3059 models.py: empty partial activity rows excluded from sidebar recency
- nesquena#3060 profiles.py: API key writes to .env (chmod 600), not config.yaml
- nesquena#3064 routes.py: MEDIA: image tokens allow exact session-referenced paths
- nesquena#3069 models.py: cron sessions with project_id surface via Cron Jobs chip
- nesquena#3077 gateway_chat.py: HTTP 401 maps to gateway_auth_error event
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
# Conflicts:
#	CHANGELOG.md
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
9-PR medium-risk cleanup:
- nesquena#3037 routes.py: argv-style prefill hook + env-var override for notes drawer
- nesquena#3046 models.py: compression parent not repaired as stale interrupted turn
- nesquena#3048 session_discoverability.py: --repair-safe CLI with default dry-run
- nesquena#3053 ui.js: streaming KaTeX guard for parser-owned equations
- nesquena#3059 models.py: empty partial activity rows excluded from sidebar recency
- nesquena#3060 profiles.py: API key writes to .env (chmod 600), not config.yaml
- nesquena#3064 routes.py: MEDIA: image tokens allow exact session-referenced paths
- nesquena#3069 models.py: cron sessions with project_id surface via Cron Jobs chip
- nesquena#3077 gateway_chat.py: HTTP 401 maps to gateway_auth_error event
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.

2 participants