`mosaic update` only re-seeded ~/.config/mosaic when the @mosaicstack/mosaic
package was upgraded *within that same command*. When the CLI is upgraded
another way — a direct `npm i -g @mosaicstack/mosaic`, or an update run where
only sibling packages were outdated — the framework files (launchers, runtime
adapters, fleet tools) silently stayed stale, so shipped fixes never activated.
Critically, the "all packages up to date" branch returned before any re-seed
could run, so a drifted-but-current host had no path to reconcile.
Add framework drift detection: compare the on-disk schema version
(~/.config/mosaic/.framework-version) against the version bundled in the
installed package (FRAMEWORK_VERSION in the bundled install.sh). `mosaic update`
now re-seeds when the mosaic package updated OR the on-disk framework is older
than bundled — including from the up-to-date branch. Detection is conservative:
if either version can't be read it reports no drift, so a missing/unreadable
version file never triggers an unexpected re-seed. `--no-reseed` still opts out.
The re-seed + unit-refresh + relaunch sequence is factored into a single local
helper shared by both the post-update and drift paths (no behavior change to the
existing path beyond also firing on drift).
New exported, unit-tested helpers in update-checker.ts:
- readInstalledFrameworkVersion / readBundledFrameworkVersion
- checkFrameworkDrift -> { drifted, installed, bundled }
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>