Skip to content

fix(signal): enforce mention gating for group messages#13124

Merged
Takhoffman merged 2 commits intoopenclaw:mainfrom
zerone0x:fix/signal-group-mention-gating
Feb 10, 2026
Merged

fix(signal): enforce mention gating for group messages#13124
Takhoffman merged 2 commits intoopenclaw:mainfrom
zerone0x:fix/signal-group-mention-gating

Conversation

@zerone0x
Copy link
Copy Markdown
Contributor

@zerone0x zerone0x commented Feb 10, 2026

Summary

Fixes #13106

Signal group messages bypassed mention gating (requireMention + mentionPatterns), causing the bot to reply to every group message even when mention gating was configured. This aligns Signal with Slack, Discord, Telegram, and iMessage which all enforce mention gating correctly.

Changes

  • Add mention gating logic to Signal event handler (resolveMentionGatingWithBypass, buildMentionRegexes, matchesMentionPatterns, resolveChannelGroupRequireMention)
  • Drop unmentioned group messages when requireMention is enabled, with pending history recording for context
  • Set WasMentioned on ctxPayload so downstream directive gating (elevated/exec) works correctly
  • Allow authorized control commands to bypass mention gating (consistent with other channels)

Test plan

  • Added 5 new tests covering:
    • Group messages without mention are dropped when requireMention is enabled
    • Group messages with mention are allowed through
    • WasMentioned is set correctly when requireMention is off
    • Pending history is recorded for skipped messages
    • Authorized control commands bypass mention gating
  • All 42 existing Signal tests pass (no regressions)
  • Mention gating unit tests pass

🤖 Generated with Claude Code

Greptile Overview

Greptile Summary

This PR adds mention-gating enforcement to Signal group message handling so requireMention + mentionPatterns behave consistently with other channels. The Signal event handler now resolves the agent route, builds mention regexes, computes wasMentioned, applies resolveMentionGatingWithBypass (allowing authorized control commands through), records pending history for skipped group messages, and plumbs WasMentioned into the inbound context. New Vitest coverage exercises the drop/allow paths, pending history, and bypass behavior.

Confidence Score: 3/5

  • Mostly safe to merge, but the mention-gating check uses the wrong message text in some cases and can incorrectly drop valid group messages.
  • Core gating logic is consistent with existing shared helpers (buildMentionRegexes, resolveMentionGatingWithBypass) and tests cover main flows. However, gating/history currently key off messageText rather than the effective inbound bodyText (which can be quote/attachment placeholder), so behavior will be wrong for quote-only/attachment-only messages and pending history recording. Addressing that would raise confidence.
  • src/signal/monitor/event-handler.ts

@openclaw-barnacle openclaw-barnacle bot added the channel: signal Channel integration: signal label Feb 10, 2026
Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +508 to +511
const route = resolveAgentRoute({
cfg: deps.cfg,
channel: "signal",
accountId: deps.accountId,
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.

Duplicate route resolution

resolveAgentRoute(...) is called here to build mention regexes, but handleSignalInboundMessage also calls resolveAgentRoute(...) again for the same message. This duplicates work on every inbound message and can lead to subtle inconsistencies if routing logic depends on mutable state. Consider computing the route once and reusing it for mention gating + context building.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/signal/monitor/event-handler.ts
Line: 508:511

Comment:
**Duplicate route resolution**

`resolveAgentRoute(...)` is called here to build mention regexes, but `handleSignalInboundMessage` also calls `resolveAgentRoute(...)` again for the same message. This duplicates work on every inbound message and can lead to subtle inconsistencies if routing logic depends on mutable state. Consider computing the route once and reusing it for mention gating + context building.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +6 to +17
vi.mock("../../auto-reply/dispatch.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../auto-reply/dispatch.js")>();
const dispatchInboundMessage = vi.fn(async (params: { ctx: MsgContext }) => {
capturedCtx = params.ctx;
return { queuedFinal: false, counts: { tool: 0, block: 0, final: 0 } };
});
return {
...actual,
dispatchInboundMessage,
dispatchInboundMessageWithDispatcher: dispatchInboundMessage,
dispatchInboundMessageWithBufferedDispatcher: dispatchInboundMessage,
};
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.

Mock can leak state

This test file uses a module-level capturedCtx plus a vi.mock that mutates it. Because Vitest runs tests in a shared module context for this file, a failure or missing reset can leak state between tests. At minimum, add a beforeEach(() => { capturedCtx = undefined }) (and consider vi.clearAllMocks()) so test order can’t affect outcomes.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/signal/monitor/event-handler.mention-gating.test.ts
Line: 6:17

Comment:
**Mock can leak state**

This test file uses a module-level `capturedCtx` plus a `vi.mock` that mutates it. Because Vitest runs tests in a shared module context for this file, a failure or missing reset can leak state between tests. At minimum, add a `beforeEach(() => { capturedCtx = undefined })` (and consider `vi.clearAllMocks()`) so test order can’t affect outcomes.

How can I resolve this? If you propose a fix, please make it concise.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 10, 2026

Additional Comments (1)

src/signal/monitor/event-handler.ts
Mention gating uses wrong text

wasMentioned and the history entry are computed from messageText, but the inbound body you later enqueue is bodyText = messageText || placeholder || quoteText. This means group messages that only contain a quoted message (or only attachments/placeholder) will always be treated as “no mention” and may be dropped even if the quote/body actually contains a mention pattern. It also records pending history with messageText (empty) rather than the effective bodyText.

Also appears at src/signal/monitor/event-handler.ts:554-555 (history entry body).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/signal/monitor/event-handler.ts
Line: 499:502

Comment:
**Mention gating uses wrong text**

`wasMentioned` and the history entry are computed from `messageText`, but the inbound body you later enqueue is `bodyText = messageText || placeholder || quoteText`. This means group messages that only contain a quoted message (or only attachments/placeholder) will always be treated as “no mention” and may be dropped even if the quote/body actually contains a mention pattern. It also records pending history with `messageText` (empty) rather than the effective `bodyText`.

Also appears at `src/signal/monitor/event-handler.ts:554-555` (history entry body).

How can I resolve this? If you propose a fix, please make it concise.

@Takhoffman Takhoffman self-assigned this Feb 10, 2026
Takhoffman added a commit to zerone0x/clawdbot that referenced this pull request Feb 10, 2026
@Takhoffman Takhoffman force-pushed the fix/signal-group-mention-gating branch from 752c20f to f034068 Compare February 10, 2026 05:09
Yansu and others added 2 commits February 9, 2026 23:10
Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106

Co-Authored-By: Claude <[email protected]>
@Takhoffman Takhoffman force-pushed the fix/signal-group-mention-gating branch from f034068 to af6c36d Compare February 10, 2026 05:17
@Takhoffman Takhoffman merged commit 1d46ca3 into openclaw:main Feb 10, 2026
23 checks passed
@Takhoffman
Copy link
Copy Markdown
Contributor

Thank you for your contribution!

ProgramCaiCai pushed a commit to ProgramCaiCai/openclaw that referenced this pull request Feb 10, 2026
* fix(signal): enforce mention gating for group messages

Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106

Co-Authored-By: Claude <[email protected]>

* fix(signal): keep pending history context for mention-gated skips (openclaw#13124) (thanks @zerone0x)

---------

Co-authored-by: Yansu <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
YanHaidao added a commit to YanHaidao/clawdbot that referenced this pull request Feb 10, 2026
* 'main' of github.com:YanHaidao/clawdbot: (94 commits)
  fix(auto-reply): prevent sender spoofing in group prompts
  Discord: add exec approval cleanup option (openclaw#13205)
  CI: extend stale timelines to be contributor-friendly (openclaw#13209)
  fix: enforce Discord agent component DM auth (openclaw#11254) (thanks @thedudeabidesai)
  refactor(security,config): split oversized files (openclaw#13182)
  Commands: add commands.allowFrom config
  CI: configure stale automation
  fix(signal): enforce mention gating for group messages (openclaw#13124)
  fix(ui): prioritize displayName over label in webchat session picker (openclaw#13108)
  Chore: add testflight auto-response
  Docker: include A2UI sources for bundle (openclaw#13114)
  fix: unify session maintenance and cron run pruning (openclaw#13083)
  docs: expand vulnerability reporting guidelines in SECURITY.md
  docs: add vulnerability reporting guidelines to CONTRIBUTING.md
  refactor: consolidate fetchWithTimeout into shared utility
  fix(memory): default batch embeddings to off
  Improve code analyzer for independent packages, CI: only run release-check on push to main
  fix(tools): correct Grok response parsing for xAI Responses API (openclaw#13049)
  chore(deps): update dependencies, remove hono pinning
  Update contributing, deduplicate more functions
  ...
Hansen1018 pushed a commit to Hansen1018/openclaw that referenced this pull request Feb 10, 2026
* fix(signal): enforce mention gating for group messages

Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106

Co-Authored-By: Claude <[email protected]>

* fix(signal): keep pending history context for mention-gated skips (openclaw#13124) (thanks @zerone0x)

---------

Co-authored-by: Yansu <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
michaelleone pushed a commit to michaelleone/openclaw that referenced this pull request Feb 11, 2026
* fix(signal): enforce mention gating for group messages

Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106

Co-Authored-By: Claude <[email protected]>

* fix(signal): keep pending history context for mention-gated skips (openclaw#13124) (thanks @zerone0x)

---------

Co-authored-by: Yansu <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
skyhawk14 pushed a commit to skyhawk14/openclaw that referenced this pull request Feb 13, 2026
* fix(signal): enforce mention gating for group messages

Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106

Co-Authored-By: Claude <[email protected]>

* fix(signal): keep pending history context for mention-gated skips (openclaw#13124) (thanks @zerone0x)

---------

Co-authored-by: Yansu <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
* fix(signal): enforce mention gating for group messages

Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.

Fixes openclaw#13106


* fix(signal): keep pending history context for mention-gated skips (openclaw#13124) (thanks @zerone0x)

---------

Co-authored-by: Yansu <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: signal Channel integration: signal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Signal group mention gating missing

2 participants