Two multiplex key/store mismatches in the gateway session layer:
- SessionStore._db_for_key resolved legacy agent:main keys to the AMBIENT
store. Named-profile keys were already pinned to profiles/<x>/state.db
(#97309), but a default-profile session touched inside a secondary's
runtime scope (a coalesced async-delegation drain, a cron mirror into a
default chat, a scoped watcher) was written into the secondary's state.db
— the profile_name='<A>' row inside B's store reported in #102157, after
which the routing index and row disagree and the #54878 self-heal drops a
live conversation. Default keys now resolve to _routing_home/state.db, the
launch home already pinned for the routing index. Single-profile gateways
(multiplex off) keep the ambient store byte-for-byte.
- /undo evicted the cached agent under build_session_key(source) —
agent:main:… — while the cache is keyed by the profile namespace, so on a
secondary profile the eviction missed and the next turn reused an agent
whose in-memory history still held the undone turns. Use
_session_key_for_source like /reset and /retry.
Addresses #102157.
hermes_state.py: delete every '# noqa: F401 (re-exported...)' import block (hermes_state_common/errors/guard/
readpool/sessions/fts/dbfile/wal/repair/registry + agent.context_compressor _DB_PERSISTED_MARKER_KEY); keep
only the names hermes_state.py itself uses, without noqa.
hermes_state_registry.py: drop get_shared_session_db/release_shared_session_db/close_shared_session_dbs
aliases; every caller (gateway/, tools/, tui_gateway/, cron/, mcp_serve, run_agent, tests) now imports
acquire/release/close_all/release_or_close from hermes_state_registry.
hermes_state_titles.py: drop set_auto_title_if_empty shim (title_generator keeps its getattr fallback).
Re-remove shim-only names restored by 34abf954bd: latest_user_message_row_id (tests call
latest_message_row_id(key, role='user'); role-targeting assertions kept) and get_session_activity (tests
build the snapshot via agent.session_activity.build_activity_snapshot over db.get_session(sid)).
hermes_state_wal._log_once resolves its dedupe sets as module globals instead of via hermes_state;
hermes_state_repair helpers call module globals directly (tests patch hermes_state_repair.<name>).
Frozen updater surface untouched (update_cmd_maint imports only SessionDB from hermes_state).
Re-applies the gateway compat removal byte-for-byte; see 92d0bd0d73 for the
full inventory (30 re-exports/aliases + 2 shim modules dropped, 3 shim-only
names re-removed, 24 callers + 34 test files repointed). No new changes.
For each issue anchor present in BASE 63279301bc non-test .py and absent on HEAD, the BASE comment/docstring block was re-attached at the HEAD location of the code it explained (matched by the distinctive code line / enclosing def). Sentences already covered by an existing HEAD comment were deduped; the issue number always survives. Insert-only: no code lines changed.