Skip to content

accounts: avoid more redundant managed settings requests - #333823

Merged
joshspicer merged 7 commits into
mainfrom
agents/managed-settings-reload-requests-debug-e19d8cd7
Sep 1, 2026
Merged

accounts: avoid more redundant managed settings requests#333823
joshspicer merged 7 commits into
mainfrom
agents/managed-settings-reload-requests-debug-e19d8cd7

Conversation

@joshspicer

@joshspicer joshspicer commented Sep 1, 2026

Copy link
Copy Markdown
Member

Summary

  • keep forceRefresh as a simple boolean that bypasses every default-account cache
  • keep ordinary account refreshes cache-aware with no force flag
  • preserve fresh quota/upgrade checks with an explicit entitlement-only refresh
  • deduplicate authentication sessions that match multiple accepted scope alternatives
  • treat a managed-settings 404 as the final cacheable no-policy result instead of retrying other sessions
  • retain bounded 401 authentication fallback and fail-closed forced-freshness behavior

Why

A workbench reload could turn one managed-settings lookup into four sequential GETs. A chat entitlement update was forcing all account data to refresh, one GitHub session was selected once per matching scope alternative, and the shared request helper retried 404 responses as though they indicated a bad token.

The refresh contract remains simple: normal operation honors fresh caches; forceRefresh: true refreshes everything and is reserved for explicit policy sync/retry actions. Quota dashboards, quota reset checks, and upgrade flows explicitly refresh only entitlement data so they do not remain stale for up to one hour or invalidate unrelated caches.

Launch validation

Using an isolated authenticated Code OSS Dev profile:

  • initial uncached account resolution made one request for each required account resource
  • explicit entitlement refresh requested only /copilot_internal/user; token, MCP, and managed-settings caches were reused
  • reload made zero managed-settings requests
  • Developer: Sync Account Policy refreshed entitlement, token, managed-settings, and MCP data exactly once each
  • the managed-settings 404 stopped after the first distinct session and was cached as “no policy”

Council review

GPT-5.5, Claude Opus 4.6, and GPT-5.3-Codex unanimously found that making forceResolveEntitlement fully cache-aware would regress quota-reset, dashboard, and post-upgrade freshness for up to one hour. The current implementation fixes that with a single entitlement-only refresh option and focused regression coverage.

Validation

  • npm run hygiene
  • npm run compile (zero errors)
  • npm run valid-layers-check
  • ./scripts/test.sh --run src/vs/workbench/services/accounts/test/browser/defaultAccount.test.ts --run src/vs/workbench/services/chat/test/common/chatEntitlementService.test.ts --run src/vs/workbench/services/policies/test/browser/accountPolicyGateContribution.test.ts (59 passing)

Copilot AI balanced review requested due to automatic review settings September 1, 2026 17:47
@joshspicer joshspicer changed the title accounts: avoid redundant managed settings requests accounts: avoid more redundant managed settings requests Sep 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

Review tier: Balanced
Findings: 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​vs/​workbench/​services/​accounts/​browser/​defaultAccount.tspreserveManagedSettingsCache is ineffective in the real refresh path when…
What changed in this PR

Reduces redundant managed-settings requests during account and entitlement refreshes.

Changes:

  • Adds managed-settings cache preservation for entitlement refreshes.
  • Deduplicates matching authentication sessions.
  • Stops session fallback after managed-settings 404 responses.
File Description
src/​vs/​platform/​defaultAccount/​common/​defaultAccount.ts Adds refresh options for cache preservation and retries.
src/​vs/​workbench/​services/​accounts/​browser/​defaultAccount.ts Updates caching, session matching, and request fallback.
src/​vs/​workbench/​services/​accounts/​test/​browser/​defaultAccount.test.ts Tests caching, deduplication, and 404 handling.
src/​vs/​workbench/​services/​chat/​common/​chatEntitlementService.ts Preserves managed-settings cache during entitlement refresh.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/vs/workbench/services/accounts/browser/defaultAccount.ts Outdated
@joshspicer
joshspicer force-pushed the agents/managed-settings-reload-requests-debug-e19d8cd7 branch 2 times, most recently from fec1225 to 71089f4 Compare September 1, 2026 18:23
@joshspicer
joshspicer marked this pull request as draft September 1, 2026 18:31
@joshspicer
joshspicer force-pushed the agents/managed-settings-reload-requests-debug-e19d8cd7 branch from 5f4c4b7 to 23ff2fe Compare September 1, 2026 19:00
@joshspicer

