Skip to content

fix(selfhost): distinguish stale codex-reviewer env var, cool down its circuit breaker#7513

Closed
JSONbored wants to merge 1 commit into
mainfrom
fix/codex-credential-isolation-env-rename
Closed

fix(selfhost): distinguish stale codex-reviewer env var, cool down its circuit breaker#7513
JSONbored wants to merge 1 commit into
mainfrom
fix/codex-credential-isolation-env-rename

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

codex_credential_isolation_required errors have been recurring since 2026-07-16 on a self-host install that was previously working (Sentry: LOOPOVER-28/2A/2C/29). The credential-isolation guard itself (assertCodexCredentialIsolation, src/selfhost/ai.ts) is correct, intentional security hardening from #1609 — not a bug. The problem is upstream: the GITTENSORY_LOOPOVER_ env var rebrand (#5652) retired dual-read support and hardcoded a strict LOOPOVER_ENABLE_UNSAFE_CODEX_REVIEWER === "1" check. An operator whose .env still uses the legacy name silently reverts to fully-disabled, with the exact same generic error as never having configured it at all.

This is compounded by isStructuralProviderConfigError's regex not matching codex_credential_isolation_required, so the per-provider circuit breaker gives this deterministic failure the default 60s cooldown instead of the hour-long structural one — the exact flood pattern that circuit breaker was built to prevent (its own comment cites LOOPOVER-K/8's 2094 + 544 events).

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Closes #7466

Validation

  • git diff --check
  • npm run typecheck
  • npm run test:coverage locally — new test cases cover both the legacy-var rename hint and the CODEX_HOME-takes-priority case (test/unit/selfhost-ai.test.ts), and both the bare + colon-suffixed codex_credential_isolation_required forms of the circuit-breaker regex (test/unit/ai-review.test.ts); isolated coverage on both changed files is 100% for the new code (the two pre-existing uncovered lines the full-file report shows are unrelated defaults elsewhere in each file)
  • npm run branding-drift:check — regenerated the baseline (npm run branding-drift:update) since the fix's own legacy-var detection necessarily references "gittensory" 3 more times in src/selfhost/ai.ts; a real, intentional increase, not drift
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (N/A — no auth/session/CORS surface touched; this only refines an existing security guard's error message and its circuit-breaker classification.)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (N/A.)
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (N/A — no UI changes.)
  • Visible UI changes include a UI Evidence section. (N/A — no visible UI change.)
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs. (N/A — internal error-message + circuit-breaker classification fix; apps/loopover-ui/content/docs/self-hosting-ai-providers.mdx already documents codex_credential_isolation_required correctly.)

Notes

  • Root-caused via Sentry triage, cross-referencing git log -S dualPrefixEnvFlag and git show on the rebrand commit to confirm the env-var retirement was deliberate (not itself a bug) before designing this fix.

…s circuit breaker (#7466)

Two related gaps in the codex_credential_isolation_required path:

1. The GITTENSORY_->LOOPOVER_ env var rebrand (#5652) retired dual-read
   support for GITTENSORY_ENABLE_UNSAFE_CODEX_REVIEWER and hardcoded a
   strict LOOPOVER_ENABLE_UNSAFE_CODEX_REVIEWER check. An operator whose
   .env still uses the legacy name silently reverts to fully-disabled, with
   no signal distinguishing that from never having configured it at all.
   assertCodexCredentialIsolation now throws a specific, actionable message
   in that one case -- CODEX_HOME being the actual blocker still takes
   priority, since renaming the var can't fix that.

2. isStructuralProviderConfigError's regex didn't match
   codex_credential_isolation_required, so the per-provider circuit breaker
   gave it the default 60s cooldown instead of the hour-long structural one
   -- the exact flood pattern that cooldown was built to prevent (see its
   own comment citing LOOPOVER-K/8's 2094 + 544 events).

Regenerated the branding-drift baseline: the fix's own detection
necessarily references the retired "gittensory" env var name in
src/selfhost/ai.ts, a genuine increase the drift check correctly flagged.
@superagent-security

Copy link
Copy Markdown
Contributor

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

@JSONbored JSONbored self-assigned this Jul 20, 2026
@JSONbored

Copy link
Copy Markdown
Owner Author

Superseded by #7473, which merged first and fixes the same root cause (the codex-reviewer env var rename regression + the circuit-breaker regex gap) via an equivalent approach. Closing to avoid landing duplicate/conflicting logic.

@JSONbored JSONbored closed this Jul 20, 2026
@JSONbored
JSONbored deleted the fix/codex-credential-isolation-env-rename branch July 20, 2026 19:56
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.

fix(selfhost): distinguish stale codex-reviewer env var from unconfigured, and cool down its circuit breaker

1 participant