Skip to content

fix(slack): ignore stale thread sessions - #55240

Closed
ooiuuii wants to merge 1 commit into
NousResearch:mainfrom
ooiuuii:fix/slack-reset-thread-context
Closed

fix(slack): ignore stale thread sessions#55240
ooiuuii wants to merge 1 commit into
NousResearch:mainfrom
ooiuuii:fix/slack-reset-thread-context

Conversation

@ooiuuii

@ooiuuii ooiuuii commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #55239.

Slack thread auto-engagement now treats an existing session key as active only if the session store would keep that entry fresh under the current reset policy. If _should_reset() says the entry is stale, _has_active_session_for_thread() returns false so the first reply after reset can fetch Slack thread context before the fresh session turn starts.

Validation

  • python -m pytest tests\gateway\test_slack_approval_buttons.py -q --basetemp .pytest-tmp-slack-reset — 27 passed
  • python -m pytest tests\gateway\test_slack.py -q --basetemp .pytest-tmp-slack-main — 209 passed
  • python -m ruff check plugins\platforms\slack\adapter.py tests\gateway\test_slack_approval_buttons.py — passed
  • git diff --check origin/main...HEAD — passed

Pytest emitted existing AsyncMock runtime warnings in Slack tests; no failures.

AI Assistance

Implemented with Codex assistance. I reviewed the diff and ran the focused validation above.

@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/slack Slack app adapter P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jun 29, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: LGTM

Clean fix — Slack stale thread sessions are now properly ignored by checking _should_reset before returning True. The test is well-designed with a mock Store class that simulates the stale session scenario.

Correctness: The check correctly prevents stale sessions from being treated as active.
Testing: Dedicated test case verifying the stale session returns False.


Reviewed by Hermes Agent

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: LGTM

Fixes Slack thread auto-engagement to treat existing session keys as active only if the session store would keep that entry fresh under the current reset policy.

  • Clean fix with dedicated test
  • Well-scoped: 2 files, 34 additions

Reviewed 2 files, 34 additions. Approved.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused stale-session fix. The current-main premise is real: Slack still classifies any retained key as active at plugins/platforms/slack/adapter.py:4043, before routing later evaluates freshness.

Problems

  • plugins/platforms/slack/adapter.py:3814 only consults _should_reset(). The real SessionStore transition additionally treats DB-ended sessions (gateway/session.py:1870, 1903-1919), suspended entries (gateway/session.py:1871-1872), and expired resume_pending entries (gateway/session.py:1873-1882) as non-reusable. Those states would still suppress the Slack thread-context reseed.
  • The added test only stubs an "idle" result from _should_reset(); it does not compare the helper with actual SessionStore behavior for the other reset paths.

Suggested changes

  • Make the Slack active-session check share a non-mutating SessionStore freshness predicate covering the full routing decision.
  • Add real-SessionStore coverage for the stale states above.

Automated hermes-sweeper review.

return False

should_reset = getattr(type(session_store), "_should_reset", None)
if callable(should_reset) and should_reset(session_store, entry, source):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_should_reset() is only one part of the routing freshness decision. SessionStore._get_or_create_session_impl() also invalidates DB-ended sessions, suspended entries, and expired resume_pending entries (gateway/session.py:1870-1884), so this still returns true for keys that the next routing step will replace.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/sessions Session lifecycle, resume, persistence, history labels Jul 15, 2026
teknium1 pushed a commit that referenced this pull request Jul 22, 2026
…eseed

A session key that exists in the store but would be rolled to a fresh
session by the reset policy (daily/idle/suspended) is not an active
session. Treating it as active suppressed the first-turn Slack
thread-history reseed after reset (#55239).

_has_active_session_for_thread() now consults SessionStore._should_reset
so a stale entry gates like a missing one, letting _fetch_thread_context
reseed the fresh session with recent thread history.

Fixes #55239.

Salvaged from #55240 by @ooiuuii.
teknium1 pushed a commit that referenced this pull request Jul 22, 2026
…eseed

A session key that exists in the store but would be rolled to a fresh
session by the reset policy (daily/idle/suspended) is not an active
session. Treating it as active suppressed the first-turn Slack
thread-history reseed after reset (#55239).

_has_active_session_for_thread() now consults SessionStore._should_reset
so a stale entry gates like a missing one, letting _fetch_thread_context
reseed the fresh session with recent thread history.

Fixes #55239.

Salvaged from #55240 by @ooiuuii.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #69320 — your commit was cherry-picked onto current main with your authorship preserved in git history: your stale-session gate was cherry-picked directly and fixes #55239.

Thanks for the contribution!

@teknium1 teknium1 closed this Jul 22, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…eseed

A session key that exists in the store but would be rolled to a fresh
session by the reset policy (daily/idle/suspended) is not an active
session. Treating it as active suppressed the first-turn Slack
thread-history reseed after reset (NousResearch#55239).

_has_active_session_for_thread() now consults SessionStore._should_reset
so a stale entry gates like a missing one, letting _fetch_thread_context
reseed the fresh session with recent thread history.

Fixes NousResearch#55239.

Salvaged from NousResearch#55240 by @ooiuuii.
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/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/slack Slack app adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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.

Slack stale thread sessions suppress reset-time thread context

4 participants