Skip to content

Work in progress: msix installer#732

Draft
kmahone wants to merge 38 commits into
mainfrom
user/kmahone/msix
Draft

Work in progress: msix installer#732
kmahone wants to merge 38 commits into
mainfrom
user/kmahone/msix

Conversation

@kmahone

@kmahone kmahone commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Not yet ready for review.

@clawsweeper

clawsweeper Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codex review: found issues before merge. Reviewed June 12, 2026, 4:11 PM ET / 20:11 UTC.

Summary
The PR replaces the Inno/Updatum distribution path with always-packaged MSIX builds, signed release packages, embedded AppInstaller update feeds, and Windows-managed updates.

Reproducibility: not applicable. as a bug reproduction; this is a distribution architecture change, although its install, upgrade, update, recovery, and uninstall behavior is concretely testable and currently unproven.

Review metrics: 3 noteworthy metrics.

  • Installer surface: 65 files affected. The change spans distribution, signing and release automation, application identity, updater UX, documentation, and installer tests.
  • Patch size: 2,201 added, 3,641 removed. The established installer and updater path is removed while a new distribution stack is introduced.
  • Temporary overrides: at least 4 active. Tag validation, build dependencies, channel classification, and update-feed routing are explicitly configured for branch rehearsal.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Remove every rehearsal-only workflow and feed override.
  • [P1] Implement and validate existing-user migration, recovery, and uninstall cleanup.
  • Post redacted real Windows evidence for the complete lifecycle.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body contains no inspectable after-fix proof of fresh installation, Inno-to-MSIX upgrade, AppInstaller update, recovery, or uninstall; add redacted screenshots, recordings, terminal output, or logs, then update the PR body to trigger a fresh review or ask a maintainer to comment @clawsweeper re-review.

Risk before merge

  • [P1] Existing users may uninstall the MSIX while leaving the app-managed WSL gateway and generated Windows state behind because the installer-owned cleanup choice is removed without a completed replacement.
  • [P1] Installed Alpha packages can become permanently bound to a mutable feature-branch feed and depend on that branch's continued availability and integrity.
  • [P1] Temporary release exceptions weaken tag/version correctness and allow package creation independently of the intended shared and E2E test gates.
  • [P1] Removing the in-app updater makes recovery depend entirely on package identity, embedded AppInstaller metadata, hosted feed correctness, and Windows polling.
  • [P1] No real-system evidence currently demonstrates fresh installation, migration from the existing installer, automatic updating, recovery, or uninstall behavior.

Maintainer options:

  1. Finish the production cutover (recommended)
    Restore production workflow and feed settings, add the missing migration and cleanup contracts, and provide complete lifecycle proof before merge.
  2. Keep the cutover paused
    Leave the PR as a draft until maintainers settle permanent installer identity, update channels, migration, recovery, and uninstall policy.

Next step before merge

  • [P2] The contributor can fix the explicit branch blockers, but permanent migration, channel, recovery, identity, and uninstall policy require maintainer approval and real upgrade proof.

Security
Needs attention: The update supply chain remains tied to a mutable branch and temporary release-identity guard bypasses.

Review findings

  • [P1] Restore strict tag/version validation — .github/workflows/ci.yml:109-115
  • [P1] Restore the MSIX job's test dependencies — .github/workflows/ci.yml:362-365
  • [P1] Stop classifying rehearsal tags as Alpha releases — .github/workflows/ci.yml:425-436
Review details

Best possible solution:

Remove every rehearsal override, restore durable feeds and strict production release gates, implement an explicit Inno-to-MSIX migration and uninstall-cleanup experience, and demonstrate the full lifecycle on real Windows systems before merge.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a bug reproduction; this is a distribution architecture change, although its install, upgrade, update, recovery, and uninstall behavior is concretely testable and currently unproven.

Is this the best way to solve the issue?

No, not in its current form; MSIX is a plausible direction, but a rehearsal-configured branch without upgrade and uninstall parity is not a safe permanent replacement.

Full review comments:

  • [P1] Restore strict tag/version validation — .github/workflows/ci.yml:109-115
    Remove the msixtest exception before this becomes the production workflow. As written, a tagged build can bypass the invariant that the computed SemVer exactly matches the release tag, allowing mismatched package and release identities.
    Confidence: 0.99
  • [P1] Restore the MSIX job's test dependencies — .github/workflows/ci.yml:362-365
    This temporary needs: [] allows packaging to run without the shared and E2E jobs completing. Restore needs: [test, e2etests] and the intended version-output dependency before the job is used for releases.
    Confidence: 0.99
  • [P1] Stop classifying rehearsal tags as Alpha releases — .github/workflows/ci.yml:425-436
    The temporary pattern maps msixtest tags to the real Alpha package identity and embedded update path. If merged, future rehearsal tags would participate in the production Alpha channel instead of remaining isolated Dev packages.
    Confidence: 0.99
  • [P1] Point Alpha packages at the durable feed — installer/appinstaller/openclaw-alpha-x64.appinstaller:8-9
    This AppInstaller registers user/kmahone/msix as the canonical update endpoint. Installed clients would depend on a mutable feature branch remaining available and trustworthy; switch both architectures and the embedded URI back to the permanent main-hosted feed.
    Confidence: 0.99
  • [P1] Replace the removed uninstall cleanup contract — scripts/validate-msix-storage-paths.ps1:38-43
    The branch acknowledges that deleting the Inno cleanup path leaves packaged users needing a pre-uninstall warning and an MSIX-compatible cleanup action. Implement that replacement before retiring the existing hook, otherwise uninstalling can orphan the managed WSL gateway and related state.
    Confidence: 0.98

Overall correctness: patch is incorrect
Overall confidence: 0.99

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against ea36b12f9e4c.

Label changes

Label justifications:

  • P2: This is a substantial Windows distribution improvement with significant but platform-limited impact and no demonstrated emergency regression.
  • merge-risk: 🚨 compatibility: The PR replaces installer ownership, package identity, updater behavior, migration, and uninstall semantics for existing users.
  • merge-risk: 🚨 automation: The PR changes release signing, tag/version validation, test gating, channel selection, and AppInstaller feed automation.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body contains no inspectable after-fix proof of fresh installation, Inno-to-MSIX upgrade, AppInstaller update, recovery, or uninstall; add redacted screenshots, recordings, terminal output, or logs, then update the PR body to trigger a fresh review or ask a maintainer to comment @clawsweeper re-review.
Evidence reviewed

Security concerns:

  • [high] Mutable branch controls Alpha updates — installer/appinstaller/openclaw-alpha-x64.appinstaller:9
    The registered Alpha feed points at a feature branch, allowing later branch content to influence installed-client update polling and package selection.
    Confidence: 0.99
  • [medium] Release identity guard remains bypassable — .github/workflows/ci.yml:115
    The workflow skips strict tag-to-version verification for rehearsal tags that are also classified into the Alpha channel.
    Confidence: 0.99

What I checked:

  • Temporary tag validation bypass: The workflow deliberately skips strict tag-to-GitVersion validation for rehearsal tags and explicitly says to revert the exception before merging. (.github/workflows/ci.yml:109, b05f56190d3c)
  • Temporary CI dependency bypass: The MSIX packaging job has an explicit temporary empty dependency list instead of waiting for the shared and E2E test jobs. (.github/workflows/ci.yml:362, b05f56190d3c)
  • Temporary Alpha channel classification: Rehearsal msixtest tags currently map to the real Alpha package identity and update channel, with comments requiring a pre-merge revert. (.github/workflows/ci.yml:425, b05f56190d3c)
  • Mutable Alpha update feed: The x64 Alpha AppInstaller registers the feature branch as its canonical update endpoint rather than the durable main-hosted feed. (installer/appinstaller/openclaw-alpha-x64.appinstaller:8, b05f56190d3c)
  • Existing uninstall contract: Current main bundles and invokes Uninstall-LocalGateway.ps1 from the Inno uninstall flow, providing cleanup behavior that this branch deletes. (installer.iss:83, ea36b12f9e4c)
  • Missing MSIX cleanup replacement: The branch's own storage validation guidance states that an MSIX cleanup path and packaged pre-uninstall warning are still required, and notes that package removal does not clean up the WSL distro. (scripts/validate-msix-storage-paths.ps1:38, b05f56190d3c)

Likely related people:

  • kmahone: Authored the branch's packaging, release, channel, and update architecture and previously updated default-branch references in the current-main release workflow. (role: current feature contributor and recent release-workflow contributor; confidence: high; commits: 37b0ea672037, c0b9cc5f37d2, 4820e71754c8; files: .github/workflows/ci.yml, src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj, src/OpenClaw.Tray.WinUI/Package.appxmanifest)
  • ranjeshj: Recent merged work consolidated setup UI into the tray host and touched the current Inno installer and release workflow, making this person relevant to migration and lifecycle review. (role: recent installer and setup integration contributor; confidence: high; commits: afa6218338d6, ea36b12f9e4c; files: installer.iss, .github/workflows/ci.yml, src/OpenClaw.Tray.WinUI/App.xaml.cs)
  • christineyan4: Git history ties the current setup engine's destructive uninstall pipeline and earlier installer behavior to this contributor's merged implementation. (role: setup and installer feature introducer; confidence: high; commits: 85445c78066b; files: src/OpenClaw.SetupEngine/SetupPipeline.cs, installer.iss, .github/workflows/ci.yml)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. labels Jun 9, 2026
@kmahone kmahone force-pushed the user/kmahone/msix branch from 3559f81 to 4b0d617 Compare June 9, 2026 18:55
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 9, 2026
Keith Mahoney and others added 17 commits June 10, 2026 09:51
Master shipped sizes 24/32/48/256; Windows down-scaled larger PNGs for
Start Menu / taskbar / Alt+Tab surfaces that prefer 16/20/44. These three
PNGs fill the gap and are auto-discovered by MakePri via the existing
Assets\**\* content include and the targetsize-NN_altform-unplated
filename convention. No code, csproj, or manifest changes required.

Cherry-picked from origin/pr-468 (Square44x44Logo.targetsize-{16,20,44}_altform-unplated.png).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the conditional dispatch that produced an unpackaged
WindowsPackageType=None + app.manifest build for the Inno installer
path. Default packaging mode is now unconditionally MSIX; only the
PackageMsix=true opt-in for .msix file production remains.

Changes:
- Make <WindowsPackageType>MSIX</WindowsPackageType> +
  <WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
  unconditional.
- Delete the <PropertyGroup Condition=\'$(Unpackaged)' == 'true'\>
  block (WindowsPackageType=None + ApplicationManifest=app.manifest).
- Delete the CopyWebView2Loader target (only needed for the unpackaged
  layout; MSIX bundles the loader automatically). The unrelated
  CopyWebView2Loader target in OpenClaw.SetupPreview is untouched.
- Rewrite the explanatory comment block to drop the Unpackaged mode
  paragraph (now describes one opt-in flag instead of two).

src/OpenClaw.Tray.WinUI/app.manifest is now orphaned but left in place;
Phase 3 will delete it together with the Inno installer.

Callers that still pass -p:Unpackaged=true (scripts/build-inno-local.ps1
and the Inno publish job in .github/workflows/ci.yml) are transiently
non-functional between Phase 2 and Phase 3 — the property becomes a
no-op so the build emits an MSIX layout that Inno cannot consume. Both
callers are deleted in Phase 3, per the all-phases-land-together branch
workflow.

Audit of App.xaml.cs:355-405 _isPostSetupRestart retry: KEEP. The
branch is not Inno-specific. The tray itself spawns a fresh tray with
--post-setup-restart --wait-for-pid <oldPid> after in-process
SetupWindow completes (RestartAfterSetupAsync, line 3097). The 15s
retry + AbandonedMutexException handler prevents the new tray from
giving up on the single-instance mutex while the old tray is still
exiting. AppRefactorContractTests:135-140 enforces the call pattern.

