Skip to content

fix(telegram): multiplexed profiles keep separate DM topic lanes in the shared state.db (#76423 #87239, salvage #76487) - #101249

Merged
teknium1 merged 5 commits into
mainfrom
salvage/mux-telegram-topics
Sep 2, 2026
Merged

teknium1 merged 5 commits into
mainfrom
salvage/mux-telegram-topics

Conversation

@teknium1

@teknium1 teknium1 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two bots served by one multiplexed gateway share state.db, and a private Telegram chat_id is the user's id —
identical across bots — so telegram_dm_topic_mode/telegram_dm_topic_bindings keyed by (chat_id) /
(chat_id, thread_id) made /topic on one bot enable topic recovery for every bot, let bindings clobber each
other, and had prune/cooldowns act on the wrong profile. Both tables now carry profile_name (leading the PK),
every gateway read/write passes the routed source.profile (never the process-global active profile), and
stale-topic prune resolves the namespace from send metadata.

Changes

  • schema v3: profile_name on both topic tables; one table-driven rebuild for v1/v2 → v3, legacy rows → default
  • GatewayRunner._telegram_topic_profile_name(source) threaded through all 10 topic call sites + /topic slash paths
  • lobby-reminder / capability-hint cooldowns keyed (profile, chat); /topic off resets the same key
  • outbound _thread_metadata_for_source stamps hermes_profile; Telegram prune uses it over the adapter stamp;
    secondary adapters stamped with their profile
  • docs: telegram.md under-the-hood + manual cleanup snippet

Validation

Probe (real SessionDB/GatewayRunner/TelegramAdapter, 2 profiles, 1 chat_id) main branch
/topic on alpha → beta topic mode ON (leak) OFF
alpha & beta bind thread 77 beta clobbers alpha both kept
beta root DM recovery steered to '77' None
prune stale 77 for routed alpha via primary bot beta row deleted beta row survives
alpha lobby reminder → beta reminder suppressed sent
Tests: 4 new (2 state, 2 gateway) + existing topic/prune/resume suites green; sabotage of the profile predicate fails both gateway tests.

Credits

@crdesign8 — #76487, commits cherry-picked with authorship (first submitter, 2026-08-02; sorry the conflicts sat
unanswered). @mjshorty — #76423 first report. @cherryb16 — #87239 / #87240 fuller diagnosis. @sadgen — #93491.

Fixes #76423
Fixes #87239

Infographic

mux-telegram-topics

@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown

૮ >ﻌ< ა ci review

ran on e3e07d2 — chore: map contributor crdesign8@hotmail.com -> @crdesign8

⚠️ Warnings

CI timings · View report · View job

Wall time 6m31s vs 4m32s (+43.8%). 9 job(s) slower, 4 faster, 2 unchanged.

  • Docs Site / docs-site-checks: +13.0s
  • Python tests / Run tests: +10.0s
  • Python lints / ruff enforcement (blocking): +6.0s
  • Python lints / Windows footguns (blocking): +5.0s
  • Python tests / e2e: +4.0s

OSV vulnerability scan · View job

13 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.

@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/plugins Plugin system and bundled plugins platform/telegram Telegram bot adapter area/config Config system, migrations, profiles area/profiles Multi-profile isolation, HERMES_HOME scoping area/sessions Session lifecycle, resume, persistence, history 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 sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Sep 2, 2026
crdesign8 and others added 5 commits September 2, 2026 05:46
Issue #76423: under multiplex_profiles a shared state.db keyed topic mode
and bindings only by Telegram chat_id/thread_id, so private-chat ids
collided across bots/profiles.

- Add profile_name to telegram_dm_topic_mode and telegram_dm_topic_bindings
- Schema v2→v3 rebuild; legacy rows migrate into the "default" namespace
- Keyword-only profile_name="default" on SessionDB topic APIs (compat)
Issue #76423 follow-up: wire SessionDB profile_name through gateway paths.

- Resolve profile from source.profile (never process-global active profile)
- Stamp adapter._hermes_profile_name for prune under multiplex
- /topic enable/status and binding record/recover/disable/restore paths
Address hermes-sweeper review on #76487:

- Prefer hermes_profile from send metadata when pruning stale topic
  bindings so profile_routes cannot delete the transport adapter's
  namespace instead of the routed runtime's
- Namespace lobby/capability cooldowns and /topic off cleanup by
  (profile, chat_id)
- Document profile_name PKs and scoped cleanup SQL in telegram.md
- Regression: primary-adapter stamp + routed metadata prune isolation
…driven rebuild

Same behavior as the salvaged #76487 migration (fresh installs get the v3
shape; v1/v2 tables rebuild with profile_name leading the PK, legacy rows
into 'default' only, CASCADE FK supplied on the way), with the per-table
DDL written once instead of three times and the now-redundant v1->v2
CASCADE-only rebuild dropped (the v3 rebuild subsumes it).

Co-authored-by: Celio Monteiro <crdesign8@hotmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles area/profiles Multi-profile isolation, HERMES_HOME scoping area/sessions Session lifecycle, resume, persistence, history comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades 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

3 participants