🤖 Filed by Will's AI agent as a follow-up from the #1568 review.
#1568 added the identity_lost recovery mode: when the keyring was emptied after a successful migration, the app boots with an ephemeral in-memory key, setup() skips the owner-keyed startup routines (run_event_sync, launch-time agent restore, the pending-event flush loop), and the frontend pins the user at the nsec re-import step.
What's still open is that the Tauri command layer itself is ungated: create_auth_event, sign_event, nip44_encrypt_to_self, and the message/channel/relay-member send commands all read state.keys without checking identity_lost. Right now the onboarding gate is the only thing preventing user-initiated signing under the ephemeral key, and the relay's NIP-42 auth challenge is auto-signed with it when the socket connects — harmless to the relay, but the ephemeral pubkey does end up in relay logs, which is also a (minor) privacy consideration.
I think the right shape is for signing commands to return an explicit error while identity_lost is true, so the backend enforces recovery-only mode instead of relying on the frontend never calling them. This probably falls out naturally from the AppState.keys: Option<Keys> refactor proposed at the end of #1568's description (stop auto-generating a shadow identity before the user expresses onboarding intent) — threading None through callers would force every signing site to handle the no-identity case explicitly.
Related: #1568
🤖 Filed by Will's AI agent as a follow-up from the #1568 review.
#1568 added the
identity_lostrecovery mode: when the keyring was emptied after a successful migration, the app boots with an ephemeral in-memory key,setup()skips the owner-keyed startup routines (run_event_sync, launch-time agent restore, the pending-event flush loop), and the frontend pins the user at the nsec re-import step.What's still open is that the Tauri command layer itself is ungated:
create_auth_event,sign_event,nip44_encrypt_to_self, and the message/channel/relay-member send commands all readstate.keyswithout checkingidentity_lost. Right now the onboarding gate is the only thing preventing user-initiated signing under the ephemeral key, and the relay's NIP-42 auth challenge is auto-signed with it when the socket connects — harmless to the relay, but the ephemeral pubkey does end up in relay logs, which is also a (minor) privacy consideration.I think the right shape is for signing commands to return an explicit error while
identity_lostis true, so the backend enforces recovery-only mode instead of relying on the frontend never calling them. This probably falls out naturally from theAppState.keys: Option<Keys>refactor proposed at the end of #1568's description (stop auto-generating a shadow identity before the user expresses onboarding intent) — threadingNonethrough callers would force every signing site to handle the no-identity case explicitly.Related: #1568