The relay separates a device key replacement the old key signed for,
`rotate`, from one that arrived with no signature at all,
`rotate_unproven`, and keeps them apart in the log on purpose.
`IdentityRotation.report` says why: "a client watching the log can tell
this apart from a rotation the previous key vouched for."
No client could. Both kinds fell to `else` here and read "Their key set
changed", the same sentence a routine change gets, so the distinction
the relay records reached nobody. The unproven case is the one that
matters: it is exactly what somebody who cannot sign with the old key
would produce.
Both kinds now name themselves, and the unproven one carries a warning
that says what to do about it rather than only that something happened.
The warning is a separate sentence after the date, so the clause naming
the day stays intact.
Five tests. One is the control: a test that only checked the unproven
wording would pass if `rotate` were given the identical warning, so the
two are asserted to differ. Another pins the sentence against the iOS
text, because two apps quietly drifting apart on a security warning is
the failure this whole check exists to prevent.
iOS carries the same change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>