Wrap a random 32-byte message key with Argon2id+ChaCha20-Poly1305. sqlite messages.plaintext is nonce||ciphertext; identity keys stay plaintext. Empty/wrong passphrase fails closed. Ctrl-Q types CLEAR or QUIT then Enter (Esc cancels).
F2 shows the invite string with fp/onion hints instead of a terminal QR. Keep encode/decode and F3 paste; drop the qrcode crate.
M2: onionwire:v1 signed payload, Unicode QR, same-k locator update, unknown-k approval in TUI. F4 is a no-op stub. No Tor in the bin.