Skip to content

feat(mention-gating): suppress always-on agent when another agent is explicitly mentioned#67460

Open
MoeJaberr wants to merge 10 commits intoopenclaw:mainfrom
MoeJaberr:feat/mention-override-default-responder
Open

feat(mention-gating): suppress always-on agent when another agent is explicitly mentioned#67460
MoeJaberr wants to merge 10 commits intoopenclaw:mainfrom
MoeJaberr:feat/mention-override-default-responder

Conversation

@MoeJaberr
Copy link
Copy Markdown

Summary

  • Adds suppressIfOtherAgentMentioned?: boolean to InboundMentionPolicy
  • Adds suppressedByOtherAgentMention: boolean to InboundMentionDecision
  • When the new policy flag is true, an always-on agent (requireMention=false) sets shouldSkip=true if another agent was explicitly mentioned and this agent was not
  • 8 new tests covering all edge cases; all 24 tests in the file pass

Why

Closes #67445. In channels with a default auto-responding agent, any message that explicitly tags a different agent should reach only that agent — the default responder is noisy otherwise. The existing hasAnyMention + wasMentioned signals already carry the right information; this PR wires them into a new suppression path.

Behavior

Scenario Always-on agent responds?
Untagged message ✅ yes (unchanged)
Message mentions this agent ✅ yes
Message mentions a different agent ❌ no (new)
Mention detection unavailable ✅ yes (safe fallback)
Direct/non-group chat ✅ yes (not applicable)

Design notes

  • Opt-in: suppressIfOtherAgentMentioned defaults to undefined (off). Existing channels are unaffected until they set the flag.
  • Only for always-on agents: requireMention=true agents already have their own skip path; this only applies when requireMention=false.
  • Group-only: suppression never fires outside group chats.
  • A follow-up can wire suppressIfOtherAgentMentioned to ChannelGroupConfig so users can enable it from their config file without touching plugin code.

Test plan

  • bunx vitest run src/channels/mention-gating.test.ts — 24/24 pass
  • bunx tsc --noEmit — no errors on touched files

MoeJaberr and others added 2 commits April 15, 2026 20:37
…aversal

After a global npm upgrade, older installs left dist/extensions/*/node_modules/
in place (npm does not remove dirs absent from the new tarball). These directories
contained .bin/ symlinks that caused listInstalledDistFiles to throw
"unsafe dist entry", aborting the postinstall before acpx could be installed at
the package root. The acpx binary was then resolved from the stale nested path
instead of node_modules/.bin/acpx at the package root, causing ACP launches to fail.

Fix: call pruneBundledDistPluginNodeModules (mirroring the existing source-checkout
pruneBundledPluginSourceNodeModules) before pruneInstalledPackageDist so the stale
directories are removed before listInstalledDistFiles traverses dist/.

Fixes openclaw#65921

Co-Authored-By: claude-flow <ruv@ruv.net>
…explicitly mentioned

Implements the behavior described in openclaw#67445: when a channel has a default
always-on agent (requireMention=false) and a message explicitly mentions a
different agent, the always-on agent can now suppress itself instead of
responding to every message.

New opt-in policy field on InboundMentionPolicy:
  suppressIfOtherAgentMentioned?: boolean

When true, resolveInboundMentionDecision() sets shouldSkip=true and the
new suppressedByOtherAgentMention=true on the returned decision whenever:
- isGroup=true (group chat only)
- canDetectMention=true (platform supports mention detection)
- hasAnyMention=true (some agent was mentioned)
- wasMentioned=false (but not this agent)
- requireMention=false (this is the always-on agent path)

Untagged messages continue to reach the default agent unchanged.
Opt-in design preserves backward compatibility for existing channels.

Co-Authored-By: claude-flow <ruv@ruv.net>
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts size: M labels Apr 16, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 16, 2026

Greptile Summary

This PR adds an opt-in suppressIfOtherAgentMentioned policy flag that lets an always-on agent silence itself when another agent is explicitly mentioned in a group chat. It also adds pruneBundledDistPluginNodeModules to remove stale per-plugin node_modules directories left by older installs, fixing a postinstall abort caused by .bin/ symlinks inside those directories.

  • The new suppression logic in resolveMentionDecisionCore is correct, but normalizeMentionDecisionParams — used by the deprecated flat-params call shape — does not forward suppressIfOtherAgentMentioned to the policy object it constructs. Any caller that passes the field via the legacy flat API will silently get no suppression.

Confidence Score: 4/5

Safe to merge after fixing the silent field-drop in the deprecated flat-params normalization path.

One P1 defect: suppressIfOtherAgentMentioned is silently ignored when callers use the deprecated flat API because normalizeMentionDecisionParams doesn't destructure or forward the new field. All other changes — core suppression logic, postinstall cleanup, and tests — look correct.

src/channels/mention-gating.ts — the normalizeMentionDecisionParams function needs to forward suppressIfOtherAgentMentioned.

Comments Outside Diff (1)

  1. src/channels/mention-gating.ts, line 184-191 (link)

    P1 suppressIfOtherAgentMentioned silently dropped by deprecated flat-params path

    normalizeMentionDecisionParams converts the legacy flat call shape to the nested form but never forwards suppressIfOtherAgentMentioned. Because ResolveInboundMentionDecisionFlatParams is InboundMentionFacts & InboundMentionPolicy, TypeScript happily accepts the field on the flat form — but it is destroyed during normalization and the suppression never fires.

    Or, to avoid the cast, destructure suppressIfOtherAgentMentioned alongside the other policy fields at line 165 and include it in the returned object.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/channels/mention-gating.ts
    Line: 184-191
    
    Comment:
    **`suppressIfOtherAgentMentioned` silently dropped by deprecated flat-params path**
    
    `normalizeMentionDecisionParams` converts the legacy flat call shape to the nested form but never forwards `suppressIfOtherAgentMentioned`. Because `ResolveInboundMentionDecisionFlatParams` is `InboundMentionFacts & InboundMentionPolicy`, TypeScript happily accepts the field on the flat form — but it is destroyed during normalization and the suppression never fires.
    
    
    
    Or, to avoid the cast, destructure `suppressIfOtherAgentMentioned` alongside the other policy fields at line 165 and include it in the returned object.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/channels/mention-gating.ts
Line: 184-191

Comment:
**`suppressIfOtherAgentMentioned` silently dropped by deprecated flat-params path**

`normalizeMentionDecisionParams` converts the legacy flat call shape to the nested form but never forwards `suppressIfOtherAgentMentioned`. Because `ResolveInboundMentionDecisionFlatParams` is `InboundMentionFacts & InboundMentionPolicy`, TypeScript happily accepts the field on the flat form — but it is destroyed during normalization and the suppression never fires.

```suggestion
    policy: {
      isGroup,
      requireMention,
      allowedImplicitMentionKinds,
      allowTextCommands,
      hasControlCommand,
      commandAuthorized,
      suppressIfOtherAgentMentioned: (params as InboundMentionPolicy).suppressIfOtherAgentMentioned,
    },
```

Or, to avoid the cast, destructure `suppressIfOtherAgentMentioned` alongside the other policy fields at line 165 and include it in the returned object.

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

Reviews (1): Last reviewed commit: "feat(mention-gating): suppress always-on..." | Re-trigger Greptile

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4e3c767ba5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/channels/mention-gating.ts
…at-params normalizer

normalizeMentionDecisionParams was dropping the new field, causing the
suppression to silently not fire when callers used the deprecated flat
call shape. Destructure and forward it alongside the other policy fields.

Adds a regression test covering the flat-params path.

Co-Authored-By: claude-flow <ruv@ruv.net>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 50ba281e8b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/channels/mention-gating.ts
…ioned

Wires up the new policy flag across all 11 channel extensions so that
always-on agents (requireMention=false) automatically suppress themselves
when a message explicitly mentions a different agent.

Channels where hasAnyMention is reliably populated (Discord, Telegram,
Slack, Line, Google Chat, Zalouser) get full suppression behavior.
Channels without hasAnyMention detection (Signal, iMessage, MS Teams,
Nextcloud Talk, WhatsApp) carry the flag harmlessly with no behavioral
change until their mention-detection improves.

Closes openclaw#67445.

Co-Authored-By: claude-flow <ruv@ruv.net>
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: line Channel integration: line channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web channel: zalouser Channel integration: zalouser labels Apr 16, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 441cdd71d4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/telegram/src/bot-message-context.body.ts
The upstream commit 628b454 updated the default Anthropic model to
claude-opus-4-7 but did not update the hardcoded constant in these test
files, causing CI to fail on the merge commit.

Co-Authored-By: claude-flow <ruv@ruv.net>
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Apr 16, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb9c6e76c7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/discord/src/monitor/message-handler.preflight.ts Outdated
Comment thread extensions/slack/src/monitor/message-handler/prepare.ts
Comment thread extensions/whatsapp/src/auto-reply/monitor/group-gating.ts
@MoeJaberr
Copy link
Copy Markdown
Author

All CI checks are green (only install-smoke fails, which is a pre-existing infra issue on main unrelated to this PR). This is ready to land whenever a maintainer has bandwidth. 🙏

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ba67a94f2d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/signal/src/monitor/event-handler.ts
Comment thread extensions/msteams/src/monitor-handler/message-handler.ts
@MoeJaberr MoeJaberr force-pushed the feat/mention-override-default-responder branch from ba67a94 to ede30ff Compare April 17, 2026 16:41
…guards

Address Codex P1/P2 review findings on PR openclaw#67460:

P1 — skip guard was gated behind requireMention=true so always-on agents
never acted on mentionDecision.shouldSkip when suppression fired:
- Telegram, Slack, Signal, WhatsApp, MS Teams: expand guard to also
  short-circuit when suppressedByOtherAgentMention is true.
- Discord: add a dedicated early-return for the same case (the existing
  block is nested inside shouldRequireMention).

P1 — hasAnyMention was not passed so suppression could never trigger:
- Signal: compute from dataMessage.mentions.length
- WhatsApp: compute from msg.mentions ?? msg.mentionedJids length
- MS Teams: compute from activity.entities type=mention entries

Co-Authored-By: claude-flow <ruv@ruv.net>
@MoeJaberr MoeJaberr force-pushed the feat/mention-override-default-responder branch from ede30ff to 6f93532 Compare April 17, 2026 16:42
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f93532af1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor-handler/message-handler.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6338a30ce8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/channels/mention-gating.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc567e0275

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +671 to +673
const pluginNodeModules = join(extensionsDir, entry.name, "node_modules");
if (pathExists(pluginNodeModules)) {
removePath(pluginNodeModules, { recursive: true, force: true });
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Guard dist prune against symlinked extension roots

pruneBundledDistPluginNodeModules recursively deletes dist/extensions/*/node_modules without validating that extensionsDir is a real directory under the package root (unlike the resolveInstalledDistRoot checks used by pruneInstalledPackageDist). If dist/extensions is a symlink (or otherwise redirected), postinstall can remove node_modules outside the OpenClaw install tree, including during global installs run with elevated privileges. Add lstat/realpath boundary checks before calling rmSync.

Useful? React with 👍 / 👎.

allowTextCommands: params.allowTextCommands,
hasControlCommand: params.hasControlCommand,
commandAuthorized: params.commandAuthorized,
suppressIfOtherAgentMentioned: true,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Pass any-mention facts before enabling Nextcloud suppression

resolveNextcloudTalkMentionGate now opts into suppressIfOtherAgentMentioned, but the inbound caller (extensions/nextcloud-talk/src/inbound.ts) still does not provide hasAnyMention, so it defaults false and suppressedByOtherAgentMention cannot trigger. In always-on rooms (requireMention=false), messages that explicitly mention a different agent will still be processed by the default agent, so this commit’s suppression behavior is effectively disabled for Nextcloud.

Useful? React with 👍 / 👎.

allowTextCommands: true,
hasControlCommand: hasControlCommandInMessage,
commandAuthorized,
suppressIfOtherAgentMentioned: true,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor always-on suppression in iMessage mention gate

This handler enables suppressIfOtherAgentMentioned, but the drop path still requires requireMention before acting on mentionDecision.shouldSkip, so the new always-on suppression path (requireMention=false) is never applied. Because this function now opts into suppression, always-on iMessage groups can still respond when another agent is explicitly targeted, which defeats the new behavior on this channel.

Useful? React with 👍 / 👎.

@MoeJaberr
Copy link
Copy Markdown
Author

All Codex review threads have been resolved. The Greptile P1 finding (suppressIfOtherAgentMentioned silently dropped in the flat-params normalization path) was already addressed in a subsequent commit — normalizeMentionDecisionParams now destructures and forwards the field correctly.

The branch is up to date with main and CI is green (only the pre-existing install-smoke infra failure on main is present, unrelated to this PR).

Tagging for review: @joshavant @gumadeiras — happy to address any feedback. 🙏

@MoeJaberr MoeJaberr force-pushed the feat/mention-override-default-responder branch from 3a13a6a to b67f403 Compare April 23, 2026 19:15
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b67f403fa8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 1084 to 1086
author,
sender,
memberRoleIds,
channelInfo,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore member roles in Discord preflight return payload

This return object dropped memberRoleIds, but downstream processing still expects it: processDiscordMessage destructures memberRoleIds and forwards it into finalizeInboundContext as MemberRoleIds (extensions/discord/src/monitor/message-handler.process.ts). With this omission, inbound Discord messages lose sender role context at runtime, which can break role-scoped behavior (for example role-based command/policy decisions and prompt context). Add memberRoleIds back to the preflight context payload.

Useful? React with 👍 / 👎.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 27, 2026

Codex review: found issues before merge.

Summary
The PR adds an opt-in inbound mention suppression flag, wires it through multiple bundled channel plugins, expands mention-gating tests, changes bundled-plugin postinstall pruning, and updates one PDF test model constant.

Reproducibility: yes. Current-main behavior is reproducible by code inspection of resolveInboundMentionDecision and the channel drop guards; the PR regressions are reproducible with always-on group cases containing a non-agent user/role mention and with Discord preflight role-context checks.

Next step before merge
Maintainer review is needed because the remaining blockers include product semantics for cross-channel agent targeting and a security-sensitive install-script deletion path, not a narrow safe automation repair.

Security
Needs attention: The PR introduces a postinstall recursive deletion path without the existing package-root realpath boundary checks.

Review findings

  • [P1] Restrict suppression to agent-target mentions — src/channels/mention-gating.ts:133-139
  • [P1] Restore Discord member role ids — extensions/discord/src/monitor/message-handler.preflight.ts:1085-1086
  • [P1] Validate dist extension roots before deleting — scripts/postinstall-bundled-plugins.mjs:671-673
Review details

Best possible solution:

Land a narrower routing change or replacement branch that introduces a typed explicit-agent-target signal, wires only channels that can prove that signal, preserves Discord role context, separates postinstall cleanup into a security-reviewed patch, and adds focused shared plus channel regression coverage with a changelog entry.

Do we have a high-confidence way to reproduce the issue?

Yes. Current-main behavior is reproducible by code inspection of resolveInboundMentionDecision and the channel drop guards; the PR regressions are reproducible with always-on group cases containing a non-agent user/role mention and with Discord preflight role-context checks.

Is this the best way to solve the issue?

No. The requested behavior belongs in the shared mention-policy area, but this implementation is not the best fix because it uses generic platform mention evidence as agent-target evidence and mixes unrelated install-script cleanup into a routing feature.

