Skip to content

fix(gateway): resume cold persisted messaging sessions - #139802

Open
KoNit-K wants to merge 2 commits into
NousResearch:mainfrom
KoNit-K:fix/139796-cold-session-resume
Open

KoNit-K wants to merge 2 commits into
NousResearch:mainfrom
KoNit-K:fix/139796-cold-session-resume

Conversation

@KoNit-K

@KoNit-K KoNit-K commented Oct 16, 2026

Copy link
Copy Markdown

What does this PR do?

Restores persisted messaging sessions when Desktop calls session.resume after the gateway has restarted or its in-memory live entry was reaped. The session history remains visible and attachable instead of returning not_found.

Related Issue

Fixes #139796

Type of Change

  • Bug fix

Changes Made

  • gateway/session_authority.py — falls back from an absent API binding to durable messaging-session recovery on a live-registry miss.
  • gateway/session_messaging_recovery.py — validates the persisted routing origin, materializes the route, and restores its transport-profile identity before attaching a viewer.
  • tests/gateway/test_session_messaging_recovery.py — covers a cold Feishu group session, persisted transcript hydration, and multiplex transport identity restoration.

How to Test

Run scripts/run_tests.sh tests/gateway/test_local_session_recovery.py tests/gateway/test_session_messaging_recovery.py — 5 passed, 1 platform-specific test skipped on macOS.

Run $HERMES_PYTHON -m ruff check gateway/session_authority.py gateway/session_messaging_recovery.py tests/gateway/test_session_messaging_recovery.py — passed.

Evidence

BEFORE RED: a registry miss first tried local-policy recovery, then API-binding recovery. A persisted Feishu session has neither record, so session.resume returned not_found even though its session row and messages remained stored.

AFTER GREEN: the new cold-session regression creates a persisted Feishu group session with no live authority entry; attach() restores its history and keeps the persisted multiplex transport owner. The focused test command passed 5 tests.

CONTROL: existing local cold-recovery coverage passed in the same command; local and API recovery remain their dedicated paths.

Checklist

Code

  • I've read the Contributing Guide.
  • My commit message follows Conventional Commits.
  • I searched for competing PRs before implementation.
  • This PR contains only the session-resume recovery fix.
  • I've run the relevant tests locally (see How to Test).
  • I've added regression coverage for the reported recovery path.
  • I've tested on macOS.

Documentation & Housekeeping

  • Documentation update: N/A; this changes an internal recovery path only.
  • cli-config.yaml.example: N/A.
  • CONTRIBUTING.md and AGENTS.md: N/A.
  • Cross-platform impact considered; the Python recovery path is platform-neutral, while one Linux-marked control test remains for CI.
  • Tool descriptions and schemas: N/A.
  • Completed two rounds of P0 review; the final review reported P0=0.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery comp/desktop Electron desktop app (apps/desktop/*) platform/feishu Feishu / Lark adapter area/sessions Session lifecycle, resume, persistence, history sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Oct 16, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for this. Package 7 (#140138) fixes RT-30 in #140183 without this PR because it only works when the stored origin matches exactly, ignores the live routing entry, and doesn't check which profile owns the row. I'll close this once #140183 merges.

@KoNit-K

KoNit-K commented Oct 18, 2026

Copy link
Copy Markdown
Author

Thanks @teknium1. I checked all three points against the original implementation and the current head. The original path required an exact origin_json match; it checked the existing route for conflicts but did not prefer its source, and lacked an explicit owning-profile fence.

#140183 merged as b91f7ae and is already an ancestor of this PR’s current head, f2abe0f. Its gateway/session_route_recovery.py prefers the routing entry, falls back to the stored origin/row columns, and checks the route’s profile against the serving authority. The original helper is gone, and this PR now has zero changed files (its tree equals base b3c2883).

Self-review: no further code change is needed for this discussion; the upstream replacement covers these concerns. Verified by code inspection, commit ancestry and tree comparison. No tests were run in this follow-up; this head has no check runs or reported status contexts. Leaving closure to the maintainers.

This branch has not been deployed

No deployments
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/desktop Electron desktop app (apps/desktop/*) comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/feishu Feishu / Lark adapter sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

3 participants