feat(desktop): Windows enterprise packages - MSI (SCCM) + AppX/MSIX (Intune) targets, contract test, runbook - #346
Open
alexander-blackwell wants to merge 1 commit into
Open
Conversation
…Intune) targets, contract test, runbook Closes #345. Core-side work for the enterprise add-on's Windows-packages item (add-on #75, PI-4 / ADR-A009 epic); both foundations already landed (ADR-0225 air-gap bundle, the add-on #74 managed-config channel). Completes the platform set next to Linux deb/rpm (#147) and macOS pkg+cask (#141). - desktop/package.json: build.win += msi + appx (x64). MSI: perMachine (SYSTEM context installs to Program Files), oneClick false, runAfterFinish false, pinned UpgradeCode 2568ebca-6784-4546-9463-9765440afaf3, warningsAsErrors false (large harvested tree), versioned artifactName. AppX: identityName TechLead187.LucidAgent, publisher CN=TechLead 187 LLC, applicationId LucidAgent, versioned artifactName. - build-desktop.yml: *.msi/*.appx attached to run artifacts, tag releases, and the rolling latest release; matrix label + header updated. Signing rides the existing WIN_CSC_LINK/WIN_CSC_KEY_PASSWORD seam; builds stay unsigned without secrets. The ADR-0225 air-gap smoke still gates the job pre-upload. - desktop/win_packaging.test.ts (new): pins the UpgradeCode value + shape, perMachine, runAfterFinish, the four-target set, AppX identity shapes, and versioned artifact names. A changed UpgradeCode means a second side-by-side product on every managed fleet (broken supersedence, orphaned installs); that drift now fails CI instead of shipping. - docs/WINDOWS-ENTERPRISE-DEPLOYMENT.md (new): package facts, why upgrades never touch %APPDATA%\LucidAgentIDE, build, Authenticode signing (CI seam or signtool post-build; MSIX must be org-signed for Intune LOB), SCCM application, Intune Win32 .intunewin + supersedence, Intune MSIX LOB + cert trust, NSIS-per-user to MSI-per-machine migration, validation checklist. make test: 2630 pass / 0 fail (+4 new) + sidecar suite green.
alexander-blackwell
force-pushed
the
feat/windows-enterprise-packages
branch
from
September 4, 2026 00:19
b303ee4 to
a6fc9b8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #345. Core-side work for the enterprise add-on's Windows-packages item (add-on #75, PI-4 / ADR-A009 epic). Completes the enterprise platform set next to Linux deb/rpm (#147) and macOS pkg + cask (#141).
Why now
Both foundations this work was blocked on have landed: the air-gap build profile (ADR-0225: vendored omp, bundled SHA-pinned relocatable CPython, CI air-gap smoke that fails any non-self-contained installer) and the managed-config update channel (add-on #74, ADR-A009). Current
build.winproduces onlynsis+portable: nothing SCCM or Intune can consume for managed, in-place-upgradable deployment. Windows was the last platform without enterprise packages.What changed
1.
desktop/package.json: two new win targets (x64)msi(SCCM):perMachine: true(SCCM installs in SYSTEM context to Program Files),oneClick: false,runAfterFinish: false(silent SYSTEM installs must not launch the app), pinnedupgradeCode: 2568ebca-6784-4546-9463-9765440afaf3,warningsAsErrors: false(the harvested app tree is large; WiX warnings must not brick the build), versioned artifactLucidAgent-\${version}-x64.msi.appx(Intune LOB / MSIX family): identityTechLead187.LucidAgent, publisherCN=TechLead 187 LLC,applicationId: LucidAgent, versioned artifact name.The UpgradeCode is the load-bearing decision: it is the identity Windows Installer uses to say "same product, upgrade in place". Change it and every managed fleet gets a second side-by-side install: duplicate shortcuts, orphaned versions, broken SCCM/Intune supersedence. It is pinned once, forever.
2.
desktop/win_packaging.test.ts(new): the contract is enforced, not documentedPins the exact UpgradeCode value (+ GUID shape),
perMachine,runAfterFinish: false, the four-target set, AppX identity shapes (identityName charset/length,CN=publisher, applicationId rules), and versioned artifact names for both enterprise targets. Any silent drift in the data-loss-shaped config now failsmake testand CI instead of shipping.3.
build-desktop.yml: artifacts wired through*.msi/*.appxadded to the run-artifact upload, the tag-release attach, and the rollinglatestrelease lists; windows matrix label + header comment updated. No new secrets: Authenticode rides the existingWIN_CSC_LINK/WIN_CSC_KEY_PASSWORDseam (exported only when present, exactly as before); without them the artifacts build unsigned, same posture as the macOS pkg work in #141. The ADR-0225 air-gap smoke still runs on the same job before any upload, so the new installers cannot ship non-self-contained.4.
docs/WINDOWS-ENTERPRISE-DEPLOYMENT.md(new): the runbookMirrors the Linux/macOS runbooks: package facts, why upgrades never touch
%APPDATA%\LucidAgentIDE(nothing user-editable ships in either package; MSI major upgrades remove only owned components; admin policy arrives via ADR-A010, not the package), local + CI build, signing (CI seam orsigntoolpost-build with timestamping; MSIX must be signed with a device-trusted org cert whose subject equals the package publisher, Intune refuses unsigned LOB MSIX), SCCM application setup (ProductCode detection, msiexec install/uninstall, system context), Intune Win32 path (.intunewinwrap, supersedence as update), Intune MSIX LOB path (cert trust deployment), the NSIS-per-user to MSI-per-machine migration note, an AppContainer/MSIX composition note (ADR-A020 containment is independent of install tech), and the runner-bound validation checklist.What this deliberately does not do
%APPDATA%preservation, signed-MSIX sideload) is runner-bound, same as build(desktop): Linux rpm (YUM/DNF) + deb (APT) packages + internal-mirror runbook #147/macOS enterprise packaging: .pkg + Homebrew cask + MDM runbook #141; the checklist is runbook 6.Evidence
make test: 2630 pass / 0 fail (+4 new contract tests) + scanner-sidecar pytest green.desktop/package.jsonparses; targets verified by the new test.