Validation (per AGENTS.md):
- build.ps1: all 5 projects built.
- Shared.Tests: 2049 passed, 29 skipped (env-only), 0 failed.
- Tray.Tests: 958 passed, 0 skipped, 0 failed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Delete Inno Setup distribution path now that MSIX is the always-on package
type. Phase 3B will follow up with Updatum removal; Phase 4 will rebuild
the release pipeline around the .msix file produced by `-p:PackageMsix=true`.

Deleted files (5 source + 2 test):
- installer.iss (256 lines)
- scripts/build-inno-local.ps1
- scripts/Uninstall-LocalGateway.ps1
- src/OpenClaw.Tray.WinUI/app.manifest (orphaned by Phase 2)
- tests/PackagingTests/Test-InnoUninstallOrdering.ps1 (parent dir removed)
- tests/OpenClaw.Tray.Tests/InstallerIssAssertionTests.cs (9 tests)
- tests/OpenClaw.Tray.Tests/ReleaseSigningWorkflowTests.cs (4 tests; Phase 5
  will replace with MSIX-signing assertions)

ci.yml: drop -p:Unpackaged=true from build/publish (Phase 2 cleanup), retire
the Download VC Redist + Install Inno Setup + Build x64/arm64 Installer +
Sign Installers steps in the release job, remove .exe entries from the
release files: list and body, and update the paused build-msix comment.

App.xaml.cs: remove the AppMutex coordination comment that referenced
installer.iss; the OpenClawTray mutex itself stays unchanged.

SetupEngine.UI/LogFileLauncher.cs: rewrite the "Unpackaged process" comment
to cover both the no-package-identity and library-only call sites.

Ship-guard ported from installer.iss to MSBuild: two new targets on
OpenClaw.Tray.WinUI.csproj (ValidateSetupEngineUiNotShipped after Build,
ValidateSetupEngineUiNotPublished after Publish) fail the build if
OpenClaw.SetupEngine.UI.exe lands in the tray bin/publish output. Pairs
with a new "Hazards" section in docs/SETUP_ENGINE_REDESIGN.md explaining
the in-process design and pointing at PR #468's bootstrapper diffs as the
worked example anyone splitting SetupEngine into its own process would
need to study first.

