Skip to content

Epic: Workshop channels (mention-gated group conversations) #970

Description

@dcellison

Goal

Add channels to Workshop as the second conversation container alongside direct messages. The model: a direct message is exactly one human and one agent, and the agent responds to every message with no mention needed. Every other conversation is a channel, where agents respond only when addressed. Agent attention derives from the container kind alone; there is no per-conversation wake setting.

Why

Today every Workshop conversation behaves like a DM: each accepted inbound message atomically creates a run, so the agent answers everything everywhere. That is correct for the bootstrap direct channel and wrong for any container with more than one human-agent pair. Channels unlock topic separation (a channel per project), multiple agents as members, and eventually multi-human membership, while keeping agent attention deterministic and loop-safe.

Architecture

The schema already anticipates this work: channels has a kind column, explicit channel_memberships exist, the inbound resolver already accepts a group kind, the event vocabulary already covers channel.created / channel.member_added / channel.agent_attached, and runtime resolution already accepts an optional agent id. What this epic adds is the interaction layer:

  • Lifecycle: a client-facing create-channel route, event-sourced with the existing vocabulary; kind group, private by default, membership fixed at creation.
  • Mentions: @display-name parsed server-side at message acceptance as the single source of truth, stored on the message payload as resolved principal references.
  • Wake policy: decided inside the atomic message-acceptance transaction. Direct channels wake on every human message (unchanged). Group channels route by mention first: a message that mentions agents wakes exactly the mentioned agents, regardless of who is engaged; a message that mentions no agent wakes the currently engaged agents; human mentions are notification only. Non-waking messages are appended canonically with a new MESSAGE_ONLY disposition and no run. Agent-authored messages never wake other agents.
  • Engagement: derived, not stored. A mention engages the agent for the containing scope until it is quiet for a fixed window (900 seconds) or the agent is dismissed via a new channel.agent_dismissed fact. Before threads exist the scope is the channel; once threads land the same rule re-scopes to the thread.
  • Threads: a nullable thread_root_id on messages, a thread timeline route, and a client thread pane.

Two non-negotiables: the wake decision must live inside the same transaction as message acceptance so replay stays idempotent, and run.accepted gains the woken agent's id so multi-agent channels resolve the correct runtime.

Sub-issues

  1. Workshop channels: channel lifecycle API (POST /v1/channels, event-sourced creation) #971 Channel lifecycle API (foundation for the client surface and threads)
  2. Workshop channels: server-side mention model on message acceptance #972 Mention model (parsing and payload; ships dark)
  3. Workshop channels: kind-derived wake policy and channel-scoped engagement #973 Wake policy and interim channel-scoped engagement (depends on Workshop channels: server-side mention model on message acceptance #972)
  4. Workshop channels: client channel surface (sidebar, create flow, mentions, engagement) #974 Client channel surface (depends on Workshop channels: channel lifecycle API (POST /v1/channels, event-sourced creation) #971 and Workshop channels: kind-derived wake policy and channel-scoped engagement #973)
  5. Workshop channels: threads (thread_root_id, thread timeline route, client pane) #975 Threads (depends on Workshop channels: channel lifecycle API (POST /v1/channels, event-sourced creation) #971; parallel to Workshop channels: server-side mention model on message acceptance #972 and Workshop channels: kind-derived wake policy and channel-scoped engagement #973)
  6. Workshop channels: thread-scoped agent engagement #976 Thread-scoped engagement (depends on Workshop channels: kind-derived wake policy and channel-scoped engagement #973 and Workshop channels: threads (thread_root_id, thread timeline route, client pane) #975; closes the epic)

Critical path is 1 → 2 → 3. Each sub-issue is one PR and closes itself with fixes #N.

Out of scope

Multi-human provisioning; membership mutation on existing channels (forking a new channel is the supported flow); public channel discovery; Telegram transport bindings for group channels; agent-to-agent delegation controls; named teams and channel default agents.

Sequencing

Decision 2026-08-19: this epic is deliberately queued behind the memory audit remediation epic (#1013), which runs to completion first. Not stale; work begins when #1013 closes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicTracks a multi-issue body of work

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions