# 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..` — 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–v0.27.5 Foundation → Extensions → Surfaces → Auth ✅ → Workflows → Tasks → Team Tasks (see CHANGELOG.md for full history) │ v0.28.0 Platform Polish ├─ v0.28.1 Surfaces ICD audit ✅ ├─ v0.28.2 ICD audit — all domains ✅ ├─ v0.28.3 ICD close-out + FE decomp ✅ ├─ v0.28.4 Security tier (red team) ✅ ├─ v0.28.5 Frontend SDK + Pipes ✅ │ (switchboard-sdk.js, pipe/filter │ pipeline, component mounting) ├─ v0.28.6 Infrastructure │ (virtual scroll, Helm, task webhook │ UI, system tasks, model prefs) └─ v0.28.7 Unified Packaging + Task RBAC (.pkg archive, manifest.type, task permission gate pre-Starlark) │ v0.29.0 Starlark Sandbox (eval loop, permissions, admin UI — adds starlark capability to .pkg) │ v0.29.1 API Extensions (Starlark route handlers, outbound HTTP, requires_provider) │ v0.29.2 DB Extensions (namespaced tables, scoped db module, declarative schema in manifest) │ v0.29.3 Workflow Forms (form_template → real UI, LLM optional, .star validation, structured data) │ v0.30.0 Package Lifecycle (schema versioning, migrations, settings extension point, export/import, marketplace) │ v0.30.1 SDK Adoption (sw.notes factory, core surface migration, fix-once-fix-everywhere) │ v0.30.2 Workflow Packages (stage surfaces, custom UI per stage, team admin workflow builder) │ v0.31.0 Editor Package (E2E proof: rebuild editor as installable .pkg, zero platform special-casing) ``` --- ## v0.28.0 — Platform Polish Audit arc, frontend decomposition, security, and infrastructure improvements. ### v0.28.1 — Surfaces ICD Audit ✅ - [x] ICD `surfaces.md` corrected (6 discrepancies: field name, archive format, response shape) - [x] Surface ID slug validation + `extractableRelPath` install hardening - [x] 19 E2E surface CRUD tests in ICD runner (install, enable/disable, delete, error paths) - [x] 22 handler-level tests + 14 store-level tests (PG + SQLite) - [x] CI timeout 8m → 12m for PG integration tests ### v0.28.2 — ICD Audit: All Domains ✅ Full audit of every ICD document against code. Goal: ICD becomes the single source of truth. After this version, the workflow is ICD-first — update the contract before changing code. **Methodology:** Read ICD → grep all source → trace route → handler → store (PG + SQLite) → tests → enforce `{"data": [...]}` envelope convention → fix ICD → fix code → fix runner → CI green. Final pass picks up straggling failures across all domains. **Final score: 469/469 (100%)** **Completed audits:** *Notifications (cs0):* - [x] Notifications ICD audit: object shape, query params, response envelopes, WS events - [x] Notification type enum sync: remove aspirational types, add implemented types (`kb.ready`, `kb.error`, `grant.changed`, `task.budget_exceeded`) - [x] Implement `memory.extracted` notification (hook in memory extractor) - [x] Implement `user.mentioned` persisted notification (was WS-only) - [x] Implement `workflow.claimed` persisted notification (was WS-only) - [x] Remove dead `NotifTypeProjectInvite` constant - [x] `GET /notifications/preferences` — envelope fix (`missing key "preferences"`) *Knowledge (cs1–cs4):* - [x] `knowledge.md` corrected: KB object shape (6 field mismatches), search envelope (`data` not `results`), search result fields, status progression (`extracting` step), file type support (text-only, not binary), auth annotations - [x] Test harness: add `RequirePermission` on `POST /knowledge-bases` and `POST /:id/documents`, add missing `GET /:id/documents/:docId/status` and `DELETE /:id/documents/:docId` routes - [x] New tests: document status polling, document delete, update-empty-body 400, permission denial for non-privileged user - [x] P0 fix: `SetDiscoverable` authorization — `loadAndAuthorize` + owner/admin check, audit log, cross-user security tests (cs2) - [x] `ListDiscoverableKBs` response normalization — use `toKBResponse()`, shape assertion test (cs3) - [x] Dead code removal: `ListGlobal`/`ListForTeam` on KnowledgeBaseStore — interface + PG + SQLite (cs4) - [x] Move `CreateKB` team role check from raw `database.DB.QueryRow` to `stores.Teams.IsTeamAdmin`; remove `database` import (cs4) - [x] Team-scoped KB creation test: member denied, team admin succeeds (cs4) *Profile (cs5):* - [x] `profile.md` corrected: avatar API (was `multipart/form-data`, actually JSON base64), response shapes for all 7 endpoints, auth annotations, field table - [x] P0 fix: `GET /settings` returns bare object → wrapped in `{"settings": {...}}` - [x] `profileResponse` shape: add `last_login_at` field + dialect-safe time scan (`database.ST()` / `database.SNT()`), COALESCE guard on settings column - [x] Integration test harness: register all 7 profile/settings routes (was only `GET /profile`), remove stale `/avatar` route aliases - [x] New `profile_test.go`: GET profile shape, PUT profile (display_name, email, duplicate email 409), GET/PUT settings envelope, password change (success, wrong current 401, too short 400), avatar delete *Workspaces (cs6):* - [x] `workspaces.md` corrected: workspace object shape (added `indexing_enabled`, `git_*` fields, `total_bytes` not `storage_bytes`, `owner_type` full enum), file entry shape (`is_directory`/`size_bytes` not `is_dir`/`size`), git status full shape, git log envelope (`{"data": [...]}`), git commit request (`paths` not `files`), archive format query param, auth annotations, all response shapes - [x] P0 fix: `GET /workspaces` returns bare array → `{"data": [...]}` - [x] P0 fix: `GET /git-credentials` returns bare array → `{"data": [...]}` - [x] Fix: `GET .../git/log` returns bare array → `{"data": [...]}` + nil slice guard - [x] New `workspace_test.go`: List empty envelope, list with data + shape, root_path not exposed, user isolation, GET by ID shape, not found 404, forbidden 403, git-credentials empty envelope, auth required (11 tests) *Projects (cs7):* - [x] `projects.md` full rewrite: 6 categories of drift (ghost fields, missing fields, request shapes, association objects, `omitempty` on computed counts) - [x] 14 new Go tests: CRUD shapes, 201 status, envelope, admin list, auth, isolation - [x] P0 nil guard: `ListByProject` files `null` → `[]` - [x] P0: `ListTeamProviderModels` missing `Type` field — Venice 400 fix - [x] ICD runner projects rewritten 9 → 19 tests - [x] ICD runner tier-providers: SSE parser, model exclusion, ID fallback fixes ### v0.28.3 — ICD Close-out + Frontend Decomposition Prep ICD straggler sweep (rolled in from v0.28.2 tail) and frontend decomposition groundwork. **ICD close-out (cs0):** - [x] `websocket.md` full rewrite: event envelope field (`event` not `type`), payload shapes for 11 event types, routing table from code, room model documented as planned-not-implemented - [x] `auth.md` corrected: login response shape (added `token_type`/`expires_in`, removed phantom fields), register admin-approval path - [x] `enums.md` corrected: added missing `queued` task run status - [x] Presence status gap documented (DB allows `away`, runtime emits only `online`/`offline`) - [x] VERSION, CHANGELOG, ROADMAP updated **WebSocket delivery fix (cs1):** - [x] `workflow.claimed`, `workflow.advanced`, `workflow.completed` use room-scoped `Bus.Publish()` but rooms are never joined — events never reach WebSocket clients. Convert to `SendToUser()` per channel participant (same pattern as `message.created`, `workflow.assigned`). **Frontend decomposition:** - [x] JS dependency audit: `docs/JS-DEPENDENCY-AUDIT.md` — full map of 47 files, 431 globals, cross-file call graph, script load order per surface - [x] IIFE extraction: all 47 JS files wrapped, ~168 functions privatized, zero implicit globals remain. Explicit `window.*` exports on every file. - [x] Cross-file coupling fix: `events.js` no longer reads `_storageKey` from `api.js` — uses `API.accessToken` instead - [ ] ICD runner gains test tiers: `crud`, `envelope`, `security`, `sdk` - [ ] Runner coverage target: 100% of ICD-documented endpoints have at least one test - [x] Phase 2: onclick → addEventListener migration (143 dynamic → 5 unconvertible, 163 data-action delegated via `_uiDispatch` on document.body) - [x] Phase 3: Action registry (`sb.js`) — 248 `window.*` exports replaced with `sb.register()`/`sb.ns()`. `sb.resolve()` centralized dispatch. `sb.call()` template bridge ready for Go template migration. - [x] Phase 3b: Go template onclick → `sb.call()` migration (72 handlers across 10 templates, 4 unconvertible inline DOM ops, 3 standalone pages excluded) - [x] Phase 4: ES module conversion — IIFE wrappers removed from all 47 files, `