microsoft / microsoft/vscode

agent host: make customization resolution unskippable at publication

Open
#330,913 0 comments 0 reactions 1 assignee Claimed by @connor4312 View on GitHub
agent-host debt
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

Follow-up cleanup from the scoped-enablement work (#330566, #330715).

## Problem

Three of the six production bugs found while building scoped enablement had the same shape: a code path emitted a customization **without resolving its enablement first**. The offending sites were four in `copilotAgent`, one in `mcpCustomizationController`, and the post-startup MCP reconcile.

Each was fixed individually, and the invariant was written down — *every publication path must go through `resolveCustomizationEnablement`* — including in the [`customizations-in-the-agent-host` skill](https://github.com/microsoft/vscode/blob/main/.github/skills/customizations-in-the-agent-host/SKILL.md). But an invariant enforced by discipline is one the next contributor can violate silently, and the failure mode is bad: a customization published with stale or absent enablement means a server the user disabled still reaches the model.

## Suggestion

Make it structurally impossible rather than a documented rule. Have the emit/publish helper accept *unresolved* customizations and resolve internally, so there is no way to call it with unresolved state. Callers stop choosing whether to resolve.

This converts a recurring bug class into a compile-time impossibility. Of the simplifications spun out of this work, it has the best value-to-risk ratio.

## Notes

- Watch the pending path: resolution can legitimately return a `pending` result, and SDK-boundary consumers must keep failing closed via `isCustomizationSdkEligible`. Pending must stay *transient* — a cached pending verdict silently drops a customization forever (a separate bug fixed in #330566).
- The regression guard to keep meaningful is the gate test asserting that a server published top-level and the same server published nested resolve to the same durable decision (`customizationEnablementGate.test.ts`).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.