Skip to content

hermes peer dm reaches a hidden Bot Chat that rotated through compression (#106165, salvage #106365) - #106578

Merged
teknium1 merged 2 commits into
mainfrom
fix/peer-dm-hidden-compressed-bot-chat
Sep 9, 2026
Merged

teknium1 merged 2 commits into
mainfrom
fix/peer-dm-hidden-compressed-bot-chat

Conversation

@teknium1

@teknium1 teknium1 commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

hermes peer dm reaches a target whose canonical Bot Chat is hidden and has rotated through compression, instead of failing with HTTP 400 Title already in use.

Root cause

_project_compression_tips copies the tip's title over the root's unconditionally; the title is carried root→tip by the agent after publish_compression_child's transaction, so a rotation interrupted in between leaves "Bot Chat" on the ended root and NULL on the tip — the projected row then fails the handler's exact-title filter, the peer mints a duplicate and the UNIQUE(title) guard 400s.

Validation — live repro (real APIServerAdapter on loopback TCP, real SQLite state.db under a temp HERMES_HOME, stock hermes peer dm client; only the model turn stubbed)

python /tmp/peer_dm_repro.py <worktree> <label> — hidden Bot Chat root ended with end_reason=compression, untitled hidden tip:

[BEFORE-main] GET /api/sessions?title=Bot%20Chat&include_hidden=1 -> []
Peer 'spark': Peer already has a 'Bot Chat' session but it is hidden and the peer's gateway is too old to expose hidden sessions to this lookup (HTTP 400: Title already in use by session botchat_root). ...
[BEFORE-main] hermes peer dm spark -> rc=1
[BEFORE-main] RESULT: BUG FIRES

[AFTER-fix] GET /api/sessions?title=Bot%20Chat&include_hidden=1 -> [('botchat_tip', 'Bot Chat')]
[AFTER-fix] hermes peer dm spark -> rc=0 out={"peer": "spark", "profile": null, "session_id": "botchat_tip", "reply": "reply to: disk status?"}
[AFTER-fix] Bot Chat rows in state.db: [('botchat_root', 'Bot Chat')]   (no duplicate minted)
[AFTER-fix] RESULT: NEGATIVE (peer dm delivered into the live tip botchat_tip)

Sabotage (fix reverted, tests kept): 2 failed, 4 passed → with fix: 6 passed.

Premise check: with the normal rotation path (publish_compression_child + _carry_session_state_to_child) the title does land on the tip and the listing already finds it on main; the bug needs the carry to have not run/failed — a real, reachable state (the user hit it), so the fix goes where the title is lost rather than at the HTTP handler.

Salvage notes

Salvage of #106365 by @Finn763. Kept: the peer-dm e2e regression test (cherry-picked under their authorship). Replaced: the handler-level fallback in gateway/platforms/api_server.py::_handle_list_sessions (a second get_session_by_title + get_compression_tip lookup path with try/except: pass and nested suppress(Exception)) by the 5-line projection fix — one lookup path, every list consumer (API server, TUI gateway, dashboard, session_search) sees the name, no swallowed exceptions. Dropped: the listing-shape test (asserted the same row as the e2e test).

Closes #106165

Infographic

peer-dm-compressed-bot-chat

Finn763 and others added 2 commits September 9, 2026 05:17
…ough compression (#106165)

Regression test from PR #106365 (one of its two tests kept: the full peer-dm
e2e; the listing-shape test asserted the same row and was dropped). The
handler-level fallback that shipped with the test is replaced by a SessionDB
fix in the follow-up commit, so this commit carries only the test.
…the tip is untitled

`hermes peer dm` resolves the target's canonical Bot Chat with
GET /api/sessions?title=Bot%20Chat&include_hidden=1. list_sessions_rich
admits the hidden root via the chain search, then _project_compression_tips
overwrites every surfaced field — title included — with the live tip's. The
title is carried root->tip by the agent AFTER publish_compression_child's
transaction; a rotation cut off in between (crash, closed app, the tip's
title write failing) leaves "Bot Chat" on the ended root and NULL on the tip,
so the projected row carries title=None, the handler's exact-title filter
drops it, the peer POSTs a duplicate and the UNIQUE(title) guard answers
400 "Title already in use" (#106165).

Fix at the projection: fall back to the root's title only when the tip has
none (a titled tip keeps winning). Same COALESCE in the bounded recent-
sessions lister, the other place that projects a lineage onto its tip. This
replaces the handler-level fallback in PR #106365 (a second lookup path
bolted onto _handle_list_sessions with try/except: pass) with a 5-line fix
at the one place the title is lost, so every list consumer sees the name.

Salvage of #106365 by @Finn763.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Sep 9, 2026
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 6a86c3c — fix(state): projected compression tip inherits the root's ti

⚠️ Warnings

CI timings · View report · View job

Wall time 46m44s vs 4m48s (+873.6%). 10 job(s) slower, 3 faster, 1 unchanged.

  • Python tests / e2e: +21.0s
  • Python lints / Windows footguns (blocking): +19.0s
  • OS-specific tests / Windows-only tests: +15.0s
  • OSV scan / Emit review status: +8.0s
  • Check no committed infographics / check-no-committed-infographics: +7.0s

OSV vulnerability scan · View job

71 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.

@teknium1
teknium1 merged commit bca7cd0 into main Sep 9, 2026
94 of 98 checks passed
@teknium1
teknium1 deleted the fix/peer-dm-hidden-compressed-bot-chat branch September 9, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/cli CLI entry point, hermes_cli/, setup wizard 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.

peer dm fails against gateways whose canonical Bot Chat is hidden (incomplete #91583 fix)

3 participants