Submatter/plans/Plan-workspace-communications/Plan-workspace-communications.md

105 lines
10 KiB
Markdown
Raw Normal View History

---
kind: plan
slug: workspace-communications
title: Workspace communications — chat, notifications, and agent participation
status: ready
priority: P1
tenant_id: global
cursor_plan_id: null
updated_at: "2026-10-22"
agent_prompt: |
Build workspace communications as a durable, multitenant product surface. Keep Postgres authoritative, scope every query by workspace_id, validate external input with zod, and separate realtime delivery from durable writes. Agents request capabilities through the harness and model-routing contracts; do not couple chat to a model provider.
---
# Plan overview
Add persistent workspace chat where humans and agents collaborate, plus a unified notification inbox that brings mentions, replies, assignments, approvals, and agent outcomes into one reliable surface.
## Objectives and success criteria
- Workspace members can navigate to Chat from the left rail, participate in channels and threads, and recover complete history after reconnecting.
- A unified inbox provides durable read/unread state for chat and operational events, with chat mention counts reflected on the left rail.
- The existing AI rail destination provides Chat and Agents tabs, including an AI-assisted builder and marketplace library for explicit agent identities.
- Saved agents can participate in workspace channels through durable jobs and the provider-agnostic execution harness.
- Realtime delivery scales across web instances without making Redis or Yjs the source of truth.
- Every channel, message, notification, job, and preference is scoped by `workspace_id` and authorized against its context and channel, not merely workspace membership.
## Scope and boundaries
**In scope**
- Workspace and authorized project/supported-object conversations, memberships, messages, threads, read cursors, and attachments metadata.
- HTTP/tRPC commands and queries backed by Postgres, with WebSocket event delivery and Redis fan-out.
- Unified in-app notifications, preferences, delivery records, and left-rail badges.
- An AI workspace with Chat/Agents tabs, shared composer shell, agent registry, curated marketplace templates, and conversational agent building.
- Agent identities, mentions, durable invocation jobs, streaming run events, and approval-required states.
- Reuse of Hocuspocus/Yjs for ephemeral presence, typing, or collaborative drafts where useful.
**Out of scope**
- Replacing Postgres message history with a Yjs document.
- Browser-to-server gRPC.
- Coupling chat directly to OmniRoute, Vercel AI SDK, or any individual model provider.
- Email/mobile push delivery in the first release; the schema and outbox may prepare for them.
- Full Slack/Discord import or federation.
## Approved direction and execution boundary — 2026-10-22
The user approved beginning implementation now: conversations in workspaces, projects, and other supported contexts; mention a reusable agent to add it with explicit access review when necessary; create/manage those agents in the existing AI Chat/Agents destination. This is kickoff approval, **not** merge or release approval. Conductor and architect reconciled these artifacts in this session; no historical IA, UX, reviewer, DB registration, or MCP transition is asserted.
**Full product:** contextual conversations, reusable-agent creation/installation, mention-to-add, durable runs, and unified notifications. **Current foundation convoys:** workspace-only channel persistence/realtime/UI; AI tab shell, registry schema/contracts, and inert builder service. These foundations do not alone deliver project chat, agent installation APIs, saved-agent execution, or mention-to-add. The independent implementer is working on `Epic-agent-participation/Task-ai-workspace-tabs.md`; other implementation remains pending.
## Context authorization contract
- Inspected sources: `packages/database/src/schema/objects.ts`, `workspaces.ts`, `types.ts`, `packages/shared/src/types/objects.ts`, and `apps/web/server/routers/objects.ts`. Workspaces have a dedicated table; projects are `objects.type = 'project'`, not a separate projects table. Existing object types also include space, task, document, whiteboard, group, and form. Custom type definitions do not automatically confer chat support. The legacy `workspace` object type is not the tenant anchor.
- These schemas/router currently establish tenant ownership, not private project/object ACLs. `object_assignees`, `created_by`, parent links, and `assertObjectInWorkspace` are not proof of permission to read or delegate a private context. Do not invent a project-members table or infer inherited grants.
- Model context as an explicit workspace reference or a same-workspace object reference. Supported object contexts need an explicit allowlist and an authoritative read/write/delegate policy; unknown, archived, deleted, cross-tenant, and policy-unavailable contexts fail closed. Workspace-only foundation commands reject object context requests rather than silently downgrading them to public workspace chat.
- Effective chat access is **active workspace access AND context permission AND channel permission**. Public means public only within the authorized context audience. Private/direct channels additionally require explicit membership. Workspace `admin`/`owner` status alone is not a private-context read/delegation bypass. Joining a channel never grants access to its parent object.
- Apply that predicate to discovery, titles/previews, history/threads, writes, memberships, mentions, unread counts, notifications, subscriptions, replay, and agent context/tool reads. Recheck at use/delivery time and revoke active subscriptions/jobs when access is removed; cached membership or an old approval cannot keep access alive.
- `Epic-workspace-chat/Task-contextual-chat-authorization.md` owns the bounded project/object integration, blocked until an authoritative context policy exists. Do not broaden the first persistence brief into a general ACL product.
## Agent identity, roles, and mention-to-add contract
- One workspace agent registry supplies AI Chat selection, Agents library/builder, channel mention completion, installations, and run identity. Templates are provenance; model/harness aliases and `agent_runs` are not alternative agent identities. Runs and conversations pin immutable versions from this registry.
- Active members may create/edit their own private drafts and use explicitly available active agents; others, including admins, cannot browse those drafts. Registry API owns draft persistence, while editor and library tasks consume it. `admin`/`owner` approve installation, shared publication/activation and ordinary allowlisted capabilities; only `owner` approves mutating sandbox policy or sensitive workspace-wide tools. These roles never bypass context authority.
- Any authorized chat sender may mention an eligible visible agent and request addition. Mention text alone never installs, activates, adds, grants access, or runs an absent agent. If it is already an active member with a current sufficient grant, an explicit invocation can enqueue once without repeating review.
- A new membership or expanded/stale grant requires a review showing pinned agent version, exact conversation/context, history boundary (default: post-confirmation messages; older history only by explicit grant), requested tools, budget, and invocation policy. Confirmation requires a channel manager **and** context delegation authority; `admin`/`owner` is additionally required for new shared/tool grants, and sensitive policy remains owner-only. A channel creator can confirm an already-approved ordinary agent with no tool expansion only within context authority. Read/use permission alone is not delegation permission.
- If the sender lacks authority, return a safe approval-required state for an eligible approver without leaking restricted context or agent drafts. Denial, dismissal, or stale review grants nothing. Never silently install a missing agent from a mention; route installation to Agents.
- Confirmation binds actor, workspace, channel/context, agent/version, history/tool scope and grant revision; revalidate all inputs at commit. Atomically record audit + membership + grant and an optional requested invocation. Client request keys and source-message/job uniqueness make repeated mentions, retries, concurrent confirmation and replay idempotent. Changed scope/version invalidates review. Revocation/disable is rechecked before enqueue, execution, tools and delivery.
## Cross-team collaborators
| Name / group | Role |
|--------------|------|
| Web | Chat, inbox, navigation, accessibility |
| Database | Tenant-scoped persistence and migrations |
| Collab server | WebSocket delivery, Redis fan-out, presence |
| Worker and AI | Durable agent jobs, harness adapters, model routing |
| MCP | Tenant-scoped agent tools and deep links |
## Epics
| Epic | Link |
|------|------|
| Workspace chat foundation | `./Epic-workspace-chat/Epic-workspace-chat.md` |
| Unified notification inbox | `./Epic-unified-notifications/Epic-unified-notifications.md` |
| Agent participation in chat | `./Epic-agent-participation/Epic-agent-participation.md` |
## Metrics and milestones
| Milestone | Target date | Metric |
|-----------|-------------|--------|
| Chat foundation | TBD | Two members can exchange durable messages and reconnect without loss |
| Unified inbox | TBD | Mentions and operational events have accurate unread counts and deep links |
| Agent participation | TBD | A mentioned agent completes a harness-backed run and persists its response |
## Risks and mitigations
| Risk | Mitigation |
|------|------------|
| Lost or duplicated realtime events | Transactional outbox, idempotency keys, sequence cursors, Postgres replay |
| Cross-tenant data exposure | `workspaceProcedure`, workspace indexes, scoped joins, authorization tests |
| Redis outage interrupts chat | Durable writes remain available; clients catch up from Postgres after recovery |
| Agent loops or runaway spend | Explicit mention policy, rate limits, model policy, budgets, cancellation, approvals |
| Notification fatigue | Per-channel levels, category preferences, bundling, and durable read state |