Skip to content

Probe-local tri-review follow-ups: Status enum + shared probe + hint/test/contract fixes - #97

Merged
5uck1ess merged 3 commits into
mainfrom
chore/probe-local-tri-review-followups
Apr 17, 2026
Merged

Probe-local tri-review follow-ups: Status enum + shared probe + hint/test/contract fixes#97
5uck1ess merged 3 commits into
mainfrom
chore/probe-local-tri-review-followups

Conversation

@5uck1ess

Copy link
Copy Markdown
Owner

Summary

Applies all follow-ups from the tri-review of just-merged PR #93 (probe-local feature), plus five additional blockers surfaced by a second-pass tri-review (smart codex + fast haiku + direct verification) on this branch.

Commit 1: refactor(runners): consolidate probe core with Status enum (441dffc)

  • Move probe core out of package cmd into runners/probe.go; LocalRunner.Available and devkit-engine probe-local now share one reachability path (addresses Gemini's tri-review ask — no more drift risk).
  • Introduce ProbeStatus enum (disabled / unreachable / endpoint_error / invalid_response / model_missing / healthy) replacing the old Reachable+HTTPStatus+ModelMatch booleans. Removes the 2xx-with-bad-JSON ambiguity.
  • Unexport ProbeConfig/ProbeResult from cmd (moved to runners, where they have a real caller).
  • ModelsSeen init'd to []string{} — JSON emits [] not null.
  • unreachableHint distinguishes context.DeadlineExceeded / context.Canceled / generic.

Commit 2: docs(readme): remove LocalAI double-listing (3aa32cc)

  • README's Local models section had LocalAI in both single-model AND multi-model rows.

Commit 3: fix(runners): address second-pass tri-review blockers (d9b3848)

Five findings that reached consensus across both reviewer tiers:

Pri Finding Fix
P0 Exit-code docs said "Exit 0 on healthy, 1 otherwise" but code exits 0 on disabled too Update docs to match actual behavior
P1 Hint text said "raise DEVKIT_LOCAL_TIMEOUT" — env var is only read by LocalRunner.Run, not Probe Rephrase to point at server health + endpoint config
P1 Available_Gating test never exercised ProbeHealthy→true — a switch inversion would pass Add matching-model subtest
P1 TestProbe_CallerCanceled used goroutine+Sleep(30ms)+cancel — flaky under CI load Channel-sync: handler closes started, canceller blocks on receive
P2 cfg.Endpoint+"/models" didn't normalize trailing slash strings.TrimRight(endpoint, "/")

Skipped (both reviewers classified as padding or wrong premise): cfg.Timeout=0-infinite-wait (Go context.WithTimeout(ctx, 0) creates an already-expired context, not infinite wait), doubled context+client timeout (redundant not broken), discarded body-ReadAll err on 4xx/5xx (lost diagnostic not broken classification), "logs only default branch" (no default branch exists — fires on all non-healthy cases), bare sentinel fragility (hypothetical).

Known workflow gap

The /devkit:tri-review pass on this branch surfaced a recurrence of issue #95: the gemini-rescue general-tier subagent's internal Bash call to gemini-companion.mjs is still blocked by devkit-guard during prompt steps, even after the Agent/Task dispatch fix in v2.1.25. Ran bi-tier (smart+fast) with direct verification as the fallback.

Test plan

  • go build ./... clean
  • go test ./... → 387 passed (was 373 on PR feat: local runner health probe #93, +14 from new enum-based probe tests + format tests + new Available subtest + canceled test + models_seen-empty-not-null)
  • gofmt -l clean on all changed files
  • go vet ./... clean
  • Manual probe-local smoke test on a local endpoint (optional)

Move the /v1/models probe out of package cmd into runners so LocalRunner
and the probe-local CLI share a single reachability path. Addresses the
tri-review findings:

- new runners.Probe replaces cmd.runProbe; ProbeConfig/ProbeResult now
  live on the runners package where sharing them with LocalRunner is
  legitimate (unexports them from cmd)
- ProbeStatus enum (disabled/unreachable/endpoint_error/invalid_response/
  model_missing/healthy) replaces the Reachable+HTTPStatus+ModelMatch
  booleans, removing the 2xx-with-bad-JSON ambiguity
- ModelsSeen initialized to []string{} so JSON output emits [] not null
- LocalRunner.Available now delegates to Probe and accepts healthy or
  model_missing (preserves current permissive semantics — model checks
  stay the caller's concern)
- unreachable hint distinguishes context.DeadlineExceeded from
  context.Canceled from generic network failure; covered by a new
  TestProbe_CallerCanceled

cmd/probe_local.go now holds only the Cobra command and the two
formatters; all probe mechanics are in runners/probe.go.
LocalAI appeared in both the single-model and multi-model router example
rows. Move it to the multi-model row only and clarify that it supports
either mode depending on how it is configured.
Bi-tier tri-review (smart codex + fast haiku + direct verification — gemini
unavailable under issue #95 guard-cascade bug) reached consensus on 5 real
blockers. Applied all:

- probe.go unreachableHint: drop the "raise DEVKIT_LOCAL_TIMEOUT" wording.
  That env var is only read by LocalRunner.Run, not Probe; the hint lied.
  Rephrased to point at server health + DEVKIT_LOCAL_ENDPOINT.
- probe.go endpoint normalization: strings.TrimRight("/") before appending
  "/models" so users with a trailing slash on DEVKIT_LOCAL_ENDPOINT don't
  get http://host/v1//models.
- probe.go unreachableHint: add a doc comment explaining the intentional
  `err || ctx.Err()` OR pattern so it survives future "simplification".
- probe_local.go + README.md: update the exit-code contract to state that
  exit 0 covers both healthy and disabled (the code already did this; the
  docs lied).
- local_test.go Available_Gating: split the 200 case into "model missing"
  (empty /data) and "model present" (matching DEVKIT_LOCAL_MODEL). Without
  the second case a switch inversion at local.go:75 would pass tests.
- probe_test.go TestProbe_CallerCanceled: replace the goroutine + Sleep(30ms)
  race with a `started` channel the handler closes when it's in flight; the
  test canceller blocks on receive. Deterministic, faster, not CI-flaky.

Skipped: the pr-review-toolkit findings both reviewers independently classified
as padding (cfg.Timeout=0-infinite-wait premise is wrong per Go context
semantics; doubled context+client timeout is redundant not a bug; body ReadAll
err discard + missing Hint on 2xx-ReadAll branch are inconsistencies; "only
default branch logs" is wrong as stated — no default branch exists; bare
sentinel fragility is hypothetical).
@5uck1ess
5uck1ess merged commit eb2b70d into main Apr 17, 2026
6 checks passed
@5uck1ess
5uck1ess deleted the chore/probe-local-tri-review-followups branch April 17, 2026 21:25
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.

1 participant