feat(w7 p6): opt-in n0 DNS discovery for Discoverable presence
Wire the Discoverable presence posture to n0 DNS publish/lookup, the last
core piece of W7 (friends-first contacts). When a friend moves networks and
their saved address goes stale, they flip Discoverable to publish their
current address; everyone else resolves it by node id. Asymmetric: only the
mover publishes.
- src/discovery.rs (pure seam, +3 tests): lookup_plan(network_mode, want_publish)
-> LookupPlan { resolver, publisher }. Relay-capable modes always resolve and
publish only when Discoverable; DirectOnly (the explicit no-server posture)
gets neither, overriding the toggle. DISCOVERY_TIMEBOX = 30 min.
- apply_discovery (core edge): clears + reinstalls the bound endpoint's
address-lookup services at runtime (no endpoint rebuild). memory-lookup always;
n0 PkarrResolver + DnsAddressLookup when resolver; PkarrPublisher when publisher.
Toggling publish off drops the publisher (republish task ends; TTL-30s record
expires). build_net_stack now binds uniformly with Minimal + per-mode relay and
installs discovery via apply_discovery (drops the per-mode presets::N0 build).
- Toggle + time-box: SetPresenceMode re-applies discovery and arms/cancels a
discovery_deadline; a select! branch fires at the deadline -> revert to Normal,
stop publishing, and emit UiEvent::PresenceModeReverted so the GUI mirrors and
persists it. Re-selecting Discoverable restarts the clock.
Decisions (user, 2026-06-16): 30-min auto-revert (not sticky); resolver always
on in relay-capable modes so a stationary friend in Normal can look up a mover.
266 lib tests green, clippy clean (--all-targets). Runtime smoke-tested: the new
Minimal+apply_discovery path binds and runs with no error/panic for both Normal
and Discoverable startup postures. Cross-network publish->lookup and the live
30-min revert still want a 2-machine field test (P7).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -735,6 +735,15 @@ fn update(state: &mut AppState, message: AppMessage) -> Task<AppMessage> {
|
||||
UiEvent::FriendPresence { id, presence } => {
|
||||
state.friend_presence.insert(id, presence);
|
||||
}
|
||||
UiEvent::PresenceModeReverted { mode } => {
|
||||
// The Discoverable time-box elapsed; core dropped us back to
|
||||
// `mode` (Normal) and stopped publishing. Mirror + persist so the
|
||||
// presence picker reflects it, and tell the user why it changed.
|
||||
state.config.presence_mode = mode;
|
||||
state.config.save();
|
||||
state.status_message =
|
||||
"Discoverable timed out — back to Normal".to_string();
|
||||
}
|
||||
UiEvent::Error(err) => {
|
||||
state.status_message = format!("Error: {}", err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user