collective

Browse / github.com/storytold/craft-libs / patch

Document the proposed Windows installation and persistent-model policy

Document the proposed Windows installation and persistent-model policy ## Summary - Cover all current app MSI installers and the launcher's separate per-user folder policy. - Preserve existing/custom folders and contexts; never silently migrate installed copies. - Distinguish separately downloaded persistent models from caches and package-owned resources. - Record prepared apps, no-MSI repositories and the real-install release gates. ## Verification boundary Documentation only. The 14 installers passed 42 metadata-only fixture builds and compiled path-policy checks. Real saved-release payloads passed local install, upgrade, repair and uninstall cycles on

Status
open
Score
0.00
Adopters
0 other operators
Author
Jeremy8776 (imported from pull request #371, open)
Base
9ff719499d8f4730b93071abed993e5f12fe1be8
Size
+135 −1 in 3 files
Review
pending
Shared
2026-10-28
Id
6e2e223548869b6ff76d9261

How it went

No other operator has reported using it yet.

Diff

raw · docs/installation-policy.md docs/settings-storage.md docs/windows-installation-adoption.md

diff --git a/docs/installation-policy.md b/docs/installation-policy.mdnew file mode 100644--- /dev/null+++ b/docs/installation-policy.md@@ -0,0 +1,88 @@+# Installing the Craft apps on Windows++This is a proposed policy, not a claim about a published release. Preparation covers every+current Craft app with a Windows MSI, plus the launcher's new-install folder. The+[adoption inventory](windows-installation-adoption.md) records the scope and remaining gates.+Nothing here moves an existing installation. Storage of settings, caches and models is a+separate policy: [settings-storage.md](settings-storage.md).++## Installation contexts++One dual-scope MSI per app (Microsoft's "Single Package Authoring": `ALLUSERS=2` with+`MSIINSTALLPERUSER=1` in the Property table, written by WiX's `Package/Scope="perUserOrMachine"`):++| Context | Default destination | How it is chosen |+|---|---|---|+| Per-user (the default) | `%LOCALAPPDATA%\Programs\ArtCraft\<App>` | Just install: no UAC prompt |+| Per-machine (an explicit choice) | `%ProgramFiles%\ArtCraft\<App>` (`Program Files (x86)` for a 32-bit package) | The setup wizard's "Everyone" choice, or `msiexec ... ALLUSERS=1` |++The launcher itself remains per-user only, with new copies under+`%LOCALAPPDATA%\Programs\ArtCraft\Launcher`. Existing launcher folders and its current+self-update mechanism are preserved. A machine-wide launcher/updater service is a separate+proposal, not part of this folder change.++In a per-user install Windows Installer itself redirects the `ProgramFiles` folder to the+user's own Programs folder and the `HKMU` registry root to `HKCU`, so one package serves both+contexts. Everything a package writes follows its context automatically:++- `InstallDir` record: `HKLM\Software\<App>` per-machine, `HKCU\Software\<App>` per-user.+- File associations and "Open with" registrations: `HKLM\Software\Classes` per-machine,+  `HKCU\Software\Classes` per-user.+- Registry writes use context-sensitive roots. Existing component key paths and app-owned+  associations are retained where valid. Each package must pass the compiled install-policy+  checks; unresolved ICE57 shortcut diagnostics are tracked separately from the path policy.++Scope is chosen before launch conditions and directory costing. The scope page must not be+added as a late checkbox after the default directory has already been resolved.+The page also has to leave `ALLUSERS` unset for "Only for me". Setting `ALLUSERS=2` there makes+Windows Installer search for related products as if the run were per-machine, so an interactive+upgrade skips the existing per-user copy and installs a second registration beside it.+Windows Installer also resolves Program Files once, for the context it started in, so the wizard+sets the new-install folder itself after the choice. Without that, "Everyone" installed into the+user profile with a machine-wide registration.++The ArtCraft Launcher and a direct install of the same MSI produce the same result: the+launcher dispatches the same package and only adds `INSTALLFOLDER` (the user's chosen folder)+and the context properties of the copy being updated.++## What an update must preserve++- **The exact folder.** An ordinary update installs into the remembered folder of the copy+  being replaced, wherever the user put it. A later change to the suite default moves nothing.+- **The context.** A per-machine copy updates per-machine (`ALLUSERS=1`), a per-user copy+  per-user. MSI major upgrades cannot cross installation contexts, so a context change is a+  deliberate uninstall-and-reinstall, never an ordinary upgrade. The launcher queries+  authoritative MSI registration, not the hive containing a display entry. An unknown or+  conflicting context stops the update rather than selecting the new-install default.+- **No duplicates.** Installing in the other context while a copy already exists is a visible+  stop with a message naming the fix, never a silent second copy. The wizard pre-ticks the+  matching scope when a copy in the other context is registered.+- **The chosen folder survives elevation.** `INSTALLFOLDER` is a secure MSI property, so+  the elevated installer receives the same exact destination selected in the setup wizard.+- **Custom folders stay first-class.** A chosen exact app folder is used as-is; a chosen+  suite root gets the app subfolder appended once (`D:\Craft` becomes `D:\Craft\PhotoCraft`,+  never `D:\Craft\PhotoCraft\PhotoCraft`). A missing drive or an unavailable folder is a+  visible error, not permission to fall back to the default.++## What an app must still do without the launcher++Install, launch, update and uninstall work standalone: the MSI's own wizard, its App Paths+registration (`Win+R`), its Start Menu shortcut and its entry in "Apps & features" never+require the launcher. The launcher reuses a standalone installation it finds rather than+installing a duplicate, and detection reads both contexts' registrations.++## Other platforms++macOS `.app` bundles, Linux packages/AppImages and FreeBSD tarballs keep their platform-native+conventions; nothing imitates the Windows directory tree. Linux settings live under+`XDG_CONFIG_HOME` and persistent models under `XDG_DATA_HOME` (`~/.local/share/ArtCraft/models`)+per [settings-storage.md](settings-storage.md).++## Models are not caches++Downloaded model files are persistent user assets. An app's cache cleanup and an app's+uninstaller must never delete them, another app's data, or user documents; existing model+folders are discovered read-only. See [settings-storage.md](settings-storage.md) for where+models live and what is disposable. Model resources shipped inside an application package,+such as bundled OCR resources, remain part of that package; this does not give an installer+ownership of separately downloaded shared models or discovered model folders.diff --git a/docs/settings-storage.md b/docs/settings-storage.md--- a/docs/settings-storage.md+++ b/docs/settings-storage.md@@ -2,6 +2,8 @@  How every Craft app stores its settings, and what goes where. The shared code is [`craft-settings`](../crates/settings/README.md); this page is the policy it implements.+Where the apps install on Windows, and what an update may move, is the companion policy+[installation-policy.md](installation-policy.md). Discussion: [storytold/craft-libs#12](https://github.com/storytold/craft-libs/issues/12).  ## What goes where@@ -10,7 +12,8 @@ Discussion: [storytold/craft-libs#12](https://github.com/storytold/craft-libs/is |---|---|---| | Settings people might edit | `config.toml` in the config folder | One readable file with comments, atomic saves, backup, recovery, migrations | | Window and UI state | `ui.ron` / `app.ron` beside `config.toml` | Changes every session; not worth comments or hand edits |-| Caches and models | Platform cache folder (`paths::cache_dir`); `%LOCALAPPDATA%` on Windows so it does not roam | Disposable, large |+| Caches | Platform cache folder (`paths::cache_dir`); `%LOCALAPPDATA%` on Windows so it does not roam | Disposable, large |+| Downloaded models | The user's chosen persistent model root (suggested `%LOCALAPPDATA%\ArtCraft\models` on Windows; `XDG_DATA_HOME` on Linux) | Persistent user assets: never deleted by cache cleanup or an app's uninstaller, never disposable ([installation-policy.md](installation-policy.md)) | | Recovery and autosave files | Platform data folder (`paths::data_dir`) | Not settings; must survive a settings reset | | Settings that belong to a library or project (LightCraft) | Inside that folder, via `SettingsStore::open_at` | Travels with the library | | API keys and tokens | The OS keychain | Never in a plain-text file |diff --git a/docs/windows-installation-adoption.md b/docs/windows-installation-adoption.mdnew file mode 100644--- /dev/null+++ b/docs/windows-installation-adoption.md@@ -0,0 +1,43 @@+# Windows installation policy adoption++This is the source-preparation inventory for the proposed policy. None of these local changes+has been published, accepted or released. The inventory covers the live app repositories and+launcher, not merely the repositories on one developer's machine.++| Repository | Prepared Windows scope | Verification boundary |+|---|---|---|+| `effectcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `pdfcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `lightcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `photocraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `figcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `vectorcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `wordcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `gridcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `deckcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `filmcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `craft-launcher` | Per-user launcher; context-safe app updates | x64, x86 and arm64 metadata checks pass; real installation gates pending |+| `artcraft` | Not applicable | No Windows MSI definition on the inventoried default branch |+| `soundcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `cadcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `designcraft` | Per-user default; explicit all-users option | x64, x86 and arm64 metadata checks pass; real msiexec runs pass in both scopes (fresh install, upgrade, uninstall; wizard and silent); clean-machine and second-account gates pending |+| `artcraftx` | Not applicable | No Windows MSI definition on the inventoried default branch |+| `AniCraft` | Not applicable | No Windows MSI definition on the inventoried default branch |++## Before publication and release++- Maintainer acceptance of the shared path/scope/model-ownership policy is still required.+- Keep app changes independent. Reconcile open installer UI and file-association PRs rather+  than assuming their work is absent or overwriting it.+- Test real release payloads and previous release MSIs in an authorised clean Windows test+  environment. Verify both standalone and launcher routes, old/custom folders, both scopes,+  second-account visibility, optional shortcuts and menus, active apps, cancellation, rollback,+  uninstall and launcher self-update. Validate actual MSI assignment context, not only the+  registry hive containing a display/uninstall entry.+- Metadata-only fixtures never substitute for those tests. x86/arm64 package validation on an+  x64 host does not prove application execution on those architectures.+- No macOS/Linux layout change, settings migration, user-model relocation or new cleanup is+  included. These platforms retain their native conventions.+- ArtCraft and ArtCraftX have no Windows MSI definition in the inventoried source; AniCraft+  has no default branch/source to package. Do not invent installers for those repositories as+  part of this rollout.