joshspicer commented Sep 1, 2026

Copy link
Copy Markdown
Member Author

Completed a deterministic launch validation matrix against the current PR implementation using scripts/mock-policy-server with all four account endpoints mocked.

Passed scenarios

  • wrong endpoint scope is not reused
  • missing and stale caches make exactly one managed-settings request
  • fresh cached 404, empty 200, and policy-bearing 200 make zero managed-settings GETs on reload
  • 404 is cacheable and does not fan out across overlapping OAuth scope alternatives
  • explicit entitlement refresh calls only /copilot_internal/user
  • forceRefresh: true calls entitlement, token, managed settings, and MCP once each
  • cached forceRemoteSettingsRefresh bypasses freshness once per reload
  • 500, malformed JSON, disconnect, and timeout remain fail-closed
  • same-process automatic retry is suppressed after forced-refresh failure
  • explicit retry bypasses the failure guard with one new application request
  • 429 activates 60-second backoff; no automatic or explicit wire request occurs during backoff
  • 466 blocks, persists compatibility state, and a later 200 reload revalidates and recovers
  • broad OAuth session matching all three accepted scope alternatives is selected once
  • forced 401 uses only the selected session

Transport caveat

An immediate socket reset produced one application-level fetch and one Failed to fetch result, but Chromium retried the idempotent GET twice underneath fetch, so the mock server saw three near-simultaneous wire hits. This is bounded browser transport behavior—not auth-session fallback or an application retry loop. Normal HTTP responses (401/404/429/466/500) each produced one wire GET.

Full evidence: session launch validation report.

@joshspicer
joshspicer force-pushed the agents/managed-settings-reload-requests-debug-e19d8cd7 branch from 23ff2fe to cf605df Compare September 1, 2026 19:27
@joshspicer
joshspicer requested a balanced review from Copilot September 1, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

Review tier: Balanced
Findings: 1 Medium severity

Pre-existing issues (1)
Severity Finding
Medium severity src/​vs/​workbench/​services/​accounts/​browser/​defaultAccount.tspreserveManagedSettingsCache is ineffective in the real refresh path when… View comment

joshspicer and others added 7 commits September 1, 2026 13:03
Preserve a fresh managed-settings cache during entitlement refreshes, deduplicate authentication sessions that match overlapping scope alternatives, and treat a managed-settings 404 as a final no-policy result.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the managed-settings cache exception with explicit refresh targets. Chat entitlement updates now force only account entitlements, while policy sync and retry actions force only managed settings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep only the entitlement and managed-settings refresh modes used by production callers. Remove the general target enum, all mode, helper, and unused token and MCP refresh parameters.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore forceRefresh as a simple all-account-data boolean. Normal chat and managed-settings source updates now use ordinary cache-aware refreshes; only explicit policy sync and retry actions force all caches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep quota and upgrade checks fresh without forcing unrelated default-account caches. The all-or-nothing forceRefresh boolean remains reserved for explicit policy sync and retry actions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exercise the full account refresh path with a scoped, satisfied forceRemoteSettingsRefresh cache. Verify entitlement refresh requests only entitlement data and preserves satisfied managed-settings freshness before full force refresh.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore unrelated test wording and retry documentation, inline the managed-settings force check, and narrow the governed entitlement regression to the behavior under review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@joshspicer
joshspicer force-pushed the agents/managed-settings-reload-requests-debug-e19d8cd7 branch from 6286fb1 to 39f097e Compare September 1, 2026 20:03
@joshspicer
joshspicer requested a balanced review from Copilot September 1, 2026 20:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The focused implementation preserves fail-closed policy behavior and has appropriate regression coverage.

Review tier: Balanced
Findings: None

Issues resolved since last review (1)
Severity Finding
Medium severity src/​vs/​workbench/​services/​accounts/​browser/​defaultAccount.tspreserveManagedSettingsCache is ineffective in the real refresh path when… View resolved comment

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: c89cda63 Current: 0cb45ca0

Changed (1)

chat/aiCustomizations/aiCustomizationManagementEditor/McpServersSearch/Light
Before After
before after

@joshspicer

Copy link
Copy Markdown
Member Author

Re-ran the full deterministic E2E matrix on the current reduced head 39f097e2737 using authenticated Code OSS Dev plus mock-policy-server.

