fix(discord): PluralKit DM pairing identity + direct peer regex (#86332)#86397
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed May 25, 2026, 4:45 AM ET / 08:45 UTC. Summary PR surface: Source +12. Total +12 across 2 files. Reproducibility: yes. by source inspection: PluralKit makes Review metrics: 1 noteworthy metric.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance: Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the narrow Discord plugin fix after maintainer approval of the PK member-id pairing boundary, focused regression coverage, and redacted real Discord/PluralKit proof; avoid changing core pairing APIs unless that review finds a broader contract issue. Do we have a high-confidence way to reproduce the issue? Yes, by source inspection: PluralKit makes Is this the best way to solve the issue? Yes, the proposed code is the narrow owner-boundary fix because it makes the stored pairing key match the existing sender-based lookup and preserves AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against c791e4242bc8. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +12. Total +12 across 2 files. View PR surface stats
Security concerns:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
ClawSweeper PR egg 🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat. Where did the egg go?
|
|
Thanks for the PR. Before this can move forward, please add live proof from the affected surface, not just unit tests, mocked tests, or source inspection. A useful proof update should include:
Please redact secrets, tokens, phone numbers, and private message content from logs or screenshots. |
|
Heads up: this PR needs to be updated against current |
…claw#86332) Bug 1: resolveDiscordDmPreflightAccess passed the raw gateway author to handleDiscordDmCommandDecision while the access check used the resolved (PK-aware) sender identity. The two diverge for PluralKit users — the pairing record was keyed by the Discord user id while the ingress resolver looked it up by PK member UUID. Result: every inbound DM from a PK user triggered a fresh pairing challenge. Bug 2: extractDiscordSessionKind regex matched 'dm' but not 'direct', which is the canonical peer kind used for normalized DM session keys. No visible breakage today because all callers compare against 'dm', but a latent fragility for any future caller that distinguishes 'direct' from null. - Pass params.sender (resolved identity, includes PK UUID) to the pairing decision so the record key matches the lookup key. - Extend the kind regex to accept 'direct' and map it to 'dm'. Closes openclaw#86332
9a602f7 to
0db617d
Compare
|
Maintainer update before landing:
Verification run locally on head node scripts/run-vitest.mjs extensions/discord/src/approval-native.test.ts extensions/discord/src/monitor/dm-command-auth.test.ts extensions/discord/src/monitor/dm-command-decision.test.ts extensions/discord/src/monitor/message-handler.preflight.test.tsResult: 4 test files passed, 82 tests passed. Autoreview: .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/mainResult: clean after addressing two accepted findings. |
Fixes
Two related Discord DM-handling bugs from #86332.
Bug 1 — PluralKit DM pairing infinite loop
resolveDiscordDmPreflightAccesscalls the access check withparams.sender(the resolved, PK-aware identity) but then callshandleDiscordDmCommandDecisionwithparams.author(the raw gateway author). For non-PluralKit users these are identical, so the bug is invisible. For PluralKit-proxied users:resolveDiscordDmCommandAccess→createDiscordDmIngressSubject(params.sender)keys lookups under the PK member UUID.handleDiscordDmCommandDecisionusedparams.author.id(the Discord user/webhook id) when storing the pairing record.The next inbound DM from the same PK user looked up the PK member UUID, found nothing, and issued a new pairing challenge — forever.
Fix: pass
params.senderto the pairing handler so the stored key matches the lookup key. Fall back to gateway author for tag/name only.Bug 2 —
extractDiscordSessionKindregex missingdirectNormalized DM session keys look like
agent:<id>:discord:direct:<userId>. The regex matchedchannel|group|dmbut notdirect. Today every caller compares against\"dm\"and treatsnullthe same way, so there is no user-visible breakage — but the function silently lies about the session kind.Fix: add
directto the regex and map it todmin the return value, preserving the existing union type and downstream comparisons.Verification
Closes #86332