# Lumi Updates Lumi updates are managed from **Admin > Updates**. The page separates Core and Plugins into expandable sections and uses repository metadata to choose a safe target before any files are changed. ## Version Policy Core and plugin versions use `major.minor.patch`. - Patch: fixes only. - Minor: non-breaking features or design changes. - Major: potentially incompatible changes. The UI tracks three values separately: current version, latest available version, and safe target version. Same-major updates can target the latest version. Major crossings are blocked unless metadata exposes a compatibility bridge, usually `X.0.0`, or another version marked with `migration_kind: "compatibility_bridge"` and compatible with the current install. If the latest version is unsafe, the UI shows the safe target as the actionable version and lists why the absolute latest is not selected. Admins can also choose an exact core or plugin version. Installable releases come from `release-index.json` and resolve to immutable `refs/tags/vX.Y.Z` references. Lumi checks the version inside the selected tag before replacing live code. Reinstalling the current version is supported as a repair action; downgrades show an additional warning because preserved newer data is not automatically migrated backward. Updates to or from an unversioned install or target remain available so an admin can recover directly from the repository. They are treated as manual repo updates: the action button stays enabled, but the UI shows warnings and the confirmation modal states that version ordering, changelog range, and rollback safety cannot be verified from metadata. ## Metadata The updater looks for these files on the source branch: - `update-manifest.json` or `lumi.manifest.json` - `release-index.json` - `CHANGELOG.md` or `changelog.json` - `plugins//plugin.json` - `plugins//CHANGELOG.md` or `changelog.json` Useful metadata fields include `version`, `channel`, `compatible_from`, `migration_kind`, `migration_notes`, `rollback_safe`, `requirements`, `size`, and changelog entries. Missing changelog data is shown as a warning. Stable core releases keep `package.json`, `package-lock.json`, `update-manifest.json`, and the matching `CHANGELOG.md` heading synchronized. Changed plugins use their `plugin.json` version and a matching plugin `CHANGELOG.md`; Lumi AI tools use `tool_info.json` and their own changelog. `scripts/verify-release-metadata.js` checks those relationships, compatibility metadata, and generated OKF version references before publication. `scripts/verify-update-system.js` additionally checks the release catalog, immutable refs, exact-version selection, preserved paths, dependency recovery, and optional core/plugin boundaries. Stable checks read `main` by default. The newest `experimental-*` branch is used only when explicitly selected on the updates page. ## Snapshots And Revert Before a core, plugin, repo, or ZIP update, Lumi creates a snapshot under `data/snapshots/` and records metadata in the snapshot index: - target kind/id - from/to versions - source branch - update method - rollback safety - recovery marker id - major-crossing flag - compressed storage size New snapshots contain only the replaceable rollback payload: compressed core or plugin code and a compressed SQLite database backup. Preserved local data is not duplicated into snapshots. In particular, LLM model files, managed AI runtimes, caches, uploads, logs, plugin data, exports, secrets, and community knowledge stay in their live preserved locations. Snapshot cleanup runs during startup, before a new snapshot, when the Updates page reads the snapshot list, and after an administrator changes the cleanup policy. **Admin > Updates > Snapshots** controls both limits: - maximum snapshot age, 30 days by default; - latest snapshots per target, 5 by default, applied independently to core and each plugin. A snapshot is removed when either limit is exceeded. Retained legacy core snapshots are compacted automatically: when a valid compressed core archive is present, the redundant raw `full/` copy is deleted, and old raw database copies are converted to `database.zip`. This also removes model copies left by the earlier snapshot layout without deleting the live models. Manual revert is available for core and individual plugins. Revert actions are limited to the previous-version snapshot for that target. Major-version rollback is blocked unless the snapshot or manifest explicitly marks rollback as safe. If a repository or ZIP update fails after file replacement begins, Lumi automatically attempts to restore the snapshot. The failed recovery marker and backup are retained when automatic restore cannot finish, so safe mode can show the actionable error instead of silently deleting the recovery copy. ## Preserved Local Data Core updates, ZIP updates, plugin updates, and restores leave these local areas in place: - `data/`, including the database, feedback files, AI models/runtimes, tool settings, caches, and local exports; - plugin-owned `data/` directories; - `knowledge/community/` and `knowledge/corrections/`; - files under generated knowledge folders unless they explicitly declare both `generated: true` and `editable: false`; - local configuration, storage, uploads, logs, secrets, environment files, and the plugin directory during core-only updates. Full core updates remove stale replaceable code before copying the new version. Plugin code is prepared in a staging directory and swapped only after the new files are ready; plugin data is moved into the replacement as part of that transaction. Core updates intentionally do not copy or delete the `plugins/` directory. Core code therefore accesses optional plugin capabilities through the registered framework API instead of importing files from a plugin directory. Plugins can be installed or changed independently from their version picker. ## Runtime Dependencies Start Lumi through `run.js` (the `npm start` command does this). Before starting the application, the wrapper compares direct runtime packages with `package-lock.json`. Missing or mismatched required packages are repaired with a locked production install. This covers dependencies added by a core update even though `node_modules/` is preserved during file replacement. Optional integrations, including `obs-websocket-js`, are loaded defensively. A failed optional install is recorded and the rest of Lumi starts normally; the affected connector reports that it is unavailable. Required dependency failure opens recovery mode instead of repeatedly starting a partially installed core. ## ZIP Fallback Core and plugin ZIP updates remain available, but they are hidden under **Manual ZIP updates**. ZIP updates create snapshots and recovery markers. They may bypass repo metadata and compatibility checks unless the ZIP contains valid manifest data, so use them as a manual fallback. ## Progress Events Admin update actions publish Server-Sent Events through `GET /admin/updates/events`. Event names include `update:checking`, `update:metadata`, `update:snapshot`, `update:recovery_marker`, `update:download`, `update:apply`, `update:verify`, `update:complete`, `update:failed`, and `update:revert`. Core update success returns a five-second in-page notice before refresh/restart. Plugin update success updates progress for the affected plugin action without a whole-page refresh, then restarts Lumi so the selected plugin code is loaded. Plugin failures are shown directly beside the affected plugin instead of only changing the action button label. The error identifies the failed stage: repository metadata, selected repository version, recovery preparation, rollback snapshot, file replacement, or installed-plugin verification. The same stage and error are persisted in `data/update-state.json`; a later success clears the stale failure. When a problem occurs only on production, the optional **Admin > Diagnostics** page can expose the redacted `update_state`, `system_health`, and `recent_errors` checks to a trusted maintainer without shell or write access. See [Production diagnostics](production-diagnostics.md).