Specification: Day 0 Update#6299
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Clarify how client infers new functionality from version signal/schema - Respect --nowarn: suppress update warning, fail with error code if too old - Leverage winget resume for command relaunch after self-update - Use ShellExecute on app execution alias instead of wt.exe/cmd.exe dependency - Remove --accept-package-agreements/--accept-source-agreements; use explicit --source winget Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment was marked as outdated.
This comment was marked as outdated.
|
|
||
| ## Abstract | ||
|
|
||
| Enable WinGet to detect that it is outdated and self-update on first meaningful command execution. When the first command requiring the source index runs, the client checks a version signal in the preIndexed package source, determines whether a newer stable release exists, and — with user consent — updates itself and relaunches the original command. This eliminates the "chicken and egg" problem where WinGet must already be current to use new functionality (e.g., `winget configure`). |
There was a problem hiding this comment.
Another thought - what if the preIndexed package source is disallowed by GPO, or removed by the user before the first command that would use it? Should this perhaps be a different endpoint that gives the information?
There was a problem hiding this comment.
I'd expect enterprise customers to push out new versions to their devices. If they are blocking the default source, there might be another way to reason about updating ourself, but I haven't gone through all the thinking yet.
There was a problem hiding this comment.
Yeah, it's another 🐔 / 🥚 - especially if the auto udpate is intended to use the default source to update itself. There's also more thought needed to ensure that the version referenced in the index actually exists as a package in the winget source
…ling - Clarify 'winget default source' in abstract (line 14) - Explain Stub App friction point for winget configure enable (line 19) - Fix box-drawing alignment in detection flow diagram - Replace watchdog process with winget resume reference (line 91) - Fix spell check: rework UI prompt to avoid split-word issues - Add lockdown, myconfig, rustup, sideloading to expect.txt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Some thoughts about the timeline... Assuming that Windows' release schedule stays as it has been for the past couple of years, I think the cutoff date for being in an 2_H2 build would be around March-April, and for a 2_H1 would be around September-October the year before. If we assume further that we keep winget's release schedule the same, out options would be..
And who knows if they're even going to keep that pattern... I think ideally we would want to have this complete in the client for 1.30, so we can update the service and start getting the version metadata in the source by 1.31, and then we'd have some time to validate it works before baking it into the OS. And we'd be looking at it being included in 27H2. Anything later than that, we'd be looking at 28H1 or 28H2 (since they seem to skip H1s). This all also depends on the OS not implementing a mechanism for updating preinstalled Store apps while installing/updating Windows. If they do that before the version we'd include this on, then it all becomes moot. |
| ``` | ||
|
|
||
| - `latestStableClientVersion` — The newest stable release of the WinGet client. | ||
| - `minimumRecommendedClientVersion` — The minimum version that supports all current source features (e.g., new schema fields, API endpoints). Clients below this threshold get a stronger update prompt. |
There was a problem hiding this comment.
I think we need another field for the minimum working version. It is a different message if we say "you have an outdated version, you can update for a better experience" than if we say "you have an outdated version that doesn't work anymore, you need to update"
There was a problem hiding this comment.
I think there is going to be a tough balance between what "works" in some form or another, and the intent of getting the device quickly to the latest stable version of the client. This "chicken and egg" problem has been there for quite some time. The expired certificates for the "msstore" source, and support for dependencies, and support for configuration have all three been factors leading into where we are today.
If for example, we were to decide to force a 2.x version of the schema and that meant the device "must" update I'm not sure what that would look like. The notion of 1.x is deprecated, however seems like a good idea, and we could keep that around as a logical "minimal" source without manifests in it could be a way to help a future migration succeed faster/better.
| { | ||
| "latestStableClientVersion": "1.30.1234.0", | ||
| "minimumRecommendedClientVersion": "1.28.0.0", | ||
| "day0UpdatePackageId": "Microsoft.AppInstaller" |
There was a problem hiding this comment.
Maybe this is just me, but "day 0" makes me think of zero-day exploits. I would prefer if we used another term.
There was a problem hiding this comment.
I'm open to suggestions :)
| User runs: winget configure myconfig.yaml | ||
| │ | ||
| ▼ | ||
| ┌───────────────────────────────────┐ | ||
| │ Source index access required │ |
There was a problem hiding this comment.
winget configure now requires installing the source?
There was a problem hiding this comment.
"Most" configuration files I've seen involve installing packages which would require having a "source".
| ``` | ||
|
|
||
| 2. **If accepted:** | ||
| - Record the original command line arguments via `winget resume` infrastructure. |
There was a problem hiding this comment.
I have no idea how winget resume is implemented, but it is intended for reboots, right? If so, I don't think that would be the right tool. I would expect a resume across a reboot to require something like a RunOnce key, and that doesn't seem appropriate here.
There was a problem hiding this comment.
When the resume experimental feature is enabled, the client creates checkpoints. The resume command should just load that checkpoint #3508. I also don't believe that in the restart flow registry keys are used, instead the application is registered for restart with Win32 APIs #3858.
There may be some minor work to ensure the checkpoint is there for when WinGet aborts it's own process and re-schedules itself, but I think it's absolutely the right use case for the resume - as it's effectively a reboot, just in this case it's a process reboot and not a machine reboot
|
|
||
| 2. **If accepted:** | ||
| - Record the original command line arguments via `winget resume` infrastructure. | ||
| - Initiate the self-update via `winget upgrade Microsoft.AppInstaller --source winget --silent`. |
There was a problem hiding this comment.
nit: maybe that's an equivalent of what we'd do, but I doubt we would want to invoke the command line like this.
There was a problem hiding this comment.
That's why the PR is still in Draft :) The robot is making all kinds of assumptions. I'm very appreciative of all the feedback to whip this into shape. Once we get "closer" to what's reasonable, I'll condense some of those learnings into copilot-instructions files to help future specs to become "better".
| - Day 0 Update check runs **once per session** (once per process lifetime). | ||
| - After dismissal, suppress for 24 hours (configurable). | ||
| - After N dismissals (default: 3), suppress permanently until the setting is reset or a major version ships. | ||
| - The check adds negligible latency (metadata is already being fetched as part of source index access). |
There was a problem hiding this comment.
Not if we're doing something that does not use the source index.
|
|
||
| To avoid pestering users: | ||
|
|
||
| - Day 0 Update check runs **once per session** (once per process lifetime). |
There was a problem hiding this comment.
What is a session? Just a process?
| |--------|------|---------|-------------| | ||
| | `EnableDay0Update` | Bool | Enabled | Master toggle for Day 0 Update | | ||
| | `Day0UpdateBehavior` | Enum | Prompt | `Prompt` / `AutoUpdate` / `NotifyOnly` | | ||
| | `Day0UpdateSource` | Enum | Store | `Store` / `Direct` (direct MSIX from CDN) | |
There was a problem hiding this comment.
Download MSIX from CDN sounds expensive.
| interface IPackageManagerStatus | ||
| { | ||
| Boolean IsClientUpdateAvailable { get; }; | ||
| String LatestStableClientVersion { get; }; | ||
| String CurrentClientVersion { get; }; | ||
| String MinimumRecommendedClientVersion { get; }; | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Would we add a function to perform the update? Otherwise, we'd have to ask them to update "Microsoft.AppInstaller" from the API, and deal with the process blocking the update. Then there is the issue that this would kill the service, and one would have to reconnect.
| ## Future Considerations | ||
|
|
||
| - **Staged rollout**: Day 0 Update could integrate with the existing feature toggle system for gradual rollout. | ||
| - **Delta updates**: Rather than full package replacement, future iterations could support incremental/delta client updates for faster Day 0 flow. |
There was a problem hiding this comment.
If we update from the Store, we should be getting this for free
📖 Description
Specification for the Day 0 Update feature — enabling WinGet to detect that it is outdated on first meaningful command execution and self-update before proceeding. This eliminates the chicken-and-egg problem where WinGet must already be current to use new functionality (e.g.,
winget configure), and removes the need forwinget configure enableon fresh installs.Key aspects:
latestStableClientVersionfield in preIndexed source metadata signals the latest stable client versionwinget resumeviaShellExecuteEnableDay0Update,ForceMinimumClientVersion)--nowarn(suppresses update warning; command fails with error code if client is too old)Microsoft.AppInstallerfrom the winget default source explicitly (no implicit agreement acceptance)Changes addressing review feedback (June 22):
--nowarnsupport: suppresses warning entirely, fails with error code if command requires newer clientwt.exe/cmd.exerelaunch withShellExecuteon app execution alias — no terminal dependencywinget resume(experimental) for restoring original command context after self-update--accept-package-agreements/--accept-source-agreementsfrom self-update command; explicit--source wingetto target the default source without asserting acceptance on behalf of the userAuthored with GitHub Copilot assistance.
🔗 References
Related Issues:
🔍 Validation
Spec document — no code changes to validate.
✅ Checklist
📋 Issue Type
Microsoft Reviewers: Open in CodeFlow