Files
amethyst/amethyst
Claude 75a0f738c8 feat: gate deleting a legacy preference file behind a read-back
LegacyPreferenceCleanup runs after each successful account load and deletes
that account's `secret_keeper_<npub>` file only when it can show nothing in it
would be lost. It refuses today, deliberately, and says why.

The check is not one rule, because the two halves of the migration are in
different states. The plain per-account groups stopped being legacy-written
when they moved, so that file is a frozen snapshot of the day they migrated —
comparing values would flag every setting the user has changed since. For
those the question is "did the copy run", which the migration marker answers
exactly: CopyOnceMigration commits the values and the marker as one
Preferences, so the marker cannot be set without them. The secrets and the
private key *are* still written to both stores, so for those the stronger
question is available and is asked: read both back, require them to agree.

Coverage runs from the file's own keys rather than a checklist. A checklist
fails silently in the one direction that matters — a key added later that no
migration carries — so instead every key present must be claimed by a table,
be one of the secrets, or be on the accepted-loss list, and anything else
stops the deletion by name. LegacyKeyCoverageTest reflects over PrefKeys and
fails the build if a key falls outside all of those, so that surfaces at the
commit that adds it rather than as a file that quietly never gets deleted.

A store that cannot be read is a reason, never a pass.

Nothing is deleted yet, and not because the check fails: LEGACY_WRITES_RETIRED
is false. The identity, key, secret and roster stores still mirror into the
legacy file so a rolled-back build finds a complete account, and while that is
true, deleting the file achieves nothing — the next save recreates it — and
would look like it had worked. Retiring those writes ends the rollback window
and waits on the device pass, which nothing here has had: no AndroidKeyStore
path has executed in this environment, so what is tested is the decision logic
against fakes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AXvKXakvup4inNFfAhhr4L
2026-09-23 22:25:18 +00:00
..
2024-06-24 14:13:55 -04:00