Skip to content

RuntimeCompatibilityOptions: Containment v2 foundation (catalog + Apply pre-prune + test infra) - #6534

Merged
Scott Jones (Scottj1s) merged 1 commit into
mainfrom
users/sjones/containment-v2-foundation
Jun 4, 2026
Merged

RuntimeCompatibilityOptions: Containment v2 foundation (catalog + Apply pre-prune + test infra)#6534
Scott Jones (Scottj1s) merged 1 commit into
mainfrom
users/sjones/containment-v2-foundation

Conversation

@Scottj1s

Copy link
Copy Markdown
Member

Implements the foundation half of the Containment v2 design proposal (see specs/design/RuntimeCompatibilityContainmentV2.md on the ADO WindowsAppSDKAggregator mirror): a WASDK-owned per-release catalog whose disabled-list pruning runs in RuntimeCompatibilityOptions::Apply, decoupling servicing engineers from naming a target release version at the callsite.

This PR is intentionally scoped to the WASDK side. No FrameworkUdk header, worker, ABI, or callsite changes. The existing FrUdk worker keeps doing its linear scan; the only change it sees is that the disabled list passed by SetConfiguration is now sorted.

What changed

  • dev/RuntimeCompatibilityOptions/RuntimeCompatibilityOptions.cpp
    • New CatalogGroup + MakeGroup helpers and two catalog arrays (s_catalogGroupsProd, empty on main; s_catalogGroupsTest with two synthetic groups straddling WinAppSDK_Latest).
    • ContainmentTestInitialize(bool) swaps the active catalog at test setup time.
    • Apply() now builds a single sorted disabledChanges vector from the union of the app's explicit DisabledChanges list and every catalog group whose releaseVersion > effective patchVersion.
    • Apply() guards both PatchLevel1 / PatchLevel2 branches against the {0,0,0} default sentinel that would otherwise collapse config.patchVersion to 0 in dev builds where WINDOWSAPPSDK_RELEASE_MAJOR / MINOR = 0 / 0.
  • dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def — exports ContainmentTestInitialize from Microsoft.WindowsAppRuntime.dll for the test catalog swap.
  • test/Compatibility/CompatibilityTests/CompatibilityTests.cpp — resolves ContainmentTestInitialize via GetModuleHandleW / GetProcAddress on the bootstrap-loaded framework copy of the WAR DLL (a static import would resolve to a test-folder copy with the production catalog and the swap would have no effect). Calls ContainmentTestInitialize(true) at TEST_METHOD_SETUP and (false) at TEST_METHOD_CLEANUP. Adds VerifyCatalogPrePrunesByPatchLevel and VerifyCatalogAndExplicitDisabledChangesCombine.
  • test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj — adds delayimp.lib + <DelayLoadDLLs>Microsoft.WindowsAppRuntime.dll. Currently emits a benign LNK4199 ... no imports found warning; left in place as defensive cover against future link-time regressions.
  • specs/Compatibility/RuntimeCompatibilityOptions.md — adds a banner pointing at the new authoring model and rollout plan.
  • specs/Compatibility/WASDK-ContainmentV2-Plan.md (new) — rollout plan: goals recap, role boundaries (servicing engineer vs release engineer), four-PR sequence, end-to-end validation status, test-catalog explanation, and the notable engineering details (Apply guard, GetModuleHandle approach, delay-load rationale).

Validation

End-to-end CompatibilityTests pass against locally-built and -installed framework MSIXes in both worktrees:

  • main worktree (catalog empty): 6/6 pass.
  • release/2.0-stable worktree (catalog populated with 8 production IDs across WinAppSDK_2_1_0 and WinAppSDK_2_1_5 groups): 6/6 pass.

