Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Failing after 1m56s
CI/CD / test-sqlite (pull_request) Successful in 2m47s
CI/CD / build-and-deploy (pull_request) Has been skipped
Drop chat-era columns (persona_id, history_mode) from workflow_stages. Rename transition_rules → stage_config. Add audience, stage_type, starlark_hook, branch_rules columns. Update stage_mode CHECK to (form, review, delegated, automated). All Go stores, handlers, routing engine, Starlark module, and frontend editors updated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
17 KiB
17 KiB
Switchboard Core — Roadmap
Current: v0.2.0 — SDK & Triggers
Fork of chat-switchboard, gutted to a pure extension platform. All AI/chat features removed from the kernel. What remains is the minimum viable platform that extensions build on.
Retained kernel capabilities
- Auth: builtin (simple), mTLS, OIDC
- Identity: users, teams, groups, permissions (RBAC)
- Packages: surfaces, extensions, libraries, workflows
- Starlark sandbox: capability-gated modules
- Storage: object storage (PVC, S3), ext_data tables
- Realtime: WebSocket hub, presence, multi-replica HA
- Ops: audit log, notifications, maintenance goroutine
Phase 0 (complete)
| Step | Status | Description |
|---|---|---|
| 1. Module rename | ✅ | chat-switchboard → switchboard-core |
| 2. Delete packages | ✅ | 15 Go packages, 29 handler files removed |
| 3. Gut stores/models | ✅ | 40 → 20 store interfaces, kernel-only models |
| 4. Fresh migrations | ✅ | 9 files × 2 dialects, 27 tables |
| 5. Fix compilation | ✅ | go build ./... clean, 300+ stale route lines cut |
| 6. Fix tests | ✅ | 8 test packages pass, ~12K stale test lines pruned |
| 7. Frontend gut | ✅ | Shell + SDK only, 50+ files of chat/notes/projects code removed |
| 8. New ICD | ✅ | Full OpenAPI 3.0.3 spec — 160 operations across 22 tag groups |
| 9. CI/CD + Dockerfile | ✅ | Single unified image, FE/BE split removed, DB names updated, k8s var alignment fixes (resource quantities, image name, rollout deployment name) |
| 10. Smoke test | ✅ | K8s deploy live at switchboard.gobha.ai/test, nginx BASE_PATH fixed, login→admin flow verified, branding updated |
v0.2.x — SDK & Triggers
The contract that extensions build against. Three trigger primitives, SDK stabilization, and the first rebuilt extension (tasks).
v0.2.0 — RBAC + Settings Cascade (complete)
| Step | Status | Description |
|---|---|---|
| Admin → RBAC group | ✅ | surface.admin.access permission + Admins system group replaces role == "admin" checks. Admin bypass removed from permission middleware. |
| Settings cascade | ✅ | user_overridable flag, three-tier resolution (global → team → user), team settings API |
| ✅ | Shipped with settings cascade above |
v0.2.1 — Default Surface + ICD
| Step | Status | Description |
|---|---|---|
| Default surface routing | ✅ | / redirects to configurable default surface. No surfaces → admin. First install becomes default. Changeable in admin settings. |
| ICD (API contract) | ✅ | Full OpenAPI 3.0.3 spec — 160 operations, 22 tag groups, reusable component schemas. Served at /api/docs. |
v0.2.2 — Event Bus + Triggers
| Step | Status | Description |
|---|---|---|
| Event bus subscriptions | ✅ | Extensions register event patterns in manifest. Wired via bus.Subscribe() on startup. Async handler invocation. |
| Webhook triggers | ✅ | Inbound HTTP at /api/v1/hooks/:package_id/:slug. HMAC-SHA256 verification. Synchronous Starlark handler response. |
| Scheduled tasks | ✅ | User-created cron tasks with restricted sandbox (no raw HTTP, no DB table creation). Runs as creator identity. Templates from extensions. Dedicated schedules API. |
| Trigger admin API | ✅ | CRUD for triggers + schedules. Enable/disable, execution logs, per-package listing. |
v0.2.3 — SDK + Task Extension
| Step | Status | Description |
|---|---|---|
| SDK stabilization | ✅ | sw.api.ext(), sw.storage, sw.theme.tokens, sw.ui, sw.slots, sw.actions — six new SDK modules for extension development |
| Task extension | ✅ | Full task surface rebuilt as Starlark extension: CRUD API, kanban/list views, event triggers, webhook integration, notifications on completion |
v0.2.4 — Shell Navigation + Schedules
| Step | Status | Description |
|---|---|---|
| SDK Topbar | ✅ | sw.shell.Topbar — composable navigation bar (title + extension slot + bell + user menu). Surfaces get consistent nav for free. |
| Schedules surface | ✅ | New packages/schedules/ wrapping kernel cron API. Table view, cron preview, enable/disable, manual run, execution logs. |
| Manifest icons | ✅ | icon field in manifest.json (emoji). Surfaces API returns icon. UserMenu renders per-surface icons. |
| UserMenu cleanup | ✅ | Removed dead Chat/Notes/Projects links. Menu driven by surfaces API. Core surfaces filtered. |
| isAdmin RBAC fix | ✅ | can.js isAdmin() now checks surface.admin.access grant instead of deprecated role column. |
v0.2.5 — UI Polish + Dead Code Audit
| Step | Status | Description |
|---|---|---|
| UI bug pass | ✅ | Reviewed admin, settings, login, welcome surfaces in light/dark themes. Fixed settings crash (models API undefined). Removed dead chat settings from both user and admin settings. |
| Dead code sweep | ✅ | Removed ~700 lines: orphaned CSS, dead Go types, stale event code, unused test helpers, dead settings UI (chat defaults, system prompt, default model, policies, web search, compaction, memory). |
| Template cleanup | ✅ | Removed stale CSS link tags and orphaned chat-pane.html. Updated doc comments throughout. |
| Package proof-of-concept status | ✅ | Created README.md for tasks + schedules with graduation criteria. Added missing manifest icons. |
| Welcome surface | ✅ | New fallback surface when no extensions installed. Topbar + welcome card with admin link. Replaces /admin as final redirect target. |
| Default surface routing | ✅ | Resolution chain: user preference → global config → first extension → /welcome. Users can set personal default in Settings > General. Admin sets global default in Admin > Settings. |
| Admin navigation | ✅ | Replaced Back button with UserMenu in admin topbar. Eliminates back-button infinite loop. |
v0.2.6 — Admin Settings Audit
| Step | Status | Description |
|---|---|---|
| Admin settings E2E | ✅ | All 7 admin settings sections verified (default surface, registration, banner, message bar, footer, vault, email). Dead code removed: sectionCategory() pruned of AI/routing/channel vestiges, PublicSettings() stripped of chat-era fields (system_prompt, retention_ttl, paste_to_file, allow_user_personas), dead PolicyDefaults removed (allow_raw_model_access, default_model), dead policy lookups removed (kb_direct_access), test seed data cleaned. |
| Packages surface | ✅ | Package list loads (17 total/17 enabled), type filters work, enable/disable visible, settings/export buttons present, core package (admin) protected. Removed dead chat from CORE_IDS. |
v0.2.7 — User Settings Audit
| Step | Status | Description |
|---|---|---|
| User settings E2E | ✅ | All 6 user settings sections verified (General, Appearance, Profile, Teams, Connections, Notifications). Dead code removed: BYOK nav section + state, personas gate filter, Message Font Size slider, auth.permissions.changed listener. localStorage key renamed cs-appearance → sb-appearance with one-time migration. |
| Visibility gating | ✅ | Dead BYOK/personas policy lookups removed from bootstrap and permissions handlers. allow_user_byok removed from PublicSettings. PolicyDefaults cleaned of allow_user_byok and allow_user_personas. Dead msgFont early-apply removed from base template. Stale policy-gating test assertions replaced. No empty nav sections remain. |
v0.2.8 — Team Admin Settings Audit (Pass 1)
| Step | Status | Description |
|---|---|---|
| Team admin E2E | ✅ | Audited team member management, settings cascade, role assignment. Removed dead code: HasPrivateProviderRequirement (BYOK vestige), UserRole on TeamMember (deprecated role column), allow_team_providers policy default, dead personas/providers/models ICD tests. |
| Workflow stage UI cleanup | ✅ | Removed dead personas dropdown, history_mode selector, stale chat_only mode. Updated STAGE_MODES to match backend CHECK constraint (form_only, form_chat, review, custom). Removed stale comments referencing deleted files. |
v0.2.9 — Builtin Extension Retirement
| Step | Status | Description |
|---|---|---|
| Retire builtin seeder | ✅ | Removed SeedBuiltinPackages, seed_packages.go, Dockerfile COPY, and extensions/builtin/ directory. These extensions are dormant until a chat surface exists to consume them. |
| Convert to regular packages | ✅ | Repackaged 6 extensions as standard directories in packages/ with js/ layout and "requires": ["chat"] manifest metadata. Built via build.sh like all other packages. No auto-install — explicit install only. |
v0.3.x — Workflow Architecture
Workflows are the core platform capability. This series implements the full multi-step automation system with team role integration and finalizes the extension lifecycle model.
v0.3.0 — Schema Redesign + Stage CRUD Modernization (complete)
| Step | Status | Description |
|---|---|---|
| Workflow schema redesign | ✅ | Dropped persona_id, history_mode from workflow_stages. Renamed transition_rules → stage_config. Updated stage_mode CHECK to (form, review, delegated, automated). Added audience, stage_type, starlark_hook, branch_rules. Both PG + SQLite. |
| Model + store updates | ✅ | Go structs, constants, and PG/SQLite queries updated. New ValidStageTypes, ValidAudiences maps. Routing engine reads branch_rules directly. |
| Handler + Starlark updates | ✅ | Stage CRUD validation for new fields. Package export/import updated. Hook handler reads stage_config. Starlark module exposes audience, stage_type. |
| Frontend updates | ✅ | Team-admin and admin stage editors updated with new modes, audience selector, stage type selector, conditional Starlark hook input. Fixed admin STAGE_MODES bug. |
v0.3.1 — Instance + Assignment Tables + Store
| Step | Status | Description |
|---|---|---|
| Instance schema | ⬚ | Add workflow_instances table to 007_workflows.sql (PG + SQLite). Tracks execution state: workflow_version, current_stage, stage_data, status, entry_token. |
| Assignment schema | ⬚ | Add workflow_assignments table. Per-stage queue: instance_id, stage, team_id, assigned_to, status, review_data. Optimistic claim lock. |
| Models + store interface | ⬚ | WorkflowInstance, WorkflowAssignment structs. Store methods for instance lifecycle (Create, Get, Advance, Complete, Cancel, MarkStale) and assignments (Create, Claim, Unclaim, Complete). |
| Event types | ⬚ | Add workflow.started, workflow.cancelled, workflow.sla.warning, workflow.sla.breached, workflow.error to bus. |
v0.3.2 — Workflow Engine + Handlers
| Step | Status | Description |
|---|---|---|
| Stage execution engine | ⬚ | server/workflow/engine.go — advance lifecycle: validate → merge data → fire hooks → resolve next → create assignments → emit events. |
| Automated stages | ⬚ | server/workflow/automated.go — fire Starlark hook, auto-advance, cycle guard (max 10 consecutive). |
| Instance handlers | ⬚ | HTTP API: Start, GetInstance, Advance, Cancel, ListInstances. |
| Assignment handlers | ⬚ | HTTP API: Claim, Unclaim, Complete, Cancel, ListByTeam, ListMine. |
| Starlark module expansion | ⬚ | workflow.get_instance(), workflow.advance(), etc. |
v0.3.3 — Public Entry + Background Jobs
| Step | Status | Description |
|---|---|---|
| Public entry | ⬚ | StartPublic, ResumePublic, AdvancePublic — token-based anonymous workflow participation. |
| SLA scanner | ⬚ | Periodic goroutine checking active instances. Fire events + notifications on breach. |
| Staleness sweep | ⬚ | Mark idle instances as stale after configurable timeout. |
v0.3.4 — Team Roles + Multi-party Validation
| Step | Status | Description |
|---|---|---|
| Team roles | ⬚ | Expand team_members.role beyond admin/member. Role-based stage assignment rules. |
| Multi-party sign-off | ⬚ | 2-party validation at stage boundaries. |
| Extension lifecycle | ⬚ | Define permanent vs PoC packages. Graduation criteria. |
| Trigger composition | ⬚ | How triggers, schedules, and workflows compose. Design doc. |
v0.3.5 — Settings Audit + ICD + Tests
| Step | Status | Description |
|---|---|---|
| Settings audit pass 2 | ⬚ | Validate team admin + user settings for workflow/team-role changes. |
| Integration tests | ⬚ | Full instance lifecycle coverage. |
| ICD update | ⬚ | OpenAPI spec with all new endpoints. |
| Clone endpoint | ⬚ | POST /api/v1/workflows/:id/clone — deep copy workflow + stages. |
v0.4.0 — Notes Surface
Obsidian-style rich-text notes rebuilt as an installable surface package. Zero platform special-casing. Proves the full extension stack E2E.
- Notes as
.pkgarchive - Rich text editor (ProseMirror or similar)
- Folder tree, backlinks, tags — all extension-provided
- Markdown import/export
v0.5.0 — MVP
Extension and operations tracks converge. First externally usable release.
- Package registry (browse, install, update, uninstall)
- Package distribution model (no auto-install; explicit install only)
- Health monitoring dashboard
- Backup/restore tooling
- Documentation site
Post-MVP
- Chat extension (provider registry, streaming, personas, tool system)
- Rich media extensions: image generation, code sandbox, STT/TTS
- Desktop app (Tauri or Electron)
- Sidecar tier: container-based extensions
- Federation: cross-instance package sharing
- Plugin marketplace with signing and review
- Mermaid diagrams extension (nice-to-have)
Design Decisions Log
| Decision | Rationale |
|---|---|
| Tasks → extension | Scheduler was the most entangled kernel component (~3,400 lines). Rebuilding as extension validates the trigger system and removes the worst compilation debt. Three trigger primitives (time, webhook, event) replace the monolithic scheduler. |
| Sessions removed | Channel-based sessions coupled to deleted chat system. Workflow instances need new storage model — either ext_data tables or a dedicated kernel table. |
chat_only → custom |
Stage mode chat_only implied chat as a kernel concept. Renamed to custom which delegates to a surface package, proving extension composability. |
| Providers removed from kernel | Provider configs, model catalog, routing policies — all moved to extension track. Kernel provides credential storage (connections) and the Starlark provider.complete module as the interface. |
| Kernel permissions simplified | From 16 chat-centric permissions to 6 platform permissions. Extensions define their own capability requirements in manifests. |
| Preact+htm retained | 3KB runtime, no build step, works for extension authors without bundler config. KISS. |
| Single Docker image | Drop the frontend/backend split. Go binary + assets + migrations in one image. Simpler deployment, fewer moving parts. |
| Admin → RBAC group | The role column is pre-RBAC. v0.2.0 replaces it with a seeded "Admins" group + surface.admin.access grant. All users auto-join "Everyone" group. Admin middleware becomes a grant check, not a role check. |
| Settings cascade | RBAC controls scope auth (who can set at what level). user_overridable flag controls whether lower scopes can override higher. Two orthogonal axes, composes cleanly with extension manifests. |
| No new migrations pre-MVP | Edit existing migration SQL files in place. No migration chains until schema is in production. |
| Notes over Editor | First surface is Obsidian-style notes (rich text, folders, backlinks) instead of a code editor. Notes is a stronger E2E proof — it exercises ext_data, storage, and the SDK more fully than a pure-browser CM6 editor. |
| No built-in auto-install | Extensions ship in the repo but are not auto-installed. Distribution model TBD — explicit install only. Keeps the kernel clean and avoids opinionated defaults. |
| Chat → post-MVP | Chat extension (providers, streaming, personas) is valuable but not MVP-critical. The platform must prove itself with simpler surfaces first. Chat moves to post-MVP track. |
| Two trigger tiers | Event + webhook triggers are extension-declared (manifest contract, full sandbox). Scheduled tasks are user-created ad-hoc (restricted sandbox — no raw HTTP, no DB table creation, connections-only outbound). Separation keeps extension contracts static and user automation safe. |
| Scheduled task identity | Tasks run as their creator (RBAC-scoped). Admin-created tasks can opt into system context. Creator deactivation pauses the schedule. Ensures audit trail and permission boundaries. |