Skip to content

polish(cli): make identity-export vk-mismatch error message conditional on override-set vs not #285

@sanity

Description

@sanity

Follow-up from PR #282 skeptical round-2 review.

Context

PR #282 added a vk-match guard in `cli/src/commands/identity.rs::export_identity` that errors when `signing_key.verifying_key() != authorized_member.member.member_vk`. The current error message says:

"This usually happens when `--signing-key-file` / `RIVER_SIGNING_KEY_FILE` overrides the signing identity but `rooms.json` still holds another identity's cached membership state."

Polish

That message assumes the override is set. The check can also fire WITHOUT an override if rooms.json gets corrupted (e.g., the chat-delegate sync writes `signing_key_bytes` for one identity but `self_authorized_member` for another — exactly the bug-class that motivated PR #282 in the first place). When the check fires without an override, the message misleads the user into re-running without an override they never set.

Fix shape

Add `Storage::has_signing_key_override() -> bool` or expose the field. In `export_identity`'s error path, branch on it:

```rust
let hint = if storage.has_signing_key_override() {
"This usually happens when --signing-key-file overrides the signing identity ..."
} else {
"rooms.json appears corrupted: the cached AuthorizedMember.member_vk does not match \
signing_key_bytes. Try re-accepting the invitation, or import a fresh identity token."
};
```

Test

Skeptical reviewer also noted: no test pins the vk-match guard. Extract `check_export_coherence(signing_key, authorized_member)` as a pure helper and write a unit test that constructs an AuthorizedMember signed by key A, calls the helper with signing key B as override → asserts error.

Severity

LOW. Message clarity issue, not a correctness bug. The guard itself works correctly; only the user-facing diagnostic could mislead in the rare rooms.json-corruption case.

[AI-assisted - Claude]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions