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/ROADMAP.md
Jeffrey Smith 2abf406db8
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Successful in 5s
CI/CD / test-go-pg (push) Successful in 2m36s
CI/CD / test-sqlite (push) Successful in 2m43s
CI/CD / build-and-deploy (push) Successful in 1m19s
Feat v0.5.0 realtime dialog (#30)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-03-30 11:07:27 +00:00

38 KiB
Raw Blame History

Switchboard Core — Roadmap

Current: v0.5.0 — Realtime Primitive + Dialog Audit + Permissions UI

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-switchboardswitchboard-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
Settings override model 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-appearancesb-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_rulesstage_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 (complete)

Step Status Description
Instance schema workflow_instances table in 007_workflows.sql (PG + SQLite). Tracks execution state: workflow_version, current_stage, stage_data, status, entry_token.
Assignment schema 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. 15 store methods for instance lifecycle and assignments across PG + SQLite.
Event types workflow.started, workflow.cancelled, workflow.error added to bus route table.

v0.3.2 — Workflow Engine + Handlers (complete)

Step Status Description
Store tests Round-trip tests for all 15 v0.3.1 store methods (instance + assignment CRUD). TruncateAll updated for new tables.
Stage execution engine server/workflow/engine.go — Start, Advance (with branch_rules), Cancel. Merges stage_data, creates assignments, emits 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. Team-scoped mirrors.
Assignment handlers HTTP API: Claim, Unclaim, Complete, Cancel, ListByTeam, ListMine. Claimer identity verification.
Starlark module expansion workflow.get_instance(), workflow.list_instances() (read-only). Mutating builtins deferred pending interface extraction.

v0.3.3 — Public Entry + Background Jobs (complete)

Step Status Description
Public entry StartPublic, ResumePublic, AdvancePublic — token-based anonymous workflow participation. Public routes at /api/v1/public/workflows/. Audience-gated: only public stages can be advanced anonymously.
SLA scanner Background goroutine (5-min interval) checking active instances against per-stage sla_seconds. Fires workflow.sla_breach event, marks breach in instance metadata (idempotent).
Staleness sweep Per-workflow staleness_timeout_hours column. Scanner marks idle instances as stale, cancels open assignments, fires workflow.stale event.

v0.3.4 — Team Roles + Multi-party Validation (complete)

Step Status Description
Team roles Removed CHECK constraint on team_members.role. Custom roles stored in teams.settings["roles"]. Team roles API (GET/PUT /teams/:teamId/roles). Role-based stage assignment via stage_config.required_role. Frontend: dynamic role selects, role management panel.
Multi-party sign-off workflow_signoffs table (both dialects). StageConfig.validation with required_approvals, required_role, reject_action. Engine validation gate in advanceInternal. SubmitSignoff engine method. Signoff HTTP API (POST/GET /instances/:iid/signoffs). Frontend signoff panel in monitor tab.
Extension lifecycle Design doc: docs/DESIGN-EXTENSION-LIFECYCLE.md. Permanent vs PoC classification, graduation criteria, install model.
Trigger composition Design doc: docs/DESIGN-TRIGGER-COMPOSITION.md. Triggers/schedules can start workflows, workflows emit events, no circular invocation.

v0.3.5 — Settings Audit + ICD + Tests

Step Status Description
Clone endpoint POST /api/v1/workflows/:id/clone — deep copy workflow + stages. Handler-level composition of existing store methods.
Integration tests 7 engine-level tests in workflow_engine_test.go: full lifecycle, branch routing, public entry, signoff gate, rejection, cancel-clears-assignments, error cases. 28 total tests.
Settings audit pass 2 Added staleness_timeout_hours field to workflow editor. Added collapsible branch_rules JSON editor in stage form.
ICD update Fixed stale Workflow/Stage schemas. Added WorkflowInstance, WorkflowAssignment, WorkflowSignoff schemas. Added ~20 new endpoints: instances, assignments, signoffs, public entry, clone, team roles.

v0.3.6 — Example Workflows + Interactive Demo

Four installable .pkg workflow packages that prove the engine works end-to-end, plus a demo surface for guided exploration. See docs/DEMO-WORKFLOWS.md for full stage definitions and Starlark code.

Step Status Description
Bug Report Triage Public entry, progressive fieldsets, severity-based branch routing, team assignment, SLA timer. Pure-manifest .pkg.
Employee Onboarding Starlark automated stages (db.insert, notifications.send), signoff gate with required_role, rejection reroute. .pkg with script.star.
Content Approval Multi-party signoff (quorum of 2), rejection reroute creating review cycle. .pkg demonstrating signoff + reroute loop.
Webhook Notifier Starlark http.post + connections.get for outbound webhooks, delivery logging to ext_data. Proves HTTP + connections modules.
Demo surface Browser-tier walkthrough: workflow cards, stage diagrams, Starlark viewer, "Try It" buttons, API curl examples. Auto-installed, removable.
Engine context fix Add started_by to automated stage Starlark context dict (backward-compatible).
SLA package installer Added sla_seconds support to workflowPkgStage struct and install/export paths.
Snapshot format fix parseSnapshotStages helper handles both wrapped and legacy snapshot formats.
Workflow adoption POST /teams/:teamId/workflows/:id/adopt + GET .../available. Team-admin "Adopt Global" button. TeamID in WorkflowPatch.
Extension SDK boot base.html loads Preact globals + boot() for extension surfaces (was missing since Scorched Earth IV).
Admin teams tab fix Extract .data from paginated response in admin teams list.
Documentation docs/DEMO-WORKFLOWS.md: feature capability matrix, stage flows, API walkthrough, per-package READMEs.
Review pass Docker E2E walkthrough: install all packages, adopt into team, activate, publish, run each workflow end-to-end. Fix remaining UI/UX issues.

v0.3.7 — Package Audit (complete)

Verified all 16 packages install correctly. Packages with unmet requires auto-set to dormant.

Step Status Description
Manifest fixes Fixed 6 chat-extension manifests ("name""title", was blocking install). Added explicit "type": "surface" to hello-dashboard, icd-test-runner, sdk-test-runner.
Dormant status Added dormant to packages.status CHECK constraint (both dialects). Installer auto-detects unmet requires and sets status=dormant, enabled=false. Enable endpoint returns 409 for dormant packages.
Functional audit Navigated to every surface in browser. 7 working: schedules, tasks, team-activity-log, git-board, hello-dashboard, icd-test-runner, sdk-test-runner. 2 broken: dashboard + editor (depend on removed sw.* imperative SDK) — tagged requires: ["legacy-sdk"] → dormant.
Chat-dependency tagging 6 chat-dependent extensions (csv-table, diff-viewer, js-sandbox, katex-renderer, mermaid-renderer, regex-tester) install as dormant. git-board and gitea-client are standalone.
Dependency check fix Relaxed library dependency validation to allow pending_review libraries (gitea-client declares permissions). Only suspended/dormant libraries blocked.
Admin UI Dormant badge, disabled Enable button with tooltip, Dormant stat card in admin packages view.
Tests 4 handler tests (SetStatus dormant, enable blocked, surfaces exclude dormant, admin list includes dormant). All existing tests pass.

v0.3.8 — Distribution

Builder image for faster builds, bundled packages for zero-config first run.

Step Status Description
Builder image Dockerfile.builder with cached Go modules + Node vendor libs for faster custom builds.
Bundled packages Dockerfile stage builds all 12 non-dormant packages into production image. InstallBundledPackages auto-installs on first run (skip-if-present). SKIP_BUNDLED_PACKAGES=true to disable. BUNDLED_PACKAGES allowlist for selective install (Helm/K8s). Migration 012 adds bundled source to CHECK constraint.
Distribution docs docs/DISTRIBUTION.md — quick start, bundled packages, builder image, custom builds, production deployment.
Tests 6 handler tests (fresh install, skip existing, missing dir, empty dir, dormant handling, allowlist filtering). All existing tests pass.

v0.4.x — Notes Surface

Obsidian-style notes rebuilt as an installable surface package. Zero platform special-casing. Proves the full extension stack E2E.

v0.4.0 — Core Notes CRUD + Markdown Editor

Step Status Description
Package scaffold packages/notes/ with manifest, script.star, JS, CSS, README. Type: full, tier: starlark.
Notes CRUD backend Starlark on_request() — list, create, get, update, delete, search, stats. Lightweight list projection (no body).
Notes table ext_notes_notes — title, body (TEXT), folder_id, pinned, archived, creator_id, updated_at.
Markdown editor Preact+htm frontend: sidebar note list, title input, markdown textarea, auto-save (1s debounce).
Live preview Inline markdown renderer (~100 lines): headings, bold, italic, code, links, lists, blockquotes, hr.
Search Client-side LIKE search over title/body. Search bar in sidebar.
Pin/archive Pin notes to top, soft-delete via archive, hard delete with ?hard=1.

v0.4.1 — Folders + Navigation Tree (complete)

Step Status Description
Folders table ext_notes_folders — name, parent_id, creator_id, sort_order. Indexed on parent_id and creator_id.
Folder CRUD API 5 Starlark handlers: list, create, update, delete folders + POST /notes/move. Delete cascade orphans notes and reparents child folders.
Folder tree UI FolderTree + FolderNode components. Flat-to-tree builder, expand/collapse, depth indentation, inline rename via context menu.
Folder filtering Click folder → filter notes. "All Notes" / "Unfiled" virtual views. New notes inherit active folder.
Editor folder select Dropdown with nested hierarchy ( prefix). Moves notes between folders via move-note API.
Updated stats Stats include unfiled and folders counts.

v0.4.2 — Tags + Search (complete)

Step Status Description
Tags table ext_notes_tags — note_id, tag. Indexed on both columns for bidirectional lookup.
Tag CRUD API 3 Starlark handlers: list all unique tags, get tags for note, replace tags for note (delete+reinsert). Tags normalized: lowercase, trimmed, deduped.
Tags in list/get/search _list_notes batch-fetches all tags in one query, attaches tags array to each item. _get_note includes tags. _search_notes matches against tags.
Tag cascade delete Hard-deleting a note also deletes its tag rows. Stats include tags count.
Tag input in editor TagInput component: removable pills + text field, comma/Enter to add, autocomplete dropdown from all tags.
Tag pills on cards NoteCard renders up to 3 tag pills with "+N" overflow.
Tag filter in sidebar TagFilter component: clickable pills, toggle active tag, client-side note filtering.
Drag-and-drop NoteCard is draggable. FolderNode, "All Notes", and "Unfiled" are drop targets. Uses existing move-note API.
Folder context menu Replaced prompt() hack with proper right-click popup menu: Add subfolder, Rename, Delete. Positioned at click coordinates, dismissed on outside click.
Step Status Description
Links table ext_notes_links — source_id, target_id, link_text. Indexed on both source_id and target_id for bidirectional lookup.
Wikilink extraction _extract_wikilinks() parses [[...]] using split("[[") + find("]]") (no regex/while in Starlark). Deduplicates by lowercase.
Link sync on save _sync_links() called from _create_note and _update_note. Delete-all + reinsert pattern (matches tags). Resolves titles to note IDs (case-insensitive). Unresolved links stored with target_id="".
Cascade delete Hard-deleting a note removes both outgoing links (source_id) and incoming backlinks (target_id).
Link endpoints GET /links/:note_id (outgoing) and GET /backlinks/:note_id (incoming, enriched with source titles).
Wikilink preview [[Note Title]] rendered as clickable accent-colored links in markdown preview. Unresolved links styled in danger/red.
Wikilink navigation Clicking a resolved wikilink navigates to the target note. Clicking an unresolved (red) link creates the note, navigates to it, and re-saves the source so the link resolves.
Backlinks panel Collapsible panel below editor showing all notes linking to current note. Click to navigate. Hidden when empty.
Stats update /stats includes links count. Notes package version bumped to 0.4.0.

v0.4.4 — Rich Editor + Import/Export (complete)

Step Status Description
CM6 integration Load vendored CodeMirror 6 bundle via dynamic <script> tag. CM.noteEditor() factory with markdown syntax highlighting, wikilink autocomplete, and live preview decorations. Textarea fallback if CM6 unavailable.
Editor wiring EditorPane uses CM6 with onChange → auto-save debounce, onLink → wikilink navigation, linkCompleter → search API autocomplete. Ctrl/Cmd+S force save. Editor fills container via CSS override.
Export as .md Export button in editor header. Downloads note as .md file with YAML frontmatter (title, tags, created). Pure client-side Blob download.
Import .md Import button in topbar. File picker for .md/.markdown/.txt. Parses YAML frontmatter for title and tags. Creates note via API with tags.
Notes package v0.5.0 Manifest version bumped from 0.4.0 → 0.5.0.

v0.4.5 — Editor Modes + Document Outline (complete)

Step Status Description
Default-rendered mode Preview is the initial state on note open. "Edit" button enters CM6. Tri-state viewMode: rendered / edit / split.
Split view Side-by-side layout: CM6 left, rendered preview right. CSS grid two-column in .notes-editor__body--split.
Synced scroll Split mode scroll sync. CM6 scrollDOM scroll listener maps position ratio to preview scrollTop. Linear mapping.
View mode setting editor_mode in manifest settings + localStorage persistence. Toolbar cycles rendered → edit → split.
Document outline parseHeadings() extracts headings (skips code blocks). Collapsible DocumentOutline panel with click-to-scroll (CM6 line dispatch or preview scrollIntoView). Debounced 300ms updates.

v0.4.6 — Sidebar Restructure (complete)

Step Status Description
Sidebar tabs Two-tab header at top of sidebar: "Notes" (folders → tags → search → list) and "Outline" (heading tree for active note). Outline tab enabled only when a note is selected.
Heading tree Nested heading hierarchy (H1 → H2 → H3) with depth indentation. Click → scroll to heading in editor/preview. Current heading highlighted based on scroll position.

v0.4.7 — Note Graph

Step Status Description
Graph API GET /graph endpoint in Starlark — { nodes: [{id, title, folder_id, tags}], edges: [{source, target, text}] }. Full notes + links in one payload.
Graph renderer Canvas force-directed layout. Minimal force simulation (repulsion + attraction + damping). Nodes = circles with title labels, edges = lines. Zoom/pan via wheel + drag. Retina-aware rendering.
Click → focus + filter Single click a node: dims unconnected nodes/edges to 15% opacity. Clicked node + direct neighbors stay full brightness. Edges highlighted in accent color. Click empty space to reset.
Shift+click → chain Shift+click adds a second node to the focus set — union of both neighborhoods visible. Trace thought paths across two hops without losing context.
Double-click → open Double-click navigates to the note and exits graph view, opening the editor with the selected note.
Hover → tooltip Hover shows note title + tag pills + edge count in HTML overlay. No API call — all data in graph payload.
Folder/tag coloring Nodes colored by folder using 10-color palette. Active tag filter dims non-matching nodes to 30% opacity. Stacks with click focus.
Orphan highlighting Zero-edge nodes rendered with dashed stroke. "Hide orphans" checkbox toggle in toolbar.
Entry point "Graph" button in topbar. Replaces editor pane with full graph canvas. Single-click selects note in sidebar; double-click opens editor.

v0.5.x — Realtime + Chat

Communication primitive track. The kernel gains one generic realtime module. Everything else — conversations, messages, participants — is pure extension code. Human-to-human chat ships pre-MVP; LLM participation is post-MVP.

v0.5.0 — Realtime Primitive + Dialog Audit + Permissions UI

Step Status Description
realtime.publish() Starlark module: realtime.publish(channel, event, data). Publishes JSON event to WebSocket hub scoped to channel. Gated by realtime.publish permission. 7KB payload limit. Reserved prefix validation.
WS room protocol room.subscribe / room.unsubscribe client messages intercepted in readPump. Per-connection 100-room cap.
sw.realtime.subscribe() SDK method: sw.realtime.subscribe(channel, [event], callback). Auto room join/leave, reconnect recovery. Returns unsubscribe handle.
sw.ui.Dialog Pre-existing (implemented before v0.5.0). SDK modal primitive with focus trap, Promise-based API.
sw.ui.Confirm / sw.ui.Prompt Pre-existing. sw.confirm() and sw.prompt() already exposed in SDK.
Native dialog audit 5 bare confirm() calls migrated to sw.confirm() in tasks, schedules, notes (×2), editor packages.
Admin permissions UI Permissions drawer in admin Packages page. Grant/revoke per permission, grant-all bulk action. pending_review/suspended status badges. SDK API client methods added. Closes gap identified in v0.4.7.

v0.5.1 — Chat Core Library (planned)

Step Status Description
Library package chat-core library with permissions: ["db.write"]. Private ext_data tables, exported Starlark functions, REST endpoints.
Conversations table conversations — title, type (direct/group), created_by, updated_at.
Participants table participants — conversation_id, participant_id, participant_type (user/bot), display_name, role (member/admin), joined_at.
Messages table messages — conversation_id, participant_id, content, content_type (text/system/file), edited_at.
Read cursors table read_cursors — conversation_id, participant_id, last_read_message_id.
Exported Starlark API chat.create(), chat.send(), chat.history(), chat.add_participant(), chat.remove_participant(), chat.mark_read().
REST endpoints Full CRUD for conversations, messages, participants. Paginated message history. Unread counts.
Realtime integration On chat.send(): insert message, emit chat.message.created event, call realtime.publish("conversation:{id}", "message", data).

v0.5.2 — Chat Surface (planned)

Step Status Description
Conversation list Sidebar: conversation list with last message preview, unread badge, timestamp. Create conversation button.
Message thread Main pane: message history with participant avatars, timestamps, content. Virtual scroll for long threads.
Compose bar Text input with Enter-to-send, Shift+Enter for newline. Markdown support via existing inline renderer.
Participant sidebar Collapsible right panel: participant list with online status (via kernel presence hub). Add/remove participants using sw.ui.Dialog.
1:1 and group Direct messages (two participants) and group conversations. Type field on conversation.
Typing indicators realtime.publish("conversation:{id}", "typing", {participant_id}) on keypress with debounce. Surface shows "X is typing…" with auto-expire.
Read receipts Mark-read on scroll/focus via chat.mark_read(). Unread count in conversation list.
Message editing Edit own messages. edited_at timestamp displayed. Edit via PUT /messages/:id.
Message deletion Soft-delete own messages. Replaced with "message deleted" placeholder.

v0.5.3 — Chat Polish + Integration Testing (planned)

Step Status Description
Conversation search Search across conversation titles and message content.
Message pagination Cursor-based pagination on message history. Scroll-to-load-more in thread view.
Multi-user E2E Docker compose test: multiple browser sessions, verify real-time message delivery, presence indicators, cross-replica broadcast.
Workflow integration Verify: workflow stage with audience: team can create a conversation via chat.create(), add assigned members as participants. Conversation scoped to instance.

v0.5.4 — Package Updates (planned)

Step Status Description
Version comparison Compare installed package version against incoming .pkg version. Semantic version parsing. Skip if same or older.
Schema migration on update Diff declared db_tables against existing ext_data schema. Add new columns, add new tables. No destructive changes (no column drops, no type changes).
Data preservation ext_data tables survive update. Only additive schema changes applied. Settings merged (new keys added, existing preserved).
Update API PUT /api/v1/packages/:id/update — accepts .pkg archive, validates version bump, applies schema diff, replaces code (JS/CSS/Starlark).
Admin UI Update button on package card when newer version available. Version comparison badge. Update confirmation via sw.ui.Confirm.
Rollback story Export package before update (existing export). Document manual rollback: re-install old .pkg. No automatic rollback — KISS.

v0.5.5 — Upgrade Testing (planned)

Step Status Description
Test harness Docker compose environment: build v(current) image, seed data (notes, conversations, tasks, workflows), then upgrade to v(next) image. Verify data integrity post-upgrade.
Schema edge cases Force upgrade scenarios: add column to existing table, add new table, add new index. Verify ext_data migrations apply cleanly without data loss. Throwaway changes — not committed, only bug fixes.
Settings migration Verify settings cascade survives upgrade: global → team → user overrides preserved. New settings keys appear with defaults. Removed keys ignored.
Package compatibility Install older package version, upgrade kernel, verify package still loads. Install newer package version on older kernel, verify graceful failure.
Multi-replica upgrade Rolling upgrade in K8s: old and new replicas coexist briefly. Verify WebSocket hub handoff, no message loss, no split-brain on ext_data writes.

v0.6.0 — MVP

Extension, communication, and operations tracks converge. First externally usable release.

  • Health monitoring (extension package wrapping kernel /health)
  • Backup/restore tooling (ext_data export/import, admin surface)
  • Documentation site (extension authoring guide, API reference, deployment guide)

Post-MVP

  • LLM participation (llm-bridge extension: subscribes to chat.message.created, calls provider.complete(), streams response via realtime.publish, posts via chat.send(). Bot participants with persona config. Multi-model conversations.)
  • 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_onlycustom 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 as extension, not kernel Human-to-human chat built entirely as library + surface packages. Zero kernel awareness of conversations, messages, or participants. Kernel gains one generic realtime module. Proves near-infinite extensibility. LLM participation layers on top via a separate bridge extension — the chat system doesn't know or care whether a participant is human or AI.
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.