Skip to content

adapter-slack: export an inverse for the channel path segment contract #276

Description

@khaliqgant

Problem

adapter-slack owns the channel path segment contract and has changed it twice:

  1. <channelId>__<slug> — current, since 69761f13 ("v2 parity", 2026-05-12)
  2. <slug>--<channelId> — legacy, adapter-slack <= 0.2.2
  3. <channelId> — bare

The forward direction is owned here (channelSegmentV2 / channelSegmentLegacy in path-mapper.ts), and the inverse exists here too — extractSlackChannel in writeback.ts — but it is private. Consumers that need to recover a channel id from a path have to re-implement it.

Why it matters

Cloud did exactly that, and it broke. When form 1 landed, Cloud's watch matcher still assumed bare ids, so every channel-scoped Slack trigger silently stopped matching its own events — agents stopped waking on @mention, with no error anywhere. Only agents mis-scoped to /slack/channels/** kept working, waking on every message in the workspace. That went unnoticed for months.

Cloud now carries a second copy of this parser (cloud#3231). If the separator, normalization, or accepted id shape changes again, it silently desyncs the same way.

Proposal

Export the inverse, reusing the existing extractSlackChannel logic so there is one implementation:

/** Recover the canonical Slack channel id from a path segment, in any emitted form. */
export function slackChannelIdFromPathSegment(segment: string): string | null;

Handling all three forms, keyed off the id rather than the slug (channel names may contain underscores that slugification lossily replaces, so the id token is load-bearing).

Then writeback.ts consumes it internally and Cloud consumes it instead of its local regex — turning "the contract moved and a downstream matcher silently rotted" into a compile-time coupling.

Raised by an automated review on cloud#3231; filing here because the fix belongs with the contract owner.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions