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/CHANGELOG.md
Jeffrey Smith 70678cb352
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 4s
CI/CD / test-go-pg (pull_request) Failing after 2m18s
CI/CD / test-sqlite (pull_request) Successful in 2m40s
CI/CD / build-and-deploy (pull_request) Has been skipped
Feat default surface routing + fix startup hang (#4)
Default surface routing (v0.2.1):
- `/` redirects to configurable default surface with fallback chain:
  configured → first enabled extension surface → /admin
- Auto-sets default_surface on first extension surface install
- Admin settings UI: Default Surface dropdown
- disabledRedirect() and extension surface disabled redirect now go to
  /admin instead of / to prevent redirect loops

Fix Gin route param conflict causing backend startup hang:
- Team package settings routes used `:pkgId` while sibling routes used
  `:id` — Gin's radix tree entered infinite loop on conflicting param
  names. Unified to `:id`.

Docker entrypoint hardening:
- Health check timeout 10s → 60s
- Stale backend process cleanup on restart
- Crash detection (exit early if backend dies)

Roadmap direction updates:
- v0.3.0: Notes surface (Obsidian-style) replaces Editor surface
- v0.4.0: MVP (was v0.5.0) — chat moved to post-MVP
- No built-in auto-install — explicit install only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 19:38:02 +00:00

7.7 KiB
Raw Blame History

Changelog

All notable changes to Switchboard Core are documented here.

[Unreleased] — v0.2.1

Added

  • Default surface routing: / redirects to configurable default surface. Fallback chain: configured default → first enabled extension surface → /admin. First installed extension surface auto-becomes default. Admin can change via Settings > Default Surface dropdown.
  • default_surface global config key (JSON {"id": "slug"})
  • Admin settings UI: Default Surface dropdown (extension surfaces only)

Changed

  • disabledRedirect() now redirects to /admin instead of / to prevent redirect loops when the default surface is disabled
  • Disabled extension surfaces (/s/:slug) redirect to /admin instead of /

Fixed

  • Gin route param conflict causing backend startup hang: team-scoped package settings routes used :pkgId while sibling routes used :id. Gin's radix tree entered an infinite loop on the conflicting param names. Unified to :id across all /teams/:teamId/packages/ routes.
  • Docker entrypoint: increased health check timeout (10s → 60s), added stale process cleanup and crash detection to prevent zombie backends on restart

[v0.2.0] — 2026-03-26

Added

  • Full RBAC: all authorization flows through group membership and permission grants. No magic roles, no implicit group membership, no special-casing.
  • surface.admin.access permission — any group can grant admin panel access
  • Admins system group seeded with all platform permissions
  • Everyone system group — all users explicitly added on creation
  • EnsureEveryoneGroup(), AddToAdminsGroup(), RemoveFromAdminsGroup() helpers
  • SeedAdminsGroupMember(), SeedEveryoneGroupMember() test helpers
  • System groups re-seeded after TruncateAll in test helper
  • OIDC isIdPAdmin() — maps IdP role claims to Admins group membership
  • Settings cascade: three-tier resolution (global → team → user) with user_overridable flag per manifest setting key. Admins can lock settings that team admins and users cannot override.
  • package_team_settings table for team-scoped package setting overrides
  • Team admin API: GET/PUT/DELETE /api/v1/teams/:teamId/packages/:pkgId/settings
  • RunContext.TeamID for team-aware Starlark settings resolution
  • store.ResolveSettings() / store.FilterOverridableKeys() pure functions
  • store.ParseSettingsSchema() extracts user_overridable from manifests

Changed

  • RequireAdmin() / RequireAdminPage() check surface.admin.access grant
  • RequirePermission() no longer bypasses for admin role
  • ResolvePermissions() unions explicit group memberships only (no implicit Everyone)
  • All user creation paths (builtin, OIDC, mTLS, admin, bootstrap, seed) add to Everyone group. Admin users added to Admins group.
  • JWT claims no longer include role field
  • Login response no longer includes role in user object
  • Profile endpoint no longer returns role
  • Profile bootstrap resolves permissions from groups (no admin shortcut)
  • Middleware auth cache tracks isActive only (no role)
  • Admin create user accepts is_admin bool (not role string)
  • Admin update role endpoint accepts is_admin bool, manages Admins group directly
  • Demotion/deletion safeguards check Admins group member count
  • Notifications RoleFallbackHandler queries Admins group members
  • OIDC syncs Admins group on login (no role column writes)
  • Kernel permissions: 6 → 7 (added surface.admin.access)
  • Admin users UI: role dropdown removed, admin managed through groups
  • Starlark settings.get() uses cascade resolver instead of naive merge
  • User settings save (POST /extensions/:id/settings) strips non-overridable keys

Removed

  • users.role column — dropped from schema, model, JWT, all handlers
  • UserRoleAdmin, UserRoleUser constants
  • CountByRole() store method
  • DefaultRole config for OIDC and mTLS providers
  • SyncAdminsGroupMembership() (replaced by AddToAdminsGroup/RemoveFromAdminsGroup)
  • OIDC resolveRole() (replaced by isIdPAdmin())
  • Token budgets from groups: columns, ResolveTokenBudget(), all store/handler/UI
  • Allowed models from groups: column, ResolveModelAllowlist(), UI
  • Admin groups UI: Token Budgets section, Allowed Models section

Migration notes

  • 001_core.sql (both dialects): removed role column from users table
  • 002_teams.sql (both dialects): added Admins group seed, removed token_budget_daily, token_budget_monthly, allowed_models columns
  • No new migration files — edited in place per pre-MVP policy

[v0.1.0] — 2026-03-26

Forked from chat-switchboard v0.38.5. Gutted to a pure extension platform.

Removed

  • AI/Chat system: providers, model catalog, routing policies, personas, channels, messages, completion streaming, tool loop, compaction, memory, knowledge bases, notes, workspaces, projects, folders, files, export/import
  • Task scheduler: entire scheduler package, task store, task handlers. Tasks will be rebuilt as a Starlark extension with three trigger primitives (time, webhook, event)
  • Session system: channel-based anonymous sessions. Workflow instances will get new storage in v0.2.0
  • Health accumulator: provider health windows, tool health tracking. Replaced with kernel-only Prune (ws_tickets, rate_limit_counters, presence)
  • 15 Go packages: tools, compaction, extraction, roles, mentions, notelinks, export, memory, knowledge, providers, routing, capabilities, filters, retention, workspace
  • 29 handler files, 6 test files, ~44K lines total

Fixed

  • CI deploy: k8s resource quantity vars (BE_MEMORY_REQUESTMEMORY_REQUEST) aligned with CI workflow outputs — envsubst was producing empty strings
  • CI deploy: image var (BE_IMAGEIMAGE) — caused InvalidImageName in pods
  • CI rollout: deployment name (switchboardswitchboard-be) — rollout verification was looking for wrong deployment name
  • Nginx BASE_PATH: regex cache-header locations intercepted static asset requests before alias could strip the sub-path prefix — moved inside alias block
  • Post-login blank page: dead Go template references (surface-chat, surface-notes, surface-projects) caused html/template to silently produce Content-Length: 0 responses
  • Login branding: "Chat Switchboard" → "Switchboard Core", updated tagline and feature pills to reflect platform pivot

Changed

  • Module renamed: chat-switchboardswitchboard-core
  • VERSION: 0.1.0
  • Default DB name: switchboard_core
  • Fresh migrations: 9 files × 2 dialects (postgres + sqlite), 27 tables
  • Store interfaces: 40 → 20 (13 in interfaces.go + 7 in separate iface files)
  • Stage modes: chat_only removed, custom added
  • Task output modes: channel|note|webhooknotification|webhook|log
  • Kernel permissions: 16 → 6 (extension.use, extension.install, workflow.create, workflow.submit, admin.view, token.unlimited)
  • Everyone group seed: ["extension.use","workflow.submit"]
  • Global settings seed: site name "Switchboard Core"
  • Config: removed 7 dropped fields (SessionExpiryDays, WorkflowStaleHours, ProviderAutoDisableThreshold, ExtractionConcurrency, etc.)
  • Health stores rewritten: kernel-only Prune for stale tickets, counters, presence
  • Maintenance goroutine replaces scheduler for background cleanup

Retained

  • Identity & auth (builtin, mTLS, OIDC)
  • Teams, groups, permissions
  • Package system (surfaces, extensions, libraries, workflows)
  • Starlark sandbox with capability-gated modules
  • Extension connections & dependencies
  • Workflow definitions, stages, versions
  • Notifications & preferences
  • Audit log
  • Object storage (PVC, S3)
  • WebSocket hub & presence
  • Multi-replica HA (ws_tickets, rate_limit_counters)
  • Frontend shell (preact+htm, SDK, vendor libs)