# v0.24.1 upgrade and compatibility This guide covers v0.24.1. Use the [release page](https://github.com/rhoopr/kei/releases/tag/v0.24.1) to verify publication and obtain binaries. A source version bump does not update release archives, Docker `latest`, or Homebrew. ## Back up before upgrading 1. Pause schedules, automatic updates/restarts and every kei worker sharing the configuration/state or media directories. Stop other media writers while taking the backup. Keep all writers stopped until it completes. 2. Record the old binary version or immutable container digest, command, mounts, permissions and configuration privately. Retain the old binary or image for rollback. Find the resolved data directory with the old binary's `kei config show` or `kei doctor` before upgrading. 3. Take and verify a matched cold backup or filesystem snapshot of both the complete configuration/state directory and complete media/sidecar set. Include databases, SQLite WAL/SHM/journal companions, config and auth files. Preserve permissions and timestamps. Keep the backup private, unchanged and outside the working directories; check that it is restorable. 4. Check space for backup/snapshot growth and additional independent copies. Legacy preservation retains original files while storing eligible current children separately. Aggregate counts do not establish the required space. 5. Upgrade one worker with the existing configuration and metadata-write settings. Do not enable rewrites, reset state or clear tokens to remove a hold. Inspect `kei status` and a normal cycle, then an unchanged cycle after restarting that same worker. Even `kei status` can automatically migrate the state database to schema 28. An older binary cannot open that upgraded database. Stop if original bytes or records change unexpectedly, or if a new state-write error occurs; retain the working set and backup for investigation. For rollback, stop every writer and preserve the post-upgrade set first. Restore the matched pre-upgrade configuration/state and media/sidecars together with the retained old binary or image. Switching only the binary or restoring only the old database over changed media is unsafe. Do not lower the schema version, mix SQLite companions from different snapshots, or reset state as a substitute for rollback. ## Compatibility identifiers | Identifier | v0.24.1 value | Purpose | | --- | --- | --- | | Package version | `0.24.1` | Identifies the build, not release publication | | SQLite schema | 28 | Durable tables, keys, migrations and protected evidence | | JSON sync report | string `"3"` | Existing report contract with additional recovery counts | | Metadata-capture revision | Reported separately | Provider decoding and bounded catalogue repair | | Sidecar output revision | No automatic sweep | Untouched-output upgrades remain deferred in #799 | Schema 26 retains unresolved sparse-source identity evidence and retry state. Schema 27 adds metadata-capture retry schedules. Schema 28 adds protected unattributed legacy records, paths and preservation proofs. Migration does not assign historical ownership or authorize deletion, overwrite or checkpoint advancement. Earlier migration and timestamp-compatibility history remains in the [v0.24.0 guide](v0.24-upgrade.md#compatibility-identifiers). ## Interpret recovery evidence Unresolved sparse identities and ambiguous metadata capture retain their checkpoint holds. Unchanged evidence backs off from one hour to 24 hours; changed evidence can become eligible earlier. A deferred retry is unfinished work, not provider deletion or successful capture. Eligible legacy preservation retains the original rows, files, dates and retry history while independently identified current children are checked and stored. Status and reports expose `unattributed_legacy_assets` and `unattributed_legacy_pending`. Current work may need multiple normal cycles. Attribution can remain nonzero after preservation work completes and a current checkpoint advances; backup status intentionally remains unsafe until ownership is resolved. Zero download failures does not prove metadata or checkpoint completion. See [maintenance guidance](backup-maintenance.md#unresolved-provider-identities). Hard-linked originals remain unsupported for legacy preservation. A `shared_file_links` reason makes the hold identifiable, but does not clear it. The independent-file guard protects against writes through aliases. Do not unlink originals, force metadata rewrites or bypass the guard to clear counts. [#853](https://github.com/rhoopr/kei/issues/853) remains open pending the safe hardlink design in [#884](https://github.com/rhoopr/kei/issues/884). Linux guarded replacement has a recoverable fallback when exchange renames are unsupported. It requires hard-link support and can briefly leave the destination path absent. Retain `.kei-replace-*` recovery directories after a failure; cleanup by suffix or age can discard original bytes. Actual NFS/NAS mount behavior still needs reporter validation in [#858](https://github.com/rhoopr/kei/issues/858). ## Known limitations and validation scope - Reporter qualification for sparse shared-library recovery, duplicate-download fixes and NFS replacement remains pending in [#765](https://github.com/rhoopr/kei/issues/765), [#845](https://github.com/rhoopr/kei/issues/845) and [#858](https://github.com/rhoopr/kei/issues/858). Existing duplicate files, overwritten dates and unknown historical owners are not repaired automatically. - Smart-folder reconciliation (#770), companion stems after enabling Live Photo movies (#773), untouched-sidecar catch-up (#799), complete timestamp precision (#803), and HEIF memory bounds (#761) remain separate work. No general memory ceiling or representative large-HEIF qualification is established here. - The consolidation closeout's [full-test record](https://github.com/rhoopr/kei/issues/780#issuecomment-5932255322) covers an earlier exact main commit, with bounded primary-library live tests. It is historical evidence, not validation of a later release SHA. - [#819's final qualification](https://github.com/rhoopr/kei/issues/819#issuecomment-5973059409) records normal and complete optimized offline suites on the final production baseline, plus actual-main CI. That qualification did not run live tests or OS flush-fault injection. No user-media loss was established by that report. - Cross-zone album hydration requires its own prepared fixture. A real host service lifecycle, physical NFS/NAS testing, fuzz execution and OS flush-fault injection are distinct checks; ordinary service smoke, deterministic recovery tests and fuzz compilation do not establish them. Final release qualification must name its exact candidate head, commands, results and unavailable checks. Publication verification must confirm all five platform archives and their checksums, the release binary version and default XMP features, both GHCR architectures/tags/digests, and Homebrew URLs/checksums. See [the changelog](../CHANGELOG.md#0241---2026-10-03) for the shipped changes.