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/TURNOVER.md
Jeffrey Smith b9180d4184
All checks were successful
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Has been skipped
CI/CD / test-go-pg (push) Has been skipped
CI/CD / test-sqlite (push) Has been skipped
CI/CD / build-and-deploy (push) Has been skipped
phase 0 complete: turnover doc, roadmap + changelog updated
Phase 0 (Steps 1-10) is done. Codebase gutted from ~800 files/100K+
lines to 462 files/75K lines. K8s deploy live, CI green, login→admin
verified. Main should be protected — all future work via PRs.

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

4.7 KiB

Switchboard Core — Session Turnover

Date: 2026-03-26 Author: Jeffrey Smith (jasafpro@gmail.com) Session: Platform pivot gut — Phase 0 completion


What Was Done

Phase 0 (Steps 1-10) — COMPLETE

Forked from chat-switchboard v0.38.5, gutted all AI/chat features, rebranded as Switchboard Core — a pure extension platform kernel.

By the numbers:

  • Started: ~800 files, ~100K+ lines
  • Now: 462 files, ~75K lines
  • Removed: ~44K lines of chat/notes/projects/provider code
  • 15 Go packages deleted, 29 handler files removed
  • Store interfaces: 40 → 20
  • Kernel permissions: 16 → 6

Key commits this session:

  • Steps 5-8: deep gut of code, build clean, tests pass
  • Step 9: single Docker image CI/CD, drop FE/BE split
  • Step 10: K8s deploy live, nginx BASE_PATH fixes, login→admin verified
  • Branding: "Chat Switchboard" → "Switchboard Core"

Deployment state:

  • CI: Green on Gitea Actions (build + test + deploy)
  • K8s: switchboard.gobha.ai/test — live in gobha-ai-switchboard namespace
  • DB: Postgres connected, schema at 009_ha.sql
  • Storage: PVC (S3 keys not configured yet)
  • Old namespace: gobha-ai-chat — stale ingresses cleaned up

Known Issues

  1. Frontend test job: Some gutted chat/model/channel tests were removed but the FE test suite may have remaining stale references
  2. Traefik middleware: rbac-traefik.yaml needs one-time manual apply by cluster admin for retry middleware (non-blocking)
  3. SEED_USERS: Not set in K8s secrets — no initial admin user created on the test deployment. Set in Gitea secrets to bootstrap.
  4. Editor modules: src/editor/*.mjs files still reference "Chat Switchboard" — these are CodeMirror build files, low priority

What's Next

Protect main (DO NOW)

Phase 0 is complete. Main should be protected. All future work via PRs.

v0.2.0 — First PRs

PR 1: Admin → RBAC group migration

  • Add surface.admin.access to permissions table
  • Seed "Admins" group with that grant
  • Seed "Everyone" group, auto-member all users
  • Change admin middleware: role check → grant check
  • Edit existing migration SQL files in place (no new migrations pre-MVP)

PR 2: Settings cascade

  • Add user_overridable flag to settings schema
  • RBAC controls scope auth (admin → global, team-admin → team, user → personal)
  • user_overridable controls whether lower scope can override higher
  • Resolution: user → team → global (first non-null wins)

PR 3: ICD (API contract)

  • Generate full OpenAPI spec from registered routes
  • Document kernel-only endpoints
  • Mark extension API surface

PR 4: Trigger system

  • Time triggers (cron)
  • Webhook triggers (inbound HTTP)
  • Event triggers (bus subscription)
  • Extensions register match expressions at install

PR 5: SDK stabilization

  • sb.slots(), sb.actions, sb.api.ext(), sb.storage
  • Theme tokens exposed to extensions
  • Primitive UI components (toast, confirm, prompt, dialog)

Architecture Decisions (this session)

Decision Detail
No new migrations pre-MVP Edit existing SQL files in place. Schema isn't in production.
Admin → RBAC group role column replaced by "Admins" group + grant.
Settings: two axes RBAC = who can change at what scope. user_overridable = can lower scope override. Orthogonal.
Default surface No surfaces → admin is default. First installed becomes default. Configurable.
Protect main after Step 7+ Destructive surgery done on main. Additive work (ICD, triggers) goes through PRs.
Single Docker image nginx + Go binary + static assets + migrations. One image, one deployment.

File Locations

What Where
Roadmap ROADMAP.md
Changelog CHANGELOG.md
CI workflow .gitea/workflows/ci.yaml
K8s manifests k8s/ (switchboard.yaml, ingress.yaml, storage-pvc.yaml)
Docker compose (local dev) docker-compose.yml (SQLite, port 3000)
Nginx template nginx.conf.template
Entrypoint docker-entrypoint.sh
Migrations server/migrations/postgres/, server/migrations/sqlite/
Go backend server/
Frontend shell src/
Templates server/pages/templates/
Memory (Claude) .claude/projects/-config-Projects-core/memory/

Gitea Secrets/Vars Needed

Secrets: POSTGRES_USER, POSTGRES_USER_PASSWORD, POSTGRES_ADMIN_USER, POSTGRES_ADMIN_PASSWORD, ENCRYPTION_KEY

Vars: DOMAIN, NAMESPACE, S3_BUCKET, S3_ENDPOINT, STORAGE_BACKEND, STORAGE_CLASS, STORAGE_SIZE

Not yet configured: S3_ACCESS_KEY, S3_SECRET_KEY (using PVC for now), SEED_USERS (needed for initial admin bootstrap)