Skip to content

chore(doctor): one can't-check rollup rule via a CantCheck marker, not N prefix-matched arms (backend#3282) - #644

Merged
aptracebloc merged 1 commit into
developfrom
chore/3282-doctor-cantcheck-marker
Sep 7, 2026
Merged

chore(doctor): one can't-check rollup rule via a CantCheck marker, not N prefix-matched arms (backend#3282)#644
aptracebloc merged 1 commit into
developfrom
chore/3282-doctor-cantcheck-marker

Conversation

@aptracebloc

@aptracebloc aptracebloc commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Closes tracebloc/backend#3282

Follow-up to @saqlainsyed007's altitude review on cli#643 (backend#3248).

Problem

summarizeDoctor classified "a check couldn't read its subject" into the Unknown tier with four near-identical prefix-matched arms (Pod-health could not list pods, Node-capacity couldn't read RESOURCE_REQUESTS / could not list nodes / CantVerifyFreeCompute, Image-pull CantReadImagePullSecret, Dataset PVCReadErrPrefix). Each new can't-read probe needed three coordinated edits across three packages — an exported prefix constant, a checkX branch stamping it into Detail, and a matching CLI arm — coupled by fragile cross-package strings.

Change (behavior-preserving)

  • Add a structural doctor.Result.CantCheck, set by the checkX producers on their can't-read paths (a StatusWarn that is a real soft finding — over-commit, held-by-job, GPU fallback — leaves it false).
  • Replace the four arms with one rule, cantCheckReady, that surfaces the first flagged check's line. The per-check messages stay CLI copy in an ordered table (as healthLine values, so the zz-all-strings copy backstop still harvests them). stuckPending's can't-check exclusion moves from a Detail-prefix to the marker too.
  • A new can't-read probe now needs only "producer sets CantCheck" + a table row — no shared prefix constant to keep in lockstep across packages.

Distinct messages are preserved (not unified), per the behavior-preserving scope.

Behavior preservation — how it's verified

  • Both goldens are a zero diff (zz-all-strings and the rendered 05-doctor), so no user-facing output changed.
  • Every existing summarizeDoctor / producer test still holds (fixtures updated to set the marker the producers now set).
  • Producer tests assert CantCheck on the can't-read paths and its absence on the HeldByRunningJob soft finding; a rollup test pins the arm order and the unmapped-check fall-through.

Verification

go build ./..., go vet, gofmt -s -l, golangci-lint v2.12.2 (0 issues), full go test ./... — all green. No VERSION bump (develop's 0.10.24 is unreleased; the gate rides it).

— drafted with Claude Code


Note

Low Risk
Refactor is behavior-preserving with heavy test coverage and golden checks; risk is mainly mis-setting CantCheck on a producer, which could mis-classify readiness without changing auth or data paths.

Overview
tb doctor readiness rollup no longer classifies “couldn’t read this probe” (RBAC, timeouts, unreadable secrets/PVCs, etc.) by matching Detail string prefixes across packages. Producers now set a structural doctor.Result.CantCheck on those StatusWarn paths; real soft findings (over-commit, job holding compute, GPU fallback) leave it false.

The CLI replaces four near-duplicate summarizeDoctor switch arms with cantCheckReady, an ordered table that returns the same per-check “couldn’t check …” lines. stuckPending excludes pod-list failures via CantCheck instead of a "could not list pods" prefix. Tests and the copy-catalog doctor fixture set the marker like the real checks.

User-facing output is intended unchanged (same messages and severity ordering when multiple can’t-checks co-occur); this is maintainability and coupling cleanup for backend#3282.

Reviewed by Cursor Bugbot for commit a67bc19. Bugbot is set up for automated code reviews on this repo. Configure here.

…t N prefix-matched arms (backend#3282)

Follow-up to Saqlain's review on cli#643. summarizeDoctor classified "a check
couldn't READ its subject" into the Unknown tier with four near-identical
prefix-matched arms, each needing three coordinated edits across three packages
(an exported prefix constant, a checkX branch stamping it into Detail, and a
matching CLI arm) coupled by fragile cross-package strings.

Add a structural doctor.Result.CantCheck, set by the checkX producers on their
can't-read paths, and replace the four arms with one rule (cantCheckReady) that
surfaces the first flagged check's line. The per-check messages stay CLI copy in
an ordered table (healthLine values, so the copy backstop still harvests them),
so no user-facing output changes — both goldens are a zero diff — and
stuckPending's can't-check exclusion moves from a Detail-prefix to the marker
too. A new can't-read probe now needs only "producer sets CantCheck" plus a
table row, with no shared prefix constant to keep in lockstep.

Producer tests assert the marker on the can't-read paths (and its absence on the
HeldByRunningJob soft finding); a rollup test pins the arm order and the
unmapped-check fall-through.

Closes tracebloc/backend#3282

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@aptracebloc aptracebloc self-assigned this Sep 7, 2026

@saqlainsyed007 saqlainsyed007 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approve. Behaviour-preserving refactor: the four near-identical prefix-matched
can't-check arms collapse into one structural rule keyed on Result.CantCheck.

Verified each old Detail-prefix producer path now sets CantCheck (checkPods
list-error, checkNodeFit RESOURCE_REQUESTS/nodes/both CantVerifyFreeCompute
freeKnown==false paths, checkImagePull jobs-manager+secret unreadable, checkPVC
read-error), and that every StatusWarn that omits the marker is a genuine soft
finding (stuck-Pending, restart-flap, REQUESTS_PROXY_URL, HeldByRunningJob,
GPU-soft fallback) — exactly the cases the old arms did not classify as Unknown.
stuckPending's !HasPrefix→!CantCheck swap covers the identical set. cantCheckReady
keeps arm order (Pod health→Node capacity→Image pull→PVC) so co-occurrence
resolves identically, and it only runs in default so no Fail is swallowed. Tests
pin both directions (marker set on producers, NOT set on HeldByRunningJob) and add
priority + unmapped-check-inert coverage; golden copy backstop still harvests the
four lines as healthLine{} literals. CI green, Bugbot clean, no conflicts.

@aptracebloc
aptracebloc merged commit df40205 into develop Sep 7, 2026
36 checks passed
@aptracebloc
aptracebloc deleted the chore/3282-doctor-cantcheck-marker branch September 7, 2026 11:17
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.

3 participants