unify k8s naming: drop be/fe split, single switchboard deployment
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 2m0s
CI/CD / test-sqlite (push) Successful in 2m35s
CI/CD / build-and-deploy (push) Successful in 30s

- k8s/backend.yaml → k8s/switchboard.yaml (already renamed)
- Deployment/Service name: switchboard-be → switchboard
- Removed component:backend labels (single image, no component split)
- Ingress: all paths route to switchboard service on :8080
- CI: updated manifest render, apply, and rollout references
- Removed stale extractor sidecar and extraction env vars
- Updated CHANGELOG and ROADMAP with CI fixes and design decisions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 12:45:14 +00:00
parent 23a30cc6a8
commit 2dabbca5ed
5 changed files with 43 additions and 76 deletions

View File

@@ -673,7 +673,7 @@ jobs:
envsubst < k8s/storage-pvc.yaml > /tmp/storage-pvc.yaml envsubst < k8s/storage-pvc.yaml > /tmp/storage-pvc.yaml
fi fi
envsubst < k8s/backend.yaml > /tmp/backend.yaml envsubst < k8s/switchboard.yaml > /tmp/switchboard.yaml
envsubst < k8s/middleware-retry.yaml > /tmp/middleware-retry.yaml envsubst < k8s/middleware-retry.yaml > /tmp/middleware-retry.yaml
envsubst < k8s/ingress.yaml > /tmp/ingress.yaml envsubst < k8s/ingress.yaml > /tmp/ingress.yaml
@@ -687,7 +687,7 @@ jobs:
echo " ⚠ STORAGE_CLASS not set — file storage disabled" echo " ⚠ STORAGE_CLASS not set — file storage disabled"
fi fi
kubectl apply -f /tmp/backend.yaml kubectl apply -f /tmp/switchboard.yaml
# Traefik retry middleware (v0.28.8) — requires RBAC for traefik.io CRDs. # Traefik retry middleware (v0.28.8) — requires RBAC for traefik.io CRDs.
# First-time setup: kubectl apply -f k8s/rbac-traefik.yaml (cluster admin) # First-time setup: kubectl apply -f k8s/rbac-traefik.yaml (cluster admin)
@@ -718,14 +718,14 @@ jobs:
SUFFIX: ${{ steps.setup.outputs.DEPLOY_SUFFIX }} SUFFIX: ${{ steps.setup.outputs.DEPLOY_SUFFIX }}
ENV: ${{ steps.setup.outputs.ENVIRONMENT }} ENV: ${{ steps.setup.outputs.ENVIRONMENT }}
run: | run: |
kubectl rollout restart deployment/switchboard-be${SUFFIX} -n ${NAMESPACE} kubectl rollout restart deployment/switchboard${SUFFIX} -n ${NAMESPACE}
kubectl rollout status deployment/switchboard-be${SUFFIX} -n ${NAMESPACE} --timeout=180s kubectl rollout status deployment/switchboard${SUFFIX} -n ${NAMESPACE} --timeout=180s
echo "" echo ""
echo "━━━ Pod Status ━━━" echo "━━━ Pod Status ━━━"
kubectl get pods -n ${NAMESPACE} -l app=switchboard,env=${ENV} kubectl get pods -n ${NAMESPACE} -l app=switchboard,env=${ENV}
READY=$(kubectl get deployment switchboard-be${SUFFIX} -n ${NAMESPACE} -o jsonpath='{.status.readyReplicas}') READY=$(kubectl get deployment switchboard${SUFFIX} -n ${NAMESPACE} -o jsonpath='{.status.readyReplicas}')
if [[ "${READY:-0}" -gt 0 ]]; then if [[ "${READY:-0}" -gt 0 ]]; then
echo "✅ Healthy: ${READY} pods ready" echo "✅ Healthy: ${READY} pods ready"

View File

@@ -23,6 +23,14 @@ Forked from chat-switchboard v0.38.5. Gutted to a pure extension platform.
filters, retention, workspace filters, retention, workspace
- **29 handler files**, 6 test files, ~44K lines total - **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 — `envsubst` was producing empty strings
- CI deploy: image var (`BE_IMAGE``IMAGE`) — caused `InvalidImageName` in pods
- CI rollout: deployment name (`switchboard``switchboard-be`) — rollout
verification was looking for wrong deployment name
### Changed ### Changed
- Module renamed: `chat-switchboard``switchboard-core` - Module renamed: `chat-switchboard``switchboard-core`

View File

@@ -6,6 +6,16 @@ Fork of chat-switchboard, gutted to a pure extension platform. All AI/chat
features removed from the kernel. What remains is the minimum viable features removed from the kernel. What remains is the minimum viable
platform that extensions build on. 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 (in progress) ### Phase 0 (in progress)
| Step | Status | Description | | Step | Status | Description |
@@ -18,8 +28,8 @@ platform that extensions build on.
| 6. Fix tests | ✅ | 8 test packages pass, ~12K stale test lines pruned | | 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 | | 7. Frontend gut | ✅ | Shell + SDK only, 50+ files of chat/notes/projects code removed |
| 8. New ICD | 🔧 | Stub in place, full kernel-only spec TBD | | 8. New ICD | 🔧 | Stub in place, full kernel-only spec TBD |
| 9. CI/CD + Dockerfile | ✅ | Single unified image, FE/BE split removed, DB names updated | | 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 + tag | | Deploy, verify, tag v0.1.0 | | 10. Smoke test + tag | 🔧 | Deploy passes CI, verify health + ingress routing, tag v0.1.0 |
## v0.2.0 — SDK & Triggers ## v0.2.0 — SDK & Triggers
@@ -33,6 +43,14 @@ SDK stabilization, and the first rebuilt extension (tasks).
- **Theme tokens** exposed to extensions - **Theme tokens** exposed to extensions
- **Task extension**: first proof-of-concept — full task system rebuilt as a - **Task extension**: first proof-of-concept — full task system rebuilt as a
Starlark extension using triggers + ext_data + notifications Starlark extension using triggers + ext_data + notifications
- **Settings override model**: RBAC controls scope auth (admin → global,
team-admin → team, user → personal). `user_overridable` flag on each setting
controls whether lower scopes can override higher. Resolution order:
user → team → global (first non-null wins, walking up if overridable).
Extension manifests declare `user_overridable` per setting key.
- **Default surface routing**: `/` redirects to configurable default surface.
No surfaces installed → admin surface is default. First surface installed
becomes default. Changeable in admin settings.
## v0.3.0 — Editor Surface ## v0.3.0 — Editor Surface

View File

@@ -13,7 +13,7 @@
# #
# BASE_PATH is empty for prod, "/test" or "/dev" for others. # BASE_PATH is empty for prod, "/test" or "/dev" for others.
# Backend handles BASE_PATH via r.Group(cfg.BasePath). # Backend handles BASE_PATH via r.Group(cfg.BasePath).
# Frontend entrypoint injects BASE_PATH into nginx + HTML. # Single unified image serves both API and static assets.
# ============================================ # ============================================
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
@@ -36,36 +36,11 @@ spec:
- host: "${DEPLOY_HOST}" - host: "${DEPLOY_HOST}"
http: http:
paths: paths:
# API routes → backend # All traffic → switchboard (unified image)
- path: ${BASE_PATH}/api
pathType: Prefix
backend:
service:
name: switchboard-be${DEPLOY_SUFFIX}
port:
number: 8080
# Health check → backend
- path: ${BASE_PATH}/health
pathType: Prefix
backend:
service:
name: switchboard-be${DEPLOY_SUFFIX}
port:
number: 8080
# WebSocket → backend (must be Prefix, not Exact — Traefik's Exact
# doesn't reliably win over Prefix rules in the same Ingress resource)
- path: ${BASE_PATH}/ws
pathType: Prefix
backend:
service:
name: switchboard-be${DEPLOY_SUFFIX}
port:
number: 8080
# Everything else under this prefix → frontend
- path: ${BASE_PATH}/ - path: ${BASE_PATH}/
pathType: Prefix pathType: Prefix
backend: backend:
service: service:
name: switchboard-fe${DEPLOY_SUFFIX} name: switchboard${DEPLOY_SUFFIX}
port: port:
number: 80 number: 8080

View File

@@ -1,6 +1,6 @@
# k8s/backend.yaml # k8s/switchboard.yaml
# ============================================ # ============================================
# Switchboard Core - Backend Deployment # Switchboard Core - Deployment
# ============================================ # ============================================
# Secrets: # Secrets:
# switchboard-db-credentials - POSTGRES_USER, POSTGRES_PASSWORD # switchboard-db-credentials - POSTGRES_USER, POSTGRES_PASSWORD
@@ -16,8 +16,6 @@
# STORAGE_CLASS - StorageClass for PVC (e.g. "cephfs") # STORAGE_CLASS - StorageClass for PVC (e.g. "cephfs")
# STORAGE_SIZE - PVC size (e.g. "10Gi" for PVC, "1Gi" for S3) # STORAGE_SIZE - PVC size (e.g. "10Gi" for PVC, "1Gi" for S3)
# STORAGE_BACKEND - "pvc" or "s3" (default: "pvc") # STORAGE_BACKEND - "pvc" or "s3" (default: "pvc")
# EXTRACTION_CONCURRENCY - Max concurrent extractions (default "3")
# EXTRACTOR_IMAGE - Sidecar image (LibreOffice headless)
# #
# S3 secrets (Gitea Secrets — only when STORAGE_BACKEND=s3): # S3 secrets (Gitea Secrets — only when STORAGE_BACKEND=s3):
# S3_ENDPOINT - e.g. "http://minio:9000" or Ceph RGW URL # S3_ENDPOINT - e.g. "http://minio:9000" or Ceph RGW URL
@@ -32,28 +30,25 @@
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: switchboard-be${DEPLOY_SUFFIX} name: switchboard${DEPLOY_SUFFIX}
namespace: ${NAMESPACE} namespace: ${NAMESPACE}
labels: labels:
app: switchboard app: switchboard
component: backend
env: ${ENVIRONMENT} env: ${ENVIRONMENT}
spec: spec:
replicas: ${BE_REPLICAS} replicas: ${REPLICAS}
selector: selector:
matchLabels: matchLabels:
app: switchboard app: switchboard
component: backend
env: ${ENVIRONMENT} env: ${ENVIRONMENT}
template: template:
metadata: metadata:
labels: labels:
app: switchboard app: switchboard
component: backend
env: ${ENVIRONMENT} env: ${ENVIRONMENT}
spec: spec:
containers: containers:
- name: backend - name: switchboard
image: ${IMAGE}:${IMAGE_TAG} image: ${IMAGE}:${IMAGE_TAG}
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
@@ -121,10 +116,6 @@ spec:
value: "${STORAGE_BACKEND}" value: "${STORAGE_BACKEND}"
- name: STORAGE_PATH - name: STORAGE_PATH
value: "/data/storage" value: "/data/storage"
- name: EXTRACTION_MODE
value: "sidecar"
- name: EXTRACTION_CONCURRENCY
value: "${EXTRACTION_CONCURRENCY}"
# S3 storage (optional — only used when STORAGE_BACKEND=s3) # S3 storage (optional — only used when STORAGE_BACKEND=s3)
- name: S3_ENDPOINT - name: S3_ENDPOINT
valueFrom: valueFrom:
@@ -191,29 +182,6 @@ spec:
timeoutSeconds: 5 timeoutSeconds: 5
failureThreshold: 3 failureThreshold: 3
# Extractor sidecar (v0.12.0 Phase 2):
# Uncomment when switchboard-extractor image is built.
# See DESIGN-0.12.0.md — Phase 2: Extraction Pipeline.
#
# - name: extractor
# image: ${EXTRACTOR_IMAGE}:${IMAGE_TAG}
# imagePullPolicy: Always
# env:
# - name: STORAGE_PATH
# value: "/data/storage"
# - name: EXTRACTION_CONCURRENCY
# value: "${EXTRACTION_CONCURRENCY}"
# volumeMounts:
# - name: storage
# mountPath: /data/storage
# resources:
# requests:
# memory: "256Mi"
# cpu: "100m"
# limits:
# memory: "1Gi"
# cpu: "1000m"
volumes: volumes:
- name: storage - name: storage
persistentVolumeClaim: persistentVolumeClaim:
@@ -222,16 +190,14 @@ spec:
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: switchboard-be${DEPLOY_SUFFIX} name: switchboard${DEPLOY_SUFFIX}
namespace: ${NAMESPACE} namespace: ${NAMESPACE}
labels: labels:
app: switchboard app: switchboard
component: backend
env: ${ENVIRONMENT} env: ${ENVIRONMENT}
spec: spec:
selector: selector:
app: switchboard app: switchboard
component: backend
env: ${ENVIRONMENT} env: ${ENVIRONMENT}
ports: ports:
- protocol: TCP - protocol: TCP