Multi-device mesh + session-transfer program (docs/MESH_TRANSFER.md). P1 (multi-select connection methods, Mac): SyncTransportSet with legacy migration; CompositeSyncListener partial-failure tolerant + per-method health; AppStore listens on all enabled methods; HostInfo.hostID = DeviceIdentity.hostID (key hash, not display name); Settings 3 method toggles + LAN-only recommendation banner. P2 core (relay hardening, security-critical, tested): nucleic-edge relayEnroll.ts X25519 proof-of-possession enroll + server-side roomId derivation; room.ts role-routed per-peer forwarding with deviceId-tag envelope + frame cap + one-host-per-room eviction; host-bearer minting bound to the PoP room. Swift cross-stack contracts pinned to test vectors: RelayEnrollment (PoP proof), RelayEnvelope (routing tag), PairingPayload relay fields. Socket transport + iOS un-gating remain deploy-gated. P4 foundation (peer model + listPeers, tested): PeerTypes (PeerKind/ PeerCapabilities/PeerSummary); Hello.deviceKind+clientCaps; WireCapabilities.canListPeers; ClientMsg.listPeers -> HostMsg.peerList; PairedDevice.kind+capabilities (decode-defaulted); ConnectionHandler records kind at pairing; SyncHost.connectedDeviceIDs(); AppStore.peerSummaries(); SyncClient .peerList event; iOS RemoteStore.meshPeers. PeerClient + Mac<->Mac pairing UI remain. All additive + capability-gated; SyncProtocol.version stays 1; pre-mesh stores and clients unaffected. Swift 724 core + 91 protocol tests green; edge 50 green. Co-Authored-By: Claude Fable 5 <[email protected]>
NucleicRemote (iPhone client)
The thin iOS remote client for Nucleic (PLAN milestone M4). It's a pure projection of the
Mac host over LAN: monitor sessions, read transcripts/diffs, answer approvals, and send
follow-up input — scope approve. No local git or CLI; the Mac is the single authority
(see docs/UX_IOS.md and docs/SYNC_PROTOCOL.md).
Architecture
All wire/crypto logic is shared with the Mac via the NucleicProtocol SwiftPM library
(this Xcode project links it as a local package at ../..):
- Transport —
NWFrameChannel(NWConnection) +LANDiscovery(Bonjour_nucleic._tcp). - Engine —
NucleicProtocol.SyncClientruns the Noise handshake (XXpsk0 to pair, IK to reconnect), exchanges hello/welcome, and turnsHostMsgs into aSyncClient.Eventstream. - State —
RemoteStore(ObservableObject) is the single on-device UI state, a pure projection of the host. Identity + pinned host live inIdentityStore(Keychain + UserDefaults). - UI — SwiftUI:
SessionsView(attention-first list),SessionDetailView(transcript/diff + status-driven action area),ApprovalCardView(Face ID gate on high-risk),PairingScannerView(QR),SettingsView.
Build & run
# Resolves the local NucleicProtocol package automatically.
xcodebuild -project ios/NucleicRemote/NucleicRemote.xcodeproj \
-scheme NucleicRemote \
-destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
Or open NucleicRemote.xcodeproj in Xcode and run. To pair, start the sync server on the Mac
(Nucleic ▸ Settings ▸ Add iPhone shows the QR), then scan it. On a real device, both must be
on the same Wi‑Fi.
Status
The full pair → list → subscribe → approve → reconnect path is implemented and the protocol/
server side is covered by tests in Tests/NucleicProtocolTests and Tests/NucleicCoreTests.
Push notifications / Live Activity (UX_IOS §5.1/§5.3) are the M5 follow-up (needs the relay).