Full review comments:

  • [P1] Restrict suppression to agent-target mentions — src/channels/mention-gating.ts:133-139
    The new suppression path treats hasAnyMention as proof that another OpenClaw agent was targeted, but several call sites pass generic platform mentions such as Slack users, Discord users/roles/everyone, Teams mention entities, or WhatsApp JIDs. In always-on groups this drops normal chatter that mentions a person or role, even though no other agent was addressed.
    Confidence: 0.9
  • [P1] Restore Discord member role ids — extensions/discord/src/monitor/message-handler.preflight.ts:1085-1086
    The returned preflight context no longer includes memberRoleIds, while downstream Discord processing forwards that field into MemberRoleIds. This loses sender role context for role-scoped routing, policy, and prompt behavior, so the payload should include it again.
    Confidence: 0.93
  • [P1] Validate dist extension roots before deleting — scripts/postinstall-bundled-plugins.mjs:671-673
    pruneBundledDistPluginNodeModules recursively removes dist/extensions/*/node_modules after only checking existence and Dirent metadata. If dist/extensions or a plugin directory is redirected, postinstall can delete outside the OpenClaw package tree; reuse the existing realpath/lstat boundary checks before calling rmSync.
    Confidence: 0.88
  • [P3] Add the required changelog entry — src/channels/mention-gating.ts:51-56
    This is a user-facing routing feature across bundled channel plugins, but the PR does not update CHANGELOG.md. Add a single-line entry under the active release section with appropriate non-bot contributor credit before landing.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.91

Security concerns:

  • [high] Postinstall recursive deletion lacks root validation — scripts/postinstall-bundled-plugins.mjs:673
    The new pruneBundledDistPluginNodeModules deletes join(extensionsDir, entry.name, "node_modules") recursively during postinstall without proving that extensionsDir and each target resolve under the OpenClaw package root. A redirected or symlinked dist tree could cause deletion outside the install directory.
    Confidence: 0.88

Acceptance criteria:

  • pnpm test src/channels/mention-gating.test.ts
  • pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts extensions/slack/src/monitor/message-handler/prepare.test.ts extensions/msteams/src/monitor-handler/message-handler.test.ts
  • pnpm test test/scripts/postinstall-bundled-plugins.test.ts if postinstall cleanup remains
  • pnpm check:changed in Testbox before handoff

What I checked:

  • Current main lacks always-on suppression: InboundMentionPolicy has no suppressIfOtherAgentMentioned field, InboundMentionDecision has no suppression result, and shouldSkip is still gated by requireMention, so always-on agents cannot be skipped by the shared helper on current main. (src/channels/mention-gating.ts:47, 9e5d0380b0ec)
  • Slack any-mention signal is generic: Current Slack code sets hasAnyMention for any Slack user or subteam mention, so using that signal as proof of another OpenClaw agent target would suppress normal human or group mentions. (extensions/slack/src/monitor/message-handler/prepare.ts:289, 9e5d0380b0ec)
  • Discord any-mention signal is generic: Current Discord preflight treats mentioned users, roles, and everyone as hasAnyMention; that is not equivalent to a configured agent target and overlaps existing ignoreOtherMentions semantics. (extensions/discord/src/monitor/message-handler.preflight.ts:320, 9e5d0380b0ec)
  • Discord role context regression: Current main computes memberRoleIds, uses it in access checks, and passes it into the preflight context; the PR diff removes memberRoleIds from the return payload, which would drop downstream role context. (extensions/discord/src/monitor/message-handler.preflight.ts:642, 9e5d0380b0ec)
  • Postinstall deletion must use root-boundary checks: Current main's installed-dist pruning validates the real dist root and uses assertSafeInstalledDistPath before removals; the PR adds a separate recursive deletion path for dist/extensions/*/node_modules without those checks. (scripts/postinstall-bundled-plugins.mjs:134, 9e5d0380b0ec)
  • No changelog entry for user-facing routing change: The PR files do not include CHANGELOG.md, and a repo search found no mention of suppressIfOtherAgentMentioned, suppressedByOtherAgentMention, or the linked routing feature in the changelog. (CHANGELOG.md:5, 9e5d0380b0ec)

Likely related people:

  • steipete: Current-main blame and log in this checkout point the shared mention-gating, Discord preflight, and postinstall paths at the recent refactor commit by Peter Steinberger; deeper original history was not available in the shallow checkout. (role: recent maintainer; confidence: high; commits: affca3da1f; files: src/channels/mention-gating.ts, extensions/discord/src/monitor/message-handler.preflight.ts, scripts/postinstall-bundled-plugins.mjs)
  • joshavant: The PR author explicitly requested review from this maintainer in the PR discussion for the channel-routing change; local code-history evidence for this checkout was limited. (role: requested reviewer; confidence: low; files: src/channels/mention-gating.ts, extensions/discord/src/monitor/message-handler.preflight.ts)
  • gumadeiras: The PR author explicitly requested review from this maintainer in the PR discussion for the channel-routing change; local code-history evidence for this checkout was limited. (role: requested reviewer; confidence: low; files: src/channels/mention-gating.ts, extensions/*/src)

Remaining risk / open question:

  • The patch would suppress always-on agents on generic human, role, or group mentions rather than only configured OpenClaw agent mentions.
  • The postinstall pruning change performs recursive deletion during install and needs the same package-root realpath boundary checks as current installed-dist pruning.
  • The branch overlaps recent Discord and postinstall refactors on current main, so a direct merge may be stale even after functional fixes.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9e5d0380b0ec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: line Channel integration: line channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web channel: zalouser Channel integration: zalouser scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Explicit agent mentions should override channel-default auto-responder

1 participant