Test-ReleaseNativeDependencies.ps1: remove -RequireInstallerVCRedist /
-InstallerVCRedistPath params and their dead handler (only Inno called
them); -RequireAppLocalVCRuntime and -SkipNativeLoadProbe stay (still used
by ci.yml's Verify Native Runtime Payload steps).

Docs: drop the Inno helper section + .exe-installer references from
DEVELOPMENT.md, docs/RELEASING.md, docs/VERSIONING.md, and the Inno
comment in scripts/validate-msix-storage-paths.ps1. README.md + docs/SETUP.md
download tables are replaced with TODO placeholders that Phase 7 will fill
with MSIX-flavored content.

Validation (on user/kmahone/msix, Windows):
- ./build.ps1 green
- Shared.Tests: 2049 passed / 29 skipped (unchanged from Phase 2)
- Tray.Tests: 945 passed (was 958; -13 = 9 InstallerIssAssertion + 4
  ReleaseSigningWorkflow tests removed, as expected)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Updatum becomes dead under MSIX-primary publishing once <AutomaticBackgroundTask />
in the .appinstaller XML (Phase 4) is the update mechanism. No in-app updater
under MSIX, no manual "Check for updates" button.

Removed:
- Updatum NuGet PackageReference from OpenClaw.Tray.WinUI.csproj
- App.xaml.cs: using Updatum, AppUpdater static field, BuildInitialUpdateInfo
  call, startup update-check gate, IAppCommands.CheckForUpdates impl, dispatcher
  case "checkupdates", HandleDeepLink wiring, and the entire #region Updates
  block (~460 lines).
- IAppCommands.CheckForUpdates declaration.
- DeepLinkHandler.cs: case "updates"/"update"/"check-updates"/"update-check"
  block + CheckForUpdates Func field.
- AboutPage.xaml CheckUpdatesButton + AboutPage.xaml.cs OnCheckUpdatesClick.
- HubWindow.xaml.cs orphan CheckForUpdatesAction property.
- SettingsData.SkippedUpdateTag + 4 SettingsManager references.
- Dialogs/UpdateDialog.cs (deleted file).
- Dialogs/DownloadProgressDialog.cs (deleted file).
- Update*, CheckUpdates*, DownloadProgress* resource keys from all 5 locale
  resw files (en-us, zh-tw, zh-cn, nl-nl, fr-fr; 18 keys per file).
- ci.yml: Updatum auto-update ZIP comment + x64/arm64 "Create Release ZIP"
  steps + ZIP entries from release files: + Portable bullets from release
  body. Release will have no binary artifacts until Phase 4 MSIX pipeline.
- Test fixtures: SettingsRoundTrip (4 SkippedUpdateTag refs), DeepLinkParser
  (2 InlineData rows + fixture init), TrayMenuWindowMarkup (2 Assert.Contains),
  AppRefactorContract (CheckForUpdatesAsync from AssertInOrder),
  LocalizationValidation (WindowTitle_Update + Update_OK invariants).
- Docs: README.md + docs/SETUP.md (openclaw://check-updates row);
  docs/RELEASING.md (Portable ZIP Updatum block);
  docs/VERSIONING.md (Updatum Library reference).

Kept:
- UpdateCommandCenterInfo DTO in OpenClaw.Shared/Models.cs - public protocol
  type sent to external agent clients; default-initialized (Status="Unknown",
  CurrentVersion=null). AppStateSnapshot.LastUpdateInfo wiring stays.

Validation:
- ./build.ps1 green
- Shared.Tests: 2049 passed, 29 skipped (unchanged)
- Tray.Tests: 943 passed (was 945; -2 = DeepLinkParserTests InlineData rows)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Symptom (caught while smoke-testing the MSIX-primary build): asking the
agent to show a Windows notification throws

  InvalidOperationException: Your app manifest must have a
  toastNotificationActivation extension with a valid
  ToastActivatorCLSID specified.
  at ToastNotificationManagerCompat.CreateToastNotifier()
  at ToastContentBuilder.Show()
  at ToastService.ShowToast(...)

Root cause: Microsoft.Toolkit.Uwp.Notifications (which we still use for
all toasts via App.OnToastActivated + interactive AddButton flows) has
two code paths -- an unpackaged shortcut/COM-self-registration path and
a packaged path that reads ToastActivatorCLSID from the appx manifest.
Phase 2 of the MSIX-primary branch dropped -p:Unpackaged=true, so we now
always hit the packaged path. With no manifest extension declared, the
toolkit cannot find a CLSID and throws on first ShowToast call.

Fix: declare a stable CLSID for the toast activator in the manifest:

- Add desktop:Extension Category="windows.toastNotificationActivation"
  with ToastActivatorCLSID="EF9297B3-EEEB-4E50-8306-D1D118E04BC7".
- Add the matching com:Extension/com:ComServer/com:ExeServer entry so
  the COM server is wired to OpenClaw.Tray.WinUI.exe with the
  conventional -ToastActivated arg.
- Declare the desktop + com namespaces and include them in
  IgnorableNamespaces.

The CommunityToolkit generates the actual activator type at runtime and
binds it to this CLSID; no extra C# is needed. App.ToastActivation.cs
already wires ToastNotificationManagerCompat.OnActivated to
OnToastActivated and parses arguments via ToastArguments.Parse, so the
button-click roundtrip works as soon as the CLSID is reachable.

Validation:
- ./build.ps1 green (manifest passes MakeAppx schema check).
- Tray.Tests still pass (no source changes; manifest-only edit).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously the precheck only warned and the post-build summary suggested `Add-AppxPackage -AllowUnsigned`. That command does not work for this MSIX package on stock Windows (AllowUnsigned only applies to a narrow set of developer-mode scenarios), so users following the suggestion would fail at install time.

Now: missing cert => Write-Error + exit 1 in the preflight, with a clear message pointing at scripts\setup-dev-msix-cert.ps1. The post-build install hint always shows the signed Add-AppxPackage form (the unsigned branch is now unreachable). Docstring updated.

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

Adopts the publishing-infrastructure pattern from PR #468 (treated as a
reference design only, not cherry-picked) and adapts it to our
WindowsAppSDKSelfContained=true MSIX. Because the WindowsAppRuntime is
bundled inside the .msix, the AppInstaller feed has no <Dependencies>
block, no runtime-URI rendering, and no separate runtime MSIX release
asset.

What this commit adds
- installer/openclaw-companion.appinstaller.template — 6 placeholders
  (VERSION, PUBLISHER, IDENTITY_NAME, PROCESSOR_ARCHITECTURE, MSIX_URI,
  APPINSTALLER_URI), AutomaticBackgroundTask-only UpdateSettings.
- installer/appinstaller/openclaw-{x64,arm64}.appinstaller — bootstrap
  feed files at version 0.0.0.0; the appinstaller-feed-pr workflow
  rewrites these on each stable release tag.
- installer/appinstaller/README.md — explains the stable-feed model.
- scripts/render-appinstaller.ps1 — substitutes placeholders, asserts
  the rendered XML parses and contains no <Dependencies> block.
- scripts/validate-appinstaller-hosting.ps1 — Content-Type / Content-
  Length / Range checks against the hosted .appinstaller and .msix URLs,
  with -AllowGitHubContentTypes for raw.githubusercontent.com.
- scripts/test-appinstaller-update.ps1 — local HttpListener-backed
  vN -> vN+1 upgrade smoke using PackageManager
  .AddPackageByAppInstallerFileAsync.
- .github/workflows/appinstaller-feed-pr.yml — workflow_dispatch input
  takes a release tag, renders the two feed files, validates them, and
  opens a PR to advance the stable feed. Uses OpenClaw Foundation
  publisher; rejects pre-release tags; here-string PR body uses
  Set-Content -Value so the body renders as Markdown (fixes the
  8-space-indent code-block bug in PR #468's workflow).
- tests/OpenClaw.Tray.Tests/AppInstallerTemplateAssertionTests.cs — 8
  test methods covering template shape, the new
  Template_HasNoDependenciesBlock invariant, the two bootstrap feed
  files, the validation script, the smoke script, and the feed-update
  workflow.
- README.md — replaces the Phase-7 TODO placeholder with x64 and ARM64
  Install links pointing at the raw GitHub .appinstaller URLs.

What this commit does NOT add
- No in-app "Check for updates" button or AppInstallerUpdateService.
  Windows AppInstaller's AutomaticBackgroundTask handles all polling
  at OS level under MSIX.
- No Microsoft.WindowsAppRuntime.2 release asset or feed dependency —
  the runtime is bundled (WindowsAppSDKSelfContained=true).

Validation
- ./build.ps1: green.
- Shared.Tests: 2049 passed / 29 skipped (matches baseline).
- Tray.Tests: 957 passed (was 943; +14 effective test cases from the
  new file).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Phase 4 appinstaller feed workflow expected release assets named

'OpenClawCompanion-<3partVersion>-win-<arch>.msix', which would have required a

rename step in the Phase 5 release job (Option A). Switching to Option B:

match whatever MSBuild emits by default for GenerateAppxPackageOnBuild=true,

i.e. 'OpenClaw.Companion_<4partVersion>_<arch>.msix'.

* appinstaller-feed-pr.yml: Get-RequiredAsset patterns updated to use the

  4-part $version (not the 3-part $versionText), dotted identity, and

  underscore separators. Uses ${version} to keep _ from being absorbed

  into the variable name.

* AppInstallerTemplateAssertionTests: matching Assert.Contains /

  Assert.DoesNotContain updates so the pin reflects the new convention.

Inside the rendered .appinstaller, <MainPackage Uri> uses the actual

GitHub release asset name, so AppInstaller behavior is unaffected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Unpause the build-msix matrix job and wire its outputs into the release
job so that tagged builds produce signed .msix artifacts attached to the
GitHub Release.

- ci.yml build-msix: drop `if: false` paused gate and
  `continue-on-error: true` placeholder; the job is now load-bearing.
- ci.yml release: add `build-msix` to `needs:` plus matching
  `needs.build-msix.result == 'success'` guard.
- Download the per-arch `openclaw-msix-win-{x64,arm64}` artifacts.
- Sign each .msix in place using `azure/artifact-signing-action@v2`
  with `files-folder-filter: msix` (mirrors the existing exe signing
  pattern: same endpoint, signing account, certificate profile, OIDC
  auth via azure/login).
- Attach both signed .msix files to the release via `files:` and
  rewrite the release body so it points users at the AppInstaller links
  in the README (primary install path) and notes the .msix assets as a
  direct-install fallback.

Validation:
- ./build.ps1 green
- Shared.Tests: 2049 passed / 29 skipped (baseline)
- Tray.Tests: 957 passed (baseline)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After Phase 3A removed Inno and Phase 5 wired the MSIX into the release,
the `build` job's loose unpackaged-tray artifact ceased to be shipped
to any user. The release job was still downloading it, signing the
loose exe, and running signature/native-dep validation against bits
that were then discarded. This commit removes that dead infrastructure
and preserves the most valuable validation against what we actually
ship.

ci.yml changes:
- Delete the `build` job in its entirety (loose `dotnet publish`,
  Test-ReleaseNativeDependencies on publish/, GitVersion verify,
  Upload Tray Artifact -> openclaw-tray-{rid}).
- Drop `build` from `release.needs:` and from the corresponding
  `needs.build.result == 'success'` guard.
- In `release`, remove: 2 tray-artifact download steps, 2 stage exe
  for signing steps, 2 sign-loose-exe steps, and 4 verify steps
  (Test-ReleaseExecutableSignatures and Test-ReleaseNativeDependencies
  against artifacts/tray-win-*).
- In `build-msix`, add a new `Verify MSIX Package Contents` step
  that runs immediately after the .msix is produced. It extracts the
  .msix (a zip), confirms `OpenClaw.Tray.WinUI.dll` is present with
  the correct GitVersion ProductVersion, and runs the existing
  Test-ReleaseNativeDependencies.ps1 against the extracted payload so
  the libsodium / VC++ runtime presence canary continues to fire --
  but now against the actual shipped MSIX bits, not a phantom
  unpackaged build.

Net diff: -108 lines from ci.yml; pipeline shape simplified from
six jobs to five (release no longer depends on a parallel build job
whose output it never used).

Validation:
- ./build.ps1 green
- Shared.Tests: 2049 passed / 29 skipped (baseline)
- Tray.Tests: 957 passed (baseline)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Phase 4 AppInstaller infrastructure was authored against master but the default branch was renamed to main (commit 37b0ea6). The stale refs would cause silent failure: AppInstaller polling would forever fetch frozen XML from the now-inactive origin/master branch, and the feed-update PR workflow would target a branch that doesn't accept commits.

Fixed:

- installer/appinstaller/openclaw-{x64,arm64}.appinstaller: <AppInstaller Uri> -> main

- installer/appinstaller/README.md: hosting URLs + prose -> main

- README.md: end-user install links -> main

- .github/workflows/appinstaller-feed-pr.yml: ref/raw URL/PR --base -> main

- scripts/render-appinstaller.ps1: docstring URLs -> main

- scripts/validate-appinstaller-hosting.ps1: docstring -> main

- tests/OpenClaw.Tray.Tests/AppInstallerTemplateAssertionTests.cs: assertions tracking the above

Also swept pre-existing master refs that the rename PR (37b0ea6) missed:

- docs/RELEASING.md, docs/VERSIONING.md: prerelease prose

- tests/.../LocalizationValidationTests.cs: comment

- src/.../ConnectionPage.xaml.cs: comment

Left alone (per main's rename PR intent): dual [main, master] CI

triggers, GitVersion ^(master|main)$ regex, third-party URLs, and all

'Master switch/toggle/control' UX terminology (unrelated to git branch).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build-msix invokes VS MSBuild without first running GitVersion, so the GitVersion.MsBuild package can't compute version metadata and the WinUI .dll inside the MSIX falls back to AssemblyVersion 1.0.0. The Verify MSIX Package Contents step then correctly fails:

  MSIX-internal ProductVersion '1.0.0' did not match GitVersion SemVer '0.6.4-PullRequest732.54'.

Mirror the gitversion/setup + gitversion/execute steps from the test job before Build MSIX Package. The execute action exports GitVersion_* environment variables that GitVersion.MsBuild picks up to inject Assembly/File/InformationalVersion, satisfying the verify assertion.

fetch-depth: 0 is already set on the checkout, so GitVersion can read git history. The existing manifest-patch step (which sets Appx package identity version) is unaffected.

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

build-msix only consumed needs.test.outputs.{semVer,majorMinorPatch}, which are now produced locally by the gitversion/execute step inside the job. e2etests was a pure gate (no outputs).

Swap manifest-patch + verify references from needs.test.outputs.* to steps.gitversion.outputs.*, then drop the needs:[] list so build-msix starts in parallel with test/e2etests on every push.

REVERT before merge — release job still gates on all four (line 491), so production releases are unaffected by this temporary change; the only effect is faster PR feedback. Restore 'needs: [test, e2etests]' on build-msix and switch the two version refs back to needs.test.outputs.*.

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

Test-ReleaseNativeDependencies.ps1 -RequireAppLocalVCRuntime fails after the MSIX-payload extract because vcruntime140.dll is missing next to libsodium.dll:
  Missing app-local vcruntime140.dll next to libsodium.dll.

Root cause: the CopyOpenClawVCRuntime* targets in src/Directory.Build.targets only ship a current VS-resolved runtime via CopyOpenClawVCRuntimeToPublish (AfterTargets=Publish). The pre-fix CI step ran 'msbuild /t:Build', which only triggers CopyOpenClawVCRuntimeToOutput - x64-only AND sourced from the stale 14.29 NuGet that the comment explicitly warns is too old for onnxruntime >= 1.20. Worse, the WinUI single-project AppX packaging task collects payload from publish output, not from the build TargetDir, so even the stale copies wouldn't end up inside the MSIX.

Switching to 'dotnet publish ... -p:PackageMsix=true' matches what build.ps1 does locally and what produces working MSIX packages on dev machines. publish triggers CopyOpenClawVCRuntimeToPublish (VS-install resolution -> current 14.40+ DLLs) and ValidateOpenClawVCRuntimePublished, which guarantees vcruntime140.dll lands in PublishDir before the AppX packager collects payload.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keith Mahoney and others added 2 commits June 10, 2026 12:53
…a is invalid" on install

The 2018 schema can choke on validators in newer Windows AppInstaller builds. Switching to the 2021 namespace makes Windows use the newer parser, which accepts the same element set we already use (MainPackage, OnLaunch, AutomaticBackgroundTask).

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

Local-file install of the standalone openclaw-msixtest-x64.appinstaller fails with LogHr 8007000D on the second-pass parse after AppInstaller refetches from raw.githubusercontent.com. Two underlying gaps in the external-feed approach we discovered:

1. raw.githubusercontent.com serves .appinstaller as text/plain instead of application/appinstaller. AppInstaller's strict parser rejects the redirected fetch.
2. ms-appinstaller://?source= protocol has been disabled by default on consumer devices since December 2023.

Docs:
  https://learn.microsoft.com/en-us/windows/msix/app-installer/installing-windows10-apps-web
  https://learn.microsoft.com/en-us/windows/msix/app-installer/how-to-embed-an-appinstaller-file

Embedded approach sidesteps both: ship openclaw-update.appinstaller inside the MSIX payload, reference it from the manifest's <uap13:AutoUpdate><uap13:AppInstaller File='...' />. Install path becomes 'download MSIX, double-click' - the .appinstaller is parsed locally from the extracted payload, no HTTP fetch, no MIME issue. Windows registers the embedded file's <AppInstaller Uri> as the canonical update-poll endpoint for the background update task.

Changes:
- src/OpenClaw.Tray.WinUI/Package.appxmanifest: add xmlns:uap13, add uap13 to IgnorableNamespaces, add <uap13:AutoUpdate><uap13:AppInstaller File='openclaw-update.appinstaller' /></uap13:AutoUpdate> in <Properties>.
- src/OpenClaw.Tray.WinUI/openclaw-update.appinstaller: new file, identical content to the on-disk installer/appinstaller/openclaw-msixtest-x64.appinstaller for the rehearsal (pinned to v0.6.4-msixtest.3 release, 0.6.4.0).
- src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj: add <Content Include='openclaw-update.appinstaller'> so the file ships in the MSIX payload.

Local validation:
- dotnet publish -p:PackageMsix=true succeeds.
- MSIX payload contains openclaw-update.appinstaller (1270 bytes).
- AppxManifest.xml carries the uap13:AutoUpdate Properties block.
- Add-AppxPackage installed OpenClaw.Companion 0.6.4.0 in 406 ms with no schema errors - <uap13:AutoUpdate> accepted by the Windows AppX deployment engine.

Still TEMP-tracked for revert before merge:
  revert-embedded-appinstaller-manifest
  revert-embedded-appinstaller-content
  ... plus the earlier msixtest reverts.

Not yet known: whether the background update poll (after install) hits the same raw.githubusercontent.com MIME issue as the install-time parse. That's the next thing to test once a higher-version MSIX is published.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 11, 2026
@kmahone kmahone temporarily deployed to release-signing June 11, 2026 19:49 — with GitHub Actions Inactive
…ate rehearsal

Phase 2 of the embedded-AppInstaller rehearsal. With v0.6.4-msixtest.4 installed, bump both feed copies to 0.6.5.0 pointing at the next test release. Order matters - push feed bump first so raw.githubusercontent.com is already serving the bumped XML by the time CI publishes the new MSIX release; otherwise the OnLaunch poll would see the new XML and 404 on MainPackage Uri.

- installer/appinstaller/openclaw-msixtest-x64.appinstaller: what raw.githubusercontent.com serves to the update poller. This is the URL Windows registered at install time via the embedded copy.
- src/OpenClaw.Tray.WinUI/openclaw-update.appinstaller: kept in lockstep for consistency; only affects future installs (existing installs read Uri once at install time, then poll that URL forever).

Next: push tag v0.6.5-msixtest.1 to produce the matching release.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kmahone kmahone temporarily deployed to release-signing June 11, 2026 20:08 — with GitHub Actions Inactive
…alse

Phase 3 of the embedded-AppInstaller rehearsal: test non-blocking update behavior. ShowPrompt stays true (per user preference) so the update dialog still surfaces; UpdateBlocksActivation=false means the app launches immediately with the OLD version while the update stages in the background. Quit and relaunch applies the new version.

The currently-installed 0.6.5.0 has embedded UpdateBlocksActivation=true, so it will use blocking behavior to install 0.6.6.0 (one more time). 0.6.6.0 has the new non-blocking settings embedded. A subsequent bump (Phase 4: 0.6.7-msixtest.1) is then needed to exercise the non-blocking path from 0.6.6 to 0.6.7.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kmahone kmahone temporarily deployed to release-signing June 11, 2026 21:26 — with GitHub Actions Inactive
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 11, 2026
@kmahone kmahone temporarily deployed to release-signing June 11, 2026 21:46 — with GitHub Actions Inactive
… source files

Commit 1 of the three-channel embedded-AppInstaller production rollout. Pure additions; no behavior changes yet.

Four new committed XML files in installer/appinstaller/:

- openclaw-alpha-x64.appinstaller, openclaw-alpha-arm64.appinstaller
    Polled-feed bootstrap files for the Alpha channel, mirroring the existing
    Stable bootstrap pattern (openclaw-{x64,arm64}.appinstaller). Version=0.0.0.0
    placeholders; bumped by the operator-driven feed-bump workflow after each
    Alpha release.

- openclaw-update.stable.appinstaller, openclaw-update.alpha.appinstaller
    Source files for the AppInstaller content shipped INSIDE each MSIX as
    openclaw-update.appinstaller (referenced from Package.appxmanifest's
    <uap13:AppInstaller File='...'/>). Hardcoded channel-specific identity +
    polled-feed URL; {{VERSION}}, {{ARCH}}, {{MAIN_PACKAGE_URI}} placeholders
    patched by MSBuild XmlPoke at build time in Commit 2. <OnLaunch> settings
    pinned to ShowPrompt=true / UpdateBlocksActivation=false / 24h interval
    per the locked-in design.

See three-channel-msix-plan.md (session state) for the full design.

Nothing in the build pipeline references these files yet; that wiring lands in
Commit 2 alongside the csproj XmlPoke target and the manifest cleanup.

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

mmorev commented Jun 12, 2026

Copy link
Copy Markdown

Hi! Looks like this PR would also make the Companion app eligible for the Windows 11 Copilot hardware key. Would you consider adding the corresponding extension to the Package.appxmanifest?

According to the Microsoft docs (https://learn.microsoft.com/en-us/windows/apps/develop/windows-integration/microsoft-copilot-key-provider), it only requires a section like this:

...
<Extensions>
  <uap3:Extension Category="windows.appExtension">
    <uap3:AppExtension Name="com.microsoft.windows.copilotkeyprovider"
      Id="OpenClawCompanion"
      DisplayName="OpenClaw Companion"
      Description="Launch OpenClaw Companion"
      PublicFolder="Public" />
  </uap3:Extension>
</Extensions>
...

Keith Mahoney and others added 4 commits June 12, 2026 09:33
…nClawChannel property

Commit 2 of the three-channel embedded-AppInstaller production rollout. Wires the channel logic into the WinUI csproj and build.ps1; consumes the per-channel embedded-AppInstaller source files added in Commit 1.

Changes
=======

.gitignore
  Ignore the generated src/OpenClaw.Tray.WinUI/openclaw-update.appinstaller
  (output of the RenderEmbeddedAppInstaller MSBuild target; per-build payload).

src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj
  - Top-level OpenClawChannel property, defaulting to Dev. CI overrides with
    -p:OpenClawChannel=Stable|Alpha based on the tag pattern.
  - Extended the existing SyncAppxManifestVersion inline Roslyn task with three
    new parameters - IdentityName, DisplayName, RemoveAutoUpdate. The task now
    rewrites Identity/@name, Properties/DisplayName, and VisualElements/@DisplayName
    in addition to Identity/@Version; for Dev it also strips the uap13:AutoUpdate
    element so Dev MSIXs do not poll for updates.
  - New RenderEmbeddedAppInstaller target (Stable/Alpha only). Copies the
    per-channel source file installer/appinstaller/openclaw-update.{stable,alpha}.appinstaller
    to the WinUI project as openclaw-update.appinstaller, then XmlPokes
    placeholder values (Version, ProcessorArchitecture, MainPackage Uri, and
    the feed self-Uri for arm64).
  - Conditional <Content Include='openclaw-update.appinstaller'> picks up the
    rendered file for non-Dev channels and ships it inside the MSIX payload.

src/OpenClaw.Tray.WinUI/Package.appxmanifest
  - Identity/@Version baseline restored to 1.0.0.0 (was left at 0.6.4.0 by the
    rehearsal).
  - TEMP rehearsal comments rewritten as production language. The uap13:AutoUpdate
    element stays committed (Stable default; Dev builds strip it).

build.ps1
  - New -OpenClawChannel Dev|Alpha|Stable parameter (default Dev) and
    -OpenClawReleaseTag parameter. Threaded through to dotnet publish via
    -p:OpenClawChannel and -p:OpenClawReleaseTag.
  - Preflight: -OpenClawChannel Stable|Alpha requires -OpenClawReleaseTag.
    Dev with a tag warns. Channel/tag without -PackageMsix warns.

Deletions (rehearsal artifacts now superseded by the production wiring):
  - installer/appinstaller/openclaw-msixtest-x64.appinstaller
  - src/OpenClaw.Tray.WinUI/openclaw-update.appinstaller (now generated)

Local validation
================
- ./build.ps1: green.
- Shared.Tests: 2199 passed, 29 skipped.
- Tray.Tests: 991 passed.
- Dev MSIX via ./build.ps1 -Project WinUI -PackageMsix:
    Identity OpenClaw.Companion.Dev, no AutoUpdate, no embedded file. Confirmed.
- Alpha MSIX via ./build.ps1 -Project WinUI -PackageMsix -OpenClawChannel Alpha -OpenClawReleaseTag v0.6.4-alpha.1:
    Identity OpenClaw.Companion.Alpha, embedded openclaw-update.appinstaller
    with alpha feed Uri and release-asset Uri. Confirmed.
- Stable MSIX via -OpenClawChannel Stable -OpenClawReleaseTag v0.6.7:
    Identity OpenClaw.Companion, embedded file with stable feed Uri. Confirmed.
- Preflight: missing tag for Alpha/Stable hard-fails. Confirmed.

Resolves session todos:
- delete-msixtest-appinstaller-file
- revert-embedded-appinstaller-manifest (Package.appxmanifest now in production shape)
- revert-embedded-appinstaller-content (no more committed openclaw-update.appinstaller)

Next: Commit 3 wires CI (.github/workflows/ci.yml) to pass -p:OpenClawChannel
based on the tag pattern and reverts the remaining TEMP rehearsal CI edits.

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

Rename the MSBuild property and matching build.ps1 parameter to drop the
OpenClaw prefix. The names are scoped enough to be unambiguous without it and
shorter to type.

  OpenClawChannel  -> ReleaseChannel
  OpenClawReleaseTag -> ReleaseTag

Mechanical rename across 3 files (50 total swaps): src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj, src/OpenClaw.Tray.WinUI/Package.appxmanifest, build.ps1. The internal csproj-local properties (_OpenClawIdentityName, _OpenClawDisplayName, _OpenClawRemoveAutoUpdate, _OpenClawArch, _OpenClawEmbedArch, etc.) keep their _OpenClaw prefix since they are private to the csproj and the convention is that private MSBuild properties are prefixed with _.

No behavior change. build.ps1 -Project WinUI -PackageMsix -ReleaseChannel Alpha -ReleaseTag v0.6.4-alpha.1 produces the same MSIX it did before this commit under the old parameter names.

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

Commit 3 of the three-channel embedded-AppInstaller production rollout. Wires CI's build-msix job to the channel mechanism the csproj and build.ps1 now consume.

Changes
=======
.github/workflows/ci.yml (build-msix job):
  - Replaces the inline 'Patch MSIX manifest metadata' pwsh step (which
    hand-rolled the Stable/Alpha identity rewrite via XML manipulation) with
    a tiny 'Determine release channel' step that maps the tag pattern to
    one of Stable / Alpha / Dev:
      v0.6.7              -> Stable
      v0.6.7-alpha.N      -> Alpha
      anything else       -> Dev
  - Build MSIX Package step adds -p:ReleaseChannel=<channel> and
    -p:ReleaseTag=<tag>. SyncAppxManifestVersionTarget (csproj) consumes
    them to set Identity Name / DisplayName / strip-or-keep AutoUpdate, and
    RenderEmbeddedAppInstaller uses them to render the per-channel embedded
    AppInstaller file with the correct release-asset URL.
  - The Channel/IdentityName mapping is now expressed in one place per
    layer instead of three (was: ci.yml inline pwsh + .csproj Sync logic).

Not included in this commit (still TEMP; intentional, per user instruction
to keep the rehearsal pipeline working):
  - build-msix needs:[]    (revert-msix-needs-temp todo)
  - Verify tag version output msixtest skip    (revert-verify-tag-msixtest-skip todo)
  - Upload Signed MSIX (TEMP) artifact-upload steps  (revert-msixtest-prerelease-create todo)
  - Create Prerelease (TEMP - msixtest tags only)    (revert-msixtest-prerelease-create todo)
  - Original Create Release step (still commented out)
All of the above will be reverted in a final cleanup commit before the PR
merges to main.

No push, no tag - user controls CI runs.

Local validation (Commits 1 + 2 + 2.5 + 3) was done end-to-end on a previous build of build.ps1 -PackageMsix -ReleaseChannel Alpha/Stable/Dev; CI exercise of the new channel detection requires pushing a tag, which is left to the user.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mahone/msix branch and treat msixtest tags as Alpha

Four TEMP edits to enable an end-to-end Alpha-channel install + silent-update
rehearsal on the user/kmahone/msix branch without affecting main. All four
are tracked in session todos and will be reverted before merging.

Changes
=======

installer/appinstaller/openclaw-alpha-x64.appinstaller
installer/appinstaller/openclaw-alpha-arm64.appinstaller
  Alpha polled-feed bootstrap files. Self-Uri swapped from .../main/... to
  .../user%2Fkmahone%2Fmsix/... so installed Alpha builds poll this branch's
  copy of the feed during the rehearsal. (revert-alpha-feed-branch-url todo)

src/OpenClaw.Tray.WinUI/OpenClaw.Tray.WinUI.csproj
  _OpenClawFeedUri literal swapped from .../main/... to
  .../user%2Fkmahone%2Fmsix/.... XmlPoke writes this into the embedded
  openclaw-update.appinstaller's self-Uri at build time, so each Alpha MSIX
  built from this branch registers the branch's feed as its update-poll
  endpoint. (revert-embedded-feed-branch-url todo)

.github/workflows/ci.yml
  Determine release channel regex now treats vX.Y.Z-msixtest(.N)? as Alpha
  (was: only vX.Y.Z-alpha(.N)?). Lets us push throwaway msixtest tags that
  exercise the full Alpha channel pipeline (signed MSIX, prerelease
  Release, embedded AppInstaller for auto-update) without burning real
  alpha version numbers. (revert-msixtest-as-alpha todo)

Local validation
================
build.ps1 -PackageMsix -ReleaseChannel Alpha -ReleaseTag v0.6.7-msixtest.1
builds an MSIX with the embedded openclaw-update.appinstaller correctly
pointing at user/kmahone/msix's openclaw-alpha-x64.appinstaller. Both
URL forms (with %2F and with literal /) return 200 from raw.githubusercontent.com.

Test plan (executed by hand after this push)
============================================
1. Push v0.6.7-msixtest.1. CI builds Alpha-channel MSIX, signs, publishes
   prerelease. Download and install.
2. Edit installer/appinstaller/openclaw-alpha-x64.appinstaller: bump
   Version + MainPackage Version to 0.6.8.0; MainPackage Uri to point at
   v0.6.8-msixtest.1's release asset (OpenClaw.Tray.WinUI_0.6.8.0_x64.msix).
   Commit + push.
3. Push v0.6.8-msixtest.1. CI publishes new prerelease.
4. Quit and relaunch the installed app; OS prompt should offer the update.
   Verify Get-AppxPackage OpenClaw.Companion.Alpha shows 0.6.8.0.
5. Cleanup: gh release delete v0.6.7-msixtest.1 v0.6.8-msixtest.1 --cleanup-tag,
   Get-AppxPackage OpenClaw.Companion.Alpha | Remove-AppxPackage, then run
   the 7 pending TEMP-revert todos before opening the merge PR.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kmahone kmahone temporarily deployed to release-signing June 12, 2026 18:17 — with GitHub Actions Inactive
@kmahone kmahone temporarily deployed to release-signing June 12, 2026 18:34 — with GitHub Actions Inactive
Keith Mahoney and others added 2 commits June 12, 2026 11:43
UpdateBlocksActivation=false never applies on a persistent tray app -
Windows downloads then deletes the staged package because the app is
still running. Switch to the canonical persistent-app settings and
sync OnLaunch across all six .appinstaller files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kmahone kmahone temporarily deployed to release-signing June 12, 2026 19:23 — with GitHub Actions Inactive
@kmahone kmahone deployed to release-signing June 12, 2026 19:38 — with GitHub Actions Active
Keith Mahoney and others added 3 commits June 12, 2026 12:50
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

Labels

merge-risk: 🚨 automation 🚨 Merging this PR could break CI, automerge, proof capture, label sync, or automation. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants