← Back to PRs

#15937: fix(slack): let users control threading instead of system prompt forcing it

by taw0002 open 2026-02-14 02:46 View on GitHub →
docs channel: slack agents stale size: S
## Problem The system prompt currently tells agents to **"Prefer `[[reply_to_current]]`"** — making the threading decision for the user. This removes user agency over a core UX behavior and creates problems when combined with Slack's default settings: 1. **System prompt forces threading** — "Prefer `[[reply_to_current]]`" means agents thread every reply regardless of user preference 2. **`allowTagsWhenOff: true`** (Slack dock) — reply tags override `replyToMode: off`, so even users who configured "no threading" get threading 3. **`thread.inheritParent: false`** (default) — each threaded reply spawns a new `:thread:<threadTs>` session, causing session sprawl **The core issue:** Threading should be a user preference, not a system prompt default. Users who want threading can configure `replyToMode`. Users who don't want it shouldn't have it forced on them by the agent. ### Evidence Screenshot from the OpenClaw gateway dashboard showing 5+ separate `:thread:` sessions spawned from a single Slack DM — all created because the system prompt told the agent to thread: - `agent:main:slack:channel:d0ae412sy9x:thread:1771031274.303499` - `agent:main:direct:drew:thread:1771031274.303499` - `agent:main:slack:channel:d0ae412sy9x:thread:1771030280.178839` - (and more) ## Root Cause The threading pipeline has four mechanisms that combine poorly when the system prompt overrides user intent: | Mechanism | Default | Effect | |-----------|---------|--------| | System prompt | "Prefer `[[reply_to_current]]`" | Agent always threads (ignoring user config) | | `allowTagsWhenOff` | `true` (Slack dock) | Reply tags bypass `replyToMode: off` | | `thread.inheritParent` | `false` | Each thread creates a new session | | `replyToMode` | `off` | User said "no threading" but gets it anyway | The `allowTagsWhenOff` design is correct — it lets agents selectively thread when it genuinely makes sense. The problem is the system prompt removing that selectivity by always preferring tags. ## Changes ### Fix 1: Let users decide on threading (system prompt) **Before:** ``` - Prefer [[reply_to_current]]. Use [[reply_to:<id>]] only when an id was explicitly provided. ``` **After:** ``` - Do not use reply tags by default. Threading behavior is a user preference — follow the user's configured replyToMode and threading settings. - If the user has not expressed a threading preference, do not assume one. You may ask the user if threading would be helpful for their workflow. ``` The agent still knows reply tags exist and how to use them. It just doesn't force them. If a user configures `replyToMode: all`, threading works. If they leave it at `off`, the agent respects that. If it's unclear, the agent can ask. **File:** `src/agents/system-prompt.ts` ### Fix 2: Default `inheritParent` to `true` When threads do occur (via user config or intentional agent choice), they should route to the parent session by default. Session sprawl from orphaned thread sessions is a worse default than unified sessions. Users who want isolated thread sessions can set `inheritParent: false`. **File:** `src/slack/monitor/provider.ts` ### Documentation Added "Thread session inheritance" section to Slack docs. **File:** `docs/channels/slack.md` ### Tests - Updated 3 existing tests to match new `inheritParent: true` default - Added test for explicit `inheritParent: false` opt-out - All 8 tests pass **File:** `src/slack/monitor.tool-result.threads-top-level-replies-replytomode-is-all.test.ts` ## Before/After | Behavior | Before | After | |----------|--------|-------| | Who decides threading? | System prompt (agent always threads) | User config (`replyToMode`) | | Agent default | "Prefer reply tags" | "Don't use reply tags by default" | | Thread → session mapping | New session per thread | Inherits parent session | | `inheritParent` default | `false` | `true` | | User with `replyToMode: off` | Gets threading anyway (via tags) | No threading (tags not used) | | User with `replyToMode: all` | Gets threading | Gets threading (unchanged) | ## Backward Compatibility - Users who explicitly set `replyToMode: all` or `first` are unaffected — threading still works - Users who set `inheritParent: false` are unaffected - `allowTagsWhenOff: true` is unchanged — agents CAN still thread selectively when it makes sense - The agent now respects the user's threading config instead of overriding it

Most Similar PRs