What this PR is not

  • No FrUdk changes. PR 2 (in os.2020) will switch Containment_GetChangeEnabled from a linear scan to std::binary_search (relying on this PR's sort guarantee) and add a static_assert on the now-default-0 patchVersion template arg. PR 2 also migrates all os.2020-internal 2-arg callsites to 1-arg in the same commit (the static_assert forces it).
  • No WASDK callsite migration. main has zero production WASDK callsites using the 2-arg IsChangeEnabled<id, real-version> form. The 8 2-arg test callsites in CompatibilityTests.cpp will be migrated in PR 3 alongside the Microsoft.FrameworkUdk package bump.
  • No release/2.0-stable changes. PR 4 will cherry-pick this PR + PR 3 onto 2.0 plus the two production macro edits (#define WINAPPSDK_CHANGEID_61684930 and _62382643).

See specs/Compatibility/WASDK-ContainmentV2-Plan.md for the full four-PR sequence.

…ly pre-prune + cpp-local release enum)

Implements the foundation half of the Containment v2 design proposal
(specs/design/RuntimeCompatibilityContainmentV2.md, merged via the ADO
mirror): a WASDK-owned per-release catalog whose disabled-list pruning
runs in RuntimeCompatibilityOptions::Apply, decoupling servicing
engineers from naming a target release version at the callsite.

This PR is intentionally scoped to the WASDK side. The FrameworkUdk
worker keeps doing its existing scan over the disabled-changes list
that SetConfiguration receives - the only thing it sees that's new is
that the list is now sorted ascending. FrUdk-side changes (worker
binary_search + the WinAppSDKPatchVersion enum deprecation) ship in
companion PR microsoft.visualstudio.com/OS/_git/os.2020/pullrequest/15764977.

Centralizing the patch-version enum
-----------------------------------
The WinAppSDK release-version enum (and its constexpr helper) is now
**file-local** to RuntimeCompatibilityOptions.cpp - a private
WinAppSDKReleaseVersion in the .cpp's anonymous namespace, named to
sidestep the visible-name collision with the still-unscoped legacy
WinAppSDKPatchVersion type that FrUdk's header exports. Goals:

  * Servicing engineers using IsChangeEnabled<id>() (1-arg form) never
    name a release version anywhere in their code.
  * Release engineers add new enumerators only inside Apply's .cpp -
    no public header changes, no API review.
  * The dependency from WindowsAppSDK release engineering onto the
    FrameworkUdk header's enum is broken. FrUdk's
    WinAppSDKPatchVersionDeprecated (the renamed legacy enum) carries
    only a frozen sentinel set and is no longer maintained per WASDK
    release.

On `main` the enum carries only the two sentinel values
(WinAppSDK_Latest = 999999999 and WinAppSDK_Security = 0) and the
production catalog is empty. Release engineering populates per-release
enumerators and groups at branch cut.

What changed
------------
* dev/RuntimeCompatibilityOptions/RuntimeCompatibilityOptions.cpp
  - New file-local WinAppSDKReleaseVersionFromValues + scoped enum
    WinAppSDKReleaseVersion in the anonymous namespace. Mirrors the
    selected patch level into config.patchVersion via decltype so the
    cast remains portable across FrUdk's pre- and post-deprecation enum
    shapes (the second cast keeps Containment_SetConfiguration's
    identity-divergence check working).
  - CatalogGroup + MakeGroup helpers, two catalog arrays
    (s_catalogGroupsProd, empty on main; s_catalogGroupsTest with
    two synthetic groups straddling WinAppSDK_Latest).
  - ContainmentTestInitialize(bool) swaps the active catalog at
    test setup time.
  - Apply() now builds a single sorted disabledChanges vector from
    the union of the apps explicit DisabledChanges list and every
    catalog group whose releaseVersion > effective patchVersion.
  - Apply() guards both PatchLevel branches against the {0,0,0}
    default sentinel that would otherwise collapse config.patchVersion
    to 0 in dev builds where WINDOWSAPPSDK_RELEASE_MAJOR/MINOR=0/0.

* dev/WindowsAppRuntime_DLL/WindowsAppRuntime.def
  - Exports ContainmentTestInitialize from
    Microsoft.WindowsAppRuntime.dll for the test catalog swap.

* test/Compatibility/CompatibilityTests/CompatibilityTests.cpp
  - New helper resolves ContainmentTestInitialize via
    GetModuleHandleW/GetProcAddress on the bootstrap-loaded
    framework copy of Microsoft.WindowsAppRuntime.dll (a static
    import would resolve to a test-folder copy with the production
    catalog and the swap would have no effect).
  - Calls ContainmentTestInitialize(true) at TEST_METHOD_SETUP and
    (false) at TEST_METHOD_CLEANUP.
  - Adds VerifyCatalogPrePrunesByPatchLevel and
    VerifyCatalogAndExplicitDisabledChangesCombine to exercise both
    branches of Applys pre-prune walk and the union with explicit
    DisabledChanges.

* test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj
  - Adds delayimp.lib + <DelayLoadDLLs>Microsoft.WindowsAppRuntime.dll
    so the (defensive) static import on ContainmentTestInitialize does
    not force the loader to find a copy at TE.exe startup. Currently
    emits LNK4199 ... no imports found which is the desired state.

* specs/Compatibility/RuntimeCompatibilityOptions.md
  - Adds a banner pointing at the new authoring model and rollout plan.

* specs/Compatibility/WASDK-ContainmentV2-Plan.md (new)
  - Rollout plan: goals recap, role boundaries, four-PR sequence,
    end-to-end validation status, test-catalog explanation, and the
    notable engineering details (Apply guard, GetModuleHandle approach,
    delay-load rationale, enum localization rationale).

Validation
----------
End-to-end CompatibilityTests pass against locally-built and -installed
framework MSIXes in both worktrees:
  * main worktree (catalog empty): 6/6 pass.
  * release/2.0-stable worktree (catalog populated with 8 production
    IDs across WinAppSDK_2_1_0 and WinAppSDK_2_1_5 groups): 6/6 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Scott Jones (Scottj1s) added a commit that referenced this pull request Jun 4, 2026
…ly pre-prune + cpp-local release enum) [release/2.0-stable cherry-pick]

Cherry-pick of the Containment v2 foundation to release/2.0-stable.
Companion to PR #6534 on main.

The diff is the same shape as PR #6534 with one important difference:
s_catalogGroupsProd is populated with the eight production change IDs
shipping on the 2.0 servicing branch, grouped under WinAppSDK_2_1_0
and WinAppSDK_2_1_5 (file-local enumerators in
RuntimeCompatibilityOptions.cpp's anonymous-namespace
WinAppSDKReleaseVersion enum). This is what lets Apply pre-prune the
disabled list correctly for apps pinned below those releases.

The release-version enum (formerly named WinAppSDKPatchVersion in
FrUdk's public header) is now WASDK-internal and lives only in
Apply's .cpp - in the anonymous namespace, named
WinAppSDKReleaseVersion to sidestep the visible-name collision with
the still-unscoped legacy FrUdk enum. The FrUdk-side rename to
WinAppSDKPatchVersionDeprecated + UINT32(-1) sentinel happens in
companion ADO PR 15764977 (os.2020).

The two existing 2-arg production callsite macros on this branch
(#define WINAPPSDK_CHANGEID_61684930 in dev/ApplicationData/M.W.S.ApplicationData.cpp
and #define WINAPPSDK_CHANGEID_62382643 in dev/MRTCore/.../Helper.cpp,
both expanding to ", WinAppSDK_2_1_5") are NOT migrated in this PR.
The new catalog encodes the same patch association, so the worker's
existing patch check and Apply's pre-prune both agree (belt-and-
suspenders, no semantic conflict). Macro migration to the 1-arg form
will happen in a follow-up PR alongside the Microsoft.FrameworkUdk
package bump (companion to PR 3 on main); that PR is gated on the
os.2020 FrUdk publish.

Validation: TestAll.ps1 on x64 Debug runs CompatibilityTests with
the catalog populated; 6/6 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Scottj1s
Scott Jones (Scottj1s) force-pushed the users/sjones/containment-v2-foundation branch from c80fb94 to fccc631 Compare June 4, 2026 14:21

@iablaauw-MS Ian Blaauw (iablaauw-MS) left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good!

@Scottj1s

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@Scottj1s
Scott Jones (Scottj1s) merged commit d4e1798 into main Jun 4, 2026
50 checks passed
@Scottj1s
Scott Jones (Scottj1s) deleted the users/sjones/containment-v2-foundation branch June 4, 2026 19:25
Scott Jones (Scottj1s) added a commit that referenced this pull request Jun 4, 2026
…h merged #6534 wording

The merged version of #6534 on main refined the WinAppSDKReleaseVersionFromValues helper's preamble comment to explicitly call out release engineering's catalog-growth role. Forward-port that wording to the 2.0 cherry-pick so the two diverge only on the intentional branch-specific deltas (populated catalog enumerators, populated s_catalogGroupsProd, and the FrUdk-bump-pending comment in Apply).
Scott Jones (Scottj1s) added a commit that referenced this pull request Jun 4, 2026
…ly pre-prune + test infra) [release/2.0-stable cherry-pick] (#6535)

* RuntimeCompatibilityOptions: Containment v2 foundation (catalog + Apply pre-prune + cpp-local release enum) [release/2.0-stable cherry-pick]

Cherry-pick of the Containment v2 foundation to release/2.0-stable.
Companion to PR #6534 on main.

The diff is the same shape as PR #6534 with one important difference:
s_catalogGroupsProd is populated with the eight production change IDs
shipping on the 2.0 servicing branch, grouped under WinAppSDK_2_1_0
and WinAppSDK_2_1_5 (file-local enumerators in
RuntimeCompatibilityOptions.cpp's anonymous-namespace
WinAppSDKReleaseVersion enum). This is what lets Apply pre-prune the
disabled list correctly for apps pinned below those releases.

The release-version enum (formerly named WinAppSDKPatchVersion in
FrUdk's public header) is now WASDK-internal and lives only in
Apply's .cpp - in the anonymous namespace, named
WinAppSDKReleaseVersion to sidestep the visible-name collision with
the still-unscoped legacy FrUdk enum. The FrUdk-side rename to
WinAppSDKPatchVersionDeprecated + UINT32(-1) sentinel happens in
companion ADO PR 15764977 (os.2020).

The two existing 2-arg production callsite macros on this branch
(#define WINAPPSDK_CHANGEID_61684930 in dev/ApplicationData/M.W.S.ApplicationData.cpp
and #define WINAPPSDK_CHANGEID_62382643 in dev/MRTCore/.../Helper.cpp,
both expanding to ", WinAppSDK_2_1_5") are NOT migrated in this PR.
The new catalog encodes the same patch association, so the worker's
existing patch check and Apply's pre-prune both agree (belt-and-
suspenders, no semantic conflict). Macro migration to the 1-arg form
will happen in a follow-up PR alongside the Microsoft.FrameworkUdk
package bump (companion to PR 3 on main); that PR is gated on the
os.2020 FrUdk publish.

Validation: TestAll.ps1 on x64 Debug runs CompatibilityTests with
the catalog populated; 6/6 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* RuntimeCompatibilityOptions: sync WinAppSDKReleaseVersion comment with merged #6534 wording

The merged version of #6534 on main refined the WinAppSDKReleaseVersionFromValues helper's preamble comment to explicitly call out release engineering's catalog-growth role. Forward-port that wording to the 2.0 cherry-pick so the two diverge only on the intentional branch-specific deltas (populated catalog enumerators, populated s_catalogGroupsProd, and the FrUdk-bump-pending comment in Apply).

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants