Repository navigation
perf: the window package drops the unused Windows Runtime projection - R5/8b - #138
Conversation
…- R5/8b The 10.0.17763 in the window's TFM pins the support floor, and any TFM version from 10.0 up also makes the SDK add the Windows Runtime projection (Microsoft.Windows.SDK.NET.dll, 23.6 MB, and WinRT.Runtime.dll, 0.5 MB). No code here uses it, and of the 225 managed assemblies in the package none but the projection itself referenced it. IncludeWindowsSDKRefFrameworkReferences=false in gui/Directory.Build.props keeps it out while the TFM, and so the floor, stays. Measured on the published layout: 169.6 to 146.6 MB unpacked, 70.8 to 64.8 MB zipped, every method of ChronoMock.dll with the same IL and the same resources, SupportedOSPlatform still Windows10.0.17763.0, lock files unchanged, start unchanged (first frame median 784.6 against 788.2 ms, same JIT count, same assemblies loaded), state sheet render 301 files byte for byte. The switch has no page on learn.microsoft.com, so build-dist.ps1 checks the effect on the published files and stops if either file comes back, ahead of the register check that would otherwise ask for it to be declared. The register, the notices and the component-list test drop the projection, which was the one component without an SPDX licence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
| Layer / File(s) | Summary |
|---|---|
Deferred view construction and window integration gui/ChronoMock.App/Controls/DeferredView.cs, gui/ChronoMock.App/MainWindow.xaml, CHANGELOG.md |
DeferredView loads template content during measurement and retains the created child. MainWindow uses it for the session and result phases. The changelog records startup measurements and the package-size increase. |
Lifecycle validation and resource-loading notes gui/ChronoMock.App.Tests/DeferredViewTests.cs, gui/ChronoMock.App.Tests/FilledScreenSweepTests.cs, tests/mutation/entries.json, gui/ChronoMock.App/App.xaml, gui/ChronoMock.App/Themes/Parts.xaml, gui/ChronoMock.App/Views/* |
Tests cover deferred construction, reuse, data and layout propagation, invalid template roots, and settled layout before measurement. Mutation cases cover deferred-view behavior. XAML comments describe local Parts dictionary merges and converter load ordering. |
Windows packaging
| Layer / File(s) | Summary |
|---|---|
Publish configuration and output validation gui/Directory.Build.props, gui/ChronoMock.App/ChronoMock.App.csproj, packaging/build-dist.ps1 |
GUI publishing enables ReadyToRun for shipped layouts and excludes Windows Runtime projection references. The distribution script checks ReadyToRun metadata and rejects projection assemblies in the output. |
Package inventory and notices packaging/components.json, THIRD-PARTY-NOTICES.md, crates/cli/src/cli.rs, CHANGELOG.md |
The Windows SDK reference pack is removed from the component register and runtime notices. CLI component expectations and the minimum count are updated. The changelog records the package-size changes and retained platform compatibility. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Other
Sequence Diagram(s)
sequenceDiagram
participant MainWindow
participant DeferredView
participant WPFLayout
participant DataTemplate
MainWindow->>DeferredView: Assigns phase DataTemplate
WPFLayout->>DeferredView: Measures when phase is shown
DeferredView->>DataTemplate: Loads content once
DataTemplate-->>DeferredView: Returns UIElement
Suggested labels: performance, ui, packaging, dependencies
Merge Risk: 
Minimal · up to e8f5b
-
No actionable issue remains; the change is ready to merge after normal checks.
Pre-merge checks: 
13 · 
1
-
Failed checks: 1 inconclusive Passed checks: 13 passed-
Full details: Title check
-
Explanation
The title clearly describes the main user-visible and packaging change: removal of the unused Windows Runtime projection from the window package. It is specific and suitable for release notes or git history.
Full details: Tests For Changed Behavior
-
Explanation
The changed runtime behavior has test coverage.
DeferredViewTestscovers deferred construction, reuse, data-context and layout propagation, and invalid template roots.FilledScreenSweepTestsupdates layout setup for deferred phases. The component-count assertion changes from 28 to 27 because the Windows Runtime projection was removed, which the PR description explicitly justifies. No tests were deleted, skipped, or weakened without justification.
Full details: No Secrets Or Debug Leftovers
-
Explanation
No failure condition is introduced. The pull-request file inventory contains no CLAUDE.md, CLAUDE.local.md, AGENTS.md, .claude/, or .env path. Added-line scans found no credentials, private URLs, local absolute paths, IPs, personal emails, or debug output such as Console.WriteLine, Debug.WriteLine, dbg!, println!, breakpoint(), or debugger calls. The only added URL is the standard public WPF XAML namespace.
Full details: No Hardcoded Ui Styling
-
Explanation
PASS: The PR changes WPF code, but it does not add hardcoded visual styling. The new
DeferredViewonly sets defaultVisibility.Collapsedand manages template creation.MainWindow.xamluses shared bindings and reusableDeferredViewwrappers; other XAML changes are comments and resource-merge documentation. The literal200/100values occur only as test layout-probe dimensions, not control styling. No copy-pasted styled controls were added.
Full details: No Obvious Performance Problems
-
Explanation
The diff has no clear, concrete performance problem under the check's criteria. - DeferredView.cs (new): builds its child once, on the first layout measure, and keeps it. It does not rebuild on every pass. Its
Child is nullguard prevents repeated construction. Not a UI-thread hot loop or a per-item cost. - MainWindow.xaml: defers the session and result phase views until first shown. This reduces startup work. It does not add work. - build-dist.ps1: the newTest-ReadyToRunreads three PE headers once per assembly. The projection-file checks are existence tests on a fixed list. Both are build-time and negligible. - Build and config files (Directory.Build.props,ChronoMock.App.csproj,components.json,THIRD-PARTY-NOTICES.md,cli.rs,CHANGELOG.md,App.xaml, the view and theme XAML comments): no runtime loops, lists, timers, or queries. - Tests: the new test suites and the settle call inFilledScreenSweepTests.csare test-only. The PR's stated gain is a smaller package, and its startup measurements show no regression. I did not find a listed problem pattern such as blocking I/O on the UI thread, non-virtualized lists, per-item external calls, or polling. The PR description was truncated, but the diff evidence above covers the code it changes.
Full details: Desktop Robustness
-
Explanation
The changed production code only defers WPF view construction, removes a framework reference, and adds publish-time PE/file-presence checks. The diff adds no working-directory asset load, settings/data write, number/date parse or save, background task, elevation, network call, destructive action, or user-started long operation.
DeferredViewcreates and retains a child synchronously during layout; this is UI construction, not a long-running operation under the stated check. The existing checksum write is not changed by this PR.
Full details: Safe File Parsing
-
Explanation
No unsafe file parsing was introduced.
DeferredViewcallsDataTemplate.LoadContent()only for inline, compiled application XAML inMainWindow.xaml; it does not read external XAML. The only newXamlReader.Parsecall is test-only and parses a fixed literal string.Test-ReadyToRunusesFile.OpenReadandPEReaderon fixed publish DLL paths, reads PE metadata without loading assemblies, and disposes both objects. JSON and resource-file parsing changes are absent from the PR.
Full details: System Changes Are Reversible
-
Explanation
The PR does not add or change code that modifies network filters, proxies, firewalls, system time, process hooking/injection, Windows services, the registry, or drivers. The changed runtime code only defers WPF view construction. The other changes adjust MSBuild/package settings, packaging validation, documentation, and tests.
Full details: Clear User-Facing Text
-
Explanation
PASS — The changed XAML adds only the DeferredView namespace and deferred templates; it does not add or change buttons, icon-only controls, labels, tooltips, or confirmation text. The new InvalidOperationException message clearly states the template-root problem and the required fix. Other changed prose is comments, packaging diagnostics, changelog, or notices, not user-facing UI text, and no explicit text failure condition is introduced.
Full details: No Resource Leaks
-
Explanation
No resource leak is introduced.
DeferredView.MeasureOverridecreates oneUIElementonly whileChildis null, then retains that bounded child;MainWindow.xamlcontains only two such hosts. The PR adds no event subscription, timer, thread, process, file, stream, or native-resource ownership in the app. The new packaging stream is disposed on all paths by nestedfinallyblocks inpackaging/build-dist.ps1.
-
Full details: Scope, Duplication And Docs
-
Explanation
The reviewed range adds a separate startup feature:
DeferredView, deferred phase construction, ReadyToRun publishing, and mutation tests, in addition to removing the Windows Runtime projection. The visible title and description focus on projection removal, although the description is truncated before its final content. The repository has no existing equivalent deferred-view helper, andCHANGELOG.mddocuments both startup and package changes. The missing description text prevents a reliable scope decision.Resolution
Provide the complete pull request description, or explicitly state whether the R5/8 startup changes (
DeferredView, deferred phases, and ReadyToRun publishing) are part of this pull request. If they are not, split them into a separate pull request or update the title and description.
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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 @coderabbitai help to get the list of available commands.
|
@coderabbitai review |
|
@@coderabbitai full review |
✅ Action performedReview finished.
|
|
|
…with 3 updates Bumps the cargo-minor-and-patch group with 3 updates in the / directory: [serde_json](https://github.com/serde-rs/json), [toml](https://github.com/toml-rs/toml) and [winresource](https://github.com/BenjaminRi/winresource). Updates `serde_json` from 1.0.151 to 1.0.154 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](serde-rs/json@v1.0.151...v1.0.154) Updates `toml` from 1.1.6+spec-1.1.0 to 1.1.8+spec-1.1.0 - [Commits](toml-rs/toml@toml-v1.1.6...toml-v1.1.8) Updates `winresource` from 0.1.31 to 0.1.34 - [Commits](https://github.com/BenjaminRi/winresource/commits) --- updated-dependencies: - dependency-name: serde_json dependency-version: 1.0.154 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: toml dependency-version: 1.1.8+spec-1.1.0 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: winresource dependency-version: 0.1.34 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps Microsoft.NET.Test.Sdk from 18.10.1 to 18.11.0 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Bumps [semgrep](https://github.com/semgrep/semgrep) from 1.180.0 to 1.181.0. - [Release notes](https://github.com/semgrep/semgrep/releases) - [Changelog](https://github.com/semgrep/semgrep/blob/develop/CHANGELOG.md) - [Commits](semgrep/semgrep@v1.180.0...v1.181.0) --- updated-dependencies: - dependency-name: semgrep dependency-version: 1.181.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
main brings #137, which this branch was stacked on, and the actions bump of #141. The three Dependabot branches come in as they are, so their pull requests count as merged with this one: - #117 serde_json 1.0.154, toml 1.1.8, winresource 0.1.34 (Cargo.lock) - #139 Microsoft.NET.Test.Sdk 18.11.0 in the protocol tests - #140 semgrep 1.181.0, the scanner behind the Semgrep gate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…time packs Two components the packages ship moved under the register, and each stopped a check: - serde_json 1.0.154 came in with the Dependabot update of #117, and the component guard failed on it (register 1.0.151, lockfile 1.0.154). Its dependencies did not change. - The runners took .NET SDK 10.0.403 on 2026-10-26, which publishes the window with the 10.0.14 runtime packs, the .NET security release of 2026-10-25. build-dist.ps1 stopped the installer job on every open pull request (declared 10.0.13, bundled 10.0.14). packaging/components.json and THIRD-PARTY-NOTICES.md name the new versions, and the unreleased CHANGELOG line about the bundled runtime names 10.0.14. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The calculator announcement test failed on a runner with "nothing was announced" after 17.7 s, where it takes 3.3 s on a desktop run alone and cold. NextAsync checked its deadline before it read the queue, so when the UI thread was held past the deadline by other work, the announcement made just before the hold was never read and the test reported that nothing was announced. It now reads the queue once more after the deadline. A failure names how long it waited and every announcement it passed over, so a repeat on a runner says which way it failed. The deadline goes from 5 s to 20 s. It bounds only a failure, the wait ends at the announcement, and the runner spent about 12.7 s on the steps before the wait. Measured with a probe that holds the UI thread for the deadline and a second, from the moment the announcement is made: the old helper fails it with "nothing was announced", the new one reads it, and the new one without the last read fails it with the 20 s deadline too. The probe is not kept, it would add over 20 s to every run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e wait runs out AnsweredAsync in FilledScreenSweepTests had the shape NextAsync had in AnnounceTests: it returned false at the deadline without a last look, so an answer that landed while the UI thread was held past the deadline was counted as no answer and the scenario as unanswered. It now checks once more after the deadline. The deadline stays at 5 s. Measured with a probe that holds the UI thread for the deadline and a second from the moment the answer lands: the old helper counts the answer as missing, the new one finds it. The probe is not kept. FilledScreenSweepTests 4 of 4, format-cs, metrics-pin and hygiene green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
The window package no longer carries the Windows Runtime projection it never used. Unpacked 169.6 to 146.6 MB (-23.0 MB, -13.6%), zipped 70.8 to 64.8 MB, 273 to 271 files.
The 10.0.17763 in the window's TFM pins the support floor (Windows 10 1809 / Server 2019). Any TFM version from 10.0 up also makes the SDK add the projection as a framework reference, and a self-contained publish then ships
Microsoft.Windows.SDK.NET.dll(23.6 MB) andWinRT.Runtime.dll(0.5 MB). Nothing here uses it:Windows.*namespace,WinRTorApiInformationnet10.0-windows7.0and references neither)IncludeWindowsSDKRefFrameworkReferences=falseingui/Directory.Build.propskeeps the projection out of both GUI projects while the TFM, and so the floor, stays.Why this switch and not a TFM without a version
The documented route,
net10.0-windows, meansTargetPlatformVersion7.0. The floor in the assembly then drops toWindows7.0, a higherSupportedOSPlatformVersionbeside it is refused (NETSDK1135), and both lock files change their framework key. Measured: it builds without a warning, but it gives the floor up. The switch keeps the floor and the lock files as they are. It is the SDK's own property (Microsoft.NET.Windows.targetssets it to true only when a project leaves it empty) but it has no page on learn.microsoft.com, so the effect is checked where it ships (below).Also
packaging/build-dist.ps1stops if either projection file is in the publish, ahead of the register check, which would otherwise ask for the projection to be declared. The ReadyToRun check keeps its three assemblies and loses the two projection rows, andPublishReadyToRunExcludeleaves the project.packaging/components.json,THIRD-PARTY-NOTICES.mdand the component-list test drop the projection. It was the one component in the package without an SPDX licence (LicenseRef-Microsoft-Windows-SDK).Verification
build-dist.ps1publishes it: the two projection files go, and three files change -ChronoMock.deps.json(loses the runtime pack entry),ChronoMock.dlland its pdb. All 2417 methods ofChronoMock.dllhave the same IL, the metadata heaps the same sizes and the embedded resources the same bytes. The MVID differs because the compiler hashes the reference set into it.TargetPlatformandSupportedOSPlatformstayWindows10.0.17763.0.CI=true(locked restore, ReadyToRun) succeeds and is byte for byte the same as the local one. Locked restores of both GUI projects pass, also with the restoring machine's identifier set tolinux-x64as on the dependency-submission runner. No lock file changes.build-dist.ps1, taken from the file and run on real publishes: pass on the new layout, stop on the old one (naming the projection) and on an IL-only build (ChronoMock.dllnot compiled ahead). The register check stops on the new layout with the old register (declared, not bundled) and on the old layout with the new register (bundled, not declared).Directory.Build.props: 79 tests, green. Thecomponents,hygiene,namesandmsiguards and the component-list tests, green.clippy,clippy-pin,format-cs,metrics-pin,lint-ps(185 files). Mutation registry anchors: 1154 entries, 0 off.Not measured
downloadDependencies), as it does the ASP.NET Core runtime pack. Neither ships.Also in this pull request (2026-10-26)
main and three Dependabot updates. One merge commit (
39d9a81) brings main (#137, which this branch was stacked on, and the actions bump of #141) and the Dependabot branches of #117 (serde_json 1.0.154, toml 1.1.8, winresource 0.1.34), #139 (Microsoft.NET.Test.Sdk 18.11.0 in the protocol tests) and #140 (semgrep 1.181.0). Their commits come in unchanged, so those pull requests count as merged with this one.The register follows two new versions (
74717da). Each stopped a check on the open pull requests:build-dist.ps1stopped the installer job on chore(deps): Bump the cargo-minor-and-patch group across 1 directory with 3 updates #117, chore(deps): Bump the nuget-minor-and-patch group with 1 update #139 and chore(ci): Bump semgrep from 1.180.0 to 1.181.0 in /.github/semgrep #140 (declared 10.0.13, bundled 10.0.14).packaging/components.json,THIRD-PARTY-NOTICES.mdand the unreleased CHANGELOG line about the bundled runtime name the new versions. A localbuild-dist.ps1on SDK 10.0.403 passes the register check (27 components, 64.9 MB zip), and the component guards pass (components13,--bins component3).The red CI on
e8f5b9d(b2e4758).AnnounceTests.The_calculator_reads_its_answer_when_a_step_moves_itfailed with "nothing was announced" after 17.7 s, where it takes 3.3 s on a desktop run alone and cold.NextAsyncchecked its deadline before it read the queue, so an announcement made just before the UI thread was held past the deadline was never read. It now reads the queue once more after the deadline, and a failure names how long it waited and what it passed over. The deadline goes from 5 s to 20 s, as it bounds only a failure.ParallelMode.None), so no other test shares the UI thread while it waits. What held the runner for about 12.7 s before the wait is not known, the log gives only the test's total time.FilledScreenSweepTests.AnsweredAsyncreturned false at the deadline without a last look, so an answer that landed during a hold counted as none (8bddecc). The same probe, timed to the answer, fails the old helper and passes the new one. Its deadline stays at 5 s, andFilledScreenSweepTestsis 4 of 4.AnnounceTests8 of 8 andHistoryErrorTests2 of 2,format-cs,metrics-pin,clippy,clippy-pin,lint-ps,deny, thehygiene,names,componentsandnetworkguards, and the mutation anchors (1154 entries, 0 off).Not measured here: the semgrep bump is measured by this pull request's Semgrep job against the tree, as 1.179.0 and 1.180.0 were. The run against the release workflows before
3b94c4e, which must still report six, is still owed.Stacking
Branched from
perf/r5-8-cold-start(#137), merged since. With main merged in, this PR's diff is the R5/8b commit, the merge above and the three fixes.🤖 Generated with Claude Code