Skip to content

revert: 4 Telegram salvages flagged as broken or risky by post-merge audit - #28575

Merged
teknium1 merged 4 commits into
mainfrom
hermes/hermes-6063e704
May 19, 2026
Merged

revert: 4 Telegram salvages flagged as broken or risky by post-merge audit#28575
teknium1 merged 4 commits into
mainfrom
hermes/hermes-6063e704

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Post-merge audit (parallel subagent fan-out across 9 clusters) flagged 4 of the 44 Telegram salvages as broken or unsafe. Reverting them.

Reverts (newest-first to minimize conflicts)

1. Revert #26636 "pin incoming user message for duration of agent turn" (a724c3b)

Issue: Pin/unpin enabled UNCONDITIONALLY with no opt-out flag.

  • Pinning every user message is a default-on UX-invasive behavior change affecting ALL Telegram users globally.
  • Group chats: requires Pin Messages admin permission; without it every message logs a debug-level failure (silent noise).
  • Forum topics: pin semantics differ per-topic; behavior may be confusing.
  • No tests added.
  • Original PR's commit message mentions session_context.py and run.py edits, but the actual diff only touches telegram.py.

Unpin DOES fire reliably on cancel/exception (on_processing_complete invoked in both paths), so that aspect was correct — the issue is the default-on policy without an opt-in flag.

Path forward: Re-merge gated behind extra.pin_user_messages: true with tests.

2. Revert #28015 "support quick-command-only menus" (b1acf80)

Issue: Feature is non-functional. The salvage references self._runner_ref, but no code in the repo ever assigns _runner_ref to a TelegramAdapter instance. Verified:

$ grep -rn '_runner_ref' gateway/
gateway/platforms/telegram.py:1542:    _runner_ref = getattr(self, "_runner_ref", None)
gateway/platforms/telegram.py:1543:    _runner = _runner_ref() if callable(_runner_ref) else None
gateway/run.py:1266:_gateway_runner_ref: _weakref.ref = lambda: None       # ← MODULE-LEVEL, different name
gateway/run.py:1391:    global _gateway_runner_ref
gateway/run.py:1395:    _gateway_runner_ref = _weakref.ref(self)

The fallback path getattr(self, '_runner_ref', None) returns None, the top-level quick_commands is never reached, and set_my_commands([]) registers an empty menu when users set telegram.command_menu: quick_commands_only with their quick_commands defined at the top level.

Nothing populates PlatformConfig.extra.quick_commands anywhere in the codebase, so the only working code path requires users to manually duplicate quick_commands into platforms.telegram.extra.quick_commands — undocumented.

Path forward: Re-merge after either (a) wiring an actual runner ref on the adapter at attach-time, or (b) bridging gateway.quick_commandsplatforms.telegram.extra.quick_commands at config-load time.

3. Revert #27865 "auto-detect @username mentions and create Telegram entities" (cf814c9)

Issue: Three bugs, no tests:

  1. Email false-positives. The regex r'@([a-zA-Z][a-zA-Z0-9_]{4,31})' matches @example inside user@example.com:
>>> _MENTION_RE.findall("Send to user@example.com")
['example']    # ← creates a spurious 'mention' entity on email addresses
  1. parse_mode + entities are mutually exclusive per Telegram Bot API. Bot API docs: "can be specified instead of parse_mode". Passing both alongside ParseMode.MARKDOWN_V2 may cause Bot API to reject or silently ignore parse_mode.

  2. Offset miscalculation. Offsets are computed against the MarkdownV2-escaped formatted string. \@ escape bytes shift offsets relative to plain text; entity boundaries may mis-align in rendered output.

Path forward: Re-merge with (a) stricter regex (negative-lookbehind for [^a-zA-Z0-9._-]), (b) drop entities= when parse_mode is set, (c) compute offsets against unescaped text.

Conflict resolution: kept #27098's **text_kwargs split (thread-not-found retry) while removing only the entities=_entities argument.

