fix(install): stop -FromZip destroying host configuration - #46
Merged
Conversation
Closes #45, and the problem was larger than that issue described. -FromZip does not merely overwrite appsettings.json. It WIPES the entire install directory before copying: Get-ChildItem $InstallDir -Force | Remove-Item -Recurse -Force so an upgrade destroyed appsettings.json AND appsettings.local.json and left the shipped defaults in their place, with no backup and nothing said. That makes CLAUDE.md's advice -- put host-local settings in appsettings.local.json, because a deploy cannot overwrite it -- true of `dotnet publish` and FALSE here, which is the worst kind of wrong: correct-sounding guidance that does not hold on the path people actually upgrade with. The API survived by accident on the host where this was found: ResolveApiKey falls back to a file in ProgramData that the wipe does not reach. Any setting without such a fallback was simply gone. Both files are now copied out before the wipe and copied back after, and the host's appsettings.json wins over the shipped one -- the shipped file is what a FIRST install needs, not an upgrade. The copies live under ProgramData\MultiSeat\config-backups\<timestamp>\, outside the directory being wiped, and double as the backup. Preserved BYTE FOR BYTE, not as text. The first version round-tripped through Get-Content/Set-Content and handed back a file two bytes longer, because Set-Content appends a newline and may change encoding. Harmless for JSON and wrong in principle for a step whose whole purpose is to leave a file untouched. Keeping the host's file silently would hide settings a release adds, which is the one real cost of preserving over replacing. So the shipped and installed key sets are compared and anything new is named, with a note that it runs at its built-in default. Verified on a real upgrade to v0.6.3 rather than in a harness: before appsettings.json E7AC4C57508AF9BF 1579 bytes before appsettings.local.json 60CC6361B5C0EB1F 81 bytes after appsettings.json E7AC4C57508AF9BF 1579 bytes after appsettings.local.json 60CC6361B5C0EB1F 81 bytes with a deliberately edited MaxSeats surviving and a deliberately removed NvencPreset reported as newly added. Parses under Windows PowerShell 5.1 and 7; all 29 scripts pass the linter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SQvL62WkT8xDWXqyjFCGDw
This was referenced Sep 10, 2026
Merged
vibesoftwarecoder
added a commit
that referenced
this pull request
Sep 10, 2026
version.txt 0.6.3 -> 0.6.4, plus the hand-written notes the release workflow reads from docs/release-notes/<version>.md. No code changes -- both shipping commits already merged: 98b5cfa (the installer no longer destroys host configuration) and 459f88d (the documentation that claimed it could not).⚠️ The notes carry a correction. PR #46 and its commit message said the fix was "not retroactive" and would protect only the upgrade AFTER the one carrying it. That is wrong. The installer that runs during an upgrade is the one inside the release just downloaded, not the one already on the machine -- the documented command runs .\scripts\install-service.ps1 from the extracted folder. So upgrading 0.6.3 -> 0.6.4 uses 0.6.4's installer and configuration IS preserved. The only gap is running an older extracted installer against this zip. Getting that backwards understates the release: it is not insurance for a future upgrade, it protects the one the user is about to perform. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SQvL62WkT8xDWXqyjFCGDw
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 #45 — and the problem is larger than that issue described.
-FromZipwipes the whole install directoryNot just
appsettings.json:So an upgrade destroyed
appsettings.jsonandappsettings.local.json, dropped the shipped defaults in their place, backed nothing up, and said nothing.That makes
CLAUDE.md's advice — put host-local settings inappsettings.local.json, because a deploy cannot overwrite it — true ofdotnet publishand false here. Correct-sounding guidance that does not hold on the path people actually upgrade with.On the host where this was found the API survived by accident:
ResolveApiKeyfalls back to a file inProgramDatathat the wipe does not reach. Any setting without such a fallback was simply gone.The fix
Both files are copied out before the wipe and copied back after. The host's
appsettings.jsonwins over the shipped one — the shipped file is what a first install needs, not an upgrade. The copies live underProgramData\MultiSeat\config-backups\<timestamp>\, outside the directory being wiped, and double as the backup.Preserved byte for byte, not as text. The first version of this round-tripped through
Get-Content/Set-Contentand handed back a file two bytes longer, becauseSet-Contentappends a newline and can change encoding. Harmless for JSON today, wrong in principle for a step whose entire purpose is to leave a file untouched, and a trap the moment anything preserved here is not JSON.New settings are reported, not hidden. Keeping the host's file silently would conceal an option a release adds — the one real cost of preserving over replacing. The shipped and installed key sets are compared and anything new is named, with a note that it runs at its built-in default.
Verified on a real upgrade, not in a harness
Run against the published
v0.6.3asset on a live install, with two deliberate markers:MaxSeatssurvived the upgradeNvencPresetwas correctly reported as newly added by the releaseParses under Windows PowerShell 5.1 and 7; all 29 scripts pass
lint-scripts.ps1.Not retroactive
Anyone already on
0.6.3still has the destructive installer. This protects the upgrade after it ships, not the one they are on.🤖 Generated with Claude Code
https://claude.ai/code/session_01SQvL62WkT8xDWXqyjFCGDw