Three-tier settings resolution (global → team → user) with per-key user_overridable flag in package manifests. Admins can lock settings that team admins and users cannot override. - Add package_team_settings table (migration 010) - Add GetTeamSettings/SetTeamSettings/DeleteTeamSettings to PackageStore - Add ResolveSettings, ParseSettingsSchema, FilterOverridableKeys - Rewrite Starlark settings.get() to use cascade resolver - Add TeamID to RunContext for team-aware resolution - Enforce user_overridable on user settings save - Add team package settings API (GET/PUT/DELETE) - 12 unit tests for cascade resolution Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.6 KiB
6.6 KiB
Changelog
All notable changes to Switchboard Core are documented here.
[Unreleased] — v0.2.0
Added
- Full RBAC: all authorization flows through group membership and permission grants. No magic roles, no implicit group membership, no special-casing.
surface.admin.accesspermission — 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()helpersSeedAdminsGroupMember(),SeedEveryoneGroupMember()test helpers- System groups re-seeded after
TruncateAllin test helper - OIDC
isIdPAdmin()— maps IdP role claims to Admins group membership - Settings cascade: three-tier resolution (global → team → user) with
user_overridableflag per manifest setting key. Admins can lock settings that team admins and users cannot override. package_team_settingstable for team-scoped package setting overrides- Team admin API:
GET/PUT/DELETE /api/v1/teams/:teamId/packages/:pkgId/settings RunContext.TeamIDfor team-aware Starlark settings resolutionstore.ResolveSettings()/store.FilterOverridableKeys()pure functionsstore.ParseSettingsSchema()extractsuser_overridablefrom manifests
Changed
RequireAdmin()/RequireAdminPage()checksurface.admin.accessgrantRequirePermission()no longer bypasses for admin roleResolvePermissions()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
rolefield - Login response no longer includes
rolein user object - Profile endpoint no longer returns
role - Profile bootstrap resolves permissions from groups (no admin shortcut)
- Middleware auth cache tracks
isActiveonly (no role) - Admin create user accepts
is_adminbool (not role string) - Admin update role endpoint accepts
is_adminbool, manages Admins group directly - Demotion/deletion safeguards check Admins group member count
- Notifications
RoleFallbackHandlerqueries 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.rolecolumn — dropped from schema, model, JWT, all handlersUserRoleAdmin,UserRoleUserconstantsCountByRole()store methodDefaultRoleconfig for OIDC and mTLS providersSyncAdminsGroupMembership()(replaced byAddToAdminsGroup/RemoveFromAdminsGroup)- OIDC
resolveRole()(replaced byisIdPAdmin()) - 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
rolecolumn from users table - 002_teams.sql (both dialects): added Admins group seed, removed
token_budget_daily,token_budget_monthly,allowed_modelscolumns - 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_REQUEST→MEMORY_REQUEST) aligned with CI workflow outputs —envsubstwas producing empty strings - CI deploy: image var (
BE_IMAGE→IMAGE) — causedInvalidImageNamein pods - CI rollout: deployment name (
switchboard→switchboard-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-switchboard→switchboard-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_onlyremoved,customadded - Task output modes:
channel|note|webhook→notification|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)