Uh oh!
There was an error while loading. Please reload this page.
feat(doctor): plain-language redesign (connected + ready, concrete fixes, --diagnose) - #365
Conversation
LukasWodka
commented
Jul 21, 2026
@BugBot run |
LukasWodka
commented
Jul 21, 2026
👋 Heads-up — Code review queue is at 32 / 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.) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Addresses the Lint failure and both Bugbot findings on #365. - Deadcode (Lint): the redesign derives the exit code in the cli layer from the two rolled-up health lines (worseStatus), so doctor.Worst is no longer reachable from the binary. Delete it (the allowlist's own guidance is "prefer deleting"); the two Run() tests that used it as an overall-verdict assertion keep a small test-local worstStatus helper. - Bugbot HIGH — no-chart misclassified as offline: a reachable cluster with no tracebloc installed was reported as "isn't answering" and handed the kubectl remedy, and readiness never appeared. checkReachable now tags the "Cluster reachable" result with a ReachState (Unreachable / NoEnv / Error); summarizeDoctor words each failure from that class — NoEnv -> "No secure environment installed here" + the one-line installer (never a kubectl), Error -> support, Unreachable (and any unclassified fail) -> "isn't answering". Legacy hand-built results default safely to Unreachable. - Bugbot MEDIUM — image-pull skipped in readiness: a failing "Image pull secret" check now rolls up to "Not ready — the training images can't be pulled" instead of a false Ready + exit 0. summarizeDoctor gains table cases for the no-env and image-pull buckets (and a guard that the no-env remedy never leaks kubectl). gofmt/vet/lint/deadcode/ file-budget green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
Bugbot MEDIUM on #365: isLoopback only matched localhost / 127.0.0.0/8 / ::1, so a stopped k3d cluster whose kubeconfig advertises 0.0.0.0 (the host k3d writes when the installer pins no explicit --api-port host — the bash install-k8s.sh path, unlike the Windows .ps1 which pins 127.0.0.1:6550) fell through to the generic "check your secure environment is running" line instead of the redesign's main local-failure remedy, "Start Docker Desktop". isLoopback now also treats the unspecified/wildcard bind addresses (0.0.0.0, ::) and Docker Desktop's host alias (host.docker.internal) as local. None of these is ever a genuinely-remote endpoint, so there's no false-positive risk. Tests: a dedicated TestIsLoopback table (local vs remote hosts) and a checkReachable assertion that a stopped 0.0.0.0 endpoint gets the start-Docker remedy + ReachUnreachable. Also locks in the doctor-side reach classification that feeds the summary rollup — ReachNoEnv for a missing chart, ReachError otherwise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ss on connected Two Bugbot findings on #365: - WhoAmI misclassification: every non-401/426 error set tokenReachable=false, so a backend that ANSWERED with an error (5xx/403/decode) was rolled up as "can't reach tracebloc from here" with a network/proxy remedy — contradicting a green Backend-egress check and exiting 2 for a tracebloc-side problem. Split the WhoAmI outcome into a tokenState: tokenUnreachable (genuine transport failure -> network remedy) vs tokenServerErr (the backend answered, just not 200 -> "tracebloc didn't confirm your session (server error)", retry / email support, never a proxy remedy). - False readiness check: readiness only degraded to "can't check" when Cluster reachable failed, so other Connected failures (Service Bus down, backend/token unreachable, server error) still allowed a green "Ready to run training" next to a Connected ✖ — even though training can't complete while disconnected. Readiness now degrades whenever Connected is not OK. Tests: TestSummarizeDoctor gains a tokenServerErr case (asserts support remedy, not a network/proxy one) and a "disconnected but cluster healthy" case (ready must not be a green check under a Connected ✖). All 8 existing call sites move from the bool to the tokenState enum. gofmt/vet/lint/deadcode green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Two Bugbot findings on #365, both the same anti-pattern — an early return throwing away something doctor already learned: - --diagnose skipped the roll-up: it returned right after writing the bundle, so the file recorded only the raw k8s checks (never the WhoAmI/session outcome or the Connected/Ready verdict), and it always exited 0 even when checks failed — while the remedies tell owners to email that very bundle for session/server errors. --diagnose is now additive: it runs summarizeDoctor, writes session + verdict + detail into the bundle, and falls through to the real verdict/exit code (2 when something's wrong, not a misleading 0). - Kubeconfig/clientset failure hid a session fault: after WhoAmI set tokenUnreachable/tokenServerErr, a failed local-env read returned with only "no / can't connect to secure environment", steering owners to reinstall while a live backend/session problem went unmentioned. Both no-env branches now surface the session fault first via noteSessionProblem (a no-op when the session is fine; 401/426 remain hard stops upstream). Adds tokenLabel (bundle session line) + a TestRunClusterDoctor_DiagnoseBundle that asserts the bundle records session/connected/ready and that a failing check still exits 2 under --diagnose. gofmt/vet/lint/deadcode green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 23e53f7. Configure here.
…ete fixes Rebuilds `tb doctor` around the one question a workspace owner has: is my secure environment connected to tracebloc and ready to run training — and if not, exactly what to do. The 9 Kubernetes-flavoured checks (release/chart/PVC/ pods/pull-secrets/proxy/Service-Bus/kubectl) collapse into two plain lines, and everything technical moves behind --verbose. Default view: Signed in as lukas@tracebloc.io Secure environment "lukas-test" Connected to tracebloc Ready to run training - No banner, no kubeconfig block, no numbers, no Kubernetes vocabulary. - Each health line expands on failure to the specific plain problem + ONE concrete action (a command, never a kubectl): stopped env -> "start Docker Desktop"; expired -> "tb login"; no env -> the one-line installer; results can't flow / component down -> email support with `tb doctor --diagnose`. - Not-connected degrades readiness honestly to "can't check" (the #354 reachability gate, folded in here). - Remedies resolve `tb` vs `tracebloc` like the home screen. - `tb doctor --verbose` keeps the full technical breakdown (kubeconfig + every granular check) for support. - `tb doctor --diagnose` now owns the redacted support bundle (moved off install-k8s.sh, which the user may not have on disk). summarizeDoctor (the roll-up) is unit-tested for every failure bucket; the render + verdict are covered via the doctorRunFn seam; no k8s vocabulary is allowed to leak into the default view (asserted). Supersedes #354 (doctor cascade) and #351 (requests-proxy wording) — this rewrites the same output and folds in their fixes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses the Lint failure and both Bugbot findings on #365. - Deadcode (Lint): the redesign derives the exit code in the cli layer from the two rolled-up health lines (worseStatus), so doctor.Worst is no longer reachable from the binary. Delete it (the allowlist's own guidance is "prefer deleting"); the two Run() tests that used it as an overall-verdict assertion keep a small test-local worstStatus helper. - Bugbot HIGH — no-chart misclassified as offline: a reachable cluster with no tracebloc installed was reported as "isn't answering" and handed the kubectl remedy, and readiness never appeared. checkReachable now tags the "Cluster reachable" result with a ReachState (Unreachable / NoEnv / Error); summarizeDoctor words each failure from that class — NoEnv -> "No secure environment installed here" + the one-line installer (never a kubectl), Error -> support, Unreachable (and any unclassified fail) -> "isn't answering". Legacy hand-built results default safely to Unreachable. - Bugbot MEDIUM — image-pull skipped in readiness: a failing "Image pull secret" check now rolls up to "Not ready — the training images can't be pulled" instead of a false Ready + exit 0. summarizeDoctor gains table cases for the no-env and image-pull buckets (and a guard that the no-env remedy never leaks kubectl). gofmt/vet/lint/deadcode/ file-budget green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bugbot MEDIUM on #365: isLoopback only matched localhost / 127.0.0.0/8 / ::1, so a stopped k3d cluster whose kubeconfig advertises 0.0.0.0 (the host k3d writes when the installer pins no explicit --api-port host — the bash install-k8s.sh path, unlike the Windows .ps1 which pins 127.0.0.1:6550) fell through to the generic "check your secure environment is running" line instead of the redesign's main local-failure remedy, "Start Docker Desktop". isLoopback now also treats the unspecified/wildcard bind addresses (0.0.0.0, ::) and Docker Desktop's host alias (host.docker.internal) as local. None of these is ever a genuinely-remote endpoint, so there's no false-positive risk. Tests: a dedicated TestIsLoopback table (local vs remote hosts) and a checkReachable assertion that a stopped 0.0.0.0 endpoint gets the start-Docker remedy + ReachUnreachable. Also locks in the doctor-side reach classification that feeds the summary rollup — ReachNoEnv for a missing chart, ReachError otherwise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ss on connected Two Bugbot findings on #365: - WhoAmI misclassification: every non-401/426 error set tokenReachable=false, so a backend that ANSWERED with an error (5xx/403/decode) was rolled up as "can't reach tracebloc from here" with a network/proxy remedy — contradicting a green Backend-egress check and exiting 2 for a tracebloc-side problem. Split the WhoAmI outcome into a tokenState: tokenUnreachable (genuine transport failure -> network remedy) vs tokenServerErr (the backend answered, just not 200 -> "tracebloc didn't confirm your session (server error)", retry / email support, never a proxy remedy). - False readiness check: readiness only degraded to "can't check" when Cluster reachable failed, so other Connected failures (Service Bus down, backend/token unreachable, server error) still allowed a green "Ready to run training" next to a Connected ✖ — even though training can't complete while disconnected. Readiness now degrades whenever Connected is not OK. Tests: TestSummarizeDoctor gains a tokenServerErr case (asserts support remedy, not a network/proxy one) and a "disconnected but cluster healthy" case (ready must not be a green check under a Connected ✖). All 8 existing call sites move from the bool to the tokenState enum. gofmt/vet/lint/deadcode green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two Bugbot findings on #365, both the same anti-pattern — an early return throwing away something doctor already learned: - --diagnose skipped the roll-up: it returned right after writing the bundle, so the file recorded only the raw k8s checks (never the WhoAmI/session outcome or the Connected/Ready verdict), and it always exited 0 even when checks failed — while the remedies tell owners to email that very bundle for session/server errors. --diagnose is now additive: it runs summarizeDoctor, writes session + verdict + detail into the bundle, and falls through to the real verdict/exit code (2 when something's wrong, not a misleading 0). - Kubeconfig/clientset failure hid a session fault: after WhoAmI set tokenUnreachable/tokenServerErr, a failed local-env read returned with only "no / can't connect to secure environment", steering owners to reinstall while a live backend/session problem went unmentioned. Both no-env branches now surface the session fault first via noteSessionProblem (a no-op when the session is fine; 401/426 remain hard stops upstream). Adds tokenLabel (bundle session line) + a TestRunClusterDoctor_DiagnoseBundle that asserts the bundle records session/connected/ready and that a failing check still exits 2 under --diagnose. gofmt/vet/lint/deadcode green; doctor + cli packages pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
23e53f7 to
066270cCompareLukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
… WhoAmI Bugbot on #365: the Connected roll-up ORed tokenUnreachable with a failing "Backend egress (from this machine)" check, so after a successful WhoAmI a backend-egress probe miss (a different CLIENT_ENV host, a transient miss) still rendered "Not connected — can't reach tracebloc from here" + a check-your-network remedy, contradicting the session probe that had just reached the backend. WhoAmI is the definitive from-this-machine reachability+auth signal; the backend-egress check is explicitly indicative-not-definitive (it probes the cluster's configured host from here, not the cluster's real egress path). So it no longer feeds the Connected headline — it stays a --verbose/--diagnose diagnostic. Connected now keys on tok (+ reachability + Service Bus egress). Test: a backend-egress miss with a healthy session keeps Connected OK and never prints the network remedy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…ct exit Two Bugbot findings on #365, one root cause — early returns bypassing the inline --diagnose block: - Diagnose was only honored after the full probe, so every early exit (soft session fault, no environment, clientset error) wrote no bundle — the exact states whose remedies tell the user to run `doctor --diagnose`. - If checks failed (exit 2) but the bundle write errored, the run returned the write failure (exit 3), masking the health verdict. Replace the inline write with a deferred writer registered right after the sign-in gate: it fires on every exit path (so --diagnose always leaves a bundle once authenticated — "not signed in" is still answered by login, not a bundle), and via the named return it only sets the exit code when nothing worse already did, so a bundle hiccup never masks a Fail verdict. writeDiagnoseBundle records partial state (session + an "exited before probe" note) when the roll-up didn't run and skips the k8s section when there's no resolved environment. Tests: --diagnose on a clientset-fail early exit still writes a bundle and preserves exit 3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bugbot on #365: the identity header printed `Secure environment "<name>"` from the resolved kubeconfig namespace before the probe. When the cluster is reachable but no tracebloc chart is installed (ReachNoEnv), the Connected line then says none is installed here — so the default view asserted the environment both exists and does not. Move the header to after the roll-up and print it only when an environment is actually installed (reach state != ReachNoEnv). Nothing prints between it and "Signed in as …", so the two context lines still read as a pair. Every other reach state (running, stopped, RBAC) means an environment exists, so it's still named. Test: a ReachNoEnv run shows "No secure environment installed here", never names one, and exits 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
LukasWodka
commented
Jul 21, 2026
Folding cli#353 into this doctor redesign. Two points to make sure are covered here:
Closing #353 in favor of this PR. |
…faults on all Bugbot on #365: a session fault (tokenUnreachable / tokenServerErr) was hidden on the reachable-but-no-chart (ReachNoEnv) path, because that path flowed through summarizeDoctor whose Connected line ignores tok — unlike the missing-kubeconfig and clientset-error exits, which surface it via noteSessionProblem. Route ReachNoEnv through the same short-circuit as the other two "no environment" states: noteSessionProblem (surfaces any session fault) + "No secure environment on this machine yet" + the installer + earlyExitCode (a session fault dominates the exit). Remove the now-redundant ReachNoEnv case from summarizeDoctor — one source of truth. This also preserves the earlier fix (never name an environment that isn't installed): the short-circuit returns before the identity header. Tests: ReachNoEnv with a healthy session exits 3 and names no environment; with a session fault it surfaces the fault and exits 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Two Bugbot findings on #365, both from the no-environment short-circuits returning before the main render: - --verbose (Medium): renderDoctorDetails only ran on the full path, so `tb doctor --verbose` printed no Details on the ReachNoEnv / clientset failure paths — exactly where support needs the kubeconfig + granular output. Extracted renderDetailsIfVerbose and call it at every exit that has a resolved config. - --diagnose bundle (Low): on ReachNoEnv the roll-up never ran, so the bundle recorded "exited before the environment could be probed" even though the checks WERE collected and written below. The outcome line is now three-way: verdict when summarized, "no roll-up verdict (granular checks below)" when probed but not summarized, and "before the cluster was probed" only when truly not probed. Test: --verbose on a ReachNoEnv run prints the Details section with the checks. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
summarizeDoctor only degraded the "Ready to run training" verdict on Pod-health StatusFail (crash-loop). Pods stuck Pending past the grace window surface as StatusWarn, so an environment where training can't schedule still rolled up to ✔ "Ready to run training" and the "Everything looks good" verdict. Treat Pod-health Warn as not-ready (training genuinely can't schedule) with a compute / image-pull remedy, and cover it with a regression test. Bugbot (PR #365): "Warn pod states claim ready". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
…ness rollup checkPods returns StatusWarn for BOTH stuck-Pending pods AND a failure to list pods (e.g. RBAC). The previous fix gave the stuck-pending / Docker-Desktop remedy to both, misdiagnosing the read-failure case. Split them: "could not list pods" now rolls up to an honest can't-check (StatusUnknown, no compute remedy), while stuck-Pending stays not-ready with the compute/image-pull remedy. Both covered. Bugbot (PR #365): "Pod warn misclassified as pending". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
@BugBot run |
Uh oh!
There was an error while loading. Please reload this page.
…verified
The RBAC / can't-list-pods case rolls readiness up to StatusUnknown ("couldn't
check your workloads"), but worseStatus treats Unknown as non-worsening, so the
closing verdict still printed "Everything looks good — you're ready to run
training" (exit 0), contradicting that line. Extract the decision into
doctorVerdict: "everything looks good" now requires BOTH connected and ready to
be genuinely StatusOK; a can't-check reports an honest partial result instead
(still exit 0, since nothing failed). Unit-tested.
Bugbot (PR #365): "Can't-check still claims ready".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>LukasWodka
commented
Jul 21, 2026
@BugBot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
7 issues from previous reviews remain unresolved.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 81b1b28. Configure here.
LukasWodka
commented
Jul 21, 2026
@aptracebloc thanks for the careful re-review. Status against the current tip ( (a) Connected-contradicts-WhoAmI — agreed, false positive. Resolved. (b) Diagnose skipped on early exits — fixed in (c) Diagnose write masks fail exit — fixed in Also resolved since your pass: "Diagnose lies about session" ( All Bugbot threads are now resolved and CI is green — would appreciate a re-review + approval when you have a moment. |
Uh oh!
There was an error while loading. Please reload this page.
Rebased onto develop after the doctor redesign (#365), which kept the readiness-based StatusOK. checkRequestsProxy no longer greens off ReadyReplicas alone — a present + Ready relay returns a neutral StatusUnknown ("running, egress not actively verified"), never a checkmark; down / missing still fail. worstStatus ignores StatusUnknown, so a healthy environment's overall verdict is unchanged. The real green arrives once the requests-proxy health probe (backend#1143) ships and doctor consumes it. Refs #351 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebased onto develop after the doctor redesign (#365), which kept the readiness-based StatusOK. checkRequestsProxy no longer greens off ReadyReplicas alone — a present + Ready relay returns a neutral StatusUnknown ("running, egress not actively verified"), never a checkmark; down / missing still fail. worstStatus ignores StatusUnknown, so a healthy environment's overall verdict is unchanged. The real green arrives once the requests-proxy health probe (backend#1143) ships and doctor consumes it. Refs #351 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…al until the egress probe (cli#351) (#369) * fix(doctor): stop requests-proxy readiness false-green (cli#351) Rebased onto develop after the doctor redesign (#365), which kept the readiness-based StatusOK. checkRequestsProxy no longer greens off ReadyReplicas alone — a present + Ready relay returns a neutral StatusUnknown ("running, egress not actively verified"), never a checkmark; down / missing still fail. worstStatus ignores StatusUnknown, so a healthy environment's overall verdict is unchanged. The real green arrives once the requests-proxy health probe (backend#1143) ships and doctor consumes it. Refs #351 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(doctor): document StatusUnknown's second meaning (ran-but-declines-to-assert) Asad's review on #369: the StatusUnknown doc only covered the 'prerequisite unavailable' case, but the requests-proxy egress check now uses it for a different reason — the check ran fine and just declines to assert an egress green it can't back. Documents both meanings on the sentinel. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
LukasWodka
commented
Jul 21, 2026
/fr-pass — verified live on dev: |

Part of epic backend#1142. The finalized
tb doctorredesign Lukas signed off on in chat.What
tb doctornow answers the one question a workspace owner has — is my secure environment connected to tracebloc and ready to run training, and if not, what do I do — in plain language. The 9 Kubernetes-flavoured checks collapse into two lines; the technical detail moves behind--verbose.Default (healthy):
On failure each line expands to the specific plain problem + ONE concrete action (a command, never a
kubectl):Start Docker Desktop (open -a Docker) — your secure environment restarts with itrun tb loginbash <(curl -fsSL https://tracebloc.io/i.sh)email support@tracebloc.io with tb doctor --diagnoseraise the machine's allocation in Docker Desktop → ResourcesNot-connected degrades readiness to "can't check" (no false ✔). Remedies resolve
tbvstracebloclike the home screen.New
tb doctor --verbose— the full technical breakdown (kubeconfig + every granular check), for support. The only place k8s vocabulary appears.tb doctor --diagnose— owns the redacted support bundle (moved offinstall-k8s.sh, which the user may not have on disk).Tests
summarizeDoctor(the roll-up) unit-tested for every failure bucket; render + verdict via thedoctorRunFnseam; a leak-guard asserts no k8s vocabulary in the default view.Relationship to #354 and #356 (rebased onto develop)
Rebased onto
developafter #356 merged. #356 was stacked on #354, so its squash carried the entire #354 reachability gate to develop — this branch therefore no longer cherry-picks #354 (that base commit was dropped in the rebase) and now inherits #356's corrected requests-proxy wording verbatim, which the--verbose/--diagnoseview shows.Note on the parallel
resourcesworkBuilt in an isolated worktree; touches only
internal/doctor/*+internal/cli/doctor*.go(+ one home_test assertion). Nointernal/ui/ui.gochange, so it can't collide with theresourcesredesign that addsStatthere.All CI green (Lint / Test / Build ×8 / govulncheck / installer / schema+fixtures) and Bugbot clean on the tip commit; doctor + cli packages pass locally.
Note
Medium Risk
Large user-facing change to CLI diagnostics and exit-code semantics, but behavior stays read-only and is heavily covered by new tests.
Overview
tracebloc doctoris reworked for workspace owners: instead of separate auth, kubeconfig, and per-check Kubernetes sections, the default output is signed in → named secure environment → two rollup lines (“Connected to tracebloc” and “Ready to run training”) with plain remedies (login, installer URL, Docker Desktop, support/--diagnose). Granular checks move behind--verboseonly.--diagnosewrites a redactedtracebloc-doctor-*.txtsupport bundle (session state, rollup when available, technical details)—replacing the installer script path—with careful behavior on 401/426 (no bundle) and on early exits (bundle still written, real exit code preserved). Session probing distinguishes network unreachable vs server error vs 401/426 hard stops; ReachNoEnv unifies “no chart” with missing kubeconfig messaging.In
internal/doctor,ReachStateonCluster reachabledrives rollup wording;Worst()is removed (verdict lives in CLIsummarizeDoctor/doctorVerdict). Local-cluster unreachable remedies andisLoopback(e.g.0.0.0.0,host.docker.internal) are tightened.Tests cover rollup buckets, diagnose/exit-code edge cases, k8s vocabulary leak guard, and shared
doctor/cluster doctorpath.Reviewed by Cursor Bugbot for commit 81b1b28. Bugbot is set up for automated code reviews on this repo. Configure here.