Skip to content

[Bug] Antigravity live discovery is blocked under TUN Fake-IP because its canonical URL is not registered #4261

Closed

Description

@juzijia

Client or integration

Other — OpenCodex dashboard and ocx CLI in Docker behind a Clash/Mihomo-style TUN.

Provider or upstream service

google-antigravity / Google Cloud Code Assist (Gemini)

OpenCodex version

2.50.0 (2d4d7a22381a2e497c2442902104619e25f937c7)

Endpoint or capability

Live model discovery and provider connection test:

POST https://daily-cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels

Current behaviour

With TUN-only Fake-IP DNS and no HTTP_PROXY, HTTPS_PROXY, or ALL_PROXY in the Docker container, daily-cloudcode-pa.googleapis.com resolves to 198.18.7.201. OpenCodex builds the correct POST RPC, but isRegistryModelDiscoveryUrl() returns false because the google-antigravity registry entry has no modelDiscovery declaration. Destination policy blocks the request before HTTP and the dashboard falls back to configured models with “Discovery failed”.

Excluding only this hostname from Fake-IP makes the same account and configuration immediately discover 7 models. This rules out OAuth, account location, and the upstream response as the cause of this reproduction. This is not #723: no GET /models request or HTTP 404 occurs.

Expected behaviour

The exact built-in Antigravity discovery RPC should use the existing canonical TUN/Fake-IP exception. Custom hosts, modified paths or queries, literal benchmark-IP URLs, and unsafe DNS companions must remain blocked.

Minimal redacted request or reproduction

# Docker uses host/TUN DNS; no HTTP_PROXY/HTTPS_PROXY/ALL_PROXY is set.
getent ahostsv4 daily-cloudcode-pa.googleapis.com
# 198.18.7.201 ...

ocx provider test google-antigravity --json

# Runtime construction (redacted):
# method=POST
# url=https://daily-cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels
# canonicalDiscoveryProof=false

Actual response or error

Provider model discovery for "google-antigravity" was blocked by destination policy: provider URL hostname daily-cloudcode-pa.googleapis.com resolves to benchmark address (198.18.7.201) [urlClass=provider-models, fallback=configured].

No upstream HTTP status exists because the request is blocked before transmission.

Upstream documentation

No public specification was found for the private Cloud Code Assist discovery RPC. OpenCodex already implements and tests this authenticated POST contract in buildModelsRequest() and parseAntigravityAvailableModels(); #1897 established the live endpoint.

Suggested mapping or implementation notes

A minimal isolated experiment added the following declaration to the canonical google-antigravity registry entry:

modelDiscovery: { path: "./v1internal:fetchAvailableModels" }

The relative form preserves custom base URLs and path prefixes. In an isolated patched container forced to resolve the official host to 198.18.7.201, canonical proof became true, ocx provider test returned 7 models, and a Gemini 3.8 Flash request completed with HTTP 200.

A new regression test was red on the unmodified v2.50.0 image (39 pass / 1 fail) and green after the change. Four focused suites passed 87/87, along with TypeScript typecheck, Docker compatibility-manifest validation, Docker runtime build, GUI production build, and git diff --check.

The exact canonical URL was admitted. A custom https://custom.example/proxy destination retained its URL and canonicalDiscoveryProof=false; foreign-host and query-modified URLs also remained false. An absolute modelDiscovery.url experiment was rejected because it retargeted same-named custom-base-URL providers to the Google host.

Additional context and attachments

Related: #3781 (Antigravity quota-side canonical Fake-IP handling), #3618 (canonical TUN discovery infrastructure), #723 (historical GET /models bug; different endpoint and error), and #1897 (current Antigravity POST discovery RPC).

The same HTTP-preflight pattern may also affect the Grok and Claude discovery endpoints when they resolve into 198.18.0.0/15, but those providers were not authenticated or verified end to end here. They are mentioned only as possible follow-up scope for maintainers to assess, not as confirmed regressions and not as part of the requested fix.

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on the existing canonical TUN/Fake-IP contract and the concrete built-in Antigravity discovery endpoint.

Activity

  1. added
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    providerProvider adapters, OpenAI-compat presets, upstream API quirks
    on Sep 11, 2026
  2. lidge-jun commented on Sep 11, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 74 / 80

    이 이슈는 Docker + Clash/Mihomo 스타일 TUN Fake-IP 환경에서 google-antigravity 라이브 모델 디스커버리가 HTTP까지 가지 못하고 destination policy에 막히는 버그를 보고합니다. 재현 핵심은 DNS가 daily-cloudcode-pa.googleapis.com을 198.18.7.201 같은 벤치마크 대역으로만 풀어 주는 경우입니다. OpenCodex는 이미 POST …/v1internal:fetchAvailableModels RPC를 올바르게 만들고(src/oauth/index.ts의 buildModelsRequest, cloud-code-assist 분기), 응답 파싱도 parseAntigravityAvailableModels로 갖춰 두었습니다. 그런데 Fake-IP 예외를 켜는 증명 함수 isRegistryModelDiscoveryUrl()(src/providers/model-discovery.ts)은 레지스트리 항목의 modelDiscovery 선언이 있어야만 true가 됩니다. 현재 dev HEAD(ac3c3d66b)의 src/providers/registry.ts google-antigravity 줄은 liveModels: true인데 modelDiscovery가 없습니다. 그래서 canonicalDiscoveryProof=false가 되고, src/codex/catalog/provider-fetch.ts가 destination policy로 차단한 뒤 대시보드가 “Discovery failed”로 설정된 모델만 보여 줍니다. 호스트만 Fake-IP에서 빼면 같은 계정으로 7개 모델이 바로 뜨므로 OAuth·위치·업스트림 응답 문제는 아닙니다. #723(옛 GET /models 404)과도 다릅니다.

    같은 호스트·같은 :fetchAvailableModels URL은 이미 쿼터 쪽에서 Fake-IP 예외를 갖고 있습니다. src/providers/quota.ts의 isCanonicalAntigravityQuotaUrl과 #3781 테스트가 그 계약입니다. 즉 “정본 CCA URL이면 TUN DNS를 믿어도 된다”는 정책은 쿼터에는 있고, 카탈로그 디스커버리에는 빠진 반쪽 상태입니다. #3618이 깔아 둔 카노니컬 TUN discovery 인프라와 command-code 등 다른 liveModels 제공자의 modelDiscovery 선언 패턴과도 맞습니다. 제보자가 제안한 modelDiscovery: { path: "./v1internal:fetchAvailableModels" }는 레지스트리 baseUrl에 상대 경로로 붙기 때문에 커스텀 baseUrl을 구글 호스트로 덮어쓰지 않고, isRegistryModelDiscoveryUrl의 path 스펙 경로와도 일치합니다. 절대 url 실험이 커스텀 base를 구글로 되돌린 점도 제보에 잘 정리되어 있어, 상대 path가 맞는 선택입니다.

    라인 - src/providers/registry.ts google-antigravity 항목 - liveModels: true인데 modelDiscovery가 없어 isRegistryModelDiscoveryUrl이 항상 false → Fake-IP에서 정본 디스커버리 RPC가 차단됨
    src/providers/model-discovery.ts isRegistryModelDiscoveryUrl - 스펙 없으면 즉시 false; 동작은 맞지만 Antigravity 레지스트리 공백을 드러냄
    src/oauth/index.ts buildModelsRequest cloud-code-assist 분기 - RPC URL은 이미 올바름; Fake-IP 예외와 연결만 빠짐
    src/providers/quota.ts isCanonicalAntigravityQuotaUrl - 같은 :fetchAvailableModels를 쿼터용으로만 허용; 카탈로그 proof와 이중 관리됨
    src/codex/catalog/provider-fetch.ts destination policy 로그 - 증상 메시지는 정확함; 근본 수정 지점은 레지스트리 선언

    메인테이너의 판단이 필요한 지점

    • 최소 수정으로 google-antigravity에만 modelDiscovery.path를 넣을지, 쿼터 canonical 헬퍼와 카탈로그 proof를 한곳으로 모을지
    • 제보가 언급한 Grok/Claude 디스커버리 Fake-IP 후속 범위를 같은 PR에 넣을지, Antigravity만 먼저 닫을지
    • path: "./v1internal:fetchAvailableModels" vs 쿼터와 동일한 절대 URL 스펙 중 무엇을 계약으로 고정할지(커스텀 baseUrl 보존이 요구사항이면 path가 맞음)
    • 회귀 테스트를 tests/providers/provider-model-discovery-contract.test.ts / Fake-IP 계열에 Antigravity 정본 URL proof만 추가할지, 제보의 통합 재현까지 넣을지

    너의 추천
    google-antigravity 레지스트리에 modelDiscovery: { path: "./v1internal:fetchAvailableModels" }만 추가하는 작은 PR을 받고, Fake-IP로 정본 URL이 proof=true·커스텀/변조 URL은 false인 회귀 테스트를 붙이세요. 쿼터 쪽 isCanonicalAntigravityQuotaUrl과 문서/주석으로 같은 CCA URL임을 한 줄 연결해 두면 #3781과의 대칭이 보입니다. Grok/Claude Fake-IP는 확인 재현 없이 같은 PR에 넣지 마세요. help wanted로 두어도 되고, 패치가 오면 빠르게 dev에 합치세요.

    이 댓글은 grok-bot이 작성했습니다

  3. lidge-jun commented on Sep 11, 2026

    @lidge-jun
    Owner

    Fixed on dev by #4267.
    google-antigravity declares its canonical CCA discovery RPC, so isRegistryModelDiscoveryUrl proves it and the TUN Fake-IP exception applies. The request URL itself is unchanged.
    Closing manually: pull requests here target dev, so GitHub's Closes linkage only fires on a merge into main. This will reach users in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, plansproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions