Skip to content

fix(state): finish the #80216 bug class — archive-preserving rewrites at the ACP and TUI sibling sites - #80933

Merged
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:fix/replace-messages-archive-siblings
Aug 7, 2026
Merged

fix(state): finish the #80216 bug class — archive-preserving rewrites at the ACP and TUI sibling sites#80933
kshitijk4poor merged 2 commits into
NousResearch:mainfrom
kshitijk4poor:fix/replace-messages-archive-siblings

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Collaborator

Summary

Finishes the #80216 bug class: the two remaining rewrite paths that could still destroy soft-archived (active=0/compacted=1) in-place-compaction history now replace only the live rows. #80913 fixed /retry and yuanbao recall; this covers the ACP adapter and the TUI edit/regenerate path, so every production transcript-rewrite site is now archive-preserving.

Who hits this: anyone using Hermes via ACP (VS Code/Zed/JetBrains) or the desktop/TUI whose conversation has been compacted — one edit/regenerate (TUI) or one non-owned _persist with a failing probe (ACP) permanently deleted their searchable pre-compaction history, silently.

Changes

  • acp_adapter/session.py _persist: replace the fail-open has_archived_messages probe (except: has_archived = False → destructive full replace; also racy vs a concurrent archive_and_compact) with unconditional active_only=True. On a fresh create/fork all rows are active=1, so behavior is identical there; when archived rows exist they now survive.
  • tui_gateway/methods_prompt.py edit/regenerate truncation: bare replace_messages()active_only=True.
  • hermes_state.py: has_archived_messages docstring updated — its only production caller is gone; kept for tests/diagnostics.
  • tests/test_tui_gateway_server.py: 6 _StubDb.replace_messages signatures accept the new kwarg.
  • New tests/hermes_state/test_replace_messages_archive_siblings.py (5 tests): real-SQLite archive survival for both write shapes, fresh-session equivalence (the invariant the unconditional switch rests on), and source-level guards pinning that neither site re-grows the fail-open probe.

Validation

Before After
ACP _persist, probe raises full DELETE incl. archives (fail-open) archives survive
TUI edit/regenerate on compacted session archives deleted archives survive
Fresh session (no archives) full replace identical (proven by test)
Mutation check reverting either fix fails its source guard; suites 82+35 green

Follow-up to #80216 / #80913 (@Adolanium, @poisdahl). The ACP probe pattern was flagged during the #80218 review as the origin of this follow-up.

…ing rewrites at the two remaining sibling sites

NousResearch#80216 fixed /retry (and a follow-up fixed yuanbao recall) destroying
soft-archived active=0/compacted=1 in-place-compaction rows via the
destructive replace_messages default. Two sibling sites still carried the
same class:

- acp_adapter/session.py _persist (non-owned-agent branch): probed
  has_archived_messages and FAILED OPEN into the destructive full replace
  on any probe error; the probe can also race a concurrent
  archive_and_compact. Now passes active_only=True unconditionally — on a
  fresh create/fork every row is active=1 so behavior is identical, and
  the probe (its only production caller) is deleted.
- tui_gateway/methods_prompt.py edit/regenerate truncation: bare
  replace_messages() deleted the archived transcript of a compacted
  session on every edit/regenerate. Now active_only=True.

hermes_state.has_archived_messages docstring updated (probe is now
test/diagnostic-only). Test stubs in test_tui_gateway_server.py accept the
new kwarg. New regression tests: real-SQLite archive-survival for both
write shapes, fresh-session equivalence (the claim the unconditional
switch rests on), and source-level guards pinning that neither site
re-grows the fail-open probe (both mutation-checked: revert either fix and
its guard fails).
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/acp Agent Communication Protocol adapter comp/tui Terminal UI (ui-tui/ + tui_gateway/) area/sessions Session lifecycle, resume, persistence, history area/compression Context compression and continuation sessions sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Aug 7, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #80195 already covers the TUI prompt-submit rewrite site. This PR overlaps that repair and additionally addresses the ACP persistence path; please consider consolidating the TUI portion.

…public-API row counting

- state_db fixture: drop the HERMES_HOME setenv + sys.modules purge
  (SessionDB takes an explicit path; tests/conftest.py already sandboxes
  HERMES_HOME; the purge risks split-class identity for other modules
  holding the old hermes_state reference) — matches the plain
  tests/hermes_state/ sibling fixture pattern.
- probe guard asserts on the CALL ('has_archived_messages(') instead of a
  local-variable name — a reintroduced probe under any rename now trips
  it (mutation-checked: renamed-probe reintroduction fails the guard;
  restored stack green).
- _archived_count uses the public get_messages(include_inactive=True)
  instead of poking db._lock/_conn.
@kshitijk4poor
kshitijk4poor enabled auto-merge August 7, 2026 10:13
@kshitijk4poor
kshitijk4poor merged commit 427584b into NousResearch:main Aug 7, 2026
40 checks passed
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…messages-archive-siblings

fix(state): finish the NousResearch#80216 bug class — archive-preserving rewrites at the ACP and TUI sibling sites
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/compression Context compression and continuation sessions area/sessions Session lifecycle, resume, persistence, history comp/acp Agent Communication Protocol adapter comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants