Skip to content

feat: RFC 0002 Local Peer Discovery - #2

Open
gmaclennan wants to merge 2 commits into
feat/RFC-0001-privacy-connectionsfrom
feat/RFC-0002-local-peer-discovery
Open

feat: RFC 0002 Local Peer Discovery#2
gmaclennan wants to merge 2 commits into
feat/RFC-0001-privacy-connectionsfrom
feat/RFC-0002-local-peer-discovery

Conversation

@gmaclennan

@gmaclennan gmaclennan commented Aug 20, 2026

Copy link
Copy Markdown
Member

Rendered: https://github.com/digidem/comapeo-rfcs/blob/feat/RFC-0002-local-peer-discovery/rfcs/0002-p2p-discovery.md

Stacked on #1: the broadcast hints derive from RFC 0001's project secret S_P, and discovery hands off to its connection layer.

Summary

Local discovery today is mDNS-only, lives in the host app, and fails in ways common in the field (multicast-blocking routers, no shared network, broken Android NSD). This RFC moves all discovery into @comapeo/core-react-native, adds a BLE transport that works screen-off and network-free, and upgrades what discovery says: rotating, member-only hints that convey "a co-member with data you don't have is nearby, on this/another WiFi network" without broadcasting anything a bystander can use to track a device or confirm membership beyond the current day.

Key points for reviewers

The 24 h epoch default (§8). All hints rotate on a floored UTC day, chosen for clock-skew tolerance on field devices over tighter unlinkability — within a day, hints are linkable by a repeat observer. The scan-side previous/current/next overlap is free, but the period itself is the privacy lever.

State-hash gossip (§7). Broadcasting a 4-byte epoch-salted digest of sync state lets a scanner see "our states differ, worth connecting" passively — a new, deliberate information disclosure. The namespace set (excluding blob) and the epoch salt are what keep it from being a false-positive generator or a cross-day fingerprint.

The 31-byte beacon (§9.1, §10). Manufacturer data with no service UUID (a 128-bit UUID would spend 18 of 31 bytes), 2-byte truncated project hashes with accepted false positives, and one project per beacon with weighted round-robin rotation for multi-project devices — latency for many-project devices is the cost.

iOS as a silent participant (§9.3). iOS cannot advertise manufacturer data or run BLE in the background, so it scans only and introduces itself over a GATT write to the Android advertiser. Consequences accepted: an idle iOS device is undiscoverable, and iOS↔iOS BLE does not exist (mDNS covers it on a shared network). The rejected alternative — foreground service-UUID advertising — is §17.4.

Checklist

  • Rename the file to match this PR's number, and update the RFC header
  • List the affected repos in the RFC header
  • Complete the Security considerations section, or state why it doesn't apply

Open questions

From §19, the ones that need answers during review rather than implementation:

  • mDNS TXT policy (§19.3): one rotating project hash vs several at once — several is lower latency but a within-day set fingerprint of the device's memberships; global default or per-deployment toggle?
  • Network token derivation (§19.4): whether to key it by S_P (stops bystanders confirming SSID guesses, but one token per project instead of one per device), and SSID vs BSSID granularity.
  • State-hash namespace set (§19.1): confirm auth/config/data/blobIndex (excluding blob) yields "equal ⟺ nothing to sync" in practice, including partial-download edge cases.

@gmaclennan gmaclennan self-assigned this Aug 20, 2026
@gmaclennan gmaclennan changed the title fet: RFC 0002 Local Peer Discovery feat: RFC 0002 Local Peer Discovery Aug 20, 2026
@gmaclennan
gmaclennan force-pushed the feat/RFC-0002-local-peer-discovery branch from fe1a9fd to 4180b05 Compare August 25, 2026 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant