Skip to content

feat(cli): auto-discover the client's namespace, rewrite the first-touch surface, ship a tb alias#142

Merged
saadqbal merged 4 commits into
developfrom
ux/cli-surface-and-namespace-discovery
Jul 7, 2026
Merged

feat(cli): auto-discover the client's namespace, rewrite the first-touch surface, ship a tb alias#142
saadqbal merged 4 commits into
developfrom
ux/cli-surface-and-namespace-discovery

Conversation

@LukasWodka

Copy link
Copy Markdown
Contributor

Summary

Fixes the CLI's out-of-box dead end and rewrites its first-touch surface, driven by a real session on a standard install (Lukas's Mac, client in its slug namespace):

$ tracebloc data list
Error: no tracebloc parent client release found in namespace "default" …
Install with `helm install <release> tracebloc/client --namespace default` first…

A working client was right there on the cluster — the CLI just never looked beyond the kubeconfig's default namespace, then told a customer to run Helm (the exact thing its own help promises they never do).

1. Namespace auto-discovery (§7.3)

  • New cluster.FindClientNamespaces — cluster-wide scan for jobs-manager Deployments (same selector as single-namespace discovery).
  • discoverRelease fallback in the shared resolve seam: a miss in the default namespace triggers the scan. Exactly one client → retarget with a visible note (· No client in namespace "default" — using the one in "tracebloc" …); several → named, pick via --namespace / client use; none or RBAC-denied scan → the original error stands.
  • §7.5 guard: the scan never engages for an explicit --namespace/--context, and never for an active-client binding miss (that keeps the §7.3 "runs elsewhere" message — a stale binding must not silently retarget a different machine's client). Pinned by activeClientBinding.allowScan() + table test.
  • cluster info now binds the active client exactly like the data commands — the pre-flight targets what data ingest will actually target, and the multi-client "set your active client" remediation works there too.

2. First-touch surface

  • Root command: tagline + Long + home screen rewritten around the real scope (two contexts: your account / this machine's client); login leads Get started; POST /internal/… protocol jargon and issue links removed.
  • ingest vs data ingest collision: validate moved to data validate; top-level ingest is a hidden deprecated alias, and tracebloc ingest <path> now redirects: did you mean tracebloc data ingest <path>.
  • Error copy: --namespace → installer one-liner (https) → cluster doctor; never Helm. Sentinel renamed to no tracebloc client found; cluster doctor no longer advises running cluster doctor.
  • Noun sweep: "parent (client) release" → client; vendors → other collaborators; PVC jargon out of Shorts/flag help; README command names updated to data ingest/data validate.

3. tb short alias (second commit)

The installers now ship tb next to the binary (symlink on Unix, tb.cmd shim on Windows; both skip if an unrelated tb exists). tb data ingest ./data. Requested by Lukas.

Verification

  • Live on a real cluster (client in a non-default namespace): data list + cluster info auto-find it with the note; explicit -n default gets the new actionable error; invocation via a tb symlink verified.
  • go build / go vet / full go test ./... green. New tests: scan (single/multi/none/explicit-no-scan), allowScan contract table, data validate + ingest validate alias resolution, updated string pins.
  • Adversarially reviewed pre-push (multi-agent): findings folded — cluster-info binding parity, https on the curl|bash one-liner, doctor circularity, remaining noun stragglers.

Context: part of the CLI/installer UX pass with tracebloc/client#307 and the v2 spec (backend#992); complements cli#137/cli#138 (which cover client create auto-naming and the login/status contract).

🤖 Generated with Claude Code

LukasWodka and others added 2 commits July 6, 2026 21:54
… rewrite

Fixes the out-of-box dead end: on a standard install the client lives in
its slug namespace, but data/cluster commands searched only the
kubeconfig default ("default") and errored — telling customers to run
helm install, the exact thing the CLI promises they never do.

Namespace discovery (§7.3):
- New cluster.FindClientNamespaces: cluster-wide scan for jobs-manager
  Deployments (same selector as single-namespace discovery).
- discoverRelease fallback in the shared resolve seam: a miss in the
  DEFAULT namespace scans; exactly one client → visible-note retarget
  (never silent), several → named + pick via --namespace/client use,
  none/RBAC-denied → the original error stands.
- §7.5 guard: the scan NEVER engages for an explicit --namespace/
  --context or an active-client binding miss (which keeps the §7.3
  "runs elsewhere" message) — pinned by activeClientBinding.allowScan()
  + table test. cluster info now binds the active client exactly like
  the data commands, so the pre-flight targets what data ingest will.

Surface rewrite:
- Root: tagline/Long/home screen rewritten around the real scope (two
  contexts: your account / this machine's client); login leads Get
  started; protocol jargon + internal issue links removed.
- ingest/data-ingest collision: validate moved to `data validate`;
  top-level `ingest` is a hidden deprecated alias, and a bare path
  there redirects: did you mean `tracebloc data ingest <path>`.
- No-client error copy: --namespace / installer one-liner (https) /
  cluster doctor — never helm. Sentinel renamed to "no tracebloc
  client found"; doctor no longer tells you to run doctor.
- Noun sweep: parent (client) release → client; vendors → other
  collaborators; PVC jargon out of Shorts/flag help; README command
  names updated.

Verified live on a real cluster (client in a non-default namespace):
data list / cluster info auto-find it; explicit -n default gets the
actionable error. go build/vet/test green; new tests cover the scan
(single/multi/none/explicit), the alias moves, and the allowScan
contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The kubectl→k pattern for the most-typed word in the product: the shell
installer symlinks $PREFIX/tb → tracebloc (skipped if an unrelated tb
already sits there); the PowerShell installer drops a tb.cmd shim. Both
announce the alias in the install output + README.

Requested by Lukas (2026-07-06).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
LukasWodka and others added 2 commits July 6, 2026 22:00
The verification harness runs install.sh under a restricted PATH that
didn't include ln → rc=127 on the happy path. Two-sided fix: the alias
block now degrades silently when ln is unavailable or fails (an alias
must never fail an install), and the harness whitelists ln+readlink and
asserts the tb symlink exists and points at the binary on the happy
path (12 checks now).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…effort on Windows

Two review follow-ups on this PR:

- cluster info printed the "namespace" field before the cluster-wide
  fallback scan retargets resolved.Namespace, so when the scan finds the
  client in its slug namespace the pre-flight reported "default" while the
  Client-install section and ingestor-SA path below showed the real
  namespace. Print the field after the retarget — the command's whole job
  is to report what the next `data ingest` will target.

- install.ps1's tb alias wasn't actually best-effort: under
  $ErrorActionPreference='Stop' a Set-Content failure aborted the whole
  install (the third commit only hardened the Unix side). Wrap it in
  try/catch so a write failure just skips the alias. Also tighten the
  "is this tb.cmd ours?" guard from a loose "*tracebloc.exe*" substring
  (which would clobber any unrelated tb.cmd merely mentioning the name)
  to an exact match on our quoted binary path — matching install.sh's
  strict readlink-target equality.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@saadqbal

saadqbal commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Reviewed and pushed a couple of small fixes (31e8a1f):

  • cluster info was printing the namespace field before the fallback scan retargets it — so it'd show default while the Client-install section below showed the real slug namespace. Moved it after the retarget.
  • The tb alias wasn't actually best-effort on Windows: under $ErrorActionPreference='Stop' a Set-Content failure would abort the whole install (the third commit only hardened the Unix side). Wrapped it in try/catch, and tightened the "is this tb.cmd ours?" check from a loose *tracebloc.exe* substring to an exact match on our binary path.

Otherwise a clean, well-tested PR — the namespace-scan logic checks out. 👍

@saadqbal saadqbal merged commit 1de77d2 into develop Jul 7, 2026
14 checks passed
saadqbal added a commit that referenced this pull request Jul 7, 2026
…lete + nodeboot

develop's #142 landed the §7.3 namespace-discovery + cluster-info binding (the
pieces this branch had folded from #133), so those are dropped as redundant.
What remains unique to this prototype (RFC-0001 §15, cli#136) is re-applied
cleanly on top of #142:

- `client use` removed; `client list` hidden (installer #303 pre-flight only);
  `client delete` added — deprovision + helm uninstall + local cluster delete.
- internal/nodeboot (TeardownCluster + UninstallChart) + api.DeleteClient.
- RFC-0001 §15 amendment (PROPOSED).

Rebuilt via reset-to-develop + re-apply to avoid a semantic mis-merge (the
auto-merge had silently reverted the surface to develop's create/list/use).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants