#12244: fix(slack): preserve thread context for DM thread replies
channel: slack
stale
Cluster:
Slack Thread Management Fixes
## Summary
- Simplify thread detection to always preserve context when `thread_ts` exists
- Fixes edge case where DM thread replies lost thread context when `replyToMode="off"` (default for DMs)
## Root Cause
The old logic checked `(incomingThreadTs !== messageTs || Boolean(params.message.parent_user_id))` which failed when:
- `thread_ts === ts` (first reply in a DM thread)
- AND no `parent_user_id` (edge case in DM threads)
## Changes
- `isThreadReply` now simply checks `hasThreadTs` - if we have `thread_ts`, we're in a thread
- `messageThreadId` preserves `thread_ts` regardless of `replyToMode`
- Added comprehensive tests for DM thread edge cases
## Testing
- All 16 threading tests pass
- Build passes with no type errors
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates Slack threading behavior so that any inbound Slack event with a `thread_ts` is treated as a thread reply, preserving `messageThreadId`/`replyToId` even when `replyToMode="off"` (the DM default). It also expands `src/slack/threading.test.ts` with DM edge-case coverage.
Additionally, this commit adds extensive `[DIAG]` console logging across the auto-reply dispatch and Slack monitor/send pipeline to trace message handling, dispatching, and delivery decisions.
The core threading change in `src/slack/threading.ts` aligns the thread-context computation with Slack’s DM edge cases (where `thread_ts === ts` and `parent_user_id` can be missing), ensuring replies remain in the correct thread when a `thread_ts` is present.
<h3>Confidence Score: 3/5</h3>
- This PR has one blocking issue (unconditional console diagnostics) but the threading logic change itself looks correct and is test-covered.
- Thread context simplification is localized (`resolveSlackThreadContext`) and the added tests cover the reported DM edge case. However, the commit introduces widespread `console.log` of message content/session identifiers across core dispatch and Slack delivery paths without being gated by existing diagnostics controls, which is a production logging/privacy/regression concern.
- src/auto-reply/reply/dispatch-from-config.ts, src/auto-reply/reply/reply-dispatcher.ts, src/slack/monitor/message-handler.ts, src/slack/monitor/message-handler/dispatch.ts, src/slack/monitor/replies.ts, src/slack/send.ts, src/auto-reply/dispatch.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
87.9%
#23804: fix(slack): preserve string thread context in queue + DM route
by vincentkoc · 2026-02-22
86.8%
#23799: fix(slack): finalize replyToMode off threading behavior
by vincentkoc · 2026-02-22
86.4%
#19403: feat(slack): add dm.threadSession option for per-message thread ses...
by Vasiliy-Bondarenko · 2026-02-17
83.9%
#19083: Slack: preserve per-thread context and consistent thread replies
by jkimbo · 2026-02-17
83.5%
#2917: Slack: fix thread context + prevent reply spillover
by SocialNerd42069 · 2026-01-27
83.3%
#23320: fix(slack): respect replyToMode when incomingThreadTs is auto-created
by dorukardahan · 2026-02-22
83.1%
#22433: Slack: fix thread context loss after session reset
by stgarrity · 2026-02-21
82.1%
#20389: fix(slack): inject thread history on first thread turn, not only on...
by lafawnduh1966 · 2026-02-18
81.9%
#15969: fix: per-thread session isolation for Slack DMs when replyToMode is...
by neeravmakwana · 2026-02-14
81.8%