fix(#303): refuse a second client before minting, so we don't orphan one#306
Conversation
…rphan one On the browser path, `tracebloc client create` mints a fresh client whenever the backend can't match this cluster to a client in the signed-in account — e.g. a pre-anchor client whose cluster_id is still null, or one owned by a different account. The one-client-per-machine guard only ran later, in the Helm step, so by the time it refused, a brand-new client was already registered on the dashboard and would never install — an orphan (#303). Add a pre-flight in provision_client, after sign-in and before the mint: if a client is already installed locally (shared detect_installed_client probe, now also used by the Helm guard) and the signed-in account demonstrably does NOT own its namespace (via `client list`), refuse before calling create. Namespace is the only stable join key — the local Helm release stores the UUID clientId, `client list` shows the numeric id. The pre-flight fires only on a positive "not yours"; a fresh machine, an owned local client (create adopts), or an inconclusive list read all fall through to create's own idempotent adopt/conflict handling, so the same-account re-run/upgrade path is unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
👋 Heads-up — Code review queue is at 33 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
|
This is the interim band-aid; the real fix is R7 in tracebloc/cli#132, now merged to CLI develop but not yet released. The installer pulls the latest CLI release (still v0.5.1, pre-R7), so orphans are still possible until an R7 release ships — keep this merged as protection until then. Follow-up: drop this pre-flight once the R7 CLI is released and dev/prod run backend #893. The install-client-helm one-client guard stays as the backstop regardless. |
…pre-flight install-client-helm.sh + provision.sh changed; refresh the R8 signed-manifest checksums so gen-manifest.sh --check passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ef1560a. Configure here.
… account owns (Bugbot) The pre-flight keyed ownership on the local Helm release namespace via `client list`. But a client installed under the legacy fixed `tracebloc` namespace is listed on the dashboard under its minted slug, so `client list` never shows `tracebloc` even for the account's OWN older client — a skew install_client_helm reconciles by clientId (the reliable key `client list` doesn't expose). The namespace-only check wrongly refused that valid re-run. Refuse only when the absent namespace is a non-legacy slug (confident foreign); for `tracebloc`, defer to `client create` (adopts if it's yours, 409s if truly cross-account) and the Helm-step one-client guard, which both key on clientId. Regenerates manifest.sha256 for the provision.sh change (R8). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…flight-ownership # Conflicts: # scripts/manifest.sha256

Closes #303.
On the browser path,
client createmints a fresh client whenever the backend can't match this cluster to a client in the signed-in account (pre-anchor nullcluster_id, or a different account owns it). The one-client guard only ran later in the Helm step, so it refused after a new client was already registered on the dashboard — an orphan that never installs.Adds a pre-flight in
provision_client, after sign-in and before the mint: if a client is already installed here (shareddetect_installed_clientprobe, now also backing the Helm guard) and the signed-in account demonstrably does not own its namespace (viaclient list), refuse before calling create.Namespace is the only stable join key (local Helm stores the UUID clientId;
client listshows the numeric id). Fires only on a positive "not yours" — a fresh machine, an owned local client (create adopts), or an inconclusive list read all fall through to create's own idempotent adopt/conflict handling, so the same-account re-run/upgrade path is unchanged.Tests: 3 new
provision.batscases (refuse foreign / adopt same-account / fall-through on unreadable list); guard refactor keepsinstall-client-helm.batsgreen.Note: the proper root-cause fix is the deferred R7 "existing-fleet reconcile" (backfill the null
cluster_idand adopt the live in-cluster client instead of minting) — this PR stops the orphan without that larger CLI+backend change.🤖 Generated with Claude Code
Note
Medium Risk
Changes browser provisioning order and ownership heuristics (namespace vs legacy
tracebloc); wrong refusal or fall-through could block valid reinstalls or still allow orphans, though bats cover the main paths.Overview
Stops orphan dashboard clients when someone signs into a different account on a machine that already has a tracebloc Helm client. The browser path used to call
client createbefore the Helm one-client guard, so a new client could be registered even though install would later refuse.Shared local probe:
detect_installed_clientininstall-client-helm.shcentralizes jq-free Helm enumeration; both the new pre-flight and the existing Helm guard use it so they agree on what is installed.Pre-provision check in
provision_client(after login, before mint):_account_owns_namespacematches the local release namespace againsttracebloc client list. It refuses only when the list read succeeds and the namespace is missing—except for the legacy fixedtraceblocnamespace, where list skew defers toclient createand the HelmclientIdguard. Fresh machines, owned clients, and failed list reads still fall through to create as before.Tests:
provision.batsstubs the probe and adds cases for foreign-client refusal, same-account adopt, inconclusive list, and legacy namespace deferral. Manifest checksums updated.Reviewed by Cursor Bugbot for commit f490c4b. Bugbot is set up for automated code reviews on this repo. Configure here.