fix: pair-first Setup order and an actionable Add by Address failure message (#95) - #97
Merged
Merged
Conversation
…d 4 (#95) An unpaired Mac refuses incoming connections outright, so Add by Address can only ever time out until both sides hold the pairing key — yet Setup walked through the Macs tab (including Add by Address) before the Pairing tab. Pairing needs no connectivity, so pairing-first is safe in every flow. Say so explicitly in both sections, and document the one endpoint staleness case the INTRODUCE exchange can't heal: both Macs changing IP at once on a Bonjour-blocked network.
…95) An unpaired peer cancels the connection before the handshake, which the dialing side can't tell apart from a firewall drop or a dead host — the sheet just said the other Mac "didn't respond", steering users at the network when the actual fix is usually pairing first. Give the four unreachable-shaped failures one message naming all three causes; auth failures keep their precise wording.
MegaManSec
force-pushed
the
fix/pair-first-setup
branch
from
August 6, 2026 22:34
2fe625f to
21d028c
Compare
- A peer reset can land while the handshake nonce send is in flight (handshakeFailed(.sendFailed)), and a non-Magic-Switch service answering on the port yields framingFailed/frameTooLarge — the same unreachable shape, previously falling through to the generic secure-connection message. Fold all three into the lumped case. - Point at Settings → Pairing in that message, matching .notPaired. - Dialing before this Mac's own listener is bound reported the local condition as a peer-shaped connection failure; fail early with a dedicated .listenerNotReady message instead. - README: an unpaired Mac refuses the connection immediately, so say the add fails rather than times out.
MegaManSec
added a commit
that referenced
this pull request
Aug 6, 2026
* docs: recapture README screenshots against the Macs-era UI Every annotated screenshot predated the July/August UI work: the Device tab rename to Macs (with Sync and Add by Address), battery levels in the menu and peripheral rows, the uniform action pills, the keyboard-shortcut recorders, and the display-connect list. Recapture all of them, add the previously unillustrated Add a Mac by Address sheet, and update the annotation script's coordinates and legends to match (device-tab becomes macs-tab; sections without a raw capture are now skipped instead of aborting). README captions follow: battery levels in the hero and Peripheral tab, the new sheet figure in Setup, and an Other-tab caption that matches the scrolled capture. The four Pairing screenshots are still the old captures. * docs: stitch the full Other tab and keep the icon'd type-picker capture The Other tab outgrew the window, so one scrolled capture hid either the top or the bottom. Stitch three scrolled captures into a single full-height raw — slices cut on flat background between sections, aligned by crop offset, overlay scrollbar painted out — and re-badge all six affordances. Revert peripheral-type-picker.png to the previous capture: menu-item icons only render on macOS 26, and the recapture came from a Sequoia Mac, so its picker menu was text-only. * docs: recapture the menu in its reachable state, badge the display row itself - menu.png previously showed every row greyed out (peer unreachable) — the state Troubleshooting teaches as "can't switch" — under a caption inviting clicks. Recaptured with the other Mac online; legend background re-matched to the new capture's material. - The Other tab's badge 5 pointed at the marked display's trash button while its legend line describes the row; aim it at the row title. - docs/assets/raw/ is local input to annotate-screenshots.sh — gitignore it so stray git add -A can't commit raw captures. * Pair-first Setup order and an actionable Add by Address failure message (#95) (#97) * docs: pair the Macs before connecting them — reorder Setup steps 3 and 4 (#95) An unpaired Mac refuses incoming connections outright, so Add by Address can only ever time out until both sides hold the pairing key — yet Setup walked through the Macs tab (including Add by Address) before the Pairing tab. Pairing needs no connectivity, so pairing-first is safe in every flow. Say so explicitly in both sections, and document the one endpoint staleness case the INTRODUCE exchange can't heal: both Macs changing IP at once on a Bonjour-blocked network. * fix: name the likely causes when Add by Address can't reach the peer (#95) An unpaired peer cancels the connection before the handshake, which the dialing side can't tell apart from a firewall drop or a dead host — the sheet just said the other Mac "didn't respond", steering users at the network when the actual fix is usually pairing first. Give the four unreachable-shaped failures one message naming all three causes; auth failures keep their precise wording. * fix: cover every unreachable-shaped Add by Address failure (#95) - A peer reset can land while the handshake nonce send is in flight (handshakeFailed(.sendFailed)), and a non-Magic-Switch service answering on the port yields framingFailed/frameTooLarge — the same unreachable shape, previously falling through to the generic secure-connection message. Fold all three into the lumped case. - Point at Settings → Pairing in that message, matching .notPaired. - Dialing before this Mac's own listener is bound reported the local condition as a peer-shaped connection failure; fail early with a dedicated .listenerNotReady message instead. - README: an unpaired Mac refuses the connection immediately, so say the add fails rather than times out.
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.
Follow-ups from #95. Stacked on #96 (both edit the same Setup sections) — merge #96 first, then re-target this to main.
docs: Add by Address can't work before pairing — an unpaired Mac refuses every connection before the handshake (
IncomingConnection.start()), so the add fails — yet Setup ordered the Macs tab before the Pairing tab. Swap steps 3 and 4 (pairing needs no connectivity, so pair-first is safe in every flow), state the prerequisite in both sections, and add a Troubleshooting bullet for the one case the INTRODUCE exchange can't heal: both Macs changing IP at once on a Bonjour-blocked network.fix: the dialing side can't distinguish an unpaired peer from a firewall drop, a dead host, or a different service answering on the port — and "didn't respond" steered #95's reporter at the network when the fix was pairing. Every unreachable-shaped failure (connect timeout/failure; handshake timeout, close, send failure, framing garbage) now shares one Add-by-Address message naming the causes: "Couldn't reach the other Mac securely. Check that it's running Magic Switch and paired with the same code (Settings → Pairing), and that no firewall is blocking the port." Auth failures keep their precise wording, and dialing before this Mac's own listener is bound now says so (
.listenerNotReady) instead of blaming the peer. Scoped toManualAddError— switch-notification messages untouched.Not built in Xcode here, but
swiftc -typecheckagainst the macOS SDK passes — please build before merging.