Submatter/.convoys/workspace-chat-foundation.md
varutasu ff01a5f097
Some checks are pending
CI / Lint, type-check, test (push) Waiting to run
Deploy homelab (CT 116) / Deploy to CT 116 (push) Waiting to run
Make workspace Chat durable and ready for source-built deployment
2026-10-29 19:30:20 +00:00

9.5 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
roles escalate_to
role-conductor role-architect role-implementer role-reviewer
claude-planning claude-planning qwen-coder qwen-coder
claude-planning

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.
  • At kickoff, Brief 1 was the next implementable slice. Superseded by the integration checkpoint below; the independent AI shell implementer remains 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. open is the local README status, not a server lifecycle claim.

Go-live reconciliation — 2026-10-29

  • Operator reports Chat deployed on CT 116 and 14/14 checks passed, including two-member messaging, reply, reconnect, unread, edit/delete recovery and revocation. Canonical endpoint: wss://chat.stillwell.cloud/chat.
  • CT 102 ledger reported at 24 entries through 0023; Chat schema verified and table ownership corrected to echodo. No migrations rerun here.
  • Deployment evidence is now present in docs/Current Progress.md; local channel projection/plain-JSON redaction fixes preserved with regression coverage. Ticket origin handling is hardened locally to configured auth URL rather than forwarded headers; requires rebuild and post-deploy retest.
  • Direct/PVE SSH trust in this harness remains unavailable, but is not a production rollout blocker. Operator production acceptance and local automated checks are separate evidence.
  • Shared credentials password removal needs an operator decision. Source-built web rebuild, full checks and final review remain open; no lifecycle transition or release gate completion is inferred from the deployment report.

Earlier integration checkpoint — 2026-10-29 (superseded by go-live report)

  • Local implementation now includes persistence/edit/tombstone transactions, mutation catch-up, signed-ticket subscriptions, Redis outbox publication, and workspace Chat UI with scoped recovery. Cursors are in-memory, not persisted across browser reloads.
  • Deployment wiring now extends collab with CHAT_PORT (default 1235), a shared runtime signing secret, dual-listener liveness checks, standalone publication, and a public TLS proxy example. The web URL is a build argument and Turbo build input.
  • Configuration regression tests cover the wiring; actual Docker Compose/image validation still requires a Docker host. See current progress and the deployment gate.
  • Production migrations 0022/0023 remain unverified. CT 116 SSH was blocked by a missing trusted host key; no remote changes were made. Disposable-Postgres, Redis/WebSocket, browser/revocation, accessibility and final review gates remain open.
  • Earlier commit/push completion claims were incorrect: the implementation was still uncommitted at inspection. No merge, release, or server lifecycle transition is claimed by this checkpoint.

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 Chat as a first-class left-rail destination within the current workspace.
  • /[workspaceSlug]/chat selects 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

  1. A workspace-authorized tRPC mutation validates the command and channel membership.
  2. Brief 1 owns one Postgres transaction that inserts the message and its versioned outbox event.
  3. Brief 2 owns an outbox worker that claims and publishes committed events through Redis.
  4. Realtime instances fan events out to authenticated local WebSocket subscribers.
  5. 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-server or 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