54 KiB
Roadmap — Chat Switchboard
See also:
- ARCHITECTURE.md — Core services design, store layer, scope model
- EXTENSIONS.md — Extension system spec (Browser/Starlark/Sidecar tiers, manifests, browser tool bridge, surfaces/modes, model roles)
- EXTENSION-SURFACES.md — Extension surface authoring guide (manifest format, platform API, CSS properties, install workflow)
- 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.28.0 Platform Polish
(virtual scroll, KB auto-inject,
Helm chart, provider model prefs)
Completed Releases
Full details for all completed versions are in 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.
✅ 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.
✅ 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.
✅ 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.
✅ 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.
✅ 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.
✅ 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.
✅ 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
Extension loader: surfaces from manifest.json(v0.27.0 —/s/:slugroute)- 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)
PDF export via pandoc(shipped v0.22.4)- Mobile: mode selector collapses to hamburger/bottom nav (was v0.21.3)
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+)
(v0.27.0 — Reconcile walk filter).gitignorerespect in workspace indexing- Integration tests: clone, commit, push/pull cycle — requires git binary in CI (was v0.21.4)
Provider Health + Routing
(shipped v0.22.4 — tool health tracking)RecordOutcomefor web_search and url_fetchRate limit tracking per provider config(shipped v0.22.4 —rate_limit_countonprovider_health)Auto-disable: mark provider inactive when(shipped v0.22.4)downfor N consecutive health windowscapability_matchpolicy 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
Session cleanup job(shipped v0.26.0 — background goroutine,SESSION_EXPIRY_DAYS)
Tool System
Persona tool grant enforcement(shipped v0.25.0 — second-pass allowlist incompletion.go:928)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
resolveMention(): direct DB lookup — persona handle (exact/prefix) → model catalog (exact/prefix)- Autocomplete popup on
@in any chat — all enabled models + personas - Handle field on personas: auto-generated from name, unique, editable
- @mention pill rendering in message content (accent-colored, code-aware)
- Context boundaries: persona→plain and persona→persona style isolation
- Participant list injection: system prompt tells LLM who it can @mention
AI-to-AI Chaining
chainIfMentioned(): usesresolveMention()on assistant response content- Self-mention blocked, depth capped at 5
- WebSocket delivery (
message.created+ typing indicators) - Same resolution path for user→LLM and LLM→LLM routing
Provider Proxy
proxy_mode(system/direct/custom) +proxy_urlonprovider_configs- All four providers use
cfg.Client()with mode-aware HTTP transport - Bad custom URL falls back to system (not direct) — safe for mandatory-proxy environments
Channel Infrastructure
channel_participantstable with polymorphic types and roleschannel_modelspartial indexes: persona entries keyed per-persona, raw models per-provider- Per-provider model preferences (composite keys in
user_model_settings) persona_groups+persona_group_memberstables (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 for the full spec.
Conversation Types:
- Five-type taxonomy: direct (1:1 AI), dm (human-to-human), group (multi-participant), channel (named persistent), workflow (staged, deferred)
- Channel type constraint extended:
dm,channeladded totypeCHECK ai_modecolumn on channels:auto|mention_only|offai_modeguard in completion handler —offreturns 403,mention_onlywithout @mention delivers without AItopiccolumn on channels for header display
Sidebar Architecture:
- Three collapsible sections: Projects → Channels → Chats
renderChannelsSection()with # / person icons, unread badges, online dots- Channel items: context menu (rename, set topic, delete), ⋯ hover button
- Section collapse/expand state in localStorage
Folder System:
chat_folderstable, CRUD handler (handlers/folders.go)- Drag chats into/out of folders; folder context menu (rename, delete)
- Folder delete modal: "Keep chats" / "Delete chats too" / Cancel
- Unfiled drop zone when folders exist
DM Plumbing:
resolveMention()extended to resolve users (exact + prefix on username)- User @mention skips AI, delivers
user.mentionedWebSocket notification - DM creation flow with user search modal
- DM dedup guard — one channel per participant pair
Presence:
user_presencetable with heartbeat upsertPOST /presence/heartbeat(30s interval),GET /presence?users=...(90s threshold)- Presence WebSocket events:
presence.changed
Channel Participants:
channel_participantsCRUD handler, auto-created on channel creation- Persona group CRUD endpoints wired (
persona_groups,persona_group_members) - DM participant auto-creation from
req.Participants
Migration:
- 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:
App.activeConversation = { id, type }replacescurrentChatId+currentChannelIdsetActive(id, type),activeIdgetter,getActiveChat()helper- Send path, model bar, streaming, session restore all keyed off
activeConversation.id - Sidebar highlight works across both chat and channel sections
Group Chat + Persona Groups:
- Group leader default response: no @mention in group → leader persona responds
@allfan-out: routes to every persona participant, depth-1 only- Participant mutation guards: DMs keep ≥2 humans, groups keep ≥1 persona
- "New Group Chat" flow with ad-hoc persona picker
Message Attribution:
- Human sender display: other participants show avatar + display name (not "You")
- Persona sender display verified for loaded history in channel context
Channel Lifecycle:
- Archive action via context menu (
is_archived,archived_at) - Delete gated by
channel_retention.mode(flexible/retain) - Admin purge with
purge_after_daysfloor - Retention config keys in
global_config
Bug Fixes:
- Channel persistence through refresh (resp.channels → resp.data)
- Folder drag-and-drop (folderId mapping, drop handlers, unfiled zone)
- DM creation 404 → added
GET /users/searchendpoint - Channel ⋯ menu consistency (replaced ✕ with hover ⋯ pattern)
- Folder ⋯ button reflow (visibility:hidden instead of display:none)
- Unread subquery using
last_read_at(not migration-017-dependent column) - Settings Models section template wiring
u.avatar→u.avatar_urlin ListMessages JOIN and treepath
Surface Integration (deferred v0.22.8):
ChatPane.primarybridge from server-rendered mount points- Theme save/load cycle wired to settings appearance
- Admin hybrid section loaders completed
- Settings surface: models toggles, persona CRUD, BYOK, teams
@mention UX:
- Autocomplete includes users alongside personas and models
- User mention pill styling (distinct color from persona pills)
user.mentionedWebSocket notification with toast
Migration:
- 017_unread:
last_read_message_idonchannel_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 for the full spec including v0.24.1–v0.24.3 subversions.
Depends on: v0.23.0 (channel_participants), v0.16.0 (groups), v0.9.4 (vault).
Auth Provider Interface (server/auth/):
Providerinterface:Mode(),Authenticate(),SupportsRegistration(),Register()BuiltinProvider: extracts login/register fromhandlers/auth.goUniqueHandle(): collision-safe handle generation with-2,-3suffixesErrorToHTTPStatus(): maps auth errors to HTTP codesParseMode(): validatesAUTH_MODEstring with error return
Auth Handler Refactor:
AuthHandlergainsprovider auth.ProviderfieldLogin()delegates toprovider.Authenticate(), then vault unlock + JWTRegister()delegates toprovider.Register(), then vault init + JWTgenerateTokens()response includeshandle,auth_sourceBootstrapAdmin()/SeedUsers()backfill handles for existing users
User Model Extension:
AuthSource(builtin/mtls/oidc),ExternalID(nullable),Handle(unique)- All user store queries (PG + SQLite) include three new columns
GetByHandle(),GetByExternalID()on both store implementations- Unified
scanOneUser/scanOnehelpers replace per-method scan blocks
Config + Middleware:
AUTH_MODEenv var (defaultbuiltin)main.godispatch: builtin wired, mTLS/OIDC fail-fast at startup- Middleware unchanged — JWT validation is auth-mode-agnostic
@mention Resolution:
resolveMention()usesLOWER(handle)instead ofLOWER(username)SearchUsersreturnshandle, filters on handle- Frontend autocomplete matches on handle, uses handle as @mention token
Migration:
- 018_auth_abstraction:
auth_source,external_id,handlecolumns + 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 §v0.24.1 for full spec.
- mTLS provider: trusted header extraction, cert DN parsing, auto-provision
- OIDC provider: well-known discovery, JWKS caching, token validation, claim extraction
- OIDC authorization code flow: login redirect, code exchange, token handoff via fragment
- Split-horizon issuer support (
OIDC_EXTERNAL_ISSUER_URLfor Docker/K8s) - OIDC claim → group mapping (external groups sync to internal groups with
source=oidc) - Login page adapts by
AUTH_MODE(form / cert status / SSO button) - Keycloak docker-compose overlay with pre-configured realm (
ci/keycloak-realm.json) QArgs()dialect adapter: handles Postgres$Nreuse for SQLite arg expansiondatabase.QueryRow/Query/Execwrappers with automatic arg expansion- Migration 019:
oidc_auth_statetable,groups.sourcecolumn - Unit tests: mTLS (ParseDN, config), OIDC (discovery, auth URL, mode), QArgs (5 tests)
- Regression test:
TestIntegration_ChannelListWithTypeFilter - SQLite local dev fixes:
_time_formatDSN, 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 §v0.24.2 for full spec.
- Permission constants (
domain.actionconvention, code-level enum) permissionsJSONB column on groupsResolvePermissions(): union of group permissions + Everyone groupRequirePermission()middleware- Token budgets: per-group daily/monthly ceilings, enforced in completion handler
- Model access control: per-group model allowlists
- Admin UI: permission checklist, budget fields, model picker on group edit
- Everyone group supersedes
DefaultUserPerms(seeded in migration, editable in admin) - 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 §v0.24.3 for full spec.
session_participantstable (channel-scoped, ephemeral token)AuthOrSession()middleware: tries JWT first, falls back to session cookie (cookie-based, no separate session JWT needed)- Capability scoping: session participants limited to their bound channel
- mTLS anonymous path: cert fingerprint as stable session identity
channels.allow_anonymousflag- Session added as channel participant (
participant_type=session,role=visitor) - Workflow entry page:
GET /w/:id(Go template, standalone chat UI) - Migration 021:
session_participantstable,allow_anonymouscolumn
v0.25.0–v0.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 for the layer model.
See DESIGN-0.25.0.md for full spec.
Pane System ✅
- Pane container: workspace area holds 1+ panes side-by-side (replaces single-surface model)
- Pane lifecycle: create, mount, resize, minimize, destroy — independent of surface lifecycle
- Resizable splits: drag handles between panes, user-resizable
- Layout presets: single (default), split-2 (editor+chat), split-3 (tree+editor+chat)
- Default: single Chat pane — zero cognitive overhead, identical to current UX
- Unified drag-resize primitive (
drag-resize.js): overlay prevents iframe/CM6 event swallowing, touch support (v0.25.2)
Surface Manifest + Registration ✅
- Surface manifest schema:
id,route,title,components,data_requires,script,auth - Dynamic route generation in page engine from registered surfaces
- Data loader registry: surfaces declare data requirements, engine assembles loaders
- Core surfaces (chat, admin, settings, editor, notes) on manifest pattern
window.__PAGE_DATA__injection from declareddata_requiressurface_registrytable — admin can enable/disable surfaces (Migration 022)/s/:slugroute namespace for extension/dynamic surfaces (shipped v0.27.0)
Component Extraction ✅
- FileTree: extracted from
editor-mode.js, standalone component with Go template partial + JS hydration - CodeEditor: CM6
codeEditor()factory formalized as component - NoteEditor: extracted from
notes.js, standalone component - ModelSelector: extracted from chat surface, reusable across surfaces
- UserMenu: extracted as standalone component
- Each component: Go template partial (server shell) + JS class (hydration) + CSS (scoped)
Editor Surface Rebuild (Dog Food) ✅
- Editor surface rebuilt on pane system: file tree pane + code editor pane + ChatPane (assist)
- Surface manifest declares three panes with resizable splits
- File tree pane: workspace_ls backed, context menu, nested directories
- Code editor pane: CM6 with language detection, tab bar, Ctrl+S save
- Chat pane:
ChatPane.create()in assist role — same channel context, workspace-scoped tools - Replaces broken
editor-mode.js(48K, dead since v0.22.6 code pruning)
Admin + Settings Surfaces ✅
- Admin surface at
/admin/:section— full-page, category tabs, section scaffold - Settings surface at
/settings/:section— full-page, left nav, section-specific templates - Settings export/import (versioned JSON envelope) (v0.25.4)
- Bulk model visibility (Show All / Hide All) (v0.25.4)
- Workspace rename/delete (v0.25.4)
CSS Decomposition ✅
- 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 ✅
- Persona create/edit UI: "Tools" section — multi-select checklist grouped by category
loadToolList()fetches from/api/v1/tools,loadToolGrants()reads per-persona grants- Completion handler applies
GetToolGrants()as second-pass allowlist (completion.go:928) - Version snapshot includes persona tool grants at snapshot time (
workflows.go:263)
Bug Fixes (v0.25.3–v0.25.4)
- Theme system mode (system preference → dark fallback)
- Resize bar jump-on-click (inline width pin on start)
- Debug modal styling (modal-content → modal class)
- Settings/admin back-button navigation (sessionStorage return URL)
- Profile save (wrong element IDs, wrong API routes, empty user context)
- Scale slider range (120→175) and commit-on-release
- Admin surface: 6 nav/wiring fixes (stray
>, dual-bind, nav flash, history, storage, back URL) - BYOK/Personas toggles (policies store mismatch)
- Group permissions 500 (Postgres SetNull argIdx misalignment)
- Settings surface init (missing policies/models fetch, handler wiring)
- User settings NULL/null/array corruption (COALESCE + jsonb_typeof guard)
- Stale modal HTML cleanup (320 lines removed from chat surface)
- Team admin modal layout/wiring, persona create button
- Project files admin bypass
- Multi-provider live test failover
Shared Surface Routes — partially shipped
/admin/:section,/settings/:section— full-page surface routes/s/editor/:wsId,/s/article/:wsId/:path— TBD (editor uses/editor/:wsIdtoday)/p/:id— shared project view — TBD
Shipped in v0.26.0:
- Context-Aware Tool System (
ToolContext,Requirepredicates,AvailableFor()) ExecutionContextextension (WorkflowID,TeamIDfields)
Shipped (verified in code audit):
- Tool grant enforcement in completion handler (
completion.go:928) - Workflow version snapshot includes tool grants (
workflows.go:263)
Moved to v0.27.0:
Extension surface route namespace (→ v0.27.0 Phase 1/s/:slug)
Migration:
- 022_surfaces.sql:
surface_registrytable (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 for full spec and CHANGELOG-0.26.0.md for detailed release notes.
Shipped (v0.26.0–v0.26.5):
- Session cleanup job (background goroutine,
SESSION_EXPIRY_DAYS) ToolContext+Requirepredicates +BaseToolembed +AvailableFor()ExecutionContextTeamID wiring- Workflow definitions:
workflows,workflow_stages,workflow_versions(migration 023) - Full CRUD + slug generation + publish + version snapshot
- Workflow instances:
workflow_id,current_stage,stage_data,workflow_statuson channels (migration 024) - Start/advance/reject/status endpoints
- Staleness sweep (background goroutine,
WORKFLOW_STALE_HOURS) - Visitor landing page (
/w/:id/:slug, branded, session resume) - Visitor start flow (
POST /api/v1/workflow-entry/:scope/:slug) workflow_advancetool (RequireWorkflowpredicate, AI-triggered)- Form template → system prompt injection in completion handler
- Stage notes (persisted as channel-scoped notes)
workflow_assignmentstable + claim/complete/list endpoints (migration 025)- Admin builder UI (Workflows category tab, CRUD, stage editor)
- Queue sidebar section (badge count, claim/complete)
- Route registration test (
TestRouteRegistration) - Workflow CRUD test (
TestWorkflowCRUD,TestWorkflowValidation)
Shipped in v0.27.0 Phase 2 (Workflow Polish):
- Team-scoped workflow management UI (Settings → Workflows section)
- Drag-and-drop stage reorder in builder (
_wfWireStageDnD()) on_completeworkflow chaining (triggerOnComplete()in workflow_instances.go)- Workflow retention enforcement (staleness sweep extended)
- Stage persona auto-switch in chat UI (via
workflow.advancedWS event) - Round-robin auto-assignment (
tryRoundRobin()in workflow_instances.go) - Assignment notifications via WebSocket (
workflow.assigned,workflow.claimed) - Channel header stage indicator + advance/reject controls
Shipped in v0.27.0 Phase 1:
- Extension surface routes (
/s/:slugnamespace —RenderExtensionSurface())
Shipped (verified in code audit):
- 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 for full spec.
Phase 1: Extension Surface Routes (/s/:slug) ✅
surface-extensionGo template (HTML + CSS + scripts blocks)base.htmlconditional chain extended with{{if .Manifest}}fallthroughRenderExtensionSurface()catch-all handler — runtime DB lookup, no restart needed- nginx location block for
/surfaces/static assets (unified + split deployment) - Frontend nav renders extension surfaces from DB query at render time
- Admin surfaces section: upload/enable/disable/uninstall (API + UI wired)
- Sample
.surfacearchive (hello-dashboard) for testing - CSP nonce propagation for extension scripts
EXTENSION-SURFACES.mdauthoring guide (manifest, API, CSS properties, admin API)EXTENSIONS.md§6 rewritten to reference new authoring guide
Phase 2: Workflow Engine Polish (v0.26.0 debt) ✅
- Channel header workflow stage indicator + advance/reject controls
- Stage persona auto-switch in chat UI (via
workflow.advancedWS event → stage bar refresh) - Assignment notifications via WebSocket (
workflow.assigned,workflow.claimed) - Round-robin auto-assignment (per-stage
transition_rules.auto_assign) on_completeworkflow chaining (triggerOnComplete()— slug lookup, data mapping, channel creation)- Workflow retention enforcement (staleness sweep extended — archive/delete by policy)
- Drag-and-drop stage reorder in workflow builder UI (
_wfWireStageDnD()) - Team-scoped workflow management UI (Settings → Workflows section)
Phase 3: Workspace + Editor Debt (partial)
.gitignorerespect in workspace indexing (workspace/fs.go— Reconcile walk,loadGitignore,matchesGitignore)- Pane state persistence per-user/per-project (debounced sync to
user_settingsAPI, 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).
tasks+task_runstables + store interface + PG (UUID) / SQLite implementationstype: 'service'channel type (PG CHECK extended, SQLite by convention)TaskStoreinterface: CRUD,ListDue,SetNextRun,IncrementRunCount, run historyTaskSchedulerbackground goroutine (30s poll, skip-if-running, one-shot + cron)- Minimal cron parser (hourly, N-minute intervals, daily H:M, weekly DOW patterns)
- Service channel creation per task (reuse
output_channel_idon subsequent runs) - User prompt persisted as message in service channel
- Task CRUD handler with ownership checks + admin bypass
POST /tasks/:id/run— manual "Run Now" trigger- Migration 026:
tasks+task_runstables,servicechannel 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 tasksPOST /api/v1/tasks— create taskGET /api/v1/tasks/:id— get taskPUT /api/v1/tasks/:id— update taskDELETE /api/v1/tasks/:id— delete taskGET /api/v1/tasks/:id/runs— run historyPOST /api/v1/tasks/:id/run— manual triggerGET /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).
- Execution budget enforcement:
max_tokens,max_tool_calls,max_wall_clock (shipped v0.27.1 — table, PG+SQLite store, run history API)task_runstable + store- Budget breach →
budget_exceededstatus + owner notification Concurrent run skip(shipped v0.27.1 — scheduler skips ifGetActiveRunreturns non-nil)- Global config:
tasks.enabled,tasks.allow_personal,tasks.max_concurrent - Default budget ceilings in global config (overridable per task)
tasks.createandtasks.adminpermissions- Admin panel → Tasks section (CRUD, history, kill switch, budget config)
- Completion invocation from scheduler (headless executor via
CoreToolLoop) - Full cron parsing via
robfig/cron/v3(replacing minimal parser) - Provider resolution for task context (BYOK → team → global → routing policy)
- Kill switch:
POST /tasks/:id/killcancels active run
v0.27.3 — Task Chaining: Webhooks + Workflow-to-Workflow
External integration and multi-workflow orchestration. Depends on: v0.27.2 (task budgets).
- Completion webhooks (POST to external URL on task/workflow completion)
- Webhook retry (3 attempts, exponential backoff) + HMAC signature
task_createtool (AI spawns sub-tasks,RequireWorkflowpredicate, depth limit)on_completechaining via task system (completed workflow → one-shot task → target workflow)- Webhook secret generation per task/workflow
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).
- Settings → Tasks section (CRUD, schedule builder, budget config)
- Schedule builder: preset crons + custom 5-field cron + timezone selector
- BYOK provider routing for personal tasks
tasks.personal_require_byokconfig key (prevent fallthrough to org providers)- Output modes: channel (default), note, webhook
- Task notification booleans:
notify_on_complete(default false),notify_on_failure(default true) - Tasks sidebar section with status indicators (✓/✗/⏳/▶)
- "Run Now" button for manual trigger
- 3–5 optional starter templates (news digest, stock screener, standup prep, etc.)
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_iddimension inuser_model_settings)
Tier 2 — Medium value:
- Memory compaction: summarize old memories, confidence decay, prune low-confidence
capability_matchrouting policy ("cheapest model with tool_calling")- New provider types registrable via config file (OpenAI-compatible + custom schema)
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_sourcein list responses. Per-provider model preferences→ scheduled v0.28.0.user_model_settingsunique key is(user_id, model_id)— same model from different providers shares one visibility toggle. Needsprovider_config_iddimension in DB constraint, store, API, and frontendhiddenModelskeying. Frontend composite key (configId:modelId) already exists inApp.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(done in v0.17.0) (currently uses directUpdateDocumentStorageKey()toKnowledgeBaseStoreinterfacedatabase.DB.ExecContextin handler — works but bypasses store layer)
Memory — Future
Memory compaction→ scheduled v0.28.0Memory 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.0SQLite backend option (single-user / dev)→ v0.17.1Helm 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