Severity: High (orphans a live in-cluster client). Follow-up to #131/#132 (R7 adopt-backfill). Found by Cursor Bugbot on the v-next promote (#155, comment on internal/cli/client.go:267).
The gap
In runClientCreate (internal/cli/client.go), the RFC-0001 §7.2 adopt-backfill runs only inside if clusterID != "":
clusterID, cidErr := readClusterID(...) // reads kube-system UID
...
if clusterID != "" {
adoptLiveInClusterClient(...) // detects live client + fail-closed guards
}
readClusterID (= cluster.ClusterID) needs a reachable cluster and RBAC to GET namespaces/kube-system. If it fails for a reason other than unreachability — RBAC forbidden on namespaces, a transient API error — while the cluster is otherwise reachable and a tracebloc release is already installed, clusterID == "", the whole adopt block is skipped, and client create falls through to mint a duplicate, orphaning the live client. Worst in non-interactive/--yes (the interactive confirm still shows the mint).
The current comment frames a readClusterID failure as "cluster isn't reachable → mint without anchor", but that conflates unreachable with reachable-but-UID-read-failed.
Why the fix is clean
adoptLiveInClusterClient already detects the live client via readInClusterClient independently of clusterID. Only the anchor backfill (PatchClientClusterID(owner.ID, clusterID)) needs the UID. So the orphan-prevention can run without it.
Proposed fix
- Always call
adoptLiveInClusterClient (drop the if clusterID != "" gate); pass clusterID (possibly "").
- Inside, when a live owned client is found but
clusterID == "": do NOT mint. Adopt the existing client as-is (skip the backfill Patch and the cluster-mismatch check, since we couldn't read the UID) and warn that the idempotency anchor wasn't stamped because the UID read failed (point --kubeconfig/--context at a cluster where namespaces/kube-system is readable to enable backfill).
- Keep existing guards:
listErr fail-closed, cross-account refusal, different-cluster mismatch (only meaningful when clusterID != "").
- Truly-unreachable (both UID read and
readInClusterClient fail) still falls through to a non-anchored mint — unchanged, nothing detectable to orphan.
- Tests: UID-read-fails + live owned client ⇒ no mint (adopt/idempotent); UID-read-fails + fresh cluster ⇒ mint without anchor (unchanged).
Acceptance
client create --yes against a reachable cluster with a live owned tracebloc client, where the kube-system UID read fails, must NOT POST a new client.
Severity: High (orphans a live in-cluster client). Follow-up to #131/#132 (R7 adopt-backfill). Found by Cursor Bugbot on the v-next promote (#155, comment on internal/cli/client.go:267).
The gap
In
runClientCreate(internal/cli/client.go), the RFC-0001 §7.2 adopt-backfill runs only insideif clusterID != "":readClusterID(=cluster.ClusterID) needs a reachable cluster and RBAC to GET namespaces/kube-system. If it fails for a reason other than unreachability — RBAC forbidden on namespaces, a transient API error — while the cluster is otherwise reachable and a tracebloc release is already installed,clusterID == "", the whole adopt block is skipped, andclient createfalls through to mint a duplicate, orphaning the live client. Worst in non-interactive/--yes(the interactive confirm still shows the mint).The current comment frames a
readClusterIDfailure as "cluster isn't reachable → mint without anchor", but that conflates unreachable with reachable-but-UID-read-failed.Why the fix is clean
adoptLiveInClusterClientalready detects the live client viareadInClusterClientindependently ofclusterID. Only the anchor backfill (PatchClientClusterID(owner.ID, clusterID)) needs the UID. So the orphan-prevention can run without it.Proposed fix
adoptLiveInClusterClient(drop theif clusterID != ""gate); passclusterID(possibly "").clusterID == "": do NOT mint. Adopt the existing client as-is (skip the backfill Patch and the cluster-mismatch check, since we couldn't read the UID) and warn that the idempotency anchor wasn't stamped because the UID read failed (point --kubeconfig/--context at a cluster where namespaces/kube-system is readable to enable backfill).listErrfail-closed, cross-account refusal, different-cluster mismatch (only meaningful whenclusterID != "").readInClusterClientfail) still falls through to a non-anchored mint — unchanged, nothing detectable to orphan.Acceptance
client create --yesagainst a reachable cluster with a live owned tracebloc client, where the kube-system UID read fails, must NOT POST a new client.