fix(sessions): reset stale per-channel origin fields on channel switch (#95325)#95332
fix(sessions): reset stale per-channel origin fields on channel switch (#95325)#95332ruomuxydt wants to merge 2 commits into
Conversation
When session.dmScope:"main" shares one session across channels, switching channels (e.g. Slack -> Telegram) left the prior channel's nativeChannelId, nativeDirectUserId, and threadId in the session origin. Channels like Telegram DM do not carry a nativeChannelId, so mergeOrigin never overwrote the stale Slack value, which then persisted for the entire new-channel session and broke native-channel-keyed operations (reactions, native threading). Detect a provider or surface change in mergeOrigin and reset the channel- specific fields before applying the new channel's values. Same-channel turns that keep supplying nativeChannelId continue to update it as before. Fixes openclaw#95325
|
Codex review: needs maintainer review before merge. Reviewed June 20, 2026, 3:01 PM ET / 19:01 UTC. Summary PR surface: Source +13, Tests +116, Other +93. Total +222 across 3 files. Reproducibility: yes. at source level. Current Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land one canonical session-origin fix that clears stale channel-keyed origin fields on provider or surface switches while preserving same-channel sparse metadata, then close the linked issue and supersede duplicate candidate PRs. Do we have a high-confidence way to reproduce the issue? Yes, at source level. Current Is this the best way to solve the issue? Yes as a code shape: AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 3a14f247ad1b. Label changesLabel justifications:
Evidence reviewedPR surface: Source +13, Tests +116, Other +93. Total +222 across 3 files. View PR surface stats
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 re-review
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Thanks for the submission. We merged #95328, which supersedes this PR. |
Summary
With
session.dmScope: "main", a user's DMs across channels (Slack, Telegram, webchat) share one session. When the channel switches (e.g. Slack → Telegram), the session origin's per-channel identity fields were not reset.mergeOriginonly overwrites a field when the new inbound supplies it. Telegram DMs do not supplynativeChannelId(orthreadId), so the previous Slack channel id persisted in the now-Telegram session and kept persisting on every subsequent Telegram turn until the user messaged on the original channel again.Changes
src/config/sessions/metadata.ts: Detect aproviderorsurfacechange inmergeOriginand reset the channel-specific fields (nativeChannelId,nativeDirectUserId,threadId) before applying the new channel's values. Same-channel turns that keep supplyingnativeChannelIdcontinue to update it as before.src/config/sessions/metadata.test.ts: Regression tests covering the channel-switch reset and the preserved-same-channel case.scripts/repro/issue-95325-channel-switch.mts: Real behavior proof harness driving the productionderiveSessionMetaPatch.Real behavior proof
Behavior addressed: Session origin no longer retains the previous channel's
nativeChannelId/nativeDirectUserId/threadIdafter a provider or surface change.Real environment tested: Windows 10 (10.0.17763), Node.js v22.19.2, source tree at commit 0a031e7.
Exact steps or command run after this patch:
node --import tsx scripts/repro/issue-95325-channel-switch.mtsThe harness imports the real production
deriveSessionMetaPatchand drives a three-turn sequence on a shareddm:sharedsession key (Slack DM → Telegram DM → Slack DM again), reading back the mergedoriginafter each turn.Evidence after fix:
Observed result after fix: After the Slack→Telegram switch, the merged origin carries
provider: "telegram"and nonativeChannelId/nativeDirectUserId(the stale SlackDslackdm/Uslackuserare gone). Switching back to Slack re-adoptsnativeChannelId: "Dslackdm", proving the reset only fires on a real channel change and does not block later same-channel re-adoption.What was not tested: Live Slack↔Telegram round-trip over real channels (requires live credentials). The harness drives the real runtime merge path (
deriveSessionMetaPatch→mergeOrigin), which is the single function the runtime uses to update session origin on each inbound turn.Verification
node scripts/run-vitest.mjs run src/config/sessions/metadata.test.ts: 4/4 passing.node --import tsx scripts/repro/issue-95325-channel-switch.mts: all checks pass (real production function).tsgo -p tsconfig.core.json: no errors in the modified file.oxlinton modified files: clean.sessionFilepath tests (2) fail identically on baseorigin/mainwithout this change — unrelated to origin merging.Fixes #95325