Added
- Added
kei doctorwith redacted text and JSON diagnostics for config parsing, local paths, state DB access, session presence, and recent health/report files. (#600, fixes #588) - Added
kei manifest --format json|csvto export the local state catalog without iCloud auth or file writes. The export includes paths, asset IDs, versions, checksums, sizes, dates, libraries, albums, and status. (#604, fixes #590)
Changed
kei syncis now required for syncing. Running barekeishows top-level command help instead of starting a sync, and sync-only flags are rejected outside sync-capable commands. (#624, fixes #605)kei statusnow shows running sync work and full-enumeration progress markers before completed-run timestamps, so active work doesn't look finished just because a newer pass row completed. (#600, fixes #530)kei reconcilenow reports missing and truncated local files and can mark them failed so the next sync redownloads them through the normal path. (#600, fixes #550)- Count shortfalls from iCloud are now diagnostic when the records that were returned are otherwise complete; true pagination shortfalls still block token advancement. (#625, fixes #602)
- Refactored password source handling, download config cloning, and import path derivation to reduce duplicated sync and import code. (#618, #619, #620)
Fixed
- Normal incremental sync now retries known pending or failed asset-version rows with a targeted refresh pass instead of forcing full-library enumeration, and keeps sync-token advancement blocked when retry work is incomplete. (#600, fixes #506)
- Published files left behind by a failed state write now keep the sync cycle partial when kei retries from the pending row, so zone and database sync tokens stay blocked until the file is recorded in state. (#600, fixes #515)
- Incremental and watch syncs now probe a bounded page of downloaded rows for missing or truncated local files, mark drifted rows failed, and force the cycle to retry them through the normal download path. (#600, fixes #550)
- Deferred-unfiled pagination accounting no longer treats unrelated album-side counts as missing records, while real unexplained shortfalls still block sync tokens. (#603, fixes #602)
- Hard-delete tombstones that only include an asset record name can now resolve through durable per-library asset-to-master mappings, with sync-token advancement blocked when a mapping is missing or ambiguous. (#632, fixes #626)
- Clean full retry enumerations now prune stale pending retry rows for assets that no longer exist, while dry-run, print-only, recent/date-limited, and canceled retry runs keep the conservative token block. (#636, fixes #626)
- Docker images now route every current kei subcommand through the entrypoint before falling back to system commands, and a static test guards future subcommand drift. (#637)
- Notification scripts keep the existing
KEI_ICLOUD_USERNAMEand per-cycleKEI_*stat variables, and now also receiveKEI_REPORT_JSONwhen[report].jsonis configured. (#600) - Loopback-bound wiremock and metrics tests now return early with an explicit skip line when a restricted sandbox forbids
127.0.0.1binds, while normal CI hosts still run the tests strictly. (#600, fixes #479) - Added lightweight
CONTRACT:marker checks for sync-token advancement and.partno-overwrite publish invariants, each tied to regression tests. (#600, fixes #580) - Continued typed-error boundary cleanup for CLI parse exits, auth, service retry, sync-loop auth handling, download workers, incremental fallback, and CloudKit library initialization. (#600, #615, fixes #587)
- CI, release, local full-test, workflow, script-lint, and contributor-surface checks now cover more release-readiness and data-safety regressions. (#600, fixes #583, fixes #585)
- Cargo audit ignores now carry removal triggers, including the
pasteand transientrandadvisory entries. (#600, fixes #585) - URL query building for iCloud photo requests now uses the
urlserializer instead of a separate encoding dependency. (#617)
Removed
- Encrypted-file credentials now use
.kei-statedirectly. The old.credential-keyauto-rename path was removed; users who still have that pre-0.6.2 key file must rename it to.kei-statemanually before using the encrypted-file backend. (#616, fixes #613) - Startup no longer auto-copies config, cookies, or state from the old
icloudpd-rspaths. Users with those pre-rename files should copy the needed files into~/.config/keimanually. (#623, fixes #606) - Removed the legacy session cookie parser, the global string interner, stale full-enumeration cleanup code, and low-value wrapper code and dependencies. (#622, #621, #633, #635)
Full changelog: CHANGELOG.md