4. Revert #23795 "enforce TELEGRAM_ALLOWED_USERS allowlist on inbound messages" (db50af9)

Issue: P0 claim is incorrect, and salvage introduces three concrete regressions.

The PR claims TELEGRAM_ALLOWED_USERS was only checked for callback/inline-button actions but not for inbound messages. False — the gateway runner's _is_user_authorized at gateway/run.py:6025 already fail-closed inbound messages BEFORE this salvage. Default is deny.

Regressions introduced by adding the adapter-level user_id check:

  1. Channel posts dropped. message.from_user is None for channel broadcasts, so _user_id="" short-circuits to deny BEFORE the runner sees the message. This required a follow-up test fixture stub (f1cefad8c test+release: stub auth in channel_posts fixture) just to keep the fix(telegram): handle channel post updates #25327 channel-post tests green — proving the salvage broke real channel post routing.

  2. Anonymous-admin / sender_chat traffic dropped. PR fix(gateway): allow chat-scoped telegram auth without sender user_id #27806 (later-merged fix(gateway): allow chat-scoped telegram auth without sender user_id) explicitly aims to support this — but the adapter-level user_id requirement neuters it because _should_process_message returns False BEFORE the runner-level chat-scoped fallback can authorize.

  3. First-time DM users see silence. The runner's pairing-flow onboarding UX in _handle_message is skipped because the adapter drops the message first.

The salvage ships zero tests despite the P0 label, and its docstring claim "Empty TELEGRAM_ALLOWED_USERS continues to allow all users" contradicts the actual code path it goes through after #24468 made the env fallback fail-closed.

Net: only real gain over pre-existing behavior is an earlier log line, paid for with three concrete user-facing regressions.

#24468 (the fail-closed env fallback, separate PR) is correctly KEPT — it only changes a rarely-reached fallback path. #27806's chat-scoped auth is correctly KEPT (the runner-level part), and reverting #23795 unblocks it functionally.

Path forward: If we want defense-in-depth at the adapter level, do it as a parity check (only refuse when runner would also refuse), not as a hard pre-runner gate.

Audit methodology

Parallel subagent fan-out across 9 clusters (44 PRs total):

  • Auth & gating (5)
  • DM topic routing (9)
  • Tool progress & streaming (5)
  • Audio & TTS (5)
  • Network resilience (3)
  • UX features + Windows (8)
  • Document/media routing (3)
  • send_message tool (2)
  • Errors & noise (4)

Each PR audited on: bug reality (does parent code have the bug?), fix correctness, test coverage (would new tests fail against parent?), side effects (silent default changes?), interaction with other recent salvages.

Verdict counts: KEEP 33 · KEEP-WITH-FOLLOWUP 7 · REVERT 4 (this PR).

Follow-up issues to file (not in this PR):

Validation

  • scripts/run_tests.sh tests/gateway/test_telegram_group_gating.py tests/gateway/test_telegram_mention_boundaries.py tests/gateway/test_telegram_callback_auth_fail_closed.py tests/gateway/test_telegram_channel_posts.py tests/gateway/test_telegram_documents.py tests/gateway/test_unauthorized_dm_behavior.py tests/tools/test_send_message_tool.py tests/tools/test_send_message_telegram_proxy.py -q → 245/246 passing (1 pre-existing slack-parse flake unrelated)
  • scripts/run_tests.sh tests/gateway/test_telegram_thread_fallback.py -q → 41/41 passing in isolation

The 3 test-pollution failures observed when running the full telegram test set together also reproduce on plain main without the reverts — pre-existing issue not introduced here.

@teknium1
teknium1 merged commit 4d44304 into main May 19, 2026
17 of 18 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-6063e704 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8952 on HEAD, 8952 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4702 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@teknium1
teknium1 deleted the hermes/hermes-6063e704 branch May 19, 2026 07:00
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround platform/telegram Telegram bot adapter comp/gateway Gateway runner, session dispatch, delivery labels May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P1 High — major feature broken, no workaround platform/telegram Telegram bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants