The design describes a channel as "the pluggable interface" and states that "adding a channel is a plugin, not a daemon reshape; every channel reduces to the normalized message shape".
In practice, adding Slack (#1127) meant compiling a new module into the daemon and dispatching on a kind string, with its credentials added as fields on the shared ServiceChannelConfig (app_token, bot_token, allowed_workspaces, allowed_channels) rather than living behind a channel-specific shape. Adding a third channel today is another daemon change, and another few kind-specific fields on a struct every channel shares.
Two separable pieces here, and the first is worth doing regardless of whether the second ever happens:
- A real channel abstraction inside the daemon — a normalized inbound message shape and a trait each channel implements, with per-kind config carried in a per-kind shape instead of accreting optional fields on one struct. This is refactoring, and it is what stops the config type from degrading as channels are added.
- Out-of-process channel plugins — genuinely pluggable, no recompile. Much larger, needs a protocol and a lifecycle, and interacts with the sandbox story since a plugin is code the operator did not write. The design's non-goals already rule out a hosted marketplace, which bounds this.
Doing (1) first would make (2) tractable and is a prerequisite either way.
The design describes a channel as "the pluggable interface" and states that "adding a channel is a plugin, not a daemon reshape; every channel reduces to the normalized message shape".
In practice, adding Slack (#1127) meant compiling a new module into the daemon and dispatching on a
kindstring, with its credentials added as fields on the sharedServiceChannelConfig(app_token,bot_token,allowed_workspaces,allowed_channels) rather than living behind a channel-specific shape. Adding a third channel today is another daemon change, and another few kind-specific fields on a struct every channel shares.Two separable pieces here, and the first is worth doing regardless of whether the second ever happens:
Doing (1) first would make (2) tractable and is a prerequisite either way.