feat(wifi): auth-failure feedback on the secret prompt (#218)#252
Open
vibechoom wants to merge 1 commit into
Open
feat(wifi): auth-failure feedback on the secret prompt (#218)#252vibechoom wants to merge 1 commit into
vibechoom wants to merge 1 commit into
Conversation
A rejected Wi-Fi passphrase re-prompted byte-identically (reads as a shell bug), and an empty submit was a silent no-op the agent just re-asked for. Ship the robust subset from the #218 triage: - `PromptRequest` gains `prior_failure: bool` — a bool, not an attempt count, because NM can only produce the one bit, not a count. The NM secret agent maps `NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW` (0x2) on `GetSecrets` into it (stateless, per-call, authoritative "the last secret was rejected"). The iwd agent has no equivalent signal on `RequestPassphrase`, so it sets `false`. - Prompt overlay: a non-empty Connect guard (`connect_changed` → `set_sensitive`; Enter/Connect also no-op on empty), plus an error subtitle ("Authentication failed — check the passphrase") and the `.error` CSS class on the password entry when a reopened prompt carries `prior_failure`. Deferred (not built): the busy/spinner in-flight state. The triage proved it unbuildable off the prompt signal — the agents clear the prompt to `None` the instant the secret is handed to the daemon (not when the connection result is known), so a spinner keyed on `active_prompt` would flash and vanish while the seconds-long association runs with no overlay on screen. A genuine in-flight indicator has to key off `wifi::station()` `StationState::Connecting` / NM device state — a separate, larger seam. Follow-up. Live-verify: enter a wrong Wi-Fi passphrase → the reopened prompt shows the error styling + message (not a byte-identical re-ask); Connect is disabled on an empty entry. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Adversarial self-review (reviewer: vibechoom) — clean, ready for live-verify. ✅
Live-verify: enter a wrong Wi-Fi passphrase → the reopened prompt shows the error message + red entry (distinguishable from a fresh ask); Connect is greyed on an empty field. 🚂 |
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.
Ships the robust subset of #218 (per the
## Triage): distinguishable retry feedback + a non-empty submit guard on the Wi-Fi/VPN secret prompt. The busy/spinner half is deliberately deferred — the triage proved it unbuildable off the prompt signal.What changed
PromptRequest::prior_failure: bool(wifi/types.rs)A bool, not an
attempt: u32— NM cannot produce a retry count, only a single "the last secret was rejected" bit, so a count would over-promise.wifi/nm_agent.rs): mapsNM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW(0x2, already delivered in the sameGetSecretsflagsarg that we only testedALLOW_INTERACTIONon) →prior_failure. Stateless, per-call, authoritative. Addedconst FLAG_REQUEST_NEW: u32 = 0x2;and set the field at both construction sites (Wi-Fi + VPN).wifi/agent.rs):RequestPassphrasecarries no equivalent failure signal, so it setsprior_failure: false(honest no-op on that backend).The
nm_agent.rssystem tests read struct fields rather than buildingPromptRequest, so this is low-churn — only the struct + the two construction sites.Prompt overlay (
overlays/prompt.rs)Connectstarts insensitive;connect_changedon the entry togglesset_sensitive(!text.is_empty()). Enter/activate and the Connect click also no-op on empty text. Kills the silent empty-submit loop.prior_failureis set, render an error subtitle ("Authentication failed — check the passphrase") and add the stock Adwaita.errorCSS class to thePasswordEntry(red). The overlay already rebuilds per request, so no structural change — a retry no longer reads as a byte-identical re-ask.assets/trollshell/style.cssAdds a
.ts-prompt-errorrule (uses@error_color). The entry red comes free from Adwaita's built-in.error.Deferred (NOT built): the busy/spinner in-flight state
The triage proved the spinner-as-specified has a timing bug in its premise: both agents clear the prompt to
Nonethe instant the secret is handed to the daemon (agent.rs,nm_agent.rs), not when the connection result is known. On submit the sequence isSome(a) → None → Some(b); the overlay tears down within milliseconds, the seconds-long association runs with no overlay on screen, and only a failure re-emitsSome. A spinner keyed onactive_promptwould flash and vanish.Nonemeans "secret submitted", not "success". A genuine in-flight indicator has to key offwifi::station()StationState::Connecting/ NM device state — a separate, larger seam. Left as a follow-up.Scope notes
prior_failure; iwd reopens plainly. Matches the triage recommendation.Live-verify
.errorentry (not a byte-identical re-ask).Connectis disabled on an empty entry; Enter on empty is inert.Closes #218 (robust subset; busy-state follow-up tracked as deferred above).