Repository navigation
plan 0031: remote transfer, app side of the logger PIN handshake - #454
Open
TheAngryRaven wants to merge 5 commits into
Open
TheAngryRaven wants to merge 5 commits into
TheAngryRaven wants to merge 5 commits into
Conversation
The Fledgling firmware (logger plan 0019) now advertises a PIN-locked transfer service from its main menu, so a download can start without pressing Transfer on the device. This is the app side: DeviceContext.connect runs AUTH?/AUTH:<hmac> before handing out the connection, learns the PIN via PINGET on a locally started transfer, tries the stored PIN silently, and only prompts for a logger it has never seen. Pre-0019 firmware stays silent to AUTH? and connects exactly as before after 2 s. The PIN never leaves the device's browser storage. The Device tab shows the stored copy (new firmware omits it from SLIST), requires exactly four digits, and gains the remote_transfer on/off setting. Golden vectors are shared with the firmware tests and LapWing. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Coverage SummaryLines: 63.26% (9389/14840) · Statements: 62.26% · Functions: 59.03% · Branches: 59.58% Per-file coverage
|
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
lapwing | e1fa2ef | Commit Preview URL Branch Preview URL |
Oct 08 2026, 02:38 AM |
The advertised-name fallback could match two loggers: default names come from a 1-in-1000 space, so logger B's PIN could be tried silently on logger A and burn one of A's five tries. The store is now keyed by the Web Bluetooth device id alone; old name-keyed entries are never read and are pruned on the next write. A Device-tab settings reset can roll a new PIN on the logger, so the stored copy is forgotten there instead of being spent on the next connect. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
The tries-left message now has role="alert", and the PIN input asks for one-time-code autocomplete instead of turning autocomplete off. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
Reading the PIN on the logger (Transfer → PIN) leaves its main menu, and the logger drops a locked link the moment it does; a slow typist hits the 20 s squat limit instead. The dialog stayed open on a dead link, the submit failed with a DOMException that never toasted, and the typed PIN was lost (review H1). The handshake now owns the link until it hands it over: one queue of status lines per connection, emptied before every write, with each step accepting only the replies it expects. The GATT drop and the logger's session-ending notices (AUTH:TIMEOUT/CAMERA/ENGINE/IDLE) are watched the whole time, the prompt included. A drop or squat timeout leaves the prompt open; on submit the same BluetoothDevice is reconnected without the picker and the handshake reruns with the typed PIN, which is stored on success. Camera, engine and idle notices close the prompt with a toast. The dialog copy now says to return the logger to its main menu. Also from the review: - M1: GATT/write/WebCrypto failures become a translated toast. - M2: 2 s of silence to AUTH? is confirmed with a settings-read probe; a late nonce or AUTH:REQUIRED is no longer mistaken for legacy firmware. - L1: a stored PIN is forgotten on LOCKED as well as FAIL. - L2: NO_NONCE refetches at most 3 times; BUSY is retried once (the firmware also sends it when it can't read its PIN). - L4: unmounting DeviceProvider mid-prompt settles the prompt, so the half-open link is disconnected. - L5: the status line only mentions the PIN once a nonce arrives; docs say the legacy cost is paid on every connect. - L6: tests for reply timeout, typed PIN ending LOCKED, NO_NONCE, BUSY, write failure, drops and notices mid-prompt, reconnect, late nonce. - N2: auth.ts and LoggerPinDialog load on the first connect, off the landing payload; CLAUDE.md now says what the eager graph really holds. - N3: ble-protocol.md §3.3 documents the unprompted notices, including the new AUTH:ENGINE and AUTH:IDLE, which also toast after connecting. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
The logger's SRESET now preserves a valid bluetooth_pin (logger review M3/nit), so forgetting the app's copy after a reset would only cost a prompt on the next remote start. Reverted, and ble-protocol.md now says SRESET keeps the PIN, PINGET may answer SERR:NOT_FOUND (nothing learned), AUTH:BUSY to an answer means the PIN was unreadable (nonce kept, no try counted), and an engine start ends a remote session with AUTH:ENGINE even with a paired camera. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Before: to download from a Fledgling, you pressed Transfer → Bluetooth on the logger and then Connect in the app.
After: with logger firmware from DovesDataLogger#168, Connect works while the logger sits on its main menu. The logger stays locked until the app proves it knows the logger's 4-digit PIN.
PINGET) whenever a transfer is started on the logger itself.AUTH?and connects as before, after 2 s.How:
DeviceContext.connectrunsauthenticateLogger()(src/lib/ble/auth.ts) right afterconnectToDevice(). The answer is an HMAC-SHA256 computed with WebCrypto.SLIST;remote_transferon/off setting is added.docs/ble-protocol.md§3.3. Design:docs/plans/0031-remote-transfer-pin.md.Related Issues
Pairs with TheAngryRaven/DovesDataLogger#168 (firmware, plan 0019). A LapWing twin for the native shell follows.
Type of Change
Checklist
bun run lintpassesbun run typecheckpassesbun run test:runpasses (3278; golden vectors shared with the firmware tests)bun run buildsucceedsCLAUDE.md,CHANGELOG.mdunder[5.1.0] - unreleased,docs/ble.md,docs/ble-protocol.md)Notes for Reviewers
i18n:seed.AUTH:CAMERAwith a paired X4;🤖 Generated with Claude Code
https://claude.ai/code/session_01BTPVvtL3ZVDj7UBcAthaQk
Generated by Claude Code