fix(google): discover Antigravity live models - #1178
Conversation
|
✅ READY
Review readiness checklist
✅ 4/4 boxes ticked. This pull request is already Ready for Review. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughGoogle Antigravity now uses authenticated Cloud Code Assist model discovery. OAuth project IDs flow into POST requests. Responses expose account-available agent models with metadata and retain static catalog fallback behavior. Cache generations prevent stale results after account or configuration changes. ChangesAntigravity live discovery
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Provider as Google Antigravity
participant OAuth as OAuth access snapshot
participant Outbound as Provider outbound transport
participant CCA as Cloud Code Assist
participant Parser as Antigravity model parser
Provider->>OAuth: Resolve access token and projectId
OAuth->>Outbound: Build authenticated POST request
Outbound->>CCA: POST v1internal:fetchAvailableModels
CCA-->>Parser: Return available-model payload
Parser-->>Provider: Return parsed models or fallback catalog
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Requesting maintainer security review for the OAuth-bound Antigravity discovery change. The hygiene gate requires the If the review confirms this boundary is acceptable, please apply |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/codex/catalog/provider-fetch.ts`:
- Around line 951-963: Replace the direct POST fetch in provider-fetch.ts lines
951-963 with the shared policy-enforced POST outbound transport, preserving the
existing URL, headers, OAuth project body, redirect, and timeout behavior. Apply
the same transport to the connectivity probe in provider-routes.ts lines
485-497, ensuring both OAuth Bearer POST paths enforce destination controls and
HTTPS requirements.
In `@src/providers/antigravity-models.ts`:
- Around line 174-175: Update the CCA model ID loop in the model-loading flow to
apply the same identifier validation as extractProviderModelItems before adding
IDs to ids. Reject the entire malformed CCA payload, rather than publishing
partial IDs, so the existing static fallback is used.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: e43a4a2d-922d-4624-9122-be0941f5c078
📒 Files selected for processing (19)
docs-site/src/content/docs/contributing.mddocs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/guides/providers.mddocs-site/src/content/docs/ko/guides/providers.mddocs-site/src/content/docs/ru/guides/providers.mddocs-site/src/content/docs/zh-cn/guides/providers.mdsrc/codex/catalog/provider-fetch.tssrc/codex/convergence-types.tssrc/oauth/index.tssrc/providers/antigravity-models.tssrc/providers/registry.tssrc/server/management/provider-routes.tssrc/server/responses/core.tstests/antigravity-static-catalog.test.tstests/codex-catalog.test.tstests/google-models-listing.test.tstests/oauth-provider-reconcile.test.tstests/provider-connection-test.test.tstests/provider-registry-parity.test.ts
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
ast-grep outline src/oauth/index.ts --items all --type function,interface --match 'OAuthAccessSnapshot|resolveOAuthAccessSnapshot|buildModelsRequest|saveCredential|getOAuthCredentialProjectId'
ast-grep outline src/codex/catalog/provider-fetch.ts --items all --type function --match 'fetch|discover|OAuth|model'
ast-grep outline src/server/management/provider-routes.ts --items all --type function --match 'test|connection|model'
ast-grep outline src/providers/antigravity-models.ts --items all --type function,interface --match 'Antigravity|parse'
printf '\n=== OAuth snapshot, credential, request, and logging references ===\n'
rg -n -C 4 --type ts \
'OAuthAccessSnapshot|resolveOAuthAccessSnapshot|projectId|buildModelsRequest|fetchAvailableModels|console\.(log|debug|info|warn|error)|logger\.' \
src/oauth/index.ts src/codex/catalog/provider-fetch.ts src/server/management/provider-routes.ts src/server/responses/core.ts src/providers/antigravity-models.ts
printf '\n=== Persistence and serialization references ===\n'
rg -n -C 3 --type ts \
'saveCredential|loadCredential|writeFile|JSON\.stringify|credentials|projectId' \
src/oauth src/codex src/server | head -n 500Length of output: 80446 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n=== Catalog authenticated discovery path ===\n'
sed -n '810,1110p' src/codex/catalog/provider-fetch.ts
printf '\n=== OAuth request construction and snapshot refresh ===\n'
sed -n '280,395p' src/oauth/index.ts
sed -n '649,686p' src/oauth/index.ts
printf '\n=== Credential normalization and auth-store protection ===\n'
sed -n '230,270p' src/oauth/store.ts
sed -n '170,196p' src/oauth/store.ts
printf '\n=== Antigravity response parser ===\n'
sed -n '139,205p' src/providers/antigravity-models.ts
printf '\n=== Relevant test definitions and assertions ===\n'
rg -n -C 8 --type ts \
'fetchAvailableModels|oauthProjectId|projectId|Authorization|Antigravity.*discover|availableModels' \
tests/google-models-listing.test.ts tests/provider-connection-test.test.ts tests 2>/dev/null | head -n 600Length of output: 76825 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n=== Request capture and discovery URL construction ===\n'
sed -n '300,385p' src/codex/catalog/provider-fetch.ts
rg -n -C 5 --type ts \
'function providerOutboundGet|providerOutboundGet\(|ProviderOutboundPolicyError|resolveProviderModelDiscoveryUrl|modelDiscoveryTransportSeed|CapturedModelsRequest|capture.*[Mm]odels' \
src
printf '\n=== Cloud Code Assist configuration and URL override tests ===\n'
rg -n -C 6 --type ts \
'cloud-code-assist|google-antigravity|modelsUrl|modelDiscovery|baseUrl.*daily-cloudcode|daily-cloudcode.*baseUrl' \
src/providers src/oauth src/codex tests | head -n 700Length of output: 91185
I found no blocking security issue in the Antigravity discovery change.
A maintainer can apply the
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 929ef8b46c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Addressed the merge-blocking review feedback in bfaddd6.
Verification: |
|
|
|
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bfaddd6a38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Addressed the three P2 findings in 908641f.
Validation: The existing Minor CCA model-ID validation thread remains open; it is outside this P2 blocker-only scope. |
|
|
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== Repository and commit ==='
git status --short --branch
git show -s --format='%H%n%P%n%s' HEAD
git branch -a
echo '=== PR diff summary ==='
if git rev-parse --verify origin/dev >/dev/null 2>&1; then
git diff --stat origin/dev...HEAD
git diff --name-only origin/dev...HEAD
else
git diff --stat HEAD^...HEAD
git diff --name-only HEAD^...HEAD
fi
echo '=== Final incremental commit ==='
git show --format=fuller --find-renames --find-copies --stat HEAD
git diff HEAD^ HEAD -- \
src/codex/model-cache.ts \
src/codex/catalog/provider-fetch.ts \
src/providers/antigravity-models.ts \
src/providers/model-discovery.ts \
src/providers/model-discovery-limits.ts \
src/oauth/index.ts \
tests/cursor-hardening.test.ts \
tests/model-cache.test.ts \
tests/google-antigravity-wire.test.ts \
tests/google-models-listing.test.ts
echo '=== Relevant outlines ==='
ast-grep outline src/codex/model-cache.ts --items all --type function --match 'cache|generation|clear|set|reconcile'
ast-grep outline src/providers/antigravity-models.ts --items all --type function,interface --match 'Antigravity|parse|available'
ast-grep outline src/providers/model-discovery-limits.ts --items all --type function --match 'Valid|model'
ast-grep outline src/codex/catalog/provider-fetch.ts --items all --type function --match 'fetch|discover|cache|warn'
echo '=== Relevant references ==='
rg -n -C 6 --type ts \
'captureModelCacheGeneration|isModelCacheGenerationCurrent|setCached\(|clearModelCache|reconcile.*[Pp]rovider|parseAntigravityAvailableModels|isValidModelDiscoveryModelId|MODEL_DISCOVERY_MAX|stale|generation' \
src/codex/model-cache.ts src/codex/catalog/provider-fetch.ts \
src/providers/antigravity-models.ts src/providers/model-discovery.ts \
src/providers/model-discovery-limits.ts tests/cursor-hardening.test.ts \
tests/model-cache.test.ts tests/google-antigravity-wire.test.ts \
tests/google-models-listing.test.tsLength of output: 101496 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '=== OAuth migration and reconciliation ==='
sed -n '700,900p' src/oauth/index.ts
sed -n '1,180p' src/config.ts
rg -n -C 8 --type ts \
'googleAntigravityStaticCatalogVersion|reconcileOAuthProviders\(|upsertOAuthProvider\(|google-antigravity' \
src/oauth/index.ts src/config.ts src/types.ts src/providers/registry.ts \
tests/config.test.ts tests/oauth-provider-reconcile.test.ts
echo '=== Complete Antigravity parser ==='
sed -n '140,330p' src/providers/antigravity-models.ts
echo '=== Provider fetch lifecycle and cache cleanup ==='
sed -n '820,1120p' src/codex/catalog/provider-fetch.ts
sed -n '1,270p' src/codex/model-cache.ts
rg -n -C 6 --type ts \
'reconcileModelCacheGeneration|reconcileModelCacheProviders|clearGatherRoutedModelsInflight|reconcileOAuthProviders' \
src tests
echo '=== Focused migration and malformed-payload tests ==='
sed -n '1,260p' tests/oauth-provider-reconcile.test.ts
sed -n '1,220p' tests/config.test.ts
sed -n '80,230p' tests/google-models-listing.test.tsLength of output: 142542
The final changes correctly address the remaining review items:
I inspected the source and focused tests. I did not execute the test suite because the sandbox does not execute repository files.
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
base_ref="$(git merge-base HEAD origin/dev 2>/dev/null || git merge-base HEAD origin/main)"
printf '%s\n' '=== Current commit and changed files ==='
git show -s --format='%H%n%s' HEAD
git diff --stat "${base_ref}...HEAD"
git diff --name-only "${base_ref}...HEAD"
printf '%s\n' '=== Source outlines ==='
ast-grep outline src/codex/model-cache.ts --items all --type function --match 'cache|generation|clear|set|reconcile'
ast-grep outline src/codex/catalog/provider-fetch.ts --items all --type function --match 'fetch|discover|cache|generation|model'
ast-grep outline src/providers/antigravity-models.ts --items all --type function,interface --match 'Antigravity|parse'
ast-grep outline src/providers/model-discovery-limits.ts --items all --type function --match 'Valid|model'
ast-grep outline src/oauth/index.ts --items all --type function,interface --match 'OAuthAccessSnapshot|buildModelsRequest|reconcile'
printf '%s\n' '=== Final implementations ==='
sed -n '1,280p' src/codex/model-cache.ts
sed -n '780,1080p' src/codex/catalog/provider-fetch.ts
sed -n '1,280p' src/providers/antigravity-models.ts
sed -n '1,160p' src/providers/model-discovery-limits.ts
sed -n '250,420p' src/oauth/index.ts
sed -n '620,760p' src/oauth/index.ts
printf '%s\n' '=== Final-diff patch for critical paths ==='
git diff --unified=80 "${base_ref}...HEAD" -- \
src/codex/model-cache.ts \
src/codex/catalog/provider-fetch.ts \
src/providers/antigravity-models.ts \
src/providers/model-discovery-limits.ts \
src/providers/model-discovery.ts \
src/oauth/index.ts \
src/config.ts \
src/types.ts
printf '%s\n' '=== Focused regression tests ==='
rg -n -C 8 --type ts \
'parseAntigravityAvailableModels|MODEL_DISCOVERY_MAX|isValidModelDiscoveryModelId|generation|reconcile|Cursor|staticCatalogVersion|googleAntigravityStaticCatalogVersion|fetchAvailableModels' \
tests/google-antigravity-wire.test.ts tests/google-models-listing.test.ts \
tests/model-cache.test.ts tests/cursor-hardening.test.ts tests/oauth-provider-reconcile.test.ts \
tests/config.test.ts tests/provider-connection-test.test.ts 2>/dev/nullLength of output: 145462 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Cache generation implementation ==='
cat -n src/codex/model-cache.ts | sed -n '1,280p'
printf '%s\n' '=== CCA discovery and publication path ==='
rg -n -C 12 --type ts \
'parseAntigravityAvailableModels|captureModelCacheGeneration|setCached\(|isModelCacheGenerationCurrent|fetchAvailableModels|providerOutboundPost|readBoundedDiscoveryJson' \
src/codex/catalog/provider-fetch.ts src/server/management/provider-routes.ts
printf '%s\n' '=== Resolver and fixed-destination registry helper ==='
rg -n -C 12 --type ts \
'function registryEntryForProviderDestination|registryEntryForProviderDestination|function providerMatchesRegistryTransport|providerMatchesRegistryTransport|cloud-code-assist|fetchAvailableModels' \
src/providers/registry.ts src/providers/model-discovery.ts src/oauth/index.ts
printf '%s\n' '=== Antigravity parser complete range and consumers ==='
cat -n src/providers/antigravity-models.ts | sed -n '130,270p'
rg -n -C 8 --type ts \
'parseAntigravityAvailableModels\(' \
src tests
printf '%s\n' '=== Final commit patch only ==='
git diff --unified=35 HEAD^ HEAD -- \
src/codex/model-cache.ts src/codex/catalog/provider-fetch.ts \
src/providers/antigravity-models.ts src/providers/model-discovery-limits.ts \
src/providers/model-discovery.ts src/oauth/index.ts src/providers/registry.ts \
src/server/management/provider-routes.tsLength of output: 125444
I found no new blocking issue. The final changes correctly address the remaining review items:
I inspected the source and focused tests. I did not execute the test suite in this environment. You are interacting with an AI system. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 31fe1cc371
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Route Cloud Code Assist discovery POSTs through the provider outbound policy and invalidate account-scoped live model cache when OAuth credentials change.
Discard stale discovery writes after OAuth account changes, use the routed CCA project for discovery, and retain partial Gemini availability as explicit wire IDs.
Invalidate removed provider generations, migrate canonical static opt-outs, and reject malformed CCA model identifiers.
31fe1cc to
22f20ca
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Fresh rebase pushed: this branch now rebases onto the latest I also completed a real Antigravity OAuth validation on this branch using my own Google AI Pro account. The check used the branch’s observe-only OAuth discovery path: it did not refresh or persist credentials, and no credential values, account identifiers, or other personal details were emitted. Results:
Additional local validation completed successfully with Bun 1.3.14:
The fresh GitHub checks were triggered by this push. Cross-platform CI and React Doctor currently show Please re-review the updated branch, especially the OAuth-account-scoped discovery and cache invalidation behavior. Thank you. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/providers/antigravity-models.ts`:
- Around line 181-186: Update the nested parsing in the agent-sort catalog
builder around the sorts/groups/modelIds iteration to return null immediately
when a sort record, its groups, or any group’s modelIds is malformed, rather
than skipping it. Preserve normal processing for valid records so malformed
discovery payloads trigger the existing static-catalog fallback, and add
regression coverage for invalid groups and modelIds.
- Around line 170-198: Update parseAntigravityAvailableModels to derive a
validated local model limit before iterating IDs: preserve finite positive
limits smaller than MODEL_DISCOVERY_MAX_MODELS, while treating NaN, Infinity,
and larger values as the hard cap MODEL_DISCOVERY_MAX_MODELS. Use this
normalized limit for every ids.length check, including the
imageGenerationModelIds addition.
In `@tests/provider-connection-test.test.ts`:
- Line 121: Remove the duplicate const seen declaration in
tests/provider-connection-test.test.ts at lines 121-121, keeping one declaration
in the test callback. Apply the same cleanup in
tests/google-models-listing.test.ts at lines 84-84; both sites require one
duplicate declaration to be removed.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 6cdbdea9-595e-4351-940c-e7300e5dd21a
📒 Files selected for processing (33)
docs-site/src/content/docs/contributing.mddocs-site/src/content/docs/guides/providers.mddocs-site/src/content/docs/ja/guides/providers.mddocs-site/src/content/docs/ko/guides/providers.mddocs-site/src/content/docs/ru/guides/providers.mddocs-site/src/content/docs/zh-cn/guides/providers.mdsrc/codex/catalog/provider-fetch.tssrc/codex/convergence-types.tssrc/codex/model-cache.tssrc/config.tssrc/lib/pinned-http.tssrc/lib/provider-outbound.tssrc/oauth/index.tssrc/providers/antigravity-models.tssrc/providers/model-discovery-limits.tssrc/providers/model-discovery.tssrc/providers/registry.tssrc/server/management/oauth-account-routes.tssrc/server/management/provider-routes.tssrc/server/responses/core.tssrc/types.tstests/antigravity-static-catalog.test.tstests/codex-catalog.test.tstests/config.test.tstests/cursor-hardening.test.tstests/google-antigravity-wire.test.tstests/google-models-listing.test.tstests/model-cache.test.tstests/oauth-accounts-api.test.tstests/oauth-provider-reconcile.test.tstests/provider-connection-test.test.tstests/provider-outbound.test.tstests/provider-registry-parity.test.ts
|
Diagnosed the CI failure on this branch, and I have a fix if you want it.
That is a real behaviour, not just a test artefact: any routine cache clear racing an in-flight discovery loses that discovery. The fix I would suggest is to make the intent explicit rather than inferring it: export type ModelCacheClearReason = "authority" | "eviction";
export function clearModelCache(provider?: string, reason: ModelCacheClearReason = "authority"): void {
const bumpsGeneration = reason === "authority";Only Worth covering both directions, since narrowing this the wrong way would trade this bug for the one your guard exists to prevent:
I verified by ablation: forcing every clear to invalidate fails the two eviction cases plus the two failures you are seeing now; forcing none to invalidate fails the two authority cases. I have this on The security review this PR needs is unchanged and still comes after CI is green. |
|
@lidge-jun Replying to your comment above (#1178 (comment)): fixed in 2ebdb70. I adopted the core of your suggested design: cache clearing now carries explicit intent. The resulting behavior is deliberately asymmetric:
I chose the explicit parameter rather than weakening Added direct regressions for both provider-scoped and global clears:
Validation passed: the cache/authority, single-flight, and OAuth account-switch suites (26 tests), |
|
@iF2007 Approved the pending Cross-platform CI at You also fixed the cache-invalidation defect yourself —
Credential handling. The new discovery path takes a token snapshot before any outbound await ( Log surface. The two new
That is the right shape. A raw URL in a discovery warning would carry query parameters, and Vertex endpoints embed a project id. Snapshot-before-await is also the correct ordering for the cache concern: capturing before the outbound call means an OAuth account change during flight cannot make a stale-but-valid response look authoritative for the new account. No blockers from me on the security side. This is still a draft pending your four readiness boxes, which are yours to tick — the CI half of box 1 is now green at your exact head. |
|
Two corrections to my review above, and I got your PR's state wrong as well. You are not waiting on me for a checklist. I closed by saying this "is still a draft pending your four readiness boxes". It is not a draft, and all four boxes are ticked. The accurate status is: exact-head CI green, readiness complete, waiting on maintainer approval — which is on my side, not yours. Apologies for putting the ball back in your court when it was already in mine. The token path I described was the wrong one. I wrote that the new discovery path uses And I missed the strongest guard in the diff, which is worth naming because it is the one that would matter under attack. The conclusion is unchanged: no blocker on the security side, and now with the mechanism identified correctly. Sorry for the two-pass review; you fixed the cache defect quickly and deserved a more careful read the first time. |
|
A third correction, and this one is a mistake in your favour that I still need to retract. I credited this PR with adding What is actually true, and still worth stating: the pre-existing pin remains effective for the new CCA POST discovery path this PR adds, so the new path inherits the same destination guarantee rather than bypassing it. That is a real property of the change; it is just a smaller claim than the one I made. I have now corrected this review three times — wrong resolver, wrong ready-state, and now a guard I attributed to you that you did not write. The security conclusion has not moved, but you deserved a review that was right the first time rather than one assembled across four passes. Separately, and this one is mine to own publicly: I merged this without a recorded approval. |
Important
This PR enables account-scoped live model discovery for Google Antigravity through its real Cloud Code Assist endpoint; maintainers/reviewers, is this a direction OpenCodex wants to adopt—if not, please feel free to close this PR.
Summary
Verification
npx --yes bun@1.3.14 run typechecknpx --yes bun@1.3.14 test tests/provider-outbound.test.ts tests/provider-outbound-private-network.test.ts tests/google-models-listing.test.ts tests/provider-connection-test.test.ts tests/oauth-accounts-api.test.ts tests/antigravity-static-catalog.test.ts tests/google-antigravity-wire.test.ts tests/oauth-provider-reconcile.test.ts tests/provider-registry-parity.test.ts tests/config.test.ts— 259 passed.npx --yes bun@1.3.14 run privacy:scangit diff --checkcd docs-site && bun install --frozen-lockfile && bun run buildnpx --yes bun@1.3.14 run testwas also run, but did not complete successfully: unrelated slow-test timeouts occurred inrequest-history-index,cli-help, andcli-status-json, then Bun 1.3.14 crashed while the suite was finishing. The affected focused test groups above pass.Checklist
Security review: discovery uses the saved OAuth snapshot solely for the authenticated CCA request. Raw credentials and raw discovery responses are neither logged nor persisted. OAuth-bearing CCA POSTs now use the shared destination policy, direct-address pinning, redirect blocking, and HTTPS requirement.
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation