fix(slack): match both bare and labelled mention forms in mentions_bot#808
Conversation
|
Discord Discussion URL: https://discord.com/channels/1491295327620169908/1491969620754567270/1504107600520806501 |
antigenius0910
left a comment
There was a problem hiding this comment.
Confirmed the bug reproduces on 0.8.3-beta.9 and verified the fix shape is correct against the actual repro. Quick E2E — two bots, allow_bot_messages="mentions", side-by-side from the same author/channel:
| text | mentions_bot (pre-fix) |
|---|---|
<@UB> … |
true |
<@UB|handle_b> … |
false ← dropped at src/slack.rs:722 |
Tracing through the new text_mentions_uid against my TC-2 input: prefix <@UB, byte after the UID is | → matches Some(b'|') → true. Fix would resolve the bug.
Things I liked
- Helper extraction (
text_mentions_uid) means the bug now has a name and a focused test suite — much easier to extend than a sprawling substring check. - Byte-boundary match via
match_indices+as_bytes().get(i + prefix.len())is the right primitive: cheap, no regex, no UTF-8 hazard (Slack UIDs are ASCII so the byte index is the char index here). - Test set is genuinely thorough: the
mentions_uid_no_false_positive_on_uid_prefixcase (U123vs<@U123BOT>) is the easy-to-miss one and you covered it. - Updating both
mentions_bot(L582) andparent_mentions_bot(L282) call sites in the same PR — easy to forget the second one. inspect_erronget_bot_user_idis a nice observability touch for the "why is mention detection suddenly silent?" failure mode.
Things worth addressing
1. src/acp/pool.rs change looks unrelated
The diff is doc-comment-only on with_connection, clarifying the per-connection vs pool-level lock semantics. Strictly correct and benign, but it's not connected to #800. Two clean options: (a) split into its own PR, or (b) call it out in the description ("drive-by: clarify pool locking comment while in the file"). Either avoids reviewer head-scratching.
2. Cargo.lock adds serde to chrono's deps
Looks like fallout from a regenerate, not an intentional change. If a chrono feature was enabled in Cargo.toml, it should be visible there; if not, this is probably stale and should be reverted to keep the diff scoped. Could you double-check?
3. Helper-level tests only; no integration assertion
Totally fair given the change is a 1:1 substitution of two call sites by the new helper, and the helper has exhaustive unit coverage. Worth one line in the PR description making that argument explicit ("two call sites swapped; helper covers them exhaustively"), so a reviewer doesn't go looking for the missing end-to-end test.
4. resolve_slack_mentions whitespace after mid-string strip
resolve_mentions_strips_labelled_mid_sentence asserts "please ask to run" (two spaces). That's the function's actual behavior, so the test is consistent, but a // note: surrounding whitespace preserved to avoid mangling adjacent content; LLM input tolerates double spaces next to the test (or in the fn doc) would save a future reader from wondering whether it's intentional. Pure nit.
5. Paired sibling concern (out of scope for this PR)
While running the repro I also tripped bot not in trusted_bot_ids, ignoring … because resolve_bot_user_id(B…) returned None (our bot token apparently lacks users:read for bots.info). That's tracked separately as #811 with a fix in #814 — flagging here only because operators using mentions + trusted_bot_ids together will need both #808 and #814 for a clean relay; either alone leaves the other gate broken. Not asking you to change scope, just noting for whoever sequences the merges.
Nice fix. The core change is exactly what the bug needs and the tests are well thought through.
|
Thanks for the thorough E2E trace and the clear breakdown. #1 #2 #3 Integration test rationale — added to the PR description: each call site is a 1:1 substitution of #4 Double-space nit — added a three-line comment above the #5 |
OpenAB PR ScreeningThis is auto-generated by the OpenAB project-screening flow for context collection and reviewer handoff.
Screening report## IntentPR #808 fixes Slack bot-message filtering when The operator-visible problem: OpenAB may silently ignore Slack bot messages that mention the bot using Slack’s canonical labelled mention format, FeatThis is a Slack bug fix. Behavior change: mention detection now accepts both Slack mention wire forms:
It also makes mention stripping symmetric by updating There is one unrelated doc-only cleanup in Who It ServesPrimary beneficiary: Slack users and OpenAB deployers using bot-to-bot workflows. Secondary beneficiaries:
Rewritten PromptFix Slack mention detection for Implement a small pure helper for Slack UID mention matching, use it in both direct message and parent-message mention checks, and update mention resolution/stripping so detection and cleanup handle the same forms. Add focused unit tests for bare mentions, labelled mentions, malformed labels, and false positives where the UID appears inside another token. Log a warning when bot user ID lookup fails, without changing fallback behavior. Keep unrelated changes out unless they are documentation-only and clearly separated. Merge PitchThis is worth advancing because it fixes a real Slack interoperability gap: Slack commonly emits labelled mentions, and the current substring check misses them entirely. Risk profile is low to moderate. The core change is small and testable, but mention parsing is easy to get subtly wrong around byte boundaries and malformed Slack markup. Reviewer attention should focus on whether the helper rejects false positives, whether stripping remains symmetric with detection, and whether the warning log could become noisy under repeated The pool doc comment change is harmless but should be reviewed as unrelated scope. Best-Practice ComparisonOpenClaw principles mostly do not apply here. This PR is not about scheduling, persistence, isolated executions, delivery routing, retries, or run logs. Relevant OpenClaw-adjacent principle:
Hermes Agent principles also mostly do not apply. This is not a daemon tick, locking, atomic persistence, session isolation, or scheduled prompt issue. Relevant Hermes-adjacent principle:
The best-practice frame here is simpler: Slack protocol parsing should be centralized, symmetric between detection and normalization, and covered by focused edge-case tests. Implementation OptionsOption 1: Conservative fix only Option 2: Balanced parser cleanup Option 3: Ambitious Slack mention parser Comparison Table
RecommendationAdvance the balanced parser cleanup. It fixes the actual bug, keeps detection and stripping symmetric, and adds enough targeted coverage to make the behavior reviewable without turning this into a broader Slack parsing refactor. For merge discussion, I would ask reviewers to verify the byte-boundary logic and decide whether the Do not expand this PR into a full Slack parser. That can be a follow-up if more Slack token edge cases appear. |
|
Verified canonical mention parsing ( |
|
LGTM ✅ — Correct fix for labelled mention detection with thorough test coverage. What This PR DoesFixes bot-to-bot message detection under How It Works
Findings
Baseline Check
What's Good (🟢)
|
This comment has been minimized.
This comment has been minimized.
- Add text_mentions_uid() helper accepting both <@uid> and <@uid|handle> - Rewrite resolve_slack_mentions() to strip both forms symmetrically - Add .inspect_err() warning on get_bot_user_id failure - Add doc comment to pool.rs with_connection Fixes openabdev#800
d7b134d to
ebea2ac
Compare
Discord Discussion URL: https://discord.com/channels/1491295327620169908/1491969620754567270/1504107600520806501
Summary
Fixes bot-to-bot message detection under
allow_bot_messages="mentions"when the sender uses Slack's canonical labelled mention form<@UID|handle>.Root cause:
mentions_botandparent_mentions_botboth usedstr::contains("<@UID>")which is not a substring of<@UID|handle>, silently dropping all bot messages that used the recommended labelled form.Changes:
text_mentions_uid(text, uid)-- new pure helper usingmatch_indices+ byte-boundary check to accept both wire formsmentions_bot/parent_mentions_bot-- both call sites updated to usetext_mentions_uidresolve_slack_mentions-- rewritten to strip labelled form too (detection and stripping must be symmetric)get_bot_user_id-- added.inspect_err()soauth.testfailures emit awarn!instead of silently degrading mention detectionsrc/acp/pool.rs-- drive-by: clarified per-connection vs pool-level lock semantics inwith_connectiondoc comment (doc-only, no logic change)Test Coverage
All branches covered at 93% (13/14 paths):
text_mentions_uidresolve_slack_mentionsget_bot_user_id.inspect_errTests: 27 -> 29 (+2 new edge-case coverage tests added during ship review)
No separate integration test for the
mentions_bot/parent_mentions_botcall sites: each is a 1:1 substitution of the oldstr::containscall withtext_mentions_uid, andtext_mentions_uidhas exhaustive unit coverage (5/5 branches including both wire forms and false-positive guard). An integration test would duplicate that coverage without adding signal.Pre-Landing Review
2-voice mob review (Claude + Codex gpt-5.5) + adversarial pass. Quality score: 9.5/10.
inspect_errwarn fires per-call under sustainedauth.testfailure -- intentional signalTest plan
slack::teststests passFixes #800
Generated with Claude Code