This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/ROADMAP.md
2026-03-12 17:21:58 +00:00

1188 lines
59 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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)
- [EXTENSION-SURFACES.md](EXTENSION-SURFACES.md) — Extension surface authoring guide
(manifest format, platform API, CSS properties, install workflow)
- [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 Editor Surface ✅
Integration + Document Output
└───────┬──────────────┘
v0.21.7 Bugfix: scanJSON driver buffer aliasing ✅
v0.22.0 Provider Health + Capability Overrides ✅
+ Workspace Pane Refactor (FE)
v0.22.1 Provider Extensions (declarative config) ✅
v0.22.2 Routing Policies + Fallback Chains ✅
v0.22.3 Provider Admin UI + Deferred Polish ✅
v0.22.4 Provider Health UX + Project Files + Export ✅
v0.22.5 Surfaces + Go Templates + Admin Bug Fixes ✅
v0.22.6 Split Deployment Fix + CI Timeout + Code Pruning ✅
v0.22.7 Surface Prototypes (Theme + ChatPane + Splash) ✅
v0.22.8 Surface Integration (Wire into existing JS) ✅
v0.23.0 @mention Routing + Persona Handles + Proxy ✅
v0.23.1 Multi-User Navigation + Conversation Taxonomy ✅
v0.23.2 Multi-User Polish + Channel Lifecycle ✅
v0.24.0 Auth Abstraction + User Identity ✅
├── v0.24.1 mTLS + OIDC Providers (parallel) ✅
│ │
│ └── v0.24.3 Anonymous Sessions ✅
└── v0.24.2 Fine-Grained Permissions (parallel) ✅
v0.25.0 Dynamic Surfaces + Component Extraction ✅
(Go template engine, base.html shell, surface
manifests, admin/settings/editor surfaces,
pane container, persona tool grants UI)
v0.25.1 Surface Integration Fixes ✅
v0.25.2 Drag-Resize Utility ✅
(unified primitive for workspace + pane splits)
v0.25.3 UI Bug Cleanup ✅
(theme system, scaling, debug modal, settings
back-button, profile save, resize bar)
v0.25.4 Admin + Settings Surface Hardening ✅
(admin audit fixes, BYOK/persona toggles,
group permissions 500, settings surface init,
user settings NULL fix, export/import,
workspace mgmt, multi-provider test failover)
v0.26.0 Workflow Engine ✅
(team-owned staged processes,
human + AI collab, visitor
intake, assignment queue)
v0.27.0 Debt Clearance ✅
(extension surface routes,
workflow polish, editor debt)
v0.27.1 Tasks Foundation ✅
(service channels, scheduler,
task definitions, cron)
v0.27.2 Task Execution ✅
(budgets, admin controls,
run history, kill switch)
v0.27.3 Task Chaining ✅
(webhooks, task_create tool,
workflow-to-workflow)
v0.27.4 Personal Tasks ✅
(BYOK scheduling, user task UI,
starter templates)
v0.27.5 Team Tasks ✅
(team task routes, member visibility,
team badges in settings + sidebar)
v0.28.0 Platform Polish
(virtual scroll, KB auto-inject,
Helm chart, provider model prefs)
v0.29.0 Starlark Extensions
(permissioned server-side plugins,
capability-gated module access,
admin grant/revoke per-extension)
```
---
## 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 as KB gateways. `persona_knowledge_bases` binding, auto-search
mode, enterprise KB discoverability controls. Team admin workflow.
`HandleFromName()` auto-generation. Store layer sole DB interface.
### ✅ v0.17.1 — SQLite Backend
Dual-database support (Postgres + SQLite). `database/compat.go` dialect
abstraction, `database.Q()` query rewriting, SQLite-specific migration
set. Single-user / dev deployment mode.
See [v0171-sqlite-backend.md](v0171-sqlite-backend.md).
### ✅ v0.17.2 — CodeMirror 6 Integration
CM6 replaces textarea: `codeEditor()` + `chatInput()` + `noteEditor()`
factories. 20+ languages bundled, Vim/Emacs keybindings, `[[wikilink]]`
autocomplete. esbuild bundle. See [DESIGN-CM6.md](DESIGN-CM6.md).
### ✅ v0.17.3 — Notes Graph + Wikilinks
`[[wikilink]]` bi-directional linking, `note_links` junction table,
Canvas force-directed graph visualization. Daily notes, folder tree,
markdown preview. See [DESIGN-0.17.3.md](archive/DESIGN-0.17.3.md).
### ✅ v0.18.0 — Memory (User + Persona Scopes)
User + persona memory extraction pipeline. Background summarization via
utility role. Memory injection into system prompt. Admin review panel.
`memories` + `persona_memories` tables.
### ✅ v0.18.1 — Side Panel Architecture
Single-slot panel system. Panel registry with independent open/close.
Dual-view mode (two panels side-by-side). `ctx.ui.openPreview()`,
keyboard shortcuts. Extension UI participation. Mobile swipe.
### ✅ v0.19.0 — Projects / Workspaces
Project container: channels, KBs, personas, system prompt, team scope.
`projects` + `project_channels` tables. Drag-drop sidebar.
### ✅ v0.19.1 — Active Project + System Prompt + Detail Panel
Active project context in chat. Project system prompt prepend. Detail
panel (info, members, KBs, channels). Channel-project binding UI.
### ✅ v0.19.2 — Project Persona Default + Archive + Reorder
Project-level default persona. Archive/unarchive. Drag-to-reorder
sidebar items. Project settings persistence.
### ✅ v0.20.0 — Notifications + @mention Routing + Multi-model
Bell dropdown notifications. `@mention` resolves to persona handles and
model IDs. Multi-model chat. `notifications` table, WebSocket push,
`channel_participants` table. AI-to-AI chaining, context poisoning
prevention (Anthropic rewrite, OpenAI Name field).
### ✅ v0.21.x — Workspace Platform + Extension Surfaces
Seven-release series. v0.21.0: workspace storage primitive. v0.21.1:
workspace tools + channel/project binding. v0.21.2: workspace indexing +
semantic search. v0.21.3: surface infrastructure + REPL. v0.21.4: git
integration (clone/push/pull/commit, credential management). v0.21.5:
editor surface (IDE-like: file tree + CM6 + chat pane). v0.21.6: article
surface + document output pipeline + hash router. v0.21.7: scanJSON
driver buffer aliasing bugfix. See [DESIGN-0.21.0.md](archive/DESIGN-0.21.0.md).
### ✅ v0.22.0 — Provider Health + Capability Overrides
`provider_health` accumulator (5-min windows, 1h retention). Health
badges. `capability_overrides` table. Two-tier capability resolution
(catalog sync → heuristic → optional admin override). Provider-scoped
capabilities.
### ✅ v0.22.1 — Provider Extensions (Declarative Config)
YAML-based provider type registration. Settings schema per provider type.
Venice.ai provider. Provider-specific parameter pass-through. Extended
thinking support (Anthropic).
### ✅ v0.22.2 — Routing Policies + Fallback Chains
`routing_policies` table. Three policy types: `model_preference`,
`provider_failover`, `cost_optimize`. Channel-bindable. Failover
execution in completion handler. Health-aware skip.
### ✅ v0.22.3 — Provider Admin UI + Deferred Polish
Provider health dashboard, capability override editor, routing policy
builder. Model catalog sync trigger. Dynamic provider config form.
### ✅ v0.22.4 — Provider Health UX + Project Files + Export
Health dots in model selector. Project files tab (channel file
aggregation). Conversation export (JSON, Markdown). Bulk file download.
### ✅ v0.22.5 — Surfaces + Go Templates + Admin Bug Fixes
Go `html/template` engine with `//go:embed`. Six surfaces (chat, editor,
notes, settings, admin, login). Reusable components (model-select,
team-select, file-upload). `AuthOrRedirect` middleware. CSP nonces.
### ✅ v0.22.6 — Split Deployment Fix + CI Timeout + Code Pruning
`BACKEND_URL` fail-fast, ~2,430 lines OBE code removed (router.js,
surfaces.js, SPA shell). Extension surfaces intentionally broken pending
pane refactor (→ v0.25.0). Service worker BUILD_HASH cache key.
### ✅ v0.22.7 — Surface Prototypes (Theme + ChatPane + Splash)
`theme.css` with CSS custom properties. `ChatPane.create()` factory
pattern. Login/splash redesign. Toast stack, badges, icon buttons,
avatar upload, confirm dialog. Settings feature gates (BYOK, Personas).
### ✅ v0.22.8 — Surface Integration (Wire into Existing JS)
`ChatPane.primary` bridge from server-rendered mount points. Theme wired
to settings appearance. Admin hybrid section loaders. Naming cleanup:
preset → persona, APIConfigID → ProviderConfigID.
### ✅ v0.23.0 — @mention Routing + Persona Handles + Proxy
@mention resolution in any chat against full model catalog + persona registry.
AI-to-AI chaining with depth cap. Provider proxy mode (system/direct/custom).
`channel_participants` + `channel_models` tables. Persona handles.
### ✅ v0.23.1 — Multi-User Navigation + Conversation Taxonomy
Five-type conversation taxonomy (direct/dm/group/channel/workflow). Three-section
sidebar (Projects → Channels → Chats). Folder system. DM plumbing. Channel
`ai_mode` (auto/mention_only/off). Presence heartbeat. Migration 016.
### ✅ v0.23.2 — Multi-User Polish + Channel Lifecycle
Unified `App.activeConversation` replacing split tracking. Group leader
routing, `@all` fan-out. Channel archive/delete with retention policy.
Human message attribution. Unread cursor via `last_read_at`. Migration 017.
### ✅ v0.24.0 — Auth Abstraction + User Identity
`auth.Provider` interface decoupling builtin auth from handlers. User model
extended with `auth_source`, `external_id`, `handle`. @mention resolution
upgraded to handles. `UniqueHandle()` collision-safe generation. Migration 018.
### ✅ v0.24.1 — mTLS + OIDC Providers
mTLS via reverse proxy headers + cert DN parsing. OIDC authorization code flow
with JWKS caching and split-horizon issuer. Keycloak docker-compose overlay.
`QArgs()` dialect adapter for SQLite placeholder expansion. Migration 019.
### ✅ v0.24.2 — Fine-Grained Permissions
12 permission constants (`domain.action`). Per-group permissions, token budgets,
model allowlists. Everyone group (system-seeded, editable). `RequirePermission()`
middleware. BYOK bypass for personal providers. Migration 020.
### ✅ v0.24.3 — Anonymous Sessions
Unauthenticated visitors for workflow intake. `session_participants` table,
`AuthOrSession` middleware, cookie-based + mTLS session paths. Channel
`allow_anonymous` flag. Workflow entry page at `/w/:id`. Migration 021.
### ✅ v0.25.0 — Dynamic Surfaces + Component Extraction
Go template engine with `base.html` shell, surface manifest registry (DB-backed,
admin-toggleable), five core surfaces (chat, admin, settings, editor, notes).
Component extraction: UserMenu, ModelSelector, FileTree, CodeEditor, NoteEditor.
PaneContainer for multi-pane layouts. Admin and settings promoted from modals to
full-page surfaces. CSS decomposed from monolithic `styles.css` into 13 files.
Persona tool grants UI. Migration 022: `surface_registry` table.
### ✅ v0.25.1 — Surface Integration Fixes
Post-deployment corrections for v0.25.0 surface migration.
### ✅ v0.25.2 — Drag-Resize Utility
Unified `drag-resize.js` primitive for workspace handle and pane split handles.
Full-viewport overlay prevents iframe/CM6 event swallowing. Touch support.
### ✅ v0.25.3 — UI Bug Cleanup
Theme system mode fix (system → dark fallback), resize bar jump-on-click,
debug modal styling, settings/admin back-button navigation, profile save
(wrong IDs, wrong API routes, empty user context), scale slider range/commit.
### ✅ v0.25.4 — Admin + Settings Surface Hardening
Admin audit: 6 navigation/wiring fixes, settings export/import, group permissions
500 (Postgres SetNull argIdx), BYOK/persona policy store mismatch. Settings surface:
full init pipeline (policies, models, handlers, visibility checks), user settings
NULL/null/array corruption fix, model roles notice states, bulk model visibility.
Chat surface: stale modal HTML cleanup (320 lines), team admin modal layout/wiring,
persona create button. Backend: project files admin bypass, workspace delete API,
multi-provider live test failover.
---
## Technical Debt + Deferred Items
Items deferred from completed releases that remain outstanding.
Organized by domain. Pull into a version when the surrounding work
makes them a natural addition.
**Surfaces + Editor**
- [x] ~~Extension loader: surfaces from manifest.json~~ (v0.27.0 — `/s/:slug` route)
- [ ] Editor drag-drop file reorder (was v0.21.5 — deferred, no DnD infra in file-tree.js)
- [ ] Article drag-to-reorder outline sections (was v0.21.6)
- [ ] Article-specific AI tools: suggest_outline, expand_section, check_citations (was v0.21.6)
- [x] ~~PDF export via pandoc~~ (shipped v0.22.4)
- [ ] Mobile: mode selector collapses to hamburger/bottom nav (was v0.21.3)
- [x] ~~Pane state persistence per-user/per-project~~ (v0.27.0 — debounced sync to user_settings)
**Workspace + Git**
- [ ] Workspace settings UI: git config section (was v0.21.4 — deferred, needs vault-encrypted git credentials)
- [ ] User settings: git credentials management UI (was v0.21.4 — needs vault extension, v0.28.0+)
- [x] ~~`.gitignore` respect in workspace indexing~~ (v0.27.0 — Reconcile walk filter)
- [ ] Integration tests: clone, commit, push/pull cycle — requires git binary in CI (was v0.21.4)
**Provider Health + Routing**
- [x] ~~`RecordOutcome` for web_search and url_fetch~~ (shipped v0.22.4 — tool health tracking)
- [x] ~~Rate limit tracking per provider config~~ (shipped v0.22.4 — `rate_limit_count` on `provider_health`)
- [x] ~~Auto-disable: mark provider inactive when `down` for N consecutive health windows~~ (shipped v0.22.4)
- [ ] `capability_match` policy type ("cheapest model with tool_calling") — v0.28.0 candidate
- [ ] Latency-aware routing: track response time percentiles, prefer faster providers
- [ ] Cost-aware routing with budget ceiling per request
- [ ] New provider types registrable via config file (OpenAI-compatible + custom schema) — v0.28.0 candidate
- [ ] Provider profile editor: key-value config per provider type, preview of effective settings
- [ ] Fallback chain visualizer: drag-to-reorder provider priority per model family
**Sessions + Auth**
- [x] ~~Session cleanup job~~ (shipped v0.26.0 — background goroutine, `SESSION_EXPIRY_DAYS`)
**Tool System**
- [x] ~~Persona tool grant enforcement~~ (shipped v0.25.0 — second-pass allowlist in `completion.go:928`)
- [x] ~~Workflow version snapshot includes tool grants~~ (shipped v0.26.0 — `workflows.go:263`)
---
## ✅ v0.23.0 — @mention Routing + Persona Handles + Proxy
@mention routing works in any chat against the full model catalog and persona
registry. No roster, groups, or participant setup required — just type `@handle`
or `@model-id` and send.
**@mention Resolution**
- [x] `resolveMention()`: direct DB lookup — persona handle (exact/prefix) → model catalog (exact/prefix)
- [x] Autocomplete popup on `@` in any chat — all enabled models + personas
- [x] Handle field on personas: auto-generated from name, unique, editable
- [x] @mention pill rendering in message content (accent-colored, code-aware)
- [x] Context boundaries: persona→plain and persona→persona style isolation
- [x] Participant list injection: system prompt tells LLM who it can @mention
**AI-to-AI Chaining**
- [x] `chainIfMentioned()`: uses `resolveMention()` on assistant response content
- [x] Self-mention blocked, depth capped at 5
- [x] WebSocket delivery (`message.created` + typing indicators)
- [x] Same resolution path for user→LLM and LLM→LLM routing
**Provider Proxy**
- [x] `proxy_mode` (system/direct/custom) + `proxy_url` on `provider_configs`
- [x] All four providers use `cfg.Client()` with mode-aware HTTP transport
- [x] Bad custom URL falls back to system (not direct) — safe for mandatory-proxy environments
**Channel Infrastructure**
- [x] `channel_participants` table with polymorphic types and roles
- [x] `channel_models` partial indexes: persona entries keyed per-persona, raw models per-provider
- [x] Per-provider model preferences (composite keys in `user_model_settings`)
- [x] `persona_groups` + `persona_group_members` tables (schema ready, CRUD not yet wired)
---
## ✅ v0.23.1 — Multi-User Navigation + Conversation Taxonomy
Conversation type taxonomy (direct/dm/group/channel/workflow), three-section
sidebar (Projects → Channels → Chats), folder system for chats, DM plumbing,
channel configuration with `ai_mode`, presence heartbeat, and the unified
active conversation model.
Depends on: @mention routing (v0.23.0), WebSocket infrastructure (exists).
See [DESIGN-0_23_1.md](DESIGN-0_23_1.md) for the full spec.
**Conversation Types:**
- [x] Five-type taxonomy: direct (1:1 AI), dm (human-to-human), group (multi-participant), channel (named persistent), workflow (staged, deferred)
- [x] Channel type constraint extended: `dm`, `channel` added to `type` CHECK
- [x] `ai_mode` column on channels: `auto` | `mention_only` | `off`
- [x] `ai_mode` guard in completion handler — `off` returns 403, `mention_only` without @mention delivers without AI
- [x] `topic` column on channels for header display
**Sidebar Architecture:**
- [x] Three collapsible sections: Projects → Channels → Chats
- [x] `renderChannelsSection()` with # / person icons, unread badges, online dots
- [x] Channel items: context menu (rename, set topic, delete), ⋯ hover button
- [x] Section collapse/expand state in localStorage
**Folder System:**
- [x] `chat_folders` table, CRUD handler (`handlers/folders.go`)
- [x] Drag chats into/out of folders; folder context menu (rename, delete)
- [x] Folder delete modal: "Keep chats" / "Delete chats too" / Cancel
- [x] Unfiled drop zone when folders exist
**DM Plumbing:**
- [x] `resolveMention()` extended to resolve users (exact + prefix on username)
- [x] User @mention skips AI, delivers `user.mentioned` WebSocket notification
- [x] DM creation flow with user search modal
- [x] DM dedup guard — one channel per participant pair
**Presence:**
- [x] `user_presence` table with heartbeat upsert
- [x] `POST /presence/heartbeat` (30s interval), `GET /presence?users=...` (90s threshold)
- [x] Presence WebSocket events: `presence.changed`
**Channel Participants:**
- [x] `channel_participants` CRUD handler, auto-created on channel creation
- [x] Persona group CRUD endpoints wired (`persona_groups`, `persona_group_members`)
- [x] DM participant auto-creation from `req.Participants`
**Migration:**
- [x] 016_v023_multiuser: `ai_mode`, `topic`, `user_presence`, channel type extension
---
## ✅ v0.23.2 — Multi-User Polish + Channel Lifecycle
Bug fixes, unified active conversation refactor, channel lifecycle (archive/delete),
group chat leader routing, `@all` fan-out, message attribution, and deferred
surface integration from v0.22.8.
Depends on: v0.23.1 sidebar and conversation taxonomy.
**Unified Active Conversation:**
- [x] `App.activeConversation = { id, type }` replaces `currentChatId` + `currentChannelId`
- [x] `setActive(id, type)`, `activeId` getter, `getActiveChat()` helper
- [x] Send path, model bar, streaming, session restore all keyed off `activeConversation.id`
- [x] Sidebar highlight works across both chat and channel sections
**Group Chat + Persona Groups:**
- [x] Group leader default response: no @mention in group → leader persona responds
- [x] `@all` fan-out: routes to every persona participant, depth-1 only
- [x] Participant mutation guards: DMs keep ≥2 humans, groups keep ≥1 persona
- [x] "New Group Chat" flow with ad-hoc persona picker
**Message Attribution:**
- [x] Human sender display: other participants show avatar + display name (not "You")
- [x] Persona sender display verified for loaded history in channel context
**Channel Lifecycle:**
- [x] Archive action via context menu (`is_archived`, `archived_at`)
- [x] Delete gated by `channel_retention.mode` (flexible/retain)
- [x] Admin purge with `purge_after_days` floor
- [x] Retention config keys in `global_config`
**Bug Fixes:**
- [x] Channel persistence through refresh (resp.channels → resp.data)
- [x] Folder drag-and-drop (folderId mapping, drop handlers, unfiled zone)
- [x] DM creation 404 → added `GET /users/search` endpoint
- [x] Channel ⋯ menu consistency (replaced ✕ with hover ⋯ pattern)
- [x] Folder ⋯ button reflow (visibility:hidden instead of display:none)
- [x] Unread subquery using `last_read_at` (not migration-017-dependent column)
- [x] Settings Models section template wiring
- [x] `u.avatar``u.avatar_url` in ListMessages JOIN and treepath
**Surface Integration (deferred v0.22.8):**
- [x] `ChatPane.primary` bridge from server-rendered mount points
- [x] Theme save/load cycle wired to settings appearance
- [x] Admin hybrid section loaders completed
- [x] Settings surface: models toggles, persona CRUD, BYOK, teams
**@mention UX:**
- [x] Autocomplete includes users alongside personas and models
- [x] User mention pill styling (distinct color from persona pills)
- [x] `user.mentioned` WebSocket notification with toast
**Migration:**
- [x] 017_unread: `last_read_message_id` on `channel_participants`
---
## v0.24.0 — Auth Abstraction + User Identity ✅
Auth provider interface decoupling builtin auth from the handler/middleware
layer. User model extended with `auth_source`, `external_id`, `handle`.
@mention resolution upgraded to use handles. Zero behavior change for
existing users — builtin mode goes through the new abstraction identically.
See [DESIGN-0.24.0.md](DESIGN-0.24.0.md) for the full spec including
v0.24.1v0.24.3 subversions.
Depends on: v0.23.0 (channel_participants), v0.16.0 (groups), v0.9.4 (vault).
**Auth Provider Interface (`server/auth/`):**
- [x] `Provider` interface: `Mode()`, `Authenticate()`, `SupportsRegistration()`, `Register()`
- [x] `BuiltinProvider`: extracts login/register from `handlers/auth.go`
- [x] `UniqueHandle()`: collision-safe handle generation with `-2`, `-3` suffixes
- [x] `ErrorToHTTPStatus()`: maps auth errors to HTTP codes
- [x] `ParseMode()`: validates `AUTH_MODE` string with error return
**Auth Handler Refactor:**
- [x] `AuthHandler` gains `provider auth.Provider` field
- [x] `Login()` delegates to `provider.Authenticate()`, then vault unlock + JWT
- [x] `Register()` delegates to `provider.Register()`, then vault init + JWT
- [x] `generateTokens()` response includes `handle`, `auth_source`
- [x] `BootstrapAdmin()` / `SeedUsers()` backfill handles for existing users
**User Model Extension:**
- [x] `AuthSource` (builtin/mtls/oidc), `ExternalID` (nullable), `Handle` (unique)
- [x] All user store queries (PG + SQLite) include three new columns
- [x] `GetByHandle()`, `GetByExternalID()` on both store implementations
- [x] Unified `scanOneUser` / `scanOne` helpers replace per-method scan blocks
**Config + Middleware:**
- [x] `AUTH_MODE` env var (default `builtin`)
- [x] `main.go` dispatch: builtin wired, mTLS/OIDC fail-fast at startup
- [x] Middleware unchanged — JWT validation is auth-mode-agnostic
**@mention Resolution:**
- [x] `resolveMention()` uses `LOWER(handle)` instead of `LOWER(username)`
- [x] `SearchUsers` returns `handle`, filters on handle
- [x] Frontend autocomplete matches on handle, uses handle as @mention token
**Migration:**
- [x] 018_auth_abstraction: `auth_source`, `external_id`, `handle` columns + unique indexes + backfill
---
## v0.24.1 — mTLS + OIDC Providers ✅
Two external auth implementations plugging into v0.24.0's provider interface.
Keycloak integration test environment via docker-compose overlay.
Depends on: auth abstraction (v0.24.0).
See [DESIGN-0.24.0.md](DESIGN-0.24.0.md) §v0.24.1 for full spec.
- [x] mTLS provider: trusted header extraction, cert DN parsing, auto-provision
- [x] OIDC provider: well-known discovery, JWKS caching, token validation, claim extraction
- [x] OIDC authorization code flow: login redirect, code exchange, token handoff via fragment
- [x] Split-horizon issuer support (`OIDC_EXTERNAL_ISSUER_URL` for Docker/K8s)
- [x] OIDC claim → group mapping (external groups sync to internal groups with `source=oidc`)
- [x] Login page adapts by `AUTH_MODE` (form / cert status / SSO button)
- [x] Keycloak docker-compose overlay with pre-configured realm (`ci/keycloak-realm.json`)
- [x] `QArgs()` dialect adapter: handles Postgres `$N` reuse for SQLite arg expansion
- [x] `database.QueryRow/Query/Exec` wrappers with automatic arg expansion
- [x] Migration 019: `oidc_auth_state` table, `groups.source` column
- [x] Unit tests: mTLS (ParseDN, config), OIDC (discovery, auth URL, mode), QArgs (5 tests)
- [x] Regression test: `TestIntegration_ChannelListWithTypeFilter`
- [x] SQLite local dev fixes: `_time_format` DSN, store wiring, nginx resolver, extension assets
---
## v0.24.2 — Fine-Grained Permissions
Groups become capability carriers. Permission model on top of existing
group infrastructure.
Depends on: auth abstraction (v0.24.0). Parallel to v0.24.1.
See [DESIGN-0.24.0.md](DESIGN-0.24.0.md) §v0.24.2 for full spec.
- [x] Permission constants (`domain.action` convention, code-level enum)
- [x] `permissions` JSONB column on groups
- [x] `ResolvePermissions()`: union of group permissions + Everyone group
- [x] `RequirePermission()` middleware
- [x] Token budgets: per-group daily/monthly ceilings, enforced in completion handler
- [x] Model access control: per-group model allowlists
- [x] Admin UI: permission checklist, budget fields, model picker on group edit
- [x] Everyone group supersedes `DefaultUserPerms` (seeded in migration, editable in admin)
- [x] Migration 020: permissions, budgets, allowed_models on groups
---
## v0.24.3 — Anonymous / Session Participants
Unauthenticated visitors for workflow intake channels. Direct
prerequisite for v0.26.0 (Workflow Engine).
Depends on: mTLS provider (v0.24.1) for cert-based anonymous identity.
See [DESIGN-0.24.0.md](DESIGN-0.24.0.md) §v0.24.3 for full spec.
- [x] `session_participants` table (channel-scoped, ephemeral token)
- [x] `AuthOrSession()` middleware: tries JWT first, falls back to session cookie (cookie-based, no separate session JWT needed)
- [x] Capability scoping: session participants limited to their bound channel
- [x] mTLS anonymous path: cert fingerprint as stable session identity
- [x] `channels.allow_anonymous` flag
- [x] Session added as channel participant (`participant_type=session`, `role=visitor`)
- [x] Workflow entry page: `GET /w/:id` (Go template, standalone chat UI)
- [x] Migration 021: `session_participants` table, `allow_anonymous` column
---
## v0.25.0v0.25.4 — Dynamic Surfaces + Hardening ✅
Pane-based surface architecture replacing the "one surface active at a
time" model (v0.21.3). Manifest-driven surface registration, component
extraction, admin/settings promoted to full-page surfaces. Editor
surface rebuilt as proof-of-concept. Five patch releases for integration
fixes, drag-resize, UI bugs, and admin/settings surface hardening.
Depends on: Go template engine (v0.22.5), ChatPane component (v0.22.7),
surface integration (v0.22.8). See [DESIGN-SURFACES.md](DESIGN-SURFACES.md)
for the layer model.
See [DESIGN-0.25.0.md](DESIGN-0.25.0.md) for full spec.
**Pane System**
- [x] Pane container: workspace area holds 1+ panes side-by-side (replaces single-surface model)
- [x] Pane lifecycle: create, mount, resize, minimize, destroy — independent of surface lifecycle
- [x] Resizable splits: drag handles between panes, user-resizable
- [x] Layout presets: single (default), split-2 (editor+chat), split-3 (tree+editor+chat)
- [x] Default: single Chat pane — zero cognitive overhead, identical to current UX
- [x] Unified drag-resize primitive (`drag-resize.js`): overlay prevents iframe/CM6 event swallowing, touch support (v0.25.2)
**Surface Manifest + Registration**
- [x] Surface manifest schema: `id`, `route`, `title`, `components`, `data_requires`, `script`, `auth`
- [x] Dynamic route generation in page engine from registered surfaces
- [x] Data loader registry: surfaces declare data requirements, engine assembles loaders
- [x] Core surfaces (chat, admin, settings, editor, notes) on manifest pattern
- [x] `window.__PAGE_DATA__` injection from declared `data_requires`
- [x] `surface_registry` table — admin can enable/disable surfaces (Migration 022)
- [x] `/s/:slug` route namespace for extension/dynamic surfaces (shipped v0.27.0)
**Component Extraction**
- [x] FileTree: extracted from `editor-mode.js`, standalone component with Go template partial + JS hydration
- [x] CodeEditor: CM6 `codeEditor()` factory formalized as component
- [x] NoteEditor: extracted from `notes.js`, standalone component
- [x] ModelSelector: extracted from chat surface, reusable across surfaces
- [x] UserMenu: extracted as standalone component
- [x] Each component: Go template partial (server shell) + JS class (hydration) + CSS (scoped)
**Editor Surface Rebuild (Dog Food)**
- [x] Editor surface rebuilt on pane system: file tree pane + code editor pane + ChatPane (assist)
- [x] Surface manifest declares three panes with resizable splits
- [x] File tree pane: workspace_ls backed, context menu, nested directories
- [x] Code editor pane: CM6 with language detection, tab bar, Ctrl+S save
- [x] Chat pane: `ChatPane.create()` in assist role — same channel context, workspace-scoped tools
- [x] Replaces broken `editor-mode.js` (48K, dead since v0.22.6 code pruning)
**Admin + Settings Surfaces**
- [x] Admin surface at `/admin/:section` — full-page, category tabs, section scaffold
- [x] Settings surface at `/settings/:section` — full-page, left nav, section-specific templates
- [x] Settings export/import (versioned JSON envelope) (v0.25.4)
- [x] Bulk model visibility (Show All / Hide All) (v0.25.4)
- [x] Workspace rename/delete (v0.25.4)
**CSS Decomposition**
- [x] Monolithic `styles.css` → 13 files: variables, layout, primitives, modals, chat, panels, surfaces, splash, pane-container, chat-pane, user-menu, tool-grants, admin-surfaces
**Persona Tool Grants UI**
- [x] Persona create/edit UI: "Tools" section — multi-select checklist grouped by category
- [x] `loadToolList()` fetches from `/api/v1/tools`, `loadToolGrants()` reads per-persona grants
- [x] Completion handler applies `GetToolGrants()` as second-pass allowlist (`completion.go:928`)
- [x] Version snapshot includes persona tool grants at snapshot time (`workflows.go:263`)
**Bug Fixes (v0.25.3v0.25.4)**
- [x] Theme system mode (system preference → dark fallback)
- [x] Resize bar jump-on-click (inline width pin on start)
- [x] Debug modal styling (modal-content → modal class)
- [x] Settings/admin back-button navigation (sessionStorage return URL)
- [x] Profile save (wrong element IDs, wrong API routes, empty user context)
- [x] Scale slider range (120→175) and commit-on-release
- [x] Admin surface: 6 nav/wiring fixes (stray `>`, dual-bind, nav flash, history, storage, back URL)
- [x] BYOK/Personas toggles (policies store mismatch)
- [x] Group permissions 500 (Postgres SetNull argIdx misalignment)
- [x] Settings surface init (missing policies/models fetch, handler wiring)
- [x] User settings NULL/null/array corruption (COALESCE + jsonb_typeof guard)
- [x] Stale modal HTML cleanup (320 lines removed from chat surface)
- [x] Team admin modal layout/wiring, persona create button
- [x] Project files admin bypass
- [x] Multi-provider live test failover
**Shared Surface Routes** — partially shipped
- [x] `/admin/:section`, `/settings/:section` — full-page surface routes
- [ ] `/s/editor/:wsId`, `/s/article/:wsId/:path` — TBD (editor uses `/editor/:wsId` today)
- [ ] `/p/:id` — shared project view — TBD
**Shipped in v0.26.0:**
- [x] Context-Aware Tool System (`ToolContext`, `Require` predicates, `AvailableFor()`)
- [x] `ExecutionContext` extension (`WorkflowID`, `TeamID` fields)
**Shipped (verified in code audit):**
- [x] Tool grant enforcement in completion handler (`completion.go:928`)
- [x] Workflow version snapshot includes tool grants (`workflows.go:263`)
**Moved to v0.27.0:**
- [x] ~~Extension surface route namespace (`/s/:slug`)~~ → v0.27.0 Phase 1
**Migration:**
- [x] 022_surfaces.sql: `surface_registry` table (UUID PK, unique surface_id, is_enabled, is_core)
---
## ✅ v0.26.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 [DESIGN-0.26.0.md](DESIGN-0.26.0.md)
for full spec and [CHANGELOG-0.26.0.md](../CHANGELOG-0.26.0.md) for detailed
release notes.
**Shipped (v0.26.0v0.26.5):**
- [x] Session cleanup job (background goroutine, `SESSION_EXPIRY_DAYS`)
- [x] `ToolContext` + `Require` predicates + `BaseTool` embed + `AvailableFor()`
- [x] `ExecutionContext` TeamID wiring
- [x] Workflow definitions: `workflows`, `workflow_stages`, `workflow_versions` (migration 023)
- [x] Full CRUD + slug generation + publish + version snapshot
- [x] Workflow instances: `workflow_id`, `current_stage`, `stage_data`, `workflow_status` on channels (migration 024)
- [x] Start/advance/reject/status endpoints
- [x] Staleness sweep (background goroutine, `WORKFLOW_STALE_HOURS`)
- [x] Visitor landing page (`/w/:id/:slug`, branded, session resume)
- [x] Visitor start flow (`POST /api/v1/workflow-entry/:scope/:slug`)
- [x] `workflow_advance` tool (`RequireWorkflow` predicate, AI-triggered)
- [x] Form template → system prompt injection in completion handler
- [x] Stage notes (persisted as channel-scoped notes)
- [x] `workflow_assignments` table + claim/complete/list endpoints (migration 025)
- [x] Admin builder UI (Workflows category tab, CRUD, stage editor)
- [x] Queue sidebar section (badge count, claim/complete)
- [x] Route registration test (`TestRouteRegistration`)
- [x] Workflow CRUD test (`TestWorkflowCRUD`, `TestWorkflowValidation`)
**Shipped in v0.27.0 Phase 2 (Workflow Polish):**
- [x] Team-scoped workflow management UI (Settings → Workflows section)
- [x] Drag-and-drop stage reorder in builder (`_wfWireStageDnD()`)
- [x] `on_complete` workflow chaining (`triggerOnComplete()` in workflow_instances.go)
- [x] Workflow retention enforcement (staleness sweep extended)
- [x] Stage persona auto-switch in chat UI (via `workflow.advanced` WS event)
- [x] Round-robin auto-assignment (`tryRoundRobin()` in workflow_instances.go)
- [x] Assignment notifications via WebSocket (`workflow.assigned`, `workflow.claimed`)
- [x] Channel header stage indicator + advance/reject controls
**Shipped in v0.27.0 Phase 1:**
- [x] Extension surface routes (`/s/:slug` namespace — `RenderExtensionSurface()`)
**Shipped (verified in code audit):**
- [x] Persona tool grant enforcement in completion handler (`completion.go:928`)
---
## v0.27.0 — Debt Clearance
Extension surface routes, workflow engine polish, workspace/editor debt.
Depends on: workflow engine (v0.26.0), dynamic surfaces (v0.25.0).
See [DESIGN-0.27.0.md](DESIGN-0.27.0.md) for full spec.
**Phase 1: Extension Surface Routes (`/s/:slug`)**
- [x] `surface-extension` Go template (HTML + CSS + scripts blocks)
- [x] `base.html` conditional chain extended with `{{if .Manifest}}` fallthrough
- [x] `RenderExtensionSurface()` catch-all handler — runtime DB lookup, no restart needed
- [x] nginx location block for `/surfaces/` static assets (unified + split deployment)
- [x] Frontend nav renders extension surfaces from DB query at render time
- [x] Admin surfaces section: upload/enable/disable/uninstall (API + UI wired)
- [x] Sample `.surface` archive (`hello-dashboard`) for testing
- [x] CSP nonce propagation for extension scripts
- [x] `EXTENSION-SURFACES.md` authoring guide (manifest, API, CSS properties, admin API)
- [x] `EXTENSIONS.md` §6 rewritten to reference new authoring guide
**Phase 2: Workflow Engine Polish (v0.26.0 debt)**
- [x] Channel header workflow stage indicator + advance/reject controls
- [x] Stage persona auto-switch in chat UI (via `workflow.advanced` WS event → stage bar refresh)
- [x] Assignment notifications via WebSocket (`workflow.assigned`, `workflow.claimed`)
- [x] Round-robin auto-assignment (per-stage `transition_rules.auto_assign`)
- [x] `on_complete` workflow chaining (`triggerOnComplete()` — slug lookup, data mapping, channel creation)
- [x] Workflow retention enforcement (staleness sweep extended — archive/delete by policy)
- [x] Drag-and-drop stage reorder in workflow builder UI (`_wfWireStageDnD()`)
- [x] Team-scoped workflow management UI (Settings → Workflows section)
**Phase 3: Workspace + Editor Debt** (partial)
- [x] `.gitignore` respect in workspace indexing (`workspace/fs.go` — Reconcile walk, `loadGitignore`, `matchesGitignore`)
- [x] Pane state persistence per-user/per-project (debounced sync to `user_settings` API, cross-device restore)
- [ ] Workspace settings UI: git config section — deferred (broader scope, needs vault-encrypted git credentials)
- [ ] Editor drag-drop file reorder — deferred (greenfield, no existing DnD in file-tree.js)
---
## v0.27.1 — Tasks Foundation: Service Channels + Scheduler ✅
Core primitive for autonomous agents: a channel with no human
participant, driven by a cron scheduler.
Depends on: v0.27.0 (debt clearance).
- [x] `tasks` + `task_runs` tables + store interface + PG (UUID) / SQLite implementations
- [x] `type: 'service'` channel type (PG CHECK extended, SQLite by convention)
- [x] `TaskStore` interface: CRUD, `ListDue`, `SetNextRun`, `IncrementRunCount`, run history
- [x] `TaskScheduler` background goroutine (30s poll, skip-if-running, one-shot + cron)
- [x] Minimal cron parser (hourly, N-minute intervals, daily H:M, weekly DOW patterns)
- [x] Service channel creation per task (reuse `output_channel_id` on subsequent runs)
- [x] User prompt persisted as message in service channel
- [x] Task CRUD handler with ownership checks + admin bypass
- [x] `POST /tasks/:id/run` — manual "Run Now" trigger
- [x] Migration 026: `tasks` + `task_runs` tables, `service` channel type
**Deferred to v0.27.2:**
- [ ] Completion invocation from scheduler (wire into `streamWithToolLoop`)
- [ ] Full cron parsing via `robfig/cron/v3` (replacing minimal parser)
- [ ] Provider resolution for task context (BYOK → team → global → routing policy)
- [ ] Workflow task execution (instantiate workflow in service channel)
- [ ] Tasks sidebar section (read-only view of service channels)
**API routes (v0.27.1):**
- `GET /api/v1/tasks` — list my tasks
- `POST /api/v1/tasks` — create task
- `GET /api/v1/tasks/:id` — get task
- `PUT /api/v1/tasks/:id` — update task
- `DELETE /api/v1/tasks/:id` — delete task
- `GET /api/v1/tasks/:id/runs` — run history
- `POST /api/v1/tasks/:id/run` — manual trigger
- `GET /api/v1/admin/tasks` — list all tasks (admin)
---
## v0.27.2 — Task Execution: Budgets + Admin Controls ✅
Guardrails for unattended execution.
Depends on: v0.27.1 (task scheduler).
- [x] Execution budget enforcement: `max_tokens`, `max_tool_calls`, `max_wall_clock`
- [x] ~~`task_runs` table + store~~ (shipped v0.27.1 — table, PG+SQLite store, run history API)
- [x] Budget breach → `budget_exceeded` status + owner notification
- [x] ~~Concurrent run skip~~ (shipped v0.27.1 — scheduler skips if `GetActiveRun` returns non-nil)
- [x] Global config: `tasks.enabled`, `tasks.allow_personal`, `tasks.max_concurrent`
- [x] Default budget ceilings in global config (overridable per task)
- [x] `tasks.create` and `tasks.admin` permissions
- [x] Admin panel → Tasks section (CRUD, history, kill switch, budget config)
- [x] Completion invocation from scheduler (headless executor via `CoreToolLoop`)
- [x] Full cron parsing via `robfig/cron/v3` (replacing minimal parser)
- [x] Provider resolution for task context (BYOK → team → global → routing policy)
- [x] Kill switch: `POST /tasks/:id/kill` cancels active run
---
## v0.27.3 — Task Chaining: Webhooks + Workflow-to-Workflow ✅
External integration and multi-workflow orchestration.
Depends on: v0.27.2 (task budgets).
- [x] Completion webhooks (POST to external URL on task/workflow completion)
- [x] Webhook retry (3 attempts, exponential backoff) + HMAC signature
- [x] `task_create` tool (AI spawns sub-tasks, RequireWorkflow/RequireTeam predicate, depth limit)
- [x] `on_complete` chaining via task system (completed workflow → one-shot task → target workflow)
- [x] Webhook secret generation per task/workflow
- [x] Bug fix: `workflow_advance` tool now triggers `on_complete` chaining on completion
---
## v0.27.4 — Personal Tasks: BYOK Scheduling + User Task UI ✅
User-facing task experience. Personal tasks run against BYOK providers.
Depends on: v0.27.2 (admin controls, `tasks.allow_personal`).
- [x] Settings → Tasks section (CRUD, schedule builder, budget config)
- [x] Schedule builder: preset crons + custom 5-field cron + timezone selector
- [x] BYOK provider routing for personal tasks
- [x] `tasks.personal_require_byok` config key (prevent fallthrough to org providers)
- [x] Output modes: channel (default), note, webhook
- [x] Task notification booleans: `notify_on_complete` (default false), `notify_on_failure` (default true)
- [x] Tasks sidebar section with status indicators (✓/⏳/▶)
- [x] "Run Now" button for manual trigger
- [x] 5 starter templates (news digest, standup prep, weekly summary, stock check, research digest)
---
## v0.28.0 — Platform Polish
TBD pull-forward: high-value items whose dependencies are met post-tasks.
**Tier 1 — High value, dependencies met:**
- [ ] Virtual scroll for long conversations (prerequisite for heavy task output channels)
- [ ] KB auto-injection: top-K chunk prepend, context budget aware, per-channel toggle
- [ ] Helm chart (replaces raw k8s manifests, `helm install switchboard ./chart`)
- [ ] Per-provider model preferences (`provider_config_id` dimension in `user_model_settings`)
**Tier 2 — Medium value:**
- [ ] Memory compaction: summarize old memories, confidence decay, prune low-confidence
- [ ] `capability_match` routing policy ("cheapest model with tool_calling")
- [ ] New provider types registrable via config file (OpenAI-compatible + custom schema)
---
## v0.29.0 — Starlark Extensions: Permissioned Server-Side Plugins
Server-side extension runtime with capability-gated module access.
Depends on: v0.28.0 (platform polish), extension infrastructure (v0.11.0).
Manifest declares requested permissions (flatpak/Android model):
```json
{
"permissions": ["http", "store.read", "files.read", "notifications"]
}
```
Admin reviews and grants/revokes per-permission. Runtime enforces:
only approved modules are injected into the Starlark sandbox.
- [ ] `go.starlark.net` integration (eval loop, timeout, memory ceiling)
- [ ] Permission model: manifest declarations, admin grant/revoke, DB schema
(`extension_permissions` table: extension_id, permission, granted, granted_by)
- [ ] Privileged module library:
- `http` — outbound HTTP requests (allowlist/blocklist per extension)
- `store` — key/value read/write (extension-namespaced, quota-limited)
- `files` — project-scoped file read/write
- `notifications` — emit notifications to users
- `secrets` — vault-backed per-extension secret storage
- [ ] Runtime enforcement: sandbox loader checks granted permissions, injects
only approved modules. Denied permissions → clean error, not silent no-op.
- [ ] Admin UI: permission review on install, per-extension grant/revoke toggle,
audit log of permission changes
- [ ] Server-side tool execution in completion handler (Starlark tools run
server-side, browser tools run client-side — unified tool schema)
- [ ] Extension lifecycle: `install → pending_review → approved → active`
- [ ] Migration: `extension_permissions` table
- [ ] ICD: update `extensions.md` with Starlark-specific endpoints
- [ ] Multi-file asset routing: `ServeExtensionAsset` currently ignores `*path` param
and returns inline `_script` for all requests. Starlark extensions need multi-file
bundles (source + manifest + static assets). Implement path-based lookup or
replace inline `_script` with filesystem/blob serving.
- [ ] Deduplicate tool schema extraction: `ListBrowserToolSchemas` (extensions.go) and
`ListTools` (completion.go) both independently iterate user extensions, parse
manifests, and extract tool schemas. Unify into a shared helper that handles
both browser and server-side tool types. The completion handler also has a
`hub.IsConnected` guard that the extension handler lacks — reconcile.
---
## 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)~~ → scheduled v0.29.0
- ~~Server-side tool execution in completion handler~~ → scheduled v0.29.0
- Sidecar HTTP tool protocol (Tier 2 — container isolation)
**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~~ → scheduled v0.28.0. `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`.
- Git credentials store: vault-encrypted per-user git credentials (similar to BYOK pattern). Git provider abstraction (GitHub, GitLab, Gitea). Clone/pull/push handlers. Natural fit for extension sidecar tier since git operations are long-running.
- Admin settings team/user export: v0.25.4 ships admin-only settings export/import. User export blocked by vault-encrypted BYOK keys (can't round-trip). Team export needs merge-vs-replace semantics for member lists.
**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~~ → scheduled v0.28.0
- 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~~ → scheduled v0.28.0
- ~~Memory confidence decay~~ → scheduled v0.28.0 (combined with compaction)
- 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~~ → scheduled v0.28.0
- ~~SQLite backend option (single-user / dev)~~ → v0.17.1
- ~~**Helm chart.**~~ → scheduled v0.28.0
~~**Pane Architecture (Workspace Container)**~~ → shipped in v0.25.0
~~**Surfaces as Extensions**~~ → core infrastructure shipped in v0.25.0. Marketplace, Surface IDE, and project-bound defaults remain future items:
- Surface IDE: built-in surface for building surfaces — Go template editor for server-rendered shells, JS/CSS editor for client behavior, live preview in sandboxed region
- Surface marketplace: share custom surfaces across instances (presentation mode, kanban, form builder, dashboard, etc.)
- Project-bound surface/pane defaults: project config specifies which panes are available and default layout
---
## Pre-1.0 — Code Quality Sweeps
Codebase-wide refactors required before 1.0. Not tied to a feature version —
pull left when touching the affected code, or schedule a dedicated pass.
**`SELECT *` → Explicit Column Lists**
All store implementations use `SELECT * FROM <table>` with positional `rows.Scan()`.
If a migration adds a column, every scan breaks silently at runtime (wrong column
mapped to wrong field). Every `scanOne`/`scanMany` helper needs explicit column lists.
Scope: every store file in `store/postgres/` and `store/sqlite/`.
**Raw SQL Hunt**
Several handlers execute raw SQL via `database.DB.Exec` / `database.TestDB.Exec`
instead of going through the store interface. These bypass the dialect abstraction
and are a source of PG/SQLite divergence bugs. Known instances:
- `handlers/channels.go` — inline channel queries with `pq.Array`
- `handlers/workflows.go` — inline unique constraint string matching
- `handlers/participants.go``isDuplicateErr` string matching (should use `database.IsUniqueViolation`)
- `knowledge/` handlers — direct `database.DB.ExecContext` for storage key updates
Full sweep: grep for `database.DB.Exec`, `database.TestDB.Exec`, `DB.QueryRow` outside
of `store/` packages. Move to store methods or use existing dialect-safe helpers.
---
## v0.27.5 — Team Tasks ✅
Team-visible task management. Members can view, admins can CRUD.
Depends on: v0.27.4 (personal task UI).
- [x] `GET /api/v1/teams/:teamId/tasks` — member-visible team task list
- [x] Team admin CRUD: create/update/delete/run/kill via team-scoped routes
- [x] `canAccessTask` / `canMutateTask` helpers — team member read, team admin write
- [x] Access check on `ListRuns` (was missing — any authenticated user could read run history)
- [x] Settings Tasks section shows team tasks alongside personal (with team badge)
- [x] Sidebar Tasks section includes team tasks (with team label)
- [x] `CreateTeamTask` handler — injects team scope on creation