checkpoint: sync to 188b2eb — lenient NIP-46 payload parse, real decrypt-error logging (2026-09-16)

This commit is contained in:
Avi 2026-09-16 21:12:13 -05:00
commit e97d8a75f0

View file

@ -1,3 +1,73 @@
# Checkpoint — Amber pairing: lenient NIP-46 payload parse + real decrypt-error logging (2026-09-16)
## Where things are
- Project: `/home/avi/Projects/Keynctr`
- Branch: `master` @ **`188b2eb`** ("fix(pairing): never reject a decrypted
NIP-46 payload on shape"). Previous feature HEADs: `aedde8f`, `759b5dd`,
`5aa122d`, `f59c2b1`.
- Working tree: clean for tracked files. Untracked intentionally NOT
committed: `COSMIC_THEME.md`, `KeynectrAppIconPossibility02.jpeg`,
`deferred/` (stays deferred).
- Release binary rebuilt at `188b2eb` (2026-09-16 ~21:06) — the binary the
Sep 15/16 Amber scans ran against was the Sep 12 build; the id-coercion +
payload-dump diagnostics are live NOW.
- Verification (all green at `188b2eb`): `cargo test` **208 unit + 2 e2e
passed / 0 failed**, `cargo clippy --all-targets` 0 warnings,
`cargo fmt --check` clean, `cargo build --release` green. Frontend:
`npm test` **116 passed (16 files)**, `npm run typecheck` clean,
`npm run lint` clean, `npm run format:check` clean,
`npm run electron:build` and `npm run build` green.
## What was completed since the last checkpoint
- **Universal-lenient RawRequest parse (`188b2eb`)**: the derived
`Deserialize` (even after `aedde8f`'s params coercion) still rejected real
signer payloads. Replaced with a hand-written coercion deserializer: any
*valid JSON* deserializes — numeric/missing ids become text, object-shaped
`params` become a single param, a double-encoded JSON-string request is
unwrapped. A parse failure is now only possible for non-JSON plaintext,
which the log dumps verbatim. Regression tests for all five shapes.
- **Real decrypt-error logging (`188b2eb`)**: pairing decrypt failures now
log the actual NIP-44 error (invalid HMAC vs invalid padding vs wrong
conversation key) instead of a generic "wrong conversation key", and the
not-a-request log prints the exact decrypted payload.
- **Offline forensics (no commit)**: all four captured pairing frames in
`~/Tools/keynctr-debug/pairing-capture.jsonl` (latest: Sep 16 20:11) are
163-byte NIP-44 v2 payloads = 1 ver + 32 nonce + 98 buffer + 32 MAC.
98 is a VALID final-spec padding bucket (plaintext 65–96 bytes; the
observed 89 fits). So the frames are spec-conformant, decryption
succeeds, and the failure was purely the JSON-shape parse — confirming
the fix targets the right layer. Note `/tmp/keynctr-el*.log` no longer
exists (tmp-cleaner); backend stderr now only reaches the Electron
console — the next failed scan's payload dump needs
`npx electron .` launched from a terminal or with stderr redirected.
## Commits added (newest first)
- `188b2eb` fix(pairing): never reject a decrypted NIP-46 payload on shape
## How to reproduce / exercise
- Dev loop (unchanged): `npx vite --port 5173` in `frontend/` FIRST, then
`NOSTR_GUI_DEV_URL=http://localhost:5173 KEYNCTR_ENABLE_GPU=1 npx electron .`.
To capture pairing diagnostics: run electron with stderr kept, e.g.
`... npx electron . 2>&1 | tee ~/Tools/keynctr-debug/el.log`.
- E2E: `cargo test --test nip46_e2e` (no network) — green.
- GUI: Signer mode -> "Show QR" -> scan in Amber -> approve. Raw pairing
events keep appending to `~/Tools/keynctr-debug/pairing-capture.jsonl`.
## Outstanding / next steps
1. **Live Amber re-scan required** (cannot be done from an unattended run):
if pairing still fails, the backend log now contains the exact decrypted
89-byte payload and/or the exact NIP-44 error — that text names the last
possible cause.
2. If the payload turns out to be valid JSON but not `method:"connect"`
(e.g. Amber's deferred-approval `get_public_key` first), the log will
show it and the handshake gate can be relaxed accordingly.
3. `publish_profile_metadata` (kind 0) still signs locally — reroute
through `Signing` for external profiles (P2).
4. Step 5 (KDF upgrade), Step 6 (undo preserves ProfileSummary), Step 7
(rename pass incl. `homepage` URL).
---
# Checkpoint — QR pairing, identity adoption, always-allow grants + pairing-relay widening (2026-09-12)
## Where things are