Repository navigation
Simplify feature band model to two bands in 11 #373
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
marcpopMSFT
wants to merge
13
commits into
main
Choose a base branch
from
marcpopMSFT-featurebandupdate
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
0e29d85
Proposal for having a single feature band going forward with a centra…
marcpopMSFT 1692def
Update based on PR feedback
marcpopMSFT bda793d
Added some clarification from PR feedback
marcpopMSFT 67b23ed
add concern about preview versioning
marcpopMSFT 05fe1b5
Change the shipping model to only have a single version of the tools …
marcpopMSFT 212e3c8
Add alternative proposal for having minor SDK releases
marcpopMSFT f352979
Add additional context to the minor release alternative
marcpopMSFT c728222
Update from review today to make the minor version model the primary …
marcpopMSFT 0eaa3cf
Update to include a motivation section and include reference to the u…
marcpopMSFT d1bf50e
Update based on internal review and plan to transition during 11
marcpopMSFT e524e3a
Updated based on recent PR feedback
marcpopMSFT c867a36
Update based on internal feedback and focus on the 11.0.2xx plan
marcpopMSFT 77f4dd3
Add guidance for microsoft update, new features, and source build
marcpopMSFT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,251 @@ | ||
| # Single SDK Feature Band with Global Feature Channels | ||
|
|
||
| **Owner** [marcpopMSFT](https://github.com/marcpopMSFT) | ||
|
|
||
| Today, SDK feature bands, SDK tools, and Visual Studio are coupled in ways that is complex to manage and confusing for users. The challenge with changing this is users can receive new features or behavior changes without intentionally opting in. This is especially problematic for managed environments and source build partners that prioritize stability. We propose a single SDK feature band strategy, combined with a global feature channel setting that all SDK-loaded components honor. This setting has three states: baseline, stable, and preview. New behavior or new features should never show up in baseline. New features should initially be enabled only in preview. Stable is for features that have gone through some preview validation and make include some behavior changes or new warnings. | ||
|
|
||
| ## Scenarios and User Experience | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| ### Scenario 1: Source build partner requires maximum stability | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| A source build partner consumes servicing builds and needs strict behavioral predictability. They configure the global channel to baseline. New features and behavior changes remain off by default across SDK, MSBuild, Roslyn, NuGet, MSTest, and other participating components. Today, these partners stay on the N.0.1xx feature band in order to prioritize stability. | ||
|
|
||
| Outcome: | ||
|
|
||
| - Servicing updates can include security and reliability fixes. | ||
| - Existing behavior remains stable unless explicitly opted in. | ||
| - Partner validation costs and risk are reduced. | ||
| - Customers using source build SDKs can use the same SDK on multiple platforms with the same behavior with a simple environment variable | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| ### Scenario 2: Visual Studio stable users get curated, stable behavior | ||
|
|
||
| A developer on Visual Studio stable channel receives SDK updates from the internal branch insertion path. They get behavior considered production-ready for the stable channel, while preview-only changes remain off. They get the latest runtime with all security fixes and any tooling security fixes as well. | ||
|
|
||
| Outcome: | ||
|
|
||
| - Stable channel receives deliberate feature lighting. | ||
| - Behavior aligns with VS stable expectations. | ||
| - Mid-cycle surprises are reduced. | ||
|
|
||
| ### Scenario 3: Visual Studio Canary/Insider users validate upcoming behavior | ||
|
|
||
| A developer in VS canary receives the public 11.0.1xx SDK build with preview branding. Their global channel is preview, so new behavior can be enabled early for validation. | ||
|
|
||
| Outcome: | ||
|
|
||
| - Early adopter feedback happens before stable rollout. | ||
| - Preview-only changes do not leak into stable/baseline channels by default. | ||
| - Reduces the need to worry about the Insider behavior as it'll be the same as Canary | ||
|
|
||
| ### Scenario 4: VS Code user gets flexible feature control | ||
|
|
||
| A developer using VS Code and the .NET SDK can choose their preferred feature channel to match their development needs. They default to stable for a balance of new features and stability. If they want maximum stability, they can set the environment variable to baseline. If they want to try cutting-edge features early, they can opt into preview. | ||
|
|
||
| Outcome: | ||
|
|
||
| - Stable channel is a sensible default for most developers. | ||
| - Power users have direct control via environment variable configuration. | ||
| - Independent of IDE choice; behavior is consistent across any editor using the SDK. | ||
| - Easy to experiment with new features without waiting for broader SDK releases. | ||
| - With each major release, VSCode will update the SDK installed to a new band resulting in a new baseline. | ||
|
|
||
| ## Requirements | ||
|
|
||
| ### Goals | ||
|
|
||
| - Define a single global configuration that is consumed across all .NET SDK-loaded components. | ||
| - Provide three explicit feature channels: baseline, stable, preview. | ||
| - Ensure new features or behavior changes default to off for baseline. | ||
| - Ensure new features or behavior changes light up first in preview. | ||
| - Enable controlled advancement from preview to stable based on explicit promotion. | ||
| - Preserve servicing safety: no accidental behavior lights-up in servicing trains. | ||
| - Align Visual Studio channel insertion with intended behavior channel semantics. | ||
| - Keep .NET optional workload acquisition aligned to latest stable builds across VS channels. | ||
| - Reduce branch management costs down to a single feature band sourced from two branches | ||
| - Stable from major version N (eg .NET 11) will automatically be included in baseline of N+1 (eg .NET 12) | ||
|
|
||
| ### Non-Goals | ||
|
|
||
| - Redesigning component-specific feature-flag systems end-to-end. | ||
| - Guaranteeing identical behavior for non-participating tools outside the SDK composition. | ||
| - Replacing existing TFM-based compatibility controls. | ||
| - Defining every individual feature's rollout criteria in this proposal. | ||
| - Changing any rollout or versioning for optional workloads. | ||
| - Change how the feature rollout and experience of components loaded into Visual Studio are managed | ||
|
|
||
| ## Stakeholders and Reviewers | ||
|
|
||
| - SDK: feature-band ownership and global configuration contract | ||
| - MSBuild: engine behavior gating and branch/codeflow model | ||
| - Roslyn: compiler/analyzer defaults and compatibility modes | ||
| - NuGet: restore/package behavior gating where applicable | ||
| - MSTest: test SDK/runtime behavior gating | ||
| - Source build partners: default channel semantics and validation guidance | ||
| - Visual Studio: channel insertion, branding, and defaults | ||
|
|
||
| ## Design | ||
|
|
||
| ### Global feature channel | ||
|
|
||
| Introduce one SDK-wide configuration value (`SdkFeatureChannel`) with exactly three allowed values: | ||
|
|
||
| - baseline | ||
| - stable | ||
| - preview | ||
|
|
||
| All participating components must query this value through a shared contract and use it to gate behavior changes. | ||
|
|
||
| Initial policy for any new feature or behavior change: | ||
|
|
||
| - baseline: off | ||
| - stable: off (unless explicitly promoted) | ||
| - preview: on (unless explicitly held back) | ||
|
|
||
| Promotion policy: | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| - A feature starts as preview-on, stable-off, baseline-off. | ||
| - Promotion to stable requires explicit approval and release notes in a planned update. | ||
| - Baseline remains off by default, with opt-in available for customers that explicitly choose it. | ||
| - Minimum preview soak time before promotion is two months. | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| ### Configuration sources and precedence | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| The final value is provided through environment propagation so all child tools inherit the same channel. The SDK host sets the effective environment variable `DOTNET_SDK_FEATURE_CHANNEL` early in startup (first step in `Program.cs`) before invoking any tool components. | ||
|
|
||
| Default channel behavior is configured at SDK build time: | ||
|
|
||
| - Source-build distributions default to baseline. | ||
| - Microsoft SDK distributions default to stable. | ||
|
|
||
| Customers can override with the environment variable if they choose a different risk posture. | ||
|
|
||
| Precedence (highest to lowest): | ||
|
|
||
| 1. Command-line explicit override (if introduced) | ||
| 2. Environment variable explicit value | ||
| 3. Host-computed default written by SDK startup | ||
| 4. SDK build-time default | ||
|
|
||
| global.json integration may be added later, but is not required for the initial design. | ||
|
|
||
| Open questions: | ||
|
|
||
| - How do we ensure this behavior propogates from the SDK to the component tool? | ||
| - What should the behavior be inside of .NET components running inside of Visual Studio and how do we coordinate that. | ||
|
|
||
| ### Cross-component contract | ||
|
|
||
| Each participating component defines: | ||
|
|
||
| - Behavior identifier (feature or breaking behavior ID) | ||
| - First enabled channel | ||
| - Promotion history (preview to stable) | ||
| - Override mechanism (if any) | ||
|
|
||
| To improve transparency and auditing, components should also publish a machine-readable manifest of gated behaviors and channel thresholds. | ||
|
|
||
| The SDK provides the channel context; each component owns implementation details while following a common policy. | ||
|
|
||
| ### Visual Studio channel strategy | ||
|
|
||
| Proposed VS integration model: | ||
|
|
||
| - Public branch 11.0.1xx: | ||
| - Preview branding | ||
| - Insert into VS canary | ||
| - Global channel default: preview | ||
|
|
||
| - Internal branch build: | ||
| - Stable branding | ||
| - Includes MSRC fixes and latest runtimes | ||
| - Insert into VS stable and last servicing version. VS typically releases a new GA and a final release of the last minor version on the same day and we would update both. | ||
| - Global channel default: stable | ||
| - Preview behavior remains default-disabled; customer opt-in is allowed | ||
|
|
||
| - VS insiders: | ||
| - Do not insert SDK directly | ||
| - Consume preview flow from canary | ||
|
|
||
| ### Optional workloads strategy | ||
|
|
||
| For optional .NET workloads: | ||
|
|
||
| - Always build workload artifacts from internal SDK version. | ||
| - Insert workload artifacts into all VS channels. | ||
|
|
||
| No additional compatibility contract is required for workloads in this proposal. | ||
|
|
||
| ### MSBuild and similar component branch flow | ||
|
|
||
| For teams that need behavior alignment with VS stability (example: MSBuild engine): | ||
|
|
||
| - Stable branch codeflow from internal branch for stable alignment. | ||
| - Public flow for latest/preview innovation. | ||
| - Explicit merge and promotion policy to avoid accidental stable-channel behavior changes. | ||
|
|
||
| This pattern is recommended for all tooling teams that need stable-channel alignment. | ||
|
|
||
| For repositories with public-to-internal mirroring, branch topology must preserve stable and preview intent. A candidate model is: | ||
|
|
||
| - Public default branch mirrors into a public preview branch (source-preferred). Example: flow from 11.0.1xx to 11.0.1xx-featurepreviews. | ||
| - Promotion from internal preview branch to internal stable branch is controlled (target-protected, with explicit acceptance gates). | ||
| - Stable insertions are produced from the internal stable branch, while canary insertions are produced from preview-aligned flow. | ||
|
|
||
| This model needs validation with engineering systems owners before adoption. | ||
|
|
||
| ### Servicing safety rules | ||
|
|
||
| In servicing trains: | ||
|
|
||
| - No new behavior should silently turn on for stable or baseline. | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
| - Security and reliability fixes may ship, but behavior-changing defaults require explicit promotion in a planned update. | ||
| - Rollback options are: flip the feature off via hotfix when critical, or fix forward in the next servicing release. | ||
|
|
||
| ## Q and A | ||
|
|
||
| ### Why a three-state model instead of a binary preview toggle? | ||
|
|
||
| A binary model cannot represent baseline needs independently from mainstream stable users. Three states separate strict stability from normal stable adoption and preview validation. | ||
|
|
||
| ## Risks and Unknowns | ||
|
|
||
| - Cross-component adoption lag: not all components may adopt `SdkFeatureChannel` and `DOTNET_SDK_FEATURE_CHANNEL` at the same pace, leading to inconsistent behavior. | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
| - Environment propagation correctness: if the variable is not set early enough in SDK startup, child tools may observe incorrect defaults. | ||
| - Host/tooling interaction complexity: IDEs, build servers, and custom hosts may inject conflicting environment values. | ||
| - Configuration discoverability: users may not understand why behavior differs by channel without strong diagnostics and documentation. | ||
| - Manifest quality risk: machine-readable behavior manifests may drift from implementation if not validated in CI. | ||
| - Enforcement consistency risk across repos: without shared policy checks, teams may implement channel gating differently or incompletely. | ||
| - Promotion calibration risk: a two-month preview window may be too short or too long depending on feature blast radius. | ||
| - Servicing pressure: urgent fixes may tempt channel policy exceptions that undermine trust in stable/baseline promises. | ||
| - Branch/codeflow divergence: internal/public flow patterns can create merge debt and delayed fixes if governance is weak. | ||
| - Mirror topology risk for split public/internal versions: current one-way public to internal mirroring can accidentally blur stable versus preview intent. | ||
| - Cherry-pick debt risk: if internal stable and preview diverge, security and reliability fixes may require manual multi-branch propagation. | ||
| - Validation matrix risk: every participating repo may need baseline/stable/preview validation, increasing CI cost and latency. | ||
| - Diagnostics burden: support teams may need additional tooling to quickly determine the effective channel in customer environments. | ||
|
|
||
| ### Enforcement approach | ||
|
|
||
| Open questions: | ||
|
|
||
| - Do we need an enfrocement bot enabled in every participating repo? | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
| - Do we need the ability to dump all new features into a machine and human readable format for review and comparison against intent/docs/PRs? | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| Unknowns to validate during review: | ||
|
|
||
| - Whether `baseline` is intuitive enough for external customers and partners. | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
| - Whether `DOTNET_SDK_FEATURE_CHANNEL` should be the only v1 control surface or paired with a CLI switch immediately. | ||
| - Whether all in-scope components can enforce gating with acceptable performance overhead. | ||
| - Whether existing per-tool feature flags can be harmonized without migration churn. | ||
| - Which minimal cross-repo policy checks are required for v1 to avoid silent non-compliance. | ||
| - Whether current public-to-internal mirror infrastructure can support a preview-branch intermediary with controlled internal stable promotion. | ||
| - Whether stable/canary insertion branches should be structurally separated in all participating repos. | ||
|
|
||
| ### Does this replace existing feature flags? | ||
|
|
||
| No. Component-level flags can remain. This proposal adds a single, global compatibility channel that defines default behavior posture. | ||
|
|
||
| ### Open questions to resolve | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
|
|
||
| 1. Whether `DOTNET_SDK_FEATURE_CHANNEL` should be the only v1 control surface or whether a CLI switch should also ship in v1. | ||
| 2. Minimum schema for the machine-readable behavior manifest. | ||
| 3. Is there a change to the versioning schema we could do for the SDK? We could change to match runtime versioning but we sometimes have SDK hotfixes so it might be confusing to release an 11.0.108 that has 11.0.7 runtime in it. | ||
|
marcpopMSFT marked this conversation as resolved.
Resolved
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.