Test Proof observed
Wrong endpoint scope Production-scoped cache was rejected; localhost received exactly one managed-settings GET.
Missing cache Deleted defaultAccount.cachedPolicyData in the isolated profile; next launch produced one 404 GET.
Initial 404 Exactly one GET; no duplicate request despite the OAuth session matching all three accepted scope alternatives.
Fresh cached 404 reload After clearing the mock log, reload produced only two /user requests and zero managed-settings/token/MCP requests.
Entitlement-only refresh The second startup refresh added only /user; token/MCP/managed-settings counts did not increase.
Full force sync Developer: Sync Account Policy produced exactly one /user, token, managed-settings, and MCP GET.
Empty 200 cache One 200 sync request; next reload produced zero managed-settings GETs.
Policy 200 cache One 200 sync request; renderer logged policy applied; next reload produced zero managed-settings GETs.
Stale cache Aged only managedSettingsFetchedAt beyond one hour; next launch produced exactly one 200 GET.
Forced freshness success Seeded forceRemoteSettingsRefresh; reload produced exactly one 200 managed-settings GET.
Forced 500 failure Reload produced one 500; renderer restricted the policy gate and logged automatic retry suppression.
Explicit retry Sync after the 500 added exactly one second managed-settings GET.
429 backoff One 429 GET; explicit Sync during the 60-second backoff did not add another server hit.
466 recovery One 466 blocked; after dismissing the compatibility modal and switching to 200, the next real reload produced one recovery GET.
Malformed JSON One 200 malformed response; renderer logged parse failure and remained fail-closed.
Timeout One status-0 server entry; the next stage began about five seconds later and the gate remained restricted.
Normal and forced 401 The broad OAuth session produced one 401 despite matching all scope alternatives; separately seeded forced freshness also produced one selected-session 401.
Immediate disconnect Renderer/network logs showed one application fetch and one Failed to fetch; Chromium retried the reset idempotent GET twice, so the mock server saw three status-0 wire hits. No app/session retry occurred.

Result: 16 exact passes, 1 pass with the documented Chromium transport caveat. All mock wiring, processes, profiles, and caches were cleaned afterward; the worktree remains clean.

@joshspicer
joshspicer marked this pull request as ready for review September 1, 2026 20:37
@joshspicer joshspicer added the ~release-cherry-pick Trigger: cherry-pick this PR to the latest release branch label Sep 1, 2026
@joshspicer
joshspicer merged commit b8b400c into main Sep 1, 2026
41 checks passed
@joshspicer
joshspicer deleted the agents/managed-settings-reload-requests-debug-e19d8cd7 branch September 1, 2026 20:46
@joshspicer joshspicer added ~release-cherry-pick Trigger: cherry-pick this PR to the latest release branch and removed ~release-cherry-pick Trigger: cherry-pick this PR to the latest release branch labels Sep 1, 2026
@vs-code-engineering vs-code-engineering Bot added this to the 1.136.1 milestone Sep 1, 2026
@vs-code-engineering vs-code-engineering Bot added release-cherry-pick Automated cherry-pick between release and main branches and removed ~release-cherry-pick Trigger: cherry-pick this PR to the latest release branch labels Sep 1, 2026
@joshspicer

Copy link
Copy Markdown
Member Author

Completed a controlled endpoint-load A/B between the exact pre-PR merge base c89cda63706 and this PR using separate compiled worktrees, the same authenticated profile, the same warmed cache for hot cases, and identical mock-policy-server responses.

Scenario Pre-PR total PR total Delta
Cold start / new endpoint scope / 404 10 3 -7
Hot process start / cached 404 7 2 -5
Hot window reload / cached 404 7 2 -5
Explicit force sync / 404 6 4 -2
Governed reload / successful required refresh 6 3 -3
Governed reload / required refresh returns 500 5 3 -2
Explicit force sync / 401 6 4 -2

Endpoint-level result:

  • /copilot_internal/user: unchanged in every scenario
  • /v2/token: equal or lower
  • /managed_settings: equal or lower
  • MCP registry: equal or lower
  • positive endpoint deltas: 0

Key hot-reload comparison:

  • pre-PR: /user 2, token 1, managed settings 3, MCP 1
  • PR: /user 2, token 0, managed settings 0, MCP 0

Key governed-500 comparison after equal settled windows:

  • pre-PR: /user 2, token 1, managed settings 1, MCP 1
  • PR: /user 2, token 0, managed settings 1, MCP 0

The release cherry-pick #333863 has the same stable production patch ID (6755743a8478e5af6462620dbefa1121a8375791), so these production load deltas apply there as well.

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

Labels

release-cherry-pick Automated cherry-pick between release and main branches

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants