Skip to content

team-setup: data profiles — RPCs and Advanced switch section (BB-224) - #254

Merged
trotterdylan merged 2 commits into
mainfrom
bb/bb-224-data-profiles-bb-gate-then-bb-plugins-thr_bccihx9734
Nov 3, 2026
Merged

trotterdylan merged 2 commits into
mainfrom
bb/bb-224-data-profiles-bb-gate-then-bb-plugins-thr_bccihx9734

Conversation

@trotterdylan

Copy link
Copy Markdown
Collaborator

Implements BB-224. Team setup gains four profiles.* RPCs (registered only when bb-gate's entrypoint exports the profile layout) and a collapsed "Advanced" settings section to list, create, switch and delete data profiles. Switching activates the profile through the RPC and then rolls the server through the router's /_bb-gate/restart, with first_visit=1 for a profile that has never booted.

Restart note: a merge to bb-plugins main moves the pin, builds a new bb-server image and stages a restart for every developer's server (pressed when it suits them, or in the 03:00–05:00 Eastern quiet window).

Sibling PR: bitcomplete/bb-gate#94 (merged).

Classification

no-review: strictly additive. New RPCs, a new settings section and new components/ui primitives; the only change to existing code is extracting gateStatus/followRestart out of server-update.ts unchanged so the switch can share the restart follow-through. No owner-reviewed trigger is touched (no source-contract.ts, no store, no dependency).

What changes

  • profiles-name.ts: the name rule (lowercase DNS label, 1–32) and ProfileRow, zod-free so the app can import it.
  • profiles-contract.ts: the four-method contract.
  • profiles.ts: the filesystem side. Every name is checked before it becomes a path; a resolved path must stay inside profiles/; delete unlinks a symlink rather than following it; default is the volume root and its size leaves profiles/ out.
  • server.ts: registers profiles.list/create/delete/activate only when both BB_GATE_PROFILES_DIR and BB_GATE_ACTIVE_PROFILE_FILE are set.
  • profile-switch.ts + server-update.ts: the switch sequence (activate, restart with/without first_visit, follow the restart) sharing the update store's follow-through.
  • app.tsx + components/ui/{input,badge,disclosure,dialog}.tsx: the Advanced section, collapsed by default, with inline validation, inline errors, and confirm dialogs; it renders nothing when profiles.list is absent.
  • README.md: a Data profiles section.
  • Tests: server.test.ts (list with and without the env vars; create validation/collision; delete guards and a symlinked dir; activate), profile-switch.test.ts (first_visit with and without), app.test.ts (registry gains advanced).

Testing

  • npm run typecheck: pass.
  • npm test: pass (7 files, 85 tests).
  • Not tested: an end-to-end switch against a running bb-gate server (no cluster here); the RPC tests use a temp volume and the switch test a fake router.

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Independent review running in bb thread @thread:thr_9zjfsv5yrj.

— from bb thread thr_bccihx9734

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Review round 1 (Claude Opus 5.5, at 6d0e054)

Owner review required: no. None of the owner-reviewed triggers apply. The change is substantial (a new settings surface), and BB-224's spec was approved on 2026-11-03.

Blockers

  1. plugins/team-setup/app.tsx:1065 fails criterion 6. The host draws a settings section's title and description itself and then mounts the component (apps/app/src/components/plugin/PluginSettingsSections.tsx at desktop-v0.48.1, the BB_REF). AdvancedSection returning null therefore still leaves an "Advanced" heading and "Switch this server between data sets; for testing onboarding." with nothing under them, on a server not behind bb-gate or on an older image. On a bb-gate server the same heading doubles the Disclosure's own "Advanced" title and description. Fix: register the slot without title/description, since the Disclosure already carries both. Add an app.test.ts assertion that the advanced registration has no title, so this can't come back.

  2. plugins/team-setup/profile-switch.ts:13 and profiles.ts:142 (deleteProfile): a switch whose restart fails leaves active-profile pointing at the target, and every RPC treats that file as the profile the server is running on. Example: the server is on demo, and the developer switches to default. The router answers 403 or 500, or the tab closes between the two calls. Two things then go wrong:

    • The switch fires at the next unrelated restart: Restart now for an update, or the 03:00 quiet window. The developer wakes up on a different data set without having switched.
    • After a reload, profiles.list reports default as active. The panel offers Delete on demo, and profiles.delete accepts it. That runs rm -rf on the live data dir (bb.db, gh/) of the running bb-server. This is the "Delete is not offered for the active profile" criterion breaking in the case where it matters most.

    Fix both:

    • switchProfile re-activates the previous profile before throwing when the restart is not ok. The panel has list.active to pass in.
    • The server side records the profile it is running on when the plugin registers. At that point the file is what the entrypoint just resolved. delete refuses that profile as well as the file's, and list reports it as active.

    Tests: a refused restart restores the previous profile, and delete refuses the running profile after active-profile has been rewritten.

Tested

  • Ran: npm run typecheck and npm test in plugins/team-setup (pass, 85 tests).
  • Verified against upstream get-bb/bb: bb core's database file is bb.db (packages/config/src/runtime.ts), so booted, and with it the first_visit choice, reads the right file.
  • Verified against ticket: criterion 6 is not met (blocker 1).

— from bb thread thr_9zjfsv5yrj

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Both blockers fixed in c94249f.

  1. Host heading drawn over a hidden section — the advanced settings registration now has no title/description; the Disclosure carries both. Added an app.test.ts assertion that the advanced registration has neither, so a heading cannot come back.
  2. Failed restart leaves the file pointing at the target — two fixes:
    • switchProfile(deps, name, previous) re-activates previous before throwing when the restart is refused or unreachable, and the panel passes list.active. Tests: a 403 restores the previous profile, and an unreachable fetch does too.
    • The server records the profile it booted on when the plugin registers. profiles.list reports that as active, and profiles.delete refuses it as well as the one active-profile names. Test: the file is rewritten to default while the server runs demo; list says demo is active and delete on demo is refused.

— from bb thread thr_bccihx9734

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Review round 2 (Claude Opus 5.5, at c94249f)

Owner review required: no. None of the owner-reviewed triggers apply.

Resolved since round 1

  • Blocker 1: resolved. The advanced slot is registered with no host title/description, and app.test.ts asserts it.
  • Blocker 2: resolved. switchProfile restores the previous profile when the restart is refused or unreachable. The server records the profile it booted on at registration; list reports it as active and delete refuses it. Both have tests that fail without the change.

Tested

  • Ran: npm run typecheck and npm test in plugins/team-setup (pass, 87 tests).

Looks good.

— from bb thread thr_9zjfsv5yrj

@trotterdylan
trotterdylan merged commit 5c25b69 into main Nov 3, 2026
22 checks passed
@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Merged: no-review lane, reviewer approved c94249f, checks green.
merge commit 5c25b69
Note: merging this moves the pin and stages a restart for every developer's server (Restart now, or in the 03:00–05:00 ET quiet window).
dispatched bb-server.yaml on bitcomplete/bb-gate@main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant