carlos / platform Public

merge: multi-account — accounts as projects, memberships, account-scoped app identity

Console-minted durable account ids in the bucket (registry materializes,
never assigns), owner/member memberships replacing per-app grants,
account-scoped bucket keys behind a legacy read-fallback, Stripe-like
switcher with MRU landing and keymail invites, and migration as a verb.

Two adversarial review rounds found four real defects: accounts migrate
would have copied stale legacy pointers and silently rolled production
back; the console's activity feed leaked across accounts sharing an app
name; the activator returned account sqids as versions for migrated
tenants; and the bake clock was account-blind. All fixed with red-first
tests. Lands inert: no accounts exist yet, every key is legacy, and the
fallback carries the live fleet unchanged until the operator migrates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 68d6a91cccb8ae93ea5a1c3e0335b46b841741e1 parent 0b8caeaparent 0b7c3dc
45 files changed, +5399 −752
  • README.md +84 −6
  • accounts.go +549 −0
  • cli.go +34 −8
  • cmd/console/main.go +77 −1
  • cmd/console/main_test.go +106 −0
  • e2e_test.go +586 −25
  • internal/activator/activator_test.go +32 −0
  • internal/activator/backend_exec.go +12 −11
  • internal/activator/backend_unit.go +4 −11
  • internal/activator/backend_unit_test.go +8 −0
  • internal/console/account.go +101 −0
  • internal/console/account_test.go +404 −0
  • internal/console/keymail_test.go +18 −2
  • internal/console/migrate_test.go +107 −0
  • internal/console/server.go +473 −142
  • internal/console/server_account_test.go +355 −0
  • internal/console/server_test.go +161 −140
  • internal/console/store.go +631 −12
  • internal/console/store_test.go +4 −4
  • internal/console/templates/app.html +17 −4
  • internal/console/templates/apps.html +43 −5
  • internal/console/templates/layout.html +20 −1
  • internal/console/view.go +47 −16
  • internal/console/view_test.go +13 −13
  • internal/domains/reconcile.go +214 −112
  • internal/domains/reconcile_test.go +122 −27
  • internal/edge/static.go +20 −6
  • internal/edge/static_test.go +5 −5
  • internal/registry/registry.go +125 −24
  • internal/registry/registry_test.go +180 −14
  • internal/release/adopt.go +42 −19
  • internal/release/adopt_test.go +116 −17
  • internal/release/bake.go +42 −10
  • internal/release/bake_test.go +101 −26
  • internal/release/fallback.go +85 −0
  • internal/release/fallback_test.go +190 −0
  • internal/release/release.go +87 −24
  • internal/release/release_test.go +34 −34
  • internal/release/versions.go +39 −10
  • internal/release/versions_test.go +6 −6
  • internal/status/fleet.go +14 −4
  • internal/status/status_test.go +67 −0
  • internal/vet/vet.go +13 −5
  • internal/vet/vet_test.go +7 −7
  • main.go +4 −1
README.md

Loading diff…

accounts.go

Loading diff…

cli.go

Loading diff…

cmd/console/main.go

Loading diff…

cmd/console/main_test.go

Loading diff…

e2e_test.go

Loading diff…

internal/activator/activator_test.go

Loading diff…

internal/activator/backend_exec.go

Loading diff…

internal/activator/backend_unit.go

Loading diff…

internal/activator/backend_unit_test.go

Loading diff…

internal/console/account.go

Loading diff…

internal/console/account_test.go

Loading diff…

internal/console/keymail_test.go

Loading diff…

internal/console/migrate_test.go

Loading diff…

internal/console/server.go

Loading diff…

internal/console/server_account_test.go

Loading diff…

internal/console/server_test.go

Loading diff…

internal/console/store.go

Loading diff…

internal/console/store_test.go

Loading diff…

internal/console/templates/app.html

Loading diff…

internal/console/templates/apps.html

Loading diff…

internal/console/templates/layout.html

Loading diff…

internal/console/view.go

Loading diff…

internal/console/view_test.go

Loading diff…

internal/domains/reconcile.go

Loading diff…

internal/domains/reconcile_test.go

Loading diff…

internal/edge/static.go

Loading diff…

internal/edge/static_test.go

Loading diff…

internal/registry/registry.go

Loading diff…

internal/registry/registry_test.go

Loading diff…

internal/release/adopt.go

Loading diff…

internal/release/adopt_test.go

Loading diff…

internal/release/bake.go

Loading diff…

internal/release/bake_test.go

Loading diff…

internal/release/fallback.go

Loading diff…

internal/release/fallback_test.go

Loading diff…

internal/release/release.go

Loading diff…

internal/release/release_test.go

Loading diff…

internal/release/versions.go

Loading diff…

internal/release/versions_test.go

Loading diff…

internal/status/fleet.go

Loading diff…

internal/status/status_test.go

Loading diff…

internal/vet/vet.go

Loading diff…

internal/vet/vet_test.go

Loading diff…

main.go

Loading diff…