You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The env-gather autodetect mechanism has a chicken-and-egg bug: it can only detect auth types based on keys already present in the dispatch environment. When a secret (e.g., GEMINI_API_KEY) is stored as as_needed, it is excluded from the first-pass dispatch. If the harness's default_type doesn't require that key, autodetect never discovers it, the broker never requests it, and the agent starts without credentials.
Impact: Any harness whose default_type is NOT api-key (e.g., antigravity with default_type: oauth-token) will fail to receive as_needed API key secrets. The agent crashes on startup with no credentials.
This is a core upstream defect in the env-gather mechanism, not specific to any single harness.
Root cause
The two-pass env resolution creates a blind spot:
Pass 1 — Hub builds initial dispatch
resolveSecrets() (httpdispatcher.go:2780) filters out as_needed env-type secrets. GEMINI_API_KEY is excluded from req.ResolvedEnv.
Pass 1 — Broker evaluates env completeness
pickAutodetectCandidate() (auth.go:467) checks presentKeys — keys in req.ResolvedEnv. GEMINI_API_KEY is absent → autodetect finds no match → returns "".
RequiredAuthEnvKeysFromConfig() (auth.go:352) falls back to default_type:
gemini-cli: default_type=api-key → requires GEMINI_API_KEY → broker reports it as "needed" ✅
antigravity: default_type=oauth-token → requires only file secrets → broker does NOT report GEMINI_API_KEY ❌
Pass 2 — Hub resolves as_needed keys
resolveAsNeededForKeys() (httpdispatcher.go:1636) only resolves keys the broker asked for. Since the broker never asked for GEMINI_API_KEY (for antigravity), it's never sent.
Concrete example
gemini-cli
antigravity
default_type
api-key
oauth-token
autodetect.env.GEMINI_API_KEY
api-key
api-key
Autodetect finds GEMINI_API_KEY?
No (not in env)
No (not in env)
Fallback requires GEMINI_API_KEY?
Yes (api-key needs it)
No (oauth-token doesn't)
Agent gets GEMINI_API_KEY?
Yes (via pass 2)
No — crash
Fix options
Option A: Pass available as_needed key names to broker (recommended)
Hub includes as_needed secret target key names (without values) in the dispatch request (e.g., req.AvailableAsNeededKeys). Broker's autodetect treats these as "present" for candidate selection. If autodetect matches, broker reports the key as "needed" and hub resolves it in pass 2.
Option B: Broker speculatively requests all autodetect keys
Broker sends ALL keys from autodetect.env as "needed" regardless of presence. Hub resolves whichever ones exist as as_needed secrets. Simple but over-fetches.
Option C: Harness-level workaround (quickest, not durable)
Change antigravity's default_type from oauth-token to api-key in harnesses/antigravity/config.yaml:75. Fixes antigravity specifically but doesn't fix the core mechanism — any future harness with a non-api-key default_type will hit the same bug.
Existing regression test
pkg/hub/envgather_hubscope_regression_test.go (regression #721) documents this exact gap with GEMINI_API_KEY + as_needed + ScopeHub. The test comments note it "SHOULD PASS once the fix is applied."
Files
pkg/harness/auth.go:467-494 — pickAutodetectCandidate() only checks presentKeys
pkg/harness/auth.go:352-382 — RequiredAuthEnvKeysFromConfig() falls back to default_type
pkg/runtimebroker/handlers.go:2094-2236 — extractRequiredEnvKeys() runs autodetect then fallback
pkg/hub/httpdispatcher.go:1636 — resolveAsNeededForKeys() only resolves broker-requested keys
pkg/hub/httpdispatcher.go:2780 — resolveSecrets() filters out as_needed env secrets
Bug
The env-gather autodetect mechanism has a chicken-and-egg bug: it can only detect auth types based on keys already present in the dispatch environment. When a secret (e.g., GEMINI_API_KEY) is stored as
as_needed, it is excluded from the first-pass dispatch. If the harness'sdefault_typedoesn't require that key, autodetect never discovers it, the broker never requests it, and the agent starts without credentials.Impact: Any harness whose
default_typeis NOTapi-key(e.g., antigravity withdefault_type: oauth-token) will fail to receiveas_neededAPI key secrets. The agent crashes on startup with no credentials.This is a core upstream defect in the env-gather mechanism, not specific to any single harness.
Root cause
The two-pass env resolution creates a blind spot:
Pass 1 — Hub builds initial dispatch
resolveSecrets()(httpdispatcher.go:2780) filters outas_neededenv-type secrets. GEMINI_API_KEY is excluded fromreq.ResolvedEnv.Pass 1 — Broker evaluates env completeness
pickAutodetectCandidate()(auth.go:467) checkspresentKeys— keys inreq.ResolvedEnv. GEMINI_API_KEY is absent → autodetect finds no match → returns"".RequiredAuthEnvKeysFromConfig()(auth.go:352) falls back todefault_type:default_type=api-key→ requiresGEMINI_API_KEY→ broker reports it as "needed" ✅default_type=oauth-token→ requires only file secrets → broker does NOT report GEMINI_API_KEY ❌Pass 2 — Hub resolves as_needed keys
resolveAsNeededForKeys()(httpdispatcher.go:1636) only resolves keys the broker asked for. Since the broker never asked for GEMINI_API_KEY (for antigravity), it's never sent.Concrete example
default_typeapi-keyoauth-tokenautodetect.env.GEMINI_API_KEYapi-keyapi-keyFix options
Option A: Pass available as_needed key names to broker (recommended)
Hub includes
as_neededsecret target key names (without values) in the dispatch request (e.g.,req.AvailableAsNeededKeys). Broker's autodetect treats these as "present" for candidate selection. If autodetect matches, broker reports the key as "needed" and hub resolves it in pass 2.Option B: Broker speculatively requests all autodetect keys
Broker sends ALL keys from
autodetect.envas "needed" regardless of presence. Hub resolves whichever ones exist asas_neededsecrets. Simple but over-fetches.Option C: Harness-level workaround (quickest, not durable)
Change antigravity's
default_typefromoauth-tokentoapi-keyinharnesses/antigravity/config.yaml:75. Fixes antigravity specifically but doesn't fix the core mechanism — any future harness with a non-api-key default_type will hit the same bug.Existing regression test
pkg/hub/envgather_hubscope_regression_test.go(regression #721) documents this exact gap with GEMINI_API_KEY +as_needed+ScopeHub. The test comments note it "SHOULD PASS once the fix is applied."Files
pkg/harness/auth.go:467-494—pickAutodetectCandidate()only checkspresentKeyspkg/harness/auth.go:352-382—RequiredAuthEnvKeysFromConfig()falls back todefault_typepkg/runtimebroker/handlers.go:2094-2236—extractRequiredEnvKeys()runs autodetect then fallbackpkg/hub/httpdispatcher.go:1636—resolveAsNeededForKeys()only resolves broker-requested keyspkg/hub/httpdispatcher.go:2780—resolveSecrets()filters outas_neededenv secretspkg/hub/envgather_hubscope_regression_test.go— existing regression test (fix: hub-scope as_needed secrets invisible to env-gather completeness check #721)harnesses/antigravity/config.yaml:75—default_type: oauth-tokenharnesses/gemini-cli/config.yaml:70—default_type: api-keyInvestigation:
/scion-volumes/scratchpad/projects/single-node/investigations/sn-agy-crash-findings.mdReported by sn-lead.