982 lines
50 KiB
Markdown
982 lines
50 KiB
Markdown
# Roadmap — Chat Switchboard
|
||
|
||
**See also:**
|
||
- [ARCHITECTURE.md](ARCHITECTURE.md) — Core services design, store layer, scope model
|
||
- [EXTENSIONS.md](EXTENSIONS.md) — Extension system spec (Browser/Starlark/Sidecar tiers,
|
||
manifests, browser tool bridge, surfaces/modes, model roles)
|
||
- [CHANGELOG.md](../CHANGELOG.md) — Detailed release notes for all completed versions
|
||
|
||
**Versioning (pre-1.0):** `0.<major>.<minor>` — hotfixes use quad: `0.x.y.z`
|
||
No compatibility guarantees before 1.0.
|
||
|
||
---
|
||
|
||
## Dependency Graph
|
||
|
||
Features have real dependencies. This ordering respects them.
|
||
|
||
```
|
||
v0.9.x Stability + Quick UX Wins ✅
|
||
│
|
||
v0.9.3 Content Visibility & Block Controls ✅
|
||
│
|
||
v0.9.4 API Key Encryption + Vault ✅
|
||
│
|
||
v0.10.0 Model Roles (utility + embedding) ✅
|
||
+ Usage Tracking
|
||
│
|
||
v0.10.2 Summarize & Continue ✅
|
||
│
|
||
v0.10.3 Frontend Refactor ✅
|
||
│
|
||
v0.10.4 Model Type Pipeline + Role Fixes ✅
|
||
│
|
||
v0.10.5 UI Primitives + Extension Surfaces ✅
|
||
│
|
||
v0.11.0 Extension Foundation (browser tier) ✅
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.12.0 File Handling v0.13.0 Admin Panel
|
||
+ Vision ✅ Refactor (fullscreen) ✅
|
||
│ │
|
||
│ v0.13.1 Web Search
|
||
│ + url_fetch ✅
|
||
│ │
|
||
└───────┬──────────────┘
|
||
│
|
||
v0.14.0 Knowledge Bases ✅ (embedding role + file storage + pgvector)
|
||
│
|
||
v0.15.0 Compaction ✅ (utility role + background job)
|
||
│
|
||
v0.15.1 Context Recall Tools ✅ (attachment_recall, conversation_search)
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.16.0 User Groups v0.17.0 Persona-KB Binding
|
||
+ Resource Grants ✅ + Enterprise KB Mode
|
||
│ + QOL / UX Wins
|
||
└───────┬──────────────┘
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.17.1 SQLite Backend ✅ v0.17.2 CodeMirror 6 ✅
|
||
v0.17.3 Notes Graph + Wikilinks ✅
|
||
(dual DB) (editor bundle, chat
|
||
│ input, ext editor)
|
||
└───────┬──────────────┘
|
||
│
|
||
v0.18.0 Memory ✅ (user + persona scopes, review pipeline)
|
||
│
|
||
v0.18.1 Side Panel Architecture ✅ (single-slot, ctx.ui primitives, mermaid refactor)
|
||
│
|
||
v0.19.0 Projects / Workspaces ✅ (project groups, KB resolution, drag-drop sidebar)
|
||
│
|
||
v0.19.1 Active Project + System Prompt + Detail Panel ✅
|
||
│
|
||
v0.19.2 Project Persona Default + Archive + Reorder ✅
|
||
│
|
||
v0.20.0 Notifications + @mention Routing + Multi-model ✅
|
||
│
|
||
v0.21.0 Workspace Storage Primitive ✅
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.21.1 Workspace ✅ v0.21.3 Surface Infra
|
||
Tools + Bindings + REPL (parallel)
|
||
│ │
|
||
v0.21.2 Workspace ✅ v0.21.5 Editor Surface
|
||
Indexing + Search (Development Mode)
|
||
│ │
|
||
v0.21.4 Git v0.21.6 Article Surface
|
||
Integration + Document Output
|
||
└───────┬──────────────┘
|
||
│
|
||
v0.22.0 Smart Routing + Provider Extensions
|
||
│
|
||
v0.23.0 Multi-Participant Channels + Presence
|
||
│
|
||
v0.24.0 Auth Strategy (mTLS/OIDC) + Full RBAC + Group permissions
|
||
│
|
||
┌───────┴──────────────┐
|
||
│ │
|
||
v0.25.0 Workflow v0.26.0 Tasks /
|
||
Engine Autonomous Agents
|
||
(team-owned, (service channels,
|
||
staged processes, scheduler, unattended
|
||
human + AI collab) execution)
|
||
```
|
||
|
||
---
|
||
|
||
## Completed Releases
|
||
|
||
> Full details for all completed versions are in [CHANGELOG.md](../CHANGELOG.md).
|
||
|
||
### ✅ v0.9.0 — Schema Consolidation + BYOK
|
||
21 migrations → single schema, store layer abstraction, persona-as-trust-boundary,
|
||
BYOK with auto-fetch, composite model IDs, journey integration tests.
|
||
|
||
### ✅ v0.9.1 — Capability Architecture + Docs
|
||
Removed static known model table. Resolution chain: catalog → heuristic only.
|
||
Frontend relies solely on backend for capabilities. Docs rewrite.
|
||
|
||
### ✅ v0.9.2 — Quick UX Wins + Hardening
|
||
Collapsible code blocks, HTML preview, token counter, context warning, proxy
|
||
interception detection, environment injection, team admin audit scoping.
|
||
|
||
### ✅ v0.9.3 — Content Visibility & Block Controls
|
||
Button-driven code collapse, always-rendered thinking blocks, tool call
|
||
persistence in history, Notes panel → unified side panel, streaming refactor
|
||
(`streamWithToolLoop`), regenerate fix.
|
||
|
||
### ✅ v0.9.4 — API Key Encryption + Vault
|
||
Two-tier AES-256-GCM: env-var key for global/team, per-user UEK (Argon2id)
|
||
for personal BYOK. `server/crypto/` package. Migration 003. Startup backfill.
|
||
DOMPurify strict allowlist (XSS fix).
|
||
|
||
### ✅ v0.10.0 — Model Roles + Usage Tracking + Vault Debt
|
||
Named role slots (utility, embedding) with fallback. `Provider.Embed()` interface.
|
||
`usage_log` + `model_pricing` tables. Streaming token capture. Vault debt:
|
||
UEK re-wrap on password change, destruction on admin reset.
|
||
|
||
### ✅ v0.10.1 — Polish + UX
|
||
Admin system prompt injection, Personas tab, Team Management modal extraction,
|
||
preview pane enhancements, code download, personal usage scoped to BYOK.
|
||
|
||
### ✅ v0.10.2 — Summarize & Continue + Role Cleanup
|
||
User-triggered conversation compaction via utility role. Summary as tree node
|
||
with boundary metadata. BYOK role overrides (personal → team → global).
|
||
Utility rate limiting. Generation role removed.
|
||
|
||
### ✅ v0.10.3 — Frontend Refactor
|
||
2 monolith files → 13 domain-scoped files (~544 lines avg). Zero features,
|
||
no function renames. Vanilla JS, no build step.
|
||
See [REFACTOR-0.10.3.md](REFACTOR-0.10.3.md).
|
||
|
||
### ✅ v0.10.4 — Model Type Pipeline + Role Fixes
|
||
`model_type` (chat/embedding/image) captured end-to-end from provider API
|
||
through catalog to frontend. Role dropdowns filter by type.
|
||
|
||
### ✅ v0.10.5 — UI Primitives + Extension Surfaces
|
||
Shared `Providers`/`Roles` registries, 6 consolidated render primitives,
|
||
`showConfirm()` replacing native dialogs, `.popup-menu` CSS primitive.
|
||
Removed ~400 lines of duplication.
|
||
|
||
### ✅ v0.11.0 — Extension Foundation (Browser Tier)
|
||
Full extension lifecycle: manifest, loader, scoped `ctx.*` API, browser tool
|
||
bridge via WebSocket. Custom renderer pipeline. 2 server tools (calculator,
|
||
datetime), 6 built-in browser extensions (Mermaid, KaTeX, CSV, Diff, JS
|
||
Sandbox, Regex). See [EXTENSIONS.md](EXTENSIONS.md).
|
||
|
||
### ✅ v0.12.0 — File Handling + Vision
|
||
S3/PVC storage backend, image/file upload (📎, drag-drop, paste), multimodal
|
||
message assembly, text extraction pipeline (PDF/DOCX/XLSX/PPTX/ODT/RTF),
|
||
vault CLI (`rekey`/`status`), per-chat model persistence.
|
||
|
||
### ✅ v0.13.0 — Admin Panel Refactor
|
||
12-tab modal → fullscreen admin panel. 4 categories (People, AI, System,
|
||
Monitoring) × section sidebar. URL-based routing, responsive, banner-aware.
|
||
CSS design token cleanup.
|
||
|
||
### ✅ v0.13.1 — Web Search + URL Fetch
|
||
`web_search` + `url_fetch` tools. Search provider abstraction (DuckDuckGo,
|
||
SearXNG). Tool categories with per-tool toggle UI in chat bar.
|
||
|
||
### ✅ v0.14.0 — Knowledge Bases
|
||
RAG: upload → chunk → embed (pgvector) → `kb_search` tool. Channel KB toggle.
|
||
Team/personal KB scopes. Notes semantic search. Admin panel KB management.
|
||
See [DESIGN-0.14.0.md](DESIGN-0.14.0.md).
|
||
|
||
### ✅ v0.15.0 — Compaction
|
||
Background scanner with configurable thresholds. Automatic summarization via
|
||
utility role. Per-channel opt-in/out. Context budget guard rail (80% ceiling).
|
||
|
||
### ✅ v0.15.1 — Context Recall Tools
|
||
`attachment_recall` (list + read, channel-scoped), `conversation_search`
|
||
(full-text via `plainto_tsquery`). Token estimator attachment awareness.
|
||
|
||
### ✅ v0.16.0 — User Groups + Resource Grants
|
||
Groups (global/team-scoped ACLs) decoupled from team membership. Three-way
|
||
resource grants (team_only/global/groups) for Personas and KBs. Grant picker
|
||
UI. Schema consolidation: 9 migrations → single `001_v016_schema.sql`.
|
||
|
||
---
|
||
|
||
## v0.17.0 — Persona-KB Binding + Enterprise KB Mode + QOL ✅
|
||
|
||
Personas become **gateways** to knowledge. In enterprise deployments,
|
||
users don't interact with KBs directly — they talk to Personas that
|
||
have KBs attached. Plus quality-of-life improvements: chat rename,
|
||
token display, state persistence, utility model auto-naming.
|
||
|
||
Depends on: knowledge bases (v0.14.0), user groups (v0.16.0).
|
||
|
||
**Persona-KB Binding**
|
||
- [x] `persona_knowledge_bases` table: `persona_id`, `kb_id`, `auto_search` (bool — always search vs tool-only)
|
||
- [x] When a channel uses a Persona with bound KBs, `kb_search` is auto-scoped to those KBs
|
||
- [x] No user toggle needed — Persona carries its own KB context
|
||
- [x] Channel KB toggle becomes "additional KBs" on top of Persona-provided ones
|
||
- [x] Persona system prompt auto-includes KB listing hint (reuses `BuildKBHint` pattern)
|
||
- [x] Admin/team admin UI: KB picker on Persona create/edit form
|
||
|
||
**Enterprise KB Mode**
|
||
- [x] `discoverable` flag on knowledge_bases: `true` (default — appears in user's KB popup) or `false` (hidden, only accessible through Persona binding)
|
||
- [x] Hidden KBs don't appear in `GET /api/v1/knowledge-bases-discoverable` for non-admins
|
||
- [x] Hidden KBs still searchable by `kb_search` tool when accessed through a Persona
|
||
- [x] Admin panel: toggle discoverability per KB
|
||
- [x] Platform policy: `kb_direct_access` — when `false`, disables channel KB popup entirely (strict enterprise mode)
|
||
|
||
**Access Control Integration**
|
||
- [x] Persona grants (v0.16.0 groups) control who can *use* a Persona
|
||
- [x] KB grants control who can *manage* a KB (upload/delete docs)
|
||
- [x] Persona-KB binding grants implicit *search* access through the Persona
|
||
- [x] Users who can use a Persona can search its KBs, even if they can't see those KBs directly
|
||
|
||
**Team Admin Workflow**
|
||
- [x] Team admin creates KB → uploads documents → marks non-discoverable
|
||
- [x] Team admin creates Persona → binds KBs → sets access to Team Only or specific Groups
|
||
- [x] Team members see the Persona in their preset list, use it, get KB-powered answers
|
||
- [x] Team members never see or manage the underlying KBs
|
||
|
||
**Technical Debt (carried forward)**
|
||
- [x] **Security**: KB create handler authorization — team/global scope verified
|
||
- [x] **Test hygiene**: stripped DIAG diagnostics from `TestGroupBasedPersonaAccess`
|
||
- [x] **Architecture**: `KnowledgeBaseStore.UpdateDocumentStorageKey()` — moved to store layer
|
||
- [x] **UX**: Embedding dropdown fix — tolerant type filter, manual model ID fallback, auto-switch on empty _(already implemented in `ui-primitives.js`)_
|
||
- [x] **Minor**: Paste-to-file character threshold — synced from backend `PublicSettings` (`storage.paste_to_file_chars`), admin-configurable, default 2000
|
||
|
||
**Role Fallback Alerts** ([#69](https://git.gobha.me/xcaliber/chat-switchboard/issues/69))
|
||
- [x] Audit log entry on fallback fire: `action = "role.fallback"` with primary/fallback model IDs and error string
|
||
- [x] `role.fallback` WebSocket event via EventBus (`PublishAsync`, zero latency impact on completion path)
|
||
- [x] In-memory cooldown on `Resolver` (per-role, 5-minute TTL) to deduplicate repeated fallback alerts
|
||
- [x] Admin UI: persistent alert banner on `role.fallback` event (persists until dismissed)
|
||
- [x] Wire `*events.Bus` into `roles.NewResolver` via `.WithBus()` builder
|
||
|
||
**QOL / UX Wins**
|
||
- [x] **Chat rename**: inline edit on sidebar item — dblclick title → input → blur/Enter saves via `API.updateChannel(id, { title })`
|
||
- [x] **Chat token count**: display `Tokens.estimateConversation()` in model bar, update on `selectChat` and after each message
|
||
- [x] **State restore on refresh**: persist `App.currentChatId` to `sessionStorage` on select, restore on load
|
||
- [x] **Utility model auto-naming**: after first assistant response, background utility role request → `POST /channels/:id/generate-title` → re-render sidebar. Fallback to truncation when no utility model configured. Debounced via `_autoNamePending` set
|
||
- [x] **SW extension cache fix**: exclude `/extensions/` from service worker fetch handler
|
||
- [x] **Mermaid renderer**: promoted enhanced version (v2.0 — pan/zoom, SVG/PNG export, source copy) to `extensions/builtin/mermaid-renderer/`
|
||
|
||
---
|
||
|
||
## v0.17.1 — SQLite Backend ✅
|
||
|
||
Dual-database support. Every subsequent schema change is developed
|
||
against both Postgres and SQLite from day one — no retrofit. SQLite
|
||
enables single-binary deployment for dev, demo, edge, and single-user.
|
||
|
||
Depends on: v0.17.0 DB debt cleanup (store layer is sole DB interface).
|
||
|
||
**Store Layer**
|
||
- [x] 19 SQLite store implementations covering all domain interfaces
|
||
- [x] `DB_DRIVER` env var: `postgres` (default) | `sqlite`
|
||
- [x] Separate migration files per driver (`migrations/sqlite/`)
|
||
- [x] WAL mode + single-writer connection pooling for SQLite concurrency
|
||
- [x] CI matrix: full handler integration tests against both Postgres and SQLite
|
||
|
||
**Vector Search**
|
||
- [x] App-level cosine similarity in Go (pure Go, no CGO/sqlite-vec required)
|
||
- [x] Embeddings stored as JSON text in `kb_chunks.embedding` column
|
||
- [x] Full feature parity with pgvector: `SimilaritySearch`, `InsertChunks`
|
||
- [x] Graceful: adequate performance for SQLite-scale deployments (single-user, not millions of chunks)
|
||
|
||
**Schema Compatibility**
|
||
- [x] UUID generation: application-side `store.NewID()` (Go `uuid.New()`)
|
||
- [x] JSONB → JSON text columns with `ToJSON()`/`ScanJSON()` helpers
|
||
- [x] `UUID[]` arrays → JSON arrays with `ToJSONArray()`/`ScanJSONArray()`
|
||
- [x] `TIMESTAMPTZ` → SQLite `TEXT` with `datetime('now')`
|
||
- [x] `ON CONFLICT excluded.*` pattern (works in both dialects)
|
||
- [x] `INSERT RETURNING id` → separate query pattern for SQLite
|
||
|
||
**Test Infrastructure**
|
||
- [x] `dialectSQL()` converts `$N` → `?` and strips `::jsonb` at runtime
|
||
- [x] `database.PH(n)` returns dialect-appropriate placeholder
|
||
- [x] `database.TruncateAll()` dialect-aware (DELETE + PRAGMA vs TRUNCATE CASCADE)
|
||
- [x] Generic provider config: `PROVIDER`/`PROVIDER_KEY`/`PROVIDER_URL` (replaces `VENICE_API_KEY`)
|
||
- [x] Model selection prefers non-reasoning models in live tests
|
||
|
||
**What SQLite mode skips** (feature-gated, not broken):
|
||
- [x] `LISTEN/NOTIFY` — WebSocket event fan-out uses in-process EventBus (already works)
|
||
- [x] Full-text search `tsvector` — conversation_search uses LIKE fallback
|
||
|
||
---
|
||
|
||
## v0.17.2 — CodeMirror 6 Integration ✅
|
||
|
||
Rich editor infrastructure for the frontend. CM6 is ESM-native; the build
|
||
step runs in Docker (esbuild → single IIFE bundle). No change to dev
|
||
experience for non-editor code — the rest of `src/js/` stays vanilla.
|
||
|
||
Depends on: nothing (frontend-only). Prerequisite for: extension surfaces
|
||
(v0.21.5 editor surface). See [DESIGN-CM6.md](DESIGN-CM6.md) for full spec.
|
||
|
||
**Build Pipeline**
|
||
- [x] `src/editor/` directory: `package.json`, `build.mjs`, `index.mjs`, language/theme modules
|
||
- [x] `scripts/build-editor.sh`: shared build script for both Dockerfiles and local dev
|
||
- [x] New Docker stage (`cm6-build`): `npm ci` + `node build.mjs` → `vendor/codemirror/`
|
||
- [x] Both `Dockerfile.frontend` and `Dockerfile` (unified) use the shared build script
|
||
- [x] Bundle output: `codemirror.bundle.js` (~295KB min, ~90KB gzip)
|
||
- [x] Graceful degradation: all integration points check `window.CM` — falls back to `<textarea>` if bundle unavailable
|
||
|
||
**Languages (bundled)**
|
||
- [x] Markdown, JavaScript, JSON, SQL, HTML, CSS, YAML, Go, Python, Rust
|
||
- [x] Additional modes: one-line import + rebuild
|
||
|
||
**Phase 1: Extension Editor** (admin panel)
|
||
- [x] `CM.codeEditor()` factory: line numbers, bracket matching, auto-indent, search/replace
|
||
- [x] Replace manifest `<textarea>` → CM6 JSON mode
|
||
- [x] Replace script `<textarea>` → CM6 JavaScript mode
|
||
- [x] Remove manual Tab-key handler in `admin-handlers.js` (CM6 handles it)
|
||
- [x] Update `saveAdminExtension()` to use `.getValue()`
|
||
|
||
**Phase 2: Chat Input** (markdown mode)
|
||
- [x] `CM.chatInput()` factory: markdown highlighting, minimal chrome (no line numbers, no gutter)
|
||
- [x] Enter=send, Shift+Enter=newline keybindings
|
||
- [x] Auto-growing height, placeholder text
|
||
- [x] Wire `onChange` → `updateInputTokens()`
|
||
- [x] Update `chat.js`, `attachments.js`, `tokens.js` to use CM API
|
||
- [x] WYSIWYG fenced code block decorations (visual container matching claude.ai UX)
|
||
- [x] Inline code shortcut (Ctrl/Cmd+E)
|
||
|
||
**Phase 3: Polish**
|
||
- [x] Theme integration: CSS variable overrides (`--bg`, `--border`, `--accent`, etc.)
|
||
- [x] Dark/light/system mode toggle in appearance settings
|
||
- [x] Vim/Emacs keybinding preference in appearance settings (`@replit/codemirror-vim`, `@replit/codemirror-emacs`)
|
||
- [x] Vim/Emacs applies to code editor + extension editor only (never chat input)
|
||
- [x] SW cache: exclude `vendor/codemirror/` with version bust
|
||
- [x] Update `debug.js` snapshot to include CM6 version
|
||
- [x] Documentation in ARCHITECTURE.md
|
||
|
||
**CI/CD**
|
||
- [x] Path-based change detection gating (FE-only → skip BE tests, docs-only → skip all)
|
||
|
||
---
|
||
|
||
## v0.17.3 — Notes Graph + Wikilinks ✅
|
||
|
||
Knowledge graph and bi-directional linking for the notes system. Transforms
|
||
notes from flat documents into an interconnected knowledge base with
|
||
Obsidian-style `[[wikilinks]]`, backlinks, graph visualization, and
|
||
transclusion.
|
||
|
||
Depends on: CodeMirror 6 (v0.17.2), Notes CRUD (v0.13.x). See
|
||
[DESIGN-0.17.3.md](DESIGN-0.17.3.md) for full spec.
|
||
|
||
**Backend: Note Links**
|
||
- [x] `note_links` table (Postgres + SQLite migrations)
|
||
- [x] `NoteLinkStore` interface + both implementations
|
||
- [x] `ExtractWikilinks()` regex parser + tests
|
||
- [x] Link extraction on note create/update
|
||
- [x] Dangling link resolution on note create
|
||
- [x] `notes.source_message_id` column for chat-to-note provenance
|
||
|
||
**API Endpoints**
|
||
- [x] `GET /notes/:id/backlinks` — notes linking to this note
|
||
- [x] `GET /notes/search-titles?q=` — lightweight fuzzy search for autocomplete
|
||
- [x] `GET /notes/graph` — full graph topology (nodes + edges + unresolved)
|
||
|
||
**CM6 Note Editor**
|
||
- [x] `note-editor.mjs` factory: markdown live preview (heading sizes, blockquotes, code blocks)
|
||
- [x] `wikilink.mjs` CM6 extension: parse, decorate as clickable chips, autocomplete on `[[`
|
||
- [x] Textarea → CM6 swap in `notes.js` with graceful fallback
|
||
- [x] `noteEditorTheme` in `theme.mjs`
|
||
|
||
**Graph Visualization**
|
||
- [x] Canvas-based force-directed graph (~200 lines, no d3 dependency)
|
||
- [x] O(n²) Coulomb repulsion + Hooke spring + center gravity
|
||
- [x] Pan, zoom (0.15–4.0x), drag nodes, hover highlight, click to open
|
||
- [x] Node sizing by link_count, folder-based coloring
|
||
- [x] Ghost nodes for unresolved `[[links]]` with toggle
|
||
- [x] Energy-based pause (stop rAF below KE threshold)
|
||
- [x] ResizeObserver for responsive canvas
|
||
|
||
**Note-from-Selection + Daily Notes**
|
||
- [x] "Note" button in message action bar
|
||
- [x] Selection-aware capture (`window.getSelection()` within message)
|
||
- [x] Provenance tracking (`source_channel_id` + `source_message_id`)
|
||
- [x] "Today" button → find-or-create daily note in `/daily/`
|
||
|
||
**Read Mode**
|
||
- [x] `[[link]]` rendered as clickable wikilink chips
|
||
- [x] `![[embed]]` transclusion with async content fetch, recursion guard
|
||
- [x] Backlinks panel (collapsible, with count badge)
|
||
|
||
---
|
||
|
||
## v0.18.0 — Memory (User + Persona Scopes) ✅
|
||
|
||
Long-term memory across conversations, with scope-aware isolation.
|
||
Unlike KB (static documents) or compaction (within-conversation), this
|
||
captures facts and preferences that persist across channels.
|
||
|
||
**Key differentiator: Persona-scoped memory.** Each Persona can build
|
||
its own memory independently of user memory, preventing cross-context
|
||
contamination and enabling specialized knowledge accumulation.
|
||
|
||
Depends on: compaction (v0.15.0), knowledge bases (v0.14.0), persona-KB binding (v0.17.0), SQLite backend (v0.17.1).
|
||
|
||
See [DESIGN-0.18.0.md](DESIGN-0.18.0.md) for full spec.
|
||
|
||
**Memory Scopes**
|
||
- [x] `user` — personal facts/preferences, persists across all conversations (current industry standard)
|
||
- [x] `persona` — shared across all users of that Persona, accumulated from conversations (differentiator)
|
||
- [x] `persona+user` — per-user within a Persona context (e.g. tutoring progress per student)
|
||
- [x] Configurable per Persona: which scopes are active, whether user memory is passed through
|
||
|
||
**Data Model**
|
||
- [x] `memories` table: `id`, `scope` (user, persona, persona_user), `owner_id` (user_id or persona_id), `user_id` (nullable — for persona+user scope), `key`, `value`, `source_channel_id`, `confidence` (float), `status` (active, pending_review, archived), `created_at`, `updated_at`
|
||
- [x] Index on `(scope, owner_id, user_id)` for fast lookup
|
||
- [x] Embedding column (`vector(3072)`) for semantic memory search
|
||
|
||
**Tools**
|
||
- [x] `memory_save` tool: LLM explicitly stores a fact
|
||
- Scope-aware: saves to the active memory scope for the current Persona context
|
||
- Structured: `key` (short label) + `value` (detail) + `confidence`
|
||
- [x] `memory_recall` tool: LLM queries stored facts relevant to current context
|
||
- Merges results from applicable scopes (user + persona + persona+user)
|
||
- Semantic search via embeddings + keyword fallback
|
||
|
||
**Automatic Extraction**
|
||
- [x] Background job: post-conversation analysis identifies memorable facts (opt-in)
|
||
- [x] Configurable extraction prompt per Persona (e.g. "extract FAQ-worthy Q&A pairs")
|
||
- [x] Extracted memories start in `pending_review` status
|
||
|
||
**Review Pipeline**
|
||
- [x] Admin/team admin review queue: pending memories with approve/reject/edit
|
||
- [x] Persona memory review: team admins see what Personas are "learning"
|
||
- [x] User memory review: users see their own memories in Settings
|
||
|
||
**Memory Injection**
|
||
- [x] At completion time: inject relevant memories into system prompt
|
||
- [x] Context budget aware: limit injected memory tokens
|
||
- [x] Scope priority: persona+user > persona > user (most specific wins on conflicts)
|
||
|
||
**Use Cases**
|
||
- [x] Helpdesk Persona: builds FAQ from repeated questions, human-reviewable
|
||
- [x] Roleplay Persona: isolated memory prevents tone/context bleeding from user's other conversations
|
||
- [x] Tutoring Persona: tracks per-student progress, common misconceptions
|
||
- [x] Sales Persona: accumulates objection responses from real conversations
|
||
- [x] Onboarding Persona: learns what new hires commonly struggle with
|
||
|
||
**User Controls**
|
||
- [x] Settings → Memory: view, edit, delete personal memories
|
||
- [x] Per-Persona memory toggle: "Allow this persona to remember things about me"
|
||
- [x] Admin: enable/disable, retention policies, per-team scoping
|
||
- [x] Privacy: user memories never cross team boundaries; persona memories respect group access
|
||
|
||
---
|
||
|
||
## v0.18.1 — Side Panel Architecture ✅
|
||
|
||
Refactored the side panel from a shared-tab layout to independent
|
||
single-slot panels. Any action fills the slot, replacing whatever was
|
||
there — no tabs, no association between panel types. Extension UI
|
||
primitives give browser extensions safe access to host app features.
|
||
|
||
Depends on: Notes graph + wikilinks (v0.17.3). Prerequisite for: live
|
||
collaboration (v0.23.0) where multiple panels need simultaneous visibility.
|
||
|
||
**Panel System**
|
||
- [x] Panel registry: named panels with independent open/close state
|
||
- [x] Single-slot model: action-driven, each open replaces the previous
|
||
- [x] Dual-view mode: two panels side-by-side (configurable split ratio via drag divider)
|
||
- [x] Panel-persistent state: each panel remembers scroll position, open note, etc.
|
||
- [x] Header label shows active panel name (replaces tab bar)
|
||
- [x] Keyboard shortcut: Ctrl/Cmd+\ cycles panels, Ctrl/Cmd+Shift+\ toggles dual
|
||
|
||
**Preview Panel**
|
||
- [x] Dedicated preview panel (independent of Notes)
|
||
- [x] HTML/document preview with iframe sandbox
|
||
- [x] Code output preview (extension-rendered blocks via pop-out)
|
||
- [x] Live-updating during streaming responses (500ms debounce)
|
||
|
||
**Extension UI Primitives**
|
||
- [x] `ctx.ui.toast()` — toast notifications
|
||
- [x] `ctx.ui.openPreview()` — load HTML into side panel preview
|
||
- [x] `ctx.ui.isDark()` — theme detection
|
||
- [x] `ctx.ui.isMobile()` — viewport width check
|
||
- [x] `ctx.ui.isPanelOpen()` — side panel visibility
|
||
- [x] `ctx.ui.confirm()` — modal confirm dialog
|
||
- [x] Mermaid extension refactored to use primitives exclusively (zero direct globals)
|
||
- [x] Context-aware expand: single button, fullscreen or side panel pop-out
|
||
|
||
**Mobile**
|
||
- [x] Swipe navigation between panels
|
||
- [x] Tap-to-close overlay
|
||
- [x] Graceful collapse to single-panel on narrow viewports
|
||
- [x] Enlarged touch targets, fullscreen close button (40px desktop, 48px mobile)
|
||
|
||
---
|
||
|
||
## ✅ v0.19.0 — Projects / Workspaces
|
||
|
||
Organizational containers that group related conversations, KBs, and
|
||
notes into a single workspace with shared access controls.
|
||
|
||
Depends on: user groups (v0.16.0), knowledge bases (v0.14.0).
|
||
|
||
**Data Model**
|
||
- [x] `projects` table: `id`, `name`, `description`, `color`, `icon`, `scope` (personal/team/global), `owner_id`, `team_id`, `is_archived`, `settings` (JSONB)
|
||
- [x] `project_channels` junction: ordered membership with UNIQUE `channel_id`, denormalized FK on `channels.project_id`
|
||
- [x] `project_knowledge_bases` junction: with `auto_search` flag
|
||
- [x] `project_notes` junction
|
||
- [x] `resource_grants` CHECK extended to include `'project'`
|
||
|
||
**Features**
|
||
- [x] Channels can belong to a project (optional `project_id` FK)
|
||
- [x] KBs can belong to a project → auto-linked to all channels in the project (BuildKBHint + kbsearch)
|
||
- [x] Notes can belong to a project → auto-associated when created from project channel
|
||
- [x] KB resolution chain: Persona → Project → Channel → Personal
|
||
- [x] Project sidebar section: collapsible groups above time-based Recent section
|
||
|
||
**UI**
|
||
- [x] Sidebar: projects as collapsible groups with color dots, counts, options menu
|
||
- [x] Right-click context menu: move chat to project / remove / create-and-assign
|
||
- [x] Drag-and-drop channels between project groups and Recent
|
||
- [x] New Project button in split dropdown
|
||
- [x] Channel list `project_id` filter (`?project_id=uuid` or `?project_id=none`)
|
||
- [x] Collapse state persisted in localStorage
|
||
|
||
**Deferred to later versions:**
|
||
- Project creation dialog (name, description, default Persona, default KBs) — using prompt() for now
|
||
- ~~Project detail panel (KB + note management within a project)~~ → v0.19.1
|
||
- ~~Project-level Persona default~~ → v0.19.2
|
||
- Folders within projects
|
||
- Project templates
|
||
- Admin-level team/global project management
|
||
- Project-specific files (full project-level upload — deferred for proper architecture)
|
||
- Notifications (moved to v0.20.0)
|
||
|
||
---
|
||
|
||
## ✅ v0.19.1 — Active Project + Project System Prompt + Detail Panel
|
||
|
||
Quality-of-life improvements making projects usable for daily workflow.
|
||
No migrations.
|
||
|
||
Depends on: v0.19.0 Projects/Workspaces.
|
||
|
||
**Active Project**
|
||
- [x] Pin a project as active — new chats auto-assign via `addChannelToProject` after channel creation
|
||
- [x] `App.activeProjectId` persisted in `localStorage('cs-active-project')`
|
||
- [x] Visual indicator: `.project-group.active` accent border + 📌 icon
|
||
- [x] Toggle from project ⋯ menu ("Pin as active" / "Unpin project")
|
||
- [x] Cleared on project delete
|
||
|
||
**Project System Prompt**
|
||
- [x] Per-project instructions in `projects.settings` JSONB (`system_prompt` key)
|
||
- [x] Injected in `loadConversation` between persona/channel prompt and KB hint
|
||
- [x] Merge semantics on update: reads existing JSONB, overlays patch keys, writes back
|
||
- [x] Both Postgres and SQLite stores updated
|
||
|
||
**Project Detail Panel**
|
||
- [x] Registered with `PanelRegistry` (same pattern as Notes, Preview)
|
||
- [x] System prompt textarea with Save button
|
||
- [x] KB management: list with names (LEFT JOIN), [+ Add] picker dropdown, [✕] remove
|
||
- [x] Notes list with titles (LEFT JOIN), [✕] unbind
|
||
- [x] Accessible from project ⋯ menu → "Project settings"
|
||
|
||
**Bug Fixes**
|
||
- [x] `renderChatList` early return prevented project groups from rendering when zero chats
|
||
- [x] Recent section drop target: "Drop chats here to unassign" hint with `min-height: 40px`
|
||
|
||
---
|
||
|
||
## ✅ v0.19.2 — Project Persona Default + Archive + Channel Reorder
|
||
|
||
Completes the project management feature set. No migrations.
|
||
|
||
Depends on: v0.19.1.
|
||
|
||
**Project Persona Default**
|
||
- [x] Bind a persona to a project via detail panel dropdown
|
||
- [x] Stored in `projects.settings.persona_id`
|
||
- [x] Resolution chain: explicit `req.PresetID` → project persona → none
|
||
- [x] Inherits model, provider config, temperature, max tokens, system prompt as defaults
|
||
|
||
**Project Archive Toggle**
|
||
- [x] Checkbox in project detail panel
|
||
- [x] Archived projects hidden from sidebar by default
|
||
- [x] "▸ Show archived (N)" toggle button below project list
|
||
- [x] Chats in hidden-archived projects spill into Recent section (never vanish)
|
||
- [x] Dimmed + italic visual treatment for archived groups
|
||
|
||
**Channel Reorder**
|
||
- [x] `loadProjectChannelPositions()` fetches server-persisted positions on startup
|
||
- [x] `_getReorderedProjectChats()` sorts project chats by stored position
|
||
- [x] Right-click context menu: ↑ Move up / ↓ Move down (optimistic swap + API call)
|
||
- [x] Order maintained across add/remove/move operations
|
||
|
||
---
|
||
|
||
## v0.20.0 — Notifications + @mention Routing + Multi-model ✅
|
||
|
||
Notification infrastructure that makes collaboration real-time, plus
|
||
multi-model routing for channels. Three-phase delivery: notifications
|
||
core (in-app), @mention parsing + fan-out completions, email transport
|
||
+ per-user notification preferences.
|
||
|
||
_(Notifications shifted from v0.19.0; @mention routing shifted from v0.17.0)_
|
||
|
||
Depends on: v0.19.2 (Projects complete), EventBus + WebSocket hub (v0.9.x),
|
||
`channel_models` table (v0.16.0 schema). See
|
||
[DESIGN-0.20.0.md](DESIGN-0.20.0.md) for full spec.
|
||
|
||
**Phase 1 — Notifications Core (in-app)**
|
||
- [x] `notifications` table: `id`, `user_id`, `type`, `title`, `body`, `resource_type`, `resource_id`, `is_read`, `created_at` (Postgres + SQLite migrations)
|
||
- [x] `NotificationStore` interface + both implementations: Create, ListByUser (paginated), MarkRead, MarkAllRead, Delete, UnreadCount
|
||
- [x] `notifications.Service` with `Notify()` / `NotifyMany()` — centralized creation + WebSocket dispatch
|
||
- [x] EventBus routes: `notification.new`, `notification.read` (badge sync across tabs)
|
||
- [x] API endpoints: list, unread-count, mark-read, mark-all-read, delete (5 endpoints, all user-scoped)
|
||
- [x] Initial sources: `role.fallback` (EventBus subscription), `kb.ready`/`kb.error`, `grant.changed`
|
||
- [x] Frontend: bell icon + unread badge (capped 9+), notification dropdown (latest 10, click-to-navigate), full panel via PanelRegistry
|
||
- [x] WebSocket handler: real-time push + toast for high-priority types
|
||
- [x] Background cleanup goroutine (configurable retention, default 90 days)
|
||
|
||
**Phase 2 — @mention Parsing + Multi-model Routing**
|
||
- [x] `mentions.Parse()`: extract @mentions, resolve against channel model roster (case-insensitive, longest-match-first, trailing punctuation tolerant)
|
||
- [x] Parser tests: no mentions, unresolved, multiple, overlapping names, punctuation edge cases
|
||
- [x] Channel model CRUD handlers (4 endpoints: list, add, remove, update)
|
||
- [x] Completion handler: mention extraction → target resolution → sequential fan-out → N assistant messages
|
||
- [x] SSE streaming: model attribution in delta events (`model_display` field)
|
||
- [x] Frontend: model pills in chat header with add/remove UI
|
||
- [x] Frontend: @mention autocomplete via CM6 `mentionCompletion` extension (roster-backed)
|
||
- [x] Frontend: model attribution labels on multi-model assistant messages
|
||
- [x] Backward compat: channels with no extra `channel_models` rows work exactly as before
|
||
|
||
**Phase 3 — Email Transport + Notification Preferences**
|
||
- [x] `notification_preferences` table (Postgres + SQLite): per-user, per-type in_app/email toggles
|
||
- [x] Preference resolution chain: specific type → user wildcard `*` → system default (in_app=true, email=false)
|
||
- [x] `EmailTransport`: SMTP with implicit TLS (port 465) and STARTTLS (port 587), multipart MIME (HTML + plaintext)
|
||
- [x] Email templates: branded HTML + plaintext, domain-prefixed subjects, Go `html/template`
|
||
- [x] Preference CRUD endpoints (3: list, set with partial patch, delete)
|
||
- [x] Admin SMTP configuration: enable toggle, host/port/user/password/from/TLS fields, test email button
|
||
- [x] User notification preferences UI (Settings → Notifications tab, per-type checkboxes)
|
||
- [x] Notification service: preference check before dispatch, async email delivery (goroutine, 30s timeout)
|
||
- [x] Tests: preference resolution chain (7 tests), email templates (4 tests)
|
||
- [x] Deferred: digest mode (batched email), SMTP password vault encryption
|
||
|
||
**Hotfix (carried forward from v0.19.2 investigation)**
|
||
- [x] `user_model_settings` NULL scan fix: COALESCE on `hidden`/`sort_order` in SELECT + INSERT for both dialects
|
||
- [x] Gin release mode: auto-set `gin.ReleaseMode` when `ENVIRONMENT=production`, suppress health check log spam
|
||
|
||
---
|
||
|
||
## v0.21.x — Workspace Platform + Extension Surfaces
|
||
|
||
Seven-release series decomposing workspace storage, tools, indexing, git,
|
||
surface infrastructure, and editor/article modes. Full specification in
|
||
[DESIGN-0.21.0.md](DESIGN-0.21.0.md).
|
||
|
||
Depends on: file storage (v0.12.0), extension foundation (v0.11.0),
|
||
CodeMirror 6 (v0.17.2), knowledge base embedding pipeline (v0.14.0).
|
||
|
||
### v0.21.0 — Workspace Storage Primitive ✅
|
||
|
||
Pure backend foundation. Workspaces as a polymorphic platform primitive
|
||
owned by users, projects, channels, or teams. Dual-layer storage: PVC
|
||
filesystem (source of truth) + DB metadata index (queryable cache).
|
||
|
||
- [x] `workspaces` table: polymorphic owner (user/project/channel/team), root_path, max_bytes quota, status
|
||
- [x] `workspace_files` table: metadata index (path, MIME type, size, sha256, is_directory)
|
||
- [x] `WorkspaceStore` interface: CRUD, file index (upsert/delete/list/prefix), ownership lookup, stats
|
||
- [x] Postgres + SQLite store implementations with upsert-on-conflict for file index
|
||
- [x] `workspace.FS` package: read, write (atomic via temp+rename), delete, mkdir, stat, list, reconcile (FS→DB sync)
|
||
- [x] `workspace.Archive`: zip/tar.gz extract + create with archive bomb protection (10K file limit, 100MB single file, quota enforcement), common-prefix stripping
|
||
- [x] Content type detection: extension-based (40+ source code types) with http.DetectContentType fallback
|
||
- [x] SHA256 computed during write via tee reader (enables content-addressed skip in v0.21.2)
|
||
- [x] Path traversal guards: cleanPath + absPath validation, symlink rejection
|
||
- [x] 15 API endpoints: workspace CRUD, file CRUD, archive upload/download, reconcile, stats
|
||
- [x] Owner-based authorization: user=self, channel=owner, project=member, team=member
|
||
- [x] Unit tests: path cleaning, traversal detection, MIME detection, unsafe path filtering, write/read round-trip, delete, mkdir
|
||
|
||
### v0.21.1 — Workspace Tools + Channel/Project Binding ✅
|
||
|
||
Make workspaces useful in chat mode via tool calls.
|
||
|
||
- [x] Workspace tools (category: workspace): `workspace_ls`, `workspace_read` (50KB soft limit), `workspace_write` (auto-mkdir), `workspace_rm` (recursive guard), `workspace_mv`, `workspace_patch` (find/replace)
|
||
- [x] `channels.workspace_id` FK, `projects.workspace_id` FK
|
||
- [x] Workspace resolution: channel workspace → project workspace (override pattern)
|
||
- [x] Tool injection in completion handler when workspace bound
|
||
- [x] Frontend: deferred (channel settings workspace toggle, project Files tab, chat bar workspace indicator)
|
||
|
||
### v0.21.2 — Workspace Indexing + Semantic Search ✅
|
||
|
||
Embed text files for semantic search. Reuses `knowledge.SplitText` + `knowledge.Embedder`.
|
||
|
||
- [x] `workspace_chunks` table (Postgres + SQLite migrations)
|
||
- [x] `workspace_files` additions: `index_status`, `chunk_count` columns
|
||
- [x] `workspaces.indexing_enabled` boolean (default true)
|
||
- [x] Store methods: `InsertChunks`, `DeleteChunksByFile`, `SimilaritySearch`, `UpdateFileIndexStatus`
|
||
- [x] Indexable types: text MIME types + 40+ code extensions + special filenames (Makefile, Dockerfile, etc.)
|
||
- [x] Code-aware chunking: 1500-char chunks with function/class/type/sub boundary separators
|
||
- [x] Content-addressed skip: sha256 comparison before re-chunking/re-embedding
|
||
- [x] `workspace.Indexer`: background goroutine with configurable concurrency semaphore
|
||
- [x] Single-file indexing via `FS.WriteFile` hook (`SetIndexer`)
|
||
- [x] Batch indexing via `ExtractArchive` (sequential within one semaphore slot)
|
||
- [x] `workspace_search` tool: semantic search with optional glob filtering, top-K capped at 20
|
||
- [x] `GET /api/v1/workspaces/:id/index-status` endpoint (per-status file counts, total chunks)
|
||
- [x] Configuration: `WORKSPACE_INDEXING_ENABLED`, `WORKSPACE_INDEX_CONCURRENCY` env vars
|
||
- [x] Graceful degradation when no embedding role configured
|
||
- [x] Mock store updated for FS unit tests
|
||
|
||
### v0.21.3 — Surface Infrastructure + REPL
|
||
|
||
Pure UI architecture. No workspace dependency (parallel development).
|
||
|
||
- [ ] Surface registration: `ctx.surfaces.register()` with label, icon, regions, activate/deactivate
|
||
- [ ] Region management: `ctx.ui.replace()` / `ctx.ui.restore()` for CM6 state preservation
|
||
- [ ] Mode selector in sidebar when ≥1 extension surface registered
|
||
- [ ] `surface.activated` / `surface.deactivated` events
|
||
- [ ] REPL console ([#70](https://git.gobha.me/xcaliber/chat-switchboard/issues/70)): fourth debug modal tab, AsyncFunction wrapper, injected globals, command history, tab-completion, admin-gated
|
||
|
||
### v0.21.4 — Git Integration
|
||
|
||
Layer git operations onto workspaces.
|
||
|
||
- [ ] `workspaces` additions: git_remote_url, git_branch, git_credential_id, git_last_sync
|
||
- [ ] `git_credentials` table: auth_type (https_pat/https_basic/ssh_key), encrypted_data (AES-256-GCM)
|
||
- [ ] Git operations via exec: clone, pull, push, status, diff, commit, log, branch, checkout
|
||
- [ ] Workspace tools (git-aware): `git_status`, `git_diff`, `git_commit`, `git_log`, `git_branch`
|
||
- [ ] Post-operation hooks: clone/pull/checkout trigger reconcile + re-index changed files
|
||
|
||
### v0.21.5 — Editor Surface (Development Mode)
|
||
|
||
IDE-like experience. Browser-tier extension consuming workspace primitives.
|
||
|
||
- [ ] Layout: file tree (sidebar), code editor (CM6, main), AI chat panel (resizable split), status bar
|
||
- [ ] File tree: workspace_ls backed, git status indicators, context menu, drag-drop
|
||
- [ ] Code editor: CM6 codeEditor() factory, language auto-detection, tab bar, Ctrl+S save
|
||
- [ ] AI chat panel: same channel context, workspace tools auto-injected, live update via EventBus
|
||
- [ ] Keyboard shortcuts: Ctrl+P quick open, Ctrl+Shift+F workspace search
|
||
|
||
### v0.21.6 — Article Surface + Document Output Pipeline
|
||
|
||
Writing-focused surface. Document is artifact, conversation is secondary.
|
||
|
||
- [ ] Document output pipeline: write → workspace → export (markdown → HTML/PDF/DOCX via pandoc)
|
||
- [ ] Layout: outline (sidebar top), AI assistant (sidebar bottom), rich text editor (CM6 markdown, main)
|
||
- [ ] Outline: auto-generated from headings, click-to-scroll, drag to reorder
|
||
- [ ] AI assistant: lightweight chat with article-specific tools (suggest_outline, expand_section, check_citations)
|
||
- [ ] Rich text editor: CM6 noteEditor() with enhanced live preview, focus mode
|
||
- [ ] Export: download as markdown/HTML/PDF, copy to clipboard
|
||
|
||
---
|
||
|
||
## v0.22.0 — Smart Routing + Provider Extensions
|
||
|
||
Depends on: model roles (v0.10.0), usage tracking (v0.10.0).
|
||
Rules-based routing engine — policy, not ML. Plus declarative provider
|
||
configuration to replace hardcoded provider-specific behavior.
|
||
|
||
_(Shifted from v0.19.0 — routing content unchanged, provider extensions added)_
|
||
|
||
**Routing**
|
||
- [ ] Admin routing policies: "cheapest model with required capabilities",
|
||
"prefer private providers, fallback to cloud", "for team X, use Y"
|
||
- [ ] Fallback chains: primary provider down → next with same model
|
||
- [ ] Cost-aware: factor pricing into routing decisions
|
||
- [ ] Latency-aware: track response times per provider, prefer faster
|
||
|
||
**Provider Extensions (declarative provider config)**
|
||
- [ ] `provider_profiles` table (or JSONB on `api_configs`): per-provider configuration schema
|
||
- [ ] System prompt injection: provider-specific preambles (e.g. Venice character system prompt)
|
||
- [ ] Thinking mode toggle: per-provider `think` parameter support (Venice `venice_parameters.include_venice_system_prompt`, Anthropic `thinking`, etc.)
|
||
- [ ] Request transform hooks: provider-specific parameter mapping before API call
|
||
- [ ] Response transform hooks: normalize provider-specific response fields
|
||
- [ ] Admin UI: provider profile editor (key-value config per provider type)
|
||
- [ ] Preset-level overrides: Persona can override provider-specific settings (e.g. "always enable thinking for this Persona")
|
||
- [ ] Provider health: track error rates, latency percentiles, auto-disable unhealthy providers
|
||
- [ ] Search/URL fetch rate limiting per provider
|
||
- [ ] Capability admin/user override: manual correction for model capabilities (`intrinsic.go` admin override layer)
|
||
|
||
---
|
||
|
||
## v0.23.0 — Multi-Participant Channels + Presence
|
||
|
||
The channel foundation for workflows and real-time collaboration. Today
|
||
channels are single-user direct chats. This release makes channels a
|
||
shared space that multiple actors can inhabit.
|
||
|
||
Depends on: extension surfaces (v0.21.3), WebSocket infrastructure (already exists).
|
||
|
||
_(Shifted from v0.20.0 — no content changes)_
|
||
|
||
**Channel Participants**
|
||
- [ ] `channel_participants` table: `channel_id`, `participant_type` (user, session, persona), `participant_id`, `role` (owner, member, observer), `joined_at`
|
||
- [ ] Channel access queries rewritten: `WHERE user_id = $1` → participant-based lookup
|
||
- [ ] Backward compatible: existing single-user channels auto-have one participant (owner)
|
||
- [ ] Channel `type` column: `direct` (current), `group` (multi-user), `workflow` (staged)
|
||
|
||
**Presence + Real-time**
|
||
- [ ] Typing indicators and presence (who's online, who's in this channel)
|
||
- [ ] Participant join/leave events via WebSocket
|
||
- [ ] Co-editing for extension surfaces (editor mode, article mode)
|
||
- [ ] Cursor sharing, selection highlighting
|
||
|
||
**Channel-Scoped Notes**
|
||
- [ ] Optional `channel_id` FK on notes (NULL = personal notebook, set = channel-attached)
|
||
- [ ] Notes created by tool calls within a channel auto-attach to that channel
|
||
- [ ] Channel notes visible to all participants (not just creator)
|
||
|
||
---
|
||
|
||
## v0.24.0 — Auth Strategy (mTLS/OIDC) + Full RBAC
|
||
|
||
Enterprise auth modes on top of the teams + groups foundation.
|
||
Depends on: vault passphrase support from v0.9.3 (conditional unlock for
|
||
personal providers under external auth), user groups (v0.16.0).
|
||
|
||
_(Shifted from v0.21.0 — enhanced with group-based permissions)_
|
||
|
||
- [ ] `AUTH_MODE` env var: `builtin` | `mtls` | `oidc`
|
||
- [ ] All three resolve to the same internal user model
|
||
- [ ] `auth_source` + `external_id` columns on users table
|
||
- [ ] mTLS: header trust, auto-provision from cert DN
|
||
- [ ] OIDC: Keycloak/Okta token validation, claim extraction, role mapping
|
||
- [ ] Per-source auto-activate policy: auto_activate, default_team, default_role
|
||
- [ ] Vault passphrase prompt for mTLS/OIDC users (v0.9.3 conditional unlock)
|
||
- [ ] Fine-grained permissions: model access, KB write, task create, token budgets
|
||
- [ ] Group-based permission sets: assign permissions to groups, users inherit from membership
|
||
- [ ] OIDC claim → group mapping: external IdP groups auto-sync to internal groups
|
||
|
||
**Anonymous / Session Participants**
|
||
- [ ] Session-based identity for unauthenticated visitors (workflow intake)
|
||
- [ ] mTLS: cert CN/fingerprint as stable session identity (no `users` row required)
|
||
- [ ] Non-mTLS: ephemeral session token (cookie or URL token)
|
||
- [ ] Session participants can send messages and trigger tool calls within workflow channels
|
||
- [ ] Session identity visible to assigned team members (cert DN, display name, or "Anonymous #N")
|
||
|
||
---
|
||
|
||
## v0.25.0 — Workflow Engine
|
||
|
||
Team-owned, stage-based process execution. The channel is the runtime,
|
||
personas drive each stage, and the existing tool/notes infrastructure
|
||
handles structured data collection. See [ARCHITECTURE.md — Workflow
|
||
Architecture](ARCHITECTURE.md#workflow-architecture-future--v0210) for
|
||
the conceptual model.
|
||
|
||
Depends on: multi-participant channels (v0.23.0), anonymous identity (v0.24.0).
|
||
|
||
_(Shifted from v0.22.0 — no content changes, dependency refs updated)_
|
||
|
||
**Workflow Definitions**
|
||
- [ ] `workflows` table: `team_id` (owner), `name`, `description`, `is_active`, `entry_mode` (public_link, team_internal, api)
|
||
- [ ] `workflow_stages` table: `workflow_id`, `ordinal`, `persona_id`, `assignment_team_id`, `form_template` (JSONB, structured note schema), `transition_rules` (JSONB)
|
||
- [ ] Team-admin CRUD: create/edit/delete workflows and stages
|
||
- [ ] Workflow versioning: edits create new version, active instances continue on their version
|
||
|
||
**Workflow Instances (Channels)**
|
||
- [ ] Workflow-typed channels: `type='workflow'`, `workflow_id`, `current_stage`, `stage_version`
|
||
- [ ] Entry point: public link generates workflow channel, adds anonymous participant, binds stage 1 persona
|
||
- [ ] Stage transitions: triggered by AI (tool call), team member (button), or rule (form complete)
|
||
- [ ] On transition: swap active persona, notify assignment team, update channel metadata
|
||
|
||
**AI Intake**
|
||
- [ ] Stage persona drives structured collection via system prompt
|
||
- [ ] Form template → persona system prompt injection ("collect these fields: ...")
|
||
- [ ] Tool calls create channel-scoped notes as form responses
|
||
- [ ] AI determines readiness: "I have everything needed" → trigger transition
|
||
|
||
**Assignment + Queue**
|
||
- [ ] Assignment queue: unassigned workflow channels visible to team members
|
||
- [ ] Claim model: team member claims channel (becomes participant with `member` role)
|
||
- [ ] Round-robin / rule-based auto-assignment (optional, per-stage config)
|
||
- [ ] Assignment notifications via WebSocket + optional webhook
|
||
|
||
**Team Member Collaboration**
|
||
- [ ] Assigned member sees full history (AI intake + artifacts + notes)
|
||
- [ ] Persona remains active — assists both visitor and team member
|
||
- [ ] Member can trigger stage transitions, add notes, invoke tools
|
||
- [ ] Member can reassign to different team member or escalate to different team
|
||
|
||
**Frontend**
|
||
- [ ] Workflow builder UI in team admin panel (stage list, persona picker, form template editor)
|
||
- [ ] Queue view: sidebar section showing unassigned workflow channels for user's teams
|
||
- [ ] Channel header: workflow stage indicator, transition controls
|
||
- [ ] Anonymous visitor view: minimal UI, persona-driven conversation (public link entry)
|
||
|
||
---
|
||
|
||
## v0.26.0 — Tasks / Autonomous Agents
|
||
|
||
Unattended execution — workflows without a human in the loop.
|
||
Depends on: workflow engine (v0.25.0).
|
||
|
||
_(Shifted from v0.23.0 — no content changes, dependency refs updated)_
|
||
|
||
- [ ] Scheduler + task runner (cron-like triggers for workflow instantiation)
|
||
- [ ] `task_create` tool (AI can spawn sub-workflows)
|
||
- [ ] `type: 'service'` channels: workflow instances with no human participants
|
||
- [ ] Execution budgets: max tokens, max tool calls, max wall-clock per stage
|
||
- [ ] Admin controls for resource limits and kill switches
|
||
- [ ] Completion webhooks (notify external systems when workflow completes)
|
||
|
||
---
|
||
|
||
## TBD (unscheduled — real features, no immediate need)
|
||
|
||
Items that are real but don't yet have a version assignment. Pull left
|
||
based on need.
|
||
|
||
**Extension System — Additional Extensions**
|
||
- Image generation tool (browser or sidecar, provider-agnostic)
|
||
- STT/TTS (browser extension, Web Speech API — personal use case)
|
||
- Code execution sandbox (server-side, container isolation)
|
||
|
||
**Extension System — Server Tiers**
|
||
- Starlark runtime integration (Tier 1 — server sandbox)
|
||
- Sidecar HTTP tool protocol (Tier 2 — container isolation)
|
||
- Server-side tool execution in completion handler
|
||
|
||
**Desktop + Mobile**
|
||
- Desktop app (Tauri)
|
||
- Full PWA with offline capability
|
||
- Mobile-optimized layouts (beyond current responsive)
|
||
|
||
**Data + Portability**
|
||
- Bulk export/import (account data, conversations, settings)
|
||
- ChatGPT/other tool import
|
||
- GDPR-style "download my data"
|
||
- Backup/restore CronJob manifests
|
||
|
||
**UX / Multi-Seat**
|
||
- "Group" scope badge on model selector / KB list: show access-source annotation so users see _why_ they have access (global, team, group grant). Requires backend to include `access_source` in list responses.
|
||
- Per-provider model preferences: `user_model_settings` unique key is `(user_id, model_id)` — same model from different providers shares one visibility toggle. Needs `provider_config_id` dimension in DB constraint, store, API, and frontend `hiddenModels` keying. Frontend composite key (`configId:modelId`) already exists in `App.models[].id`.
|
||
|
||
**Projects — Future**
|
||
- Project-specific files: full project-level upload (own endpoint, storage path, UI surface — not just channel attachment re-linking)
|
||
- Project templates: create new projects from predefined configurations (persona, KBs, system prompt)
|
||
- Project creation dialog: replace `prompt()` with proper modal (name, description, persona, KB picker)
|
||
- Admin-level project management: cross-instance visibility, reassign ownership, enforce team policies (scope: enterprise only, BYOK personal projects stay private)
|
||
- Sub-projects / nested hierarchy: child inherits parent KBs, system prompt, persona (deferred until usage patterns clarify need vs tags/labels)
|
||
|
||
**Knowledge Bases — Future**
|
||
- KB auto-injection: top-K chunk prepend to system prompt, context budget aware, per-channel toggle (latency budgeting required)
|
||
- Hybrid search: combine vector similarity with full-text `tsvector`, re-rank
|
||
- Semantic chunking: embedding-based boundary detection for smarter splits
|
||
- HNSW index: better query performance than IVFFlat for large datasets
|
||
- Web scraping source: ingest URLs as KB documents (extends url_fetch)
|
||
- Scheduled re-indexing: periodic rebuild when source documents update
|
||
- ~~Store cleanup: add `UpdateDocumentStorageKey()` to `KnowledgeBaseStore` interface~~ _(done in v0.17.0)_
|
||
(currently uses direct `database.DB.ExecContext` in handler — works but bypasses store layer)
|
||
|
||
**Memory — Future**
|
||
- Memory compaction: summarize old memories to save context tokens
|
||
- Memory confidence decay: reduce confidence over time, prune low-confidence entries
|
||
- Memory export/import: portable memory format across instances
|
||
- Cross-persona memory sharing (opt-in): e.g. "coding assistant" can read facts from "project manager"
|
||
- Memory analytics: dashboard showing what Personas are learning, memory growth trends
|
||
|
||
**Platform**
|
||
- Rate limiting per user/team/tier (token budgets)
|
||
- ~~Provider health monitoring~~ → v0.22.0 + key rotation
|
||
- Multi-tenant SaaS mode
|
||
- Plugin/extension marketplace
|
||
- Virtual scroll for long conversations
|
||
- ~~SQLite backend option (single-user / dev)~~ → v0.17.1 |