7.2 KiB
| name | classification | success_metric | skip | status | created | model_policy | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| workspace-chat-foundation | feature | Two workspace members can exchange durable channel messages, reconnect without loss, and open Chat from the left rail with accurate unread state. | open | 2026-09-25 |
|
Workspace chat foundation
Why
Echodo has collaborative documents, convoy operator notes, and AI chat surfaces, but no durable workspace conversation layer. The first slice must establish trustworthy persistence and realtime delivery before notifications or agent participation depend on it.
Canonical backlog: plans/Plan-workspace-communications/Epic-workspace-chat/Epic-workspace-chat.md.
Scope
- Brief 1: tenant-scoped chat schema, channel lifecycle, message/outbox transaction, and workspace-authorized tRPC API.
- Brief 2: outbox publication, authenticated WebSockets, Redis fan-out, and reconnect catch-up.
- Brief 3: workspace Chat routes, channel/message UI, and left-rail unread/mention affordance.
- Postgres is authoritative; Redis and WebSockets accelerate delivery.
- Yjs/Hocuspocus may support presence/typing/drafts, but does not own message history.
Out of scope for this convoy: unified non-chat inbox, agent execution, external delivery, search, and federation.
Role activity and kickoff — 2026-10-22
- User approved beginning the integrated contextual-chat/AI-agent direction; this does not authorize merge or release.
- This session performed conductor reconciliation and architect schema/access/dependency review. IA, UX, implementation, review and release work are not claimed complete by the existing section headings.
- Chat Brief 1 remains the next implementable slice; no chat implementation is claimed started. The independent AI shell implementer is tracked in the AI convoy.
- Files are local planning artifacts. No convoy DB registration, task claim, event logging, or MCP gate transition was performed; those tools are unavailable here.
openis the local README status, not a server lifecycle claim.
Full product versus this foundation
The approved product includes workspace, project and supported-object chat plus mention-to-add agents. This convoy implements workspace-context human chat only, with an explicit fail-closed context policy seam. Object contexts must be rejected until the canonical follow-on context authorization task lands; do not treat a same-workspace object lookup as an ACL. Mention-to-add belongs to agent channel membership, not these three briefs.
All briefs follow the plan's context and agent permission contracts. Projects are generic objects rows; the inspected schema has no private-object authorization model. This gap is a blocker for contextual rollout, not a reason to silently widen access.
Todos
- User approved kickoff of the integrated direction on 2026-10-22; merge/release gates remain pending.
- Implement brief 1 and validate tenant isolation and idempotency.
- Implement brief 2 and validate outage/reconnect behavior.
- Implement brief 3 and validate accessibility and multi-device unread state.
- Reviewer checks standards and the three linked backlog tasks.
- Human performs merge and release gates.
IA
- Add
Chatas a first-class left-rail destination within the current workspace. /[workspaceSlug]/chatselects or redirects to a channel./[workspaceSlug]/chat/[channelSlug]renders channel navigation and conversation.- Threads open in the existing right-panel pattern where practical, preserving channel context.
- The global notification inbox is a later epic; Chat still exposes its own durable unread and mention counts.
UX
- Ordinary unread activity uses a dot; mentions/direct messages use a numeric badge.
- Badges include accessible labels and never rely on color alone.
- Optimistic messages show pending, failed, and retry states.
- Reconnect and catch-up are silent when successful and explicit when recovery fails.
- Keyboard navigation covers rail entry, channel switching, message history, composer, and thread opening.
Architecture
Data and command path
- A workspace-authorized tRPC mutation validates the command and channel membership.
- Brief 1 owns one Postgres transaction that inserts the message and its versioned outbox event.
- Brief 2 owns an outbox worker that claims and publishes committed events through Redis.
- Realtime instances fan events out to authenticated local WebSocket subscribers.
- Reconnecting clients query Postgres after their last durable sequence cursor.
Boundaries
packages/database: tenant-scoped chat and outbox schema plus migration.packages/shared: zod contracts and versioned realtime event types when shared across processes.apps/web: workspace-authorized tRPC router, routes, React Query state, and shell navigation.apps/collab-serveror a narrowly separated realtime entry point: authenticated subscriptions and Redis fan-out.- Existing Hocuspocus/Yjs infrastructure remains available for ephemeral presence, typing, and collaborative drafts.
Security and scale
- Every query enforces workspace AND context AND channel access. Foundation accepts workspace context only; public workspace channels require active workspace membership, private/direct also require channel membership, and archived channels are read-only. Channel owners or workspace admins/owners administer only channels they may access; role alone grants no private/direct read or self-join bypass. Object contexts require a separate verified policy.
- Brief 1 defines the versioned outbox contract and owns the atomic message/outbox transaction; Brief 2 owns claim, publication, retry, and consumer delivery.
- Message commands accept client idempotency keys and generate a per-channel monotonic sequence; reconnect cursors are
(channel_id, sequence)pairs. - Realtime events carry identifiers and cursors, not authorization truth; subscription and catch-up endpoints authorize independently.
- Redis failure cannot roll back a committed message. Outbox retries and Postgres catch-up restore delivery.
- Use bounded pagination and backpressure; do not broadcast entire message histories.
- This convoy supports one-level threads in the persistence/API contract; full thread-panel polish may remain minimal in Brief 3.
- Read state is the highest message sequence the member has intentionally viewed. In this convoy, mention counts are derived from validated persisted message-mention rows above that cursor; the notification epic later projects those mentions into the unified inbox. Mark-read emits an invalidation event for other devices.
Briefs
| Brief | Backlog task | Depends on |
|---|---|---|
| 1 | Task-chat-persistence.md |
none |
| 2 | Task-chat-realtime-delivery.md |
brief 1 |
| 3 | Task-chat-ui-and-navigation.md |
briefs 1 and 2 |