Skip to content

fix(selfhost): make AI-provider failures loud + attribute the actual reviewer + boot CLI preflight#1575

Merged
JSONbored merged 1 commit into
mainfrom
fix/selfhost-ai-fail-loud
Jun 27, 2026
Merged

fix(selfhost): make AI-provider failures loud + attribute the actual reviewer + boot CLI preflight#1575
JSONbored merged 1 commit into
mainfrom
fix/selfhost-ai-fail-loud

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

#1566. The self-host engine silently produced zero AI output for 202 reviews when the claude CLI was absent: spawn('claude') ENOENT'd, runWorkersOpinion's bare catch swallowed it, and record() logged the Workers-AI model ids — so the outage was invisible (no Review-summary/blockers/nits). (1) log every failed provider attempt; (2) attribute the actual configured reviewer (AI_PROVIDER:AI_MODEL); (3) boot preflight selfhost_ai_cli_missing when a CLI provider's binary isn't on PATH. The CLI-install itself is fixed in the deploy (compose INSTALL_AI_CLIS=true); this makes a recurrence impossible to miss.

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jun 27, 2026
@superagent-security

Copy link
Copy Markdown

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jun 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.43%. Comparing base (104ac4b) to head (3a5a3cc).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1575   +/-   ##
=======================================
  Coverage   95.43%   95.43%           
=======================================
  Files         202      202           
  Lines       21759    21763    +4     
  Branches     7862     7863    +1     
=======================================
+ Hits        20765    20769    +4     
  Misses        416      416           
  Partials      578      578           
Files with missing lines Coverage Δ
src/services/ai-review.ts 98.57% <100.00%> (+0.02%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…reviewer + boot CLI preflight

#1566. The self-host engine silently produced ZERO AI output for 202 reviews when the claude CLI was absent:
spawn('claude') ENOENT'd, runWorkersOpinion's bare catch swallowed it, and record() logged the Workers-AI model
ids — so the outage was invisible (no Review-summary/blockers/nits on any comment). Now: (1) runWorkersOpinion logs
every failed provider attempt; (2) record() attributes the actual configured reviewer (AI_PROVIDER:AI_MODEL) not
BEST_REVIEW_MODELS; (3) a boot preflight shouts selfhost_ai_cli_missing when AI_PROVIDER=claude-code|codex but the
CLI is not on PATH.
@JSONbored JSONbored force-pushed the fix/selfhost-ai-fail-loud branch from 02e563e to 3a5a3cc Compare June 27, 2026 01:39
@gittensory-orb

gittensory-orb Bot commented Jun 27, 2026

Copy link
Copy Markdown

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review — held for maintainer review

3 files · 1 AI reviewers · no blockers · readiness 66/100 · CI green · unknown

⏸️ Held for maintainer review

Review summary
This PR fixes a three-part silent outage on the self-host path: the bare `catch {}` in `runWorkersOpinion` swallowed every spawn ENOENT so provider failures were invisible, `record()` always logged Workers-AI model ids regardless of the configured provider, and there was no signal at boot that a CLI binary was missing. All three are corrected — the catch now logs via `errorMessage`, `reviewerModelLabel` returns `AI_PROVIDER:AI_MODEL` when set, and the server.ts preflight checks PATH at startup. The new test validates the degraded-but-attributed path end-to-end and is correctly structured.

Nits (5)

  • In `ai-review.ts`'s `reviewerModelLabel`, the `env as unknown as { AI_PROVIDER?: string; AI_MODEL?: string }` double-cast works today but isn't enforced by the type system — if the self-host wiring stops injecting these, the cast silently returns `undefined` and the guard falls back to `BEST_REVIEW_MODELS.join('+')`, recreating the exact mis-attribution this PR fixes; these fields should be typed on a self-host Env extension.
  • The boot preflight in `server.ts` logs at `error` level but lets the server start normally, so an operator who misses the log gets the same degraded behavior with no process-level signal; consider setting `process.exitCode = 1` so orchestrators and CI can detect the misconfiguration.
  • The new test in `ai-review-advisory.test.ts` has an unformatted ~200-char `runAiReviewForAdvisory` call on a single line; break the options object across lines to match the file's existing formatting conventions.
  • In `src/services/ai-review.ts`, define a typed self-host extension of `Env` (e.g. `type SelfHostEnv = Env & { AI_PROVIDER?: string; AI_MODEL?: string }`) and cast to that instead of the double-cast `as unknown as` — TypeScript will then catch any future struct drift that would silently break attribution.
  • In `src/server.ts`, after the `console.error` for `selfhost_ai_cli_missing`, add `process.exitCode = 1` so the misconfiguration is detectable by process supervisors and health checks without relying solely on log scraping.
Signal Result Evidence
Code review ✅ No blockers 1 reviewers, synthesized
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Review load ✅ 20/20 Readiness component derived from cached public PR metadata and labels; size label size:M.
Validation evidence ❌ 5/25 Cached preflight status is hold.
Open PR queue ❌ 3/10 20 open PR(s), 9 likely reviewable, 11 unlinked.
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 81 PR(s), 297 issue(s).
Gate result ✅ Passing No configured blocker found.
Nits — 2 non-blocking
  • Repository config was not parsed
  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository registration is not available in the local Gittensory cache.
  • Public profile languages: not available
  • Official Gittensor activity: 81 PR(s), 297 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Fix blocker.
  • Expect slower review.
  • Refresh registry data or choose a registered active repo.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Review load = cached public PR metadata such as size labels, changed paths, and preflight status.
  • Open PR queue = repo-wide review pressure; it is not a PR quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
Review details

Generated from public PR metadata and the diff. Advisory only; deterministic signals remain authoritative.

This PR fixes a three-part silent outage on the self-host path: the bare `catch {}` in `runWorkersOpinion` swallowed every spawn ENOENT so provider failures were invisible, `record()` always logged Workers-AI model ids regardless of the configured provider, and there was no signal at boot that a CLI binary was missing. All three are corrected — the catch now logs via `errorMessage`, `reviewerModelLabel` returns `AI_PROVIDER:AI_MODEL` when set, and the server.ts preflight checks PATH at startup. The new test validates the degraded-but-attributed path end-to-end and is correctly structured.

Nits (5)

  • In `ai-review.ts`'s `reviewerModelLabel`, the `env as unknown as { AI_PROVIDER?: string; AI_MODEL?: string }` double-cast works today but isn't enforced by the type system — if the self-host wiring stops injecting these, the cast silently returns `undefined` and the guard falls back to `BEST_REVIEW_MODELS.join('+')`, recreating the exact mis-attribution this PR fixes; these fields should be typed on a self-host Env extension.
  • The boot preflight in `server.ts` logs at `error` level but lets the server start normally, so an operator who misses the log gets the same degraded behavior with no process-level signal; consider setting `process.exitCode = 1` so orchestrators and CI can detect the misconfiguration.
  • The new test in `ai-review-advisory.test.ts` has an unformatted ~200-char `runAiReviewForAdvisory` call on a single line; break the options object across lines to match the file's existing formatting conventions.
  • In `src/services/ai-review.ts`, define a typed self-host extension of `Env` (e.g. `type SelfHostEnv = Env & { AI_PROVIDER?: string; AI_MODEL?: string }`) and cast to that instead of the double-cast `as unknown as` — TypeScript will then catch any future struct drift that would silently break attribution.
  • In `src/server.ts`, after the `console.error` for `selfhost_ai_cli_missing`, add `process.exitCode = 1` so the misconfiguration is detectable by process supervisors and health checks without relying solely on log scraping.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

@gittensory-orb gittensory-orb Bot added gittensor Gittensor contributor context gittensor:bug Gittensor-scored bug fix - worth 0.5x multiplier. labels Jun 27, 2026
@JSONbored JSONbored merged commit 2446a04 into main Jun 27, 2026
20 checks passed
@JSONbored JSONbored deleted the fix/selfhost-ai-fail-loud branch June 27, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix - worth 0.5x multiplier. gittensor Gittensor contributor context size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant