You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Parent: #504. Connected release remains owned by #507.
Officer impact: No live officer workflow changes. In the preserved future People finder, a keyboard or screen-reader user who starts a valid search from the name field or Search button will return to that same control after the current search resolves, instead of being stranded after both controls were disabled during loading. The connected interface remains unavailable on production.
Officer documentation: Update SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, SECURITY.md, and only the optional-directory one-sentence text alternative plus one no-terminal source-evidence procedure in docs/officers/EVENTS_SHOP_MEMBERS.md. No Mermaid change because no element, page topology, permission, or data movement changes.
Deployment evidence: None at issue creation. This is source-only keyboard-focus hardening. memberDirectoryAvailability.ts must remain byte-for-byte false; no website, Firebase, provider, account/sign-in, production-data, deployment, or connected-live action is authorized.
Atomic outcome
Restore focus to the exact connected People-finder control that held focus when one current valid search entered its pending state.
Defect
On exact released main 3ca02e19fbe9977d15f602d37b5200956db1f2b3, SearchAttempt natively disables both the name input and Search button while a search is pending. A focused input submitted with Enter or a focused Search button therefore loses keyboard focus. Completion only re-enables those controls and renders result cards, the empty state, or the fixed failure plus Clear; it records no focus destination. Keyboard and screen-reader users can be left on the document body after every completed search.
Invariants and transitions
Create a focus intent only after a valid query and request ID admit one search into pending, and only when the active element is the persistent name input or Search button.
Record only that exact origin and search-operation identity; no query, name, result, photo, account ID, or service value.
Keep the native disabled controls and duplicate-submission gate unchanged during pending.
When that exact current operation resolves to result cards, empty results, or fixed unavailable failure, consume the intent and focus the same now-enabled origin after render.
Programmatic/outside-focus submission creates no intent and never steals focus.
Validation and request-ID construction failure never enter pending; preserve enabled-control and natural-focus behavior.
Input editing and Clear remove obsolete intent. Clear keeps its zero-ID/zero-call behavior and focuses the empty name input.
App change, admin UID change, unmount, or obsolete operation cannot move focus in another context.
Focus creates no ID, search, retry, Clear action, result, audit, service call, or data URL.
Existing normalization, result disposal, fixed errors, response bounds, AdminGuard, stale fences, and voluntary-thumbnail behavior remain unchanged.
Name-prefix search plus human comparison of voluntary thumbnails only. No photo query, facial recognition, matching, embedding, similarity, biometrics, totals, export, roster authority, or membership proof.
Exact ownership
src/pages/admin/members/AdminMemberDirectory.tsx: only an operation-bound submit-origin focus intent, Search-button ref, cleanup/clear guards, and guarded post-settlement focus handoff inside SearchAttempt.
src/pages/admin/members/AdminMemberDirectory.test.tsx: one separately named MEMBERS-DIRECTORY-001L block plus minimum directly affected helpers/assertions.
SYSTEM_DESIGN.md: one separately named 001L source-only paragraph.
IMPLEMENTATION_PLAN.md: one separately named 001L current-source paragraph.
docs/officers/EVENTS_SHOP_MEMBERS.md: only the optional-directory one-sentence text alternative and one separately named no-terminal 001L source-evidence procedure; no diagram change.
No CSS: the same native controls and existing focus styles are used.
Required tests
Capture trustworthy RED by focusing input or Search, starting a deferred valid search, asserting both disabled, modeling browser disabled-control focus eviction with blur(), settling, and proving old source leaves focus off the origin.
Matrix both origins across non-empty, empty, and fixed failure; current settlement restores the same persistent origin, not Clear/results/body.
Focus handoff consumes one exact intent and creates no second request, ID, retry, or Clear.
Programmatic/outside-focus submission never steals outside focus on settlement.
Validation and request-ID construction failure remain enabled/generic/focus-inert beyond natural focus, with no request.
Existing Clear behavior still removes query/messages/cards/names/images, focuses input, and creates no new ID/call.
App/admin change and unmount make late old resolution/rejection focus-inert.
No migration. Focus handoff is accessibility behavior, not authorization, provider acknowledgement, audit proof, result correctness, or live evidence. Live #623 remains inert; #507 retains all connection/release gates.
Claim protocol
Assign and post a timestamped CLAIMED marker with exact branch/base before edits. Claim stays active through reviewed merge, exact-main audit, closure, and explicit release.
Parent: #504. Connected release remains owned by #507.
Officer impact: No live officer workflow changes. In the preserved future People finder, a keyboard or screen-reader user who starts a valid search from the name field or Search button will return to that same control after the current search resolves, instead of being stranded after both controls were disabled during loading. The connected interface remains unavailable on production.
Officer documentation: Update
SYSTEM_DESIGN.md,IMPLEMENTATION_PLAN.md,SECURITY.md, and only the optional-directory one-sentence text alternative plus one no-terminal source-evidence procedure indocs/officers/EVENTS_SHOP_MEMBERS.md. No Mermaid change because no element, page topology, permission, or data movement changes.Deployment evidence: None at issue creation. This is source-only keyboard-focus hardening.
memberDirectoryAvailability.tsmust remain byte-for-bytefalse; no website, Firebase, provider, account/sign-in, production-data, deployment, or connected-live action is authorized.Atomic outcome
Restore focus to the exact connected People-finder control that held focus when one current valid search entered its pending state.
Defect
On exact released main
3ca02e19fbe9977d15f602d37b5200956db1f2b3,SearchAttemptnatively disables both the name input and Search button while a search is pending. A focused input submitted with Enter or a focused Search button therefore loses keyboard focus. Completion only re-enables those controls and renders result cards, the empty state, or the fixed failure plus Clear; it records no focus destination. Keyboard and screen-reader users can be left on the document body after every completed search.Invariants and transitions
pending, and only when the active element is the persistent name input or Search button.pending.pending; preserve enabled-control and natural-focus behavior.Exact ownership
src/pages/admin/members/AdminMemberDirectory.tsx: only an operation-bound submit-origin focus intent, Search-button ref, cleanup/clear guards, and guarded post-settlement focus handoff insideSearchAttempt.src/pages/admin/members/AdminMemberDirectory.test.tsx: one separately named MEMBERS-DIRECTORY-001L block plus minimum directly affected helpers/assertions.SYSTEM_DESIGN.md: one separately named 001L source-only paragraph.IMPLEMENTATION_PLAN.md: one separately named 001L current-source paragraph.SECURITY.md: one separately named 001L/RISK-042 row immediately after released 001K; preserve active OAUTH-001A2L — Bound Strava activity/statistics JSON and cancel the unread statistics body #616 OAUTH-001A2L/RISK-024 byte-for-byte.docs/officers/EVENTS_SHOP_MEMBERS.md: only the optional-directory one-sentence text alternative and one separately named no-terminal 001L source-evidence procedure; no diagram change.No CSS: the same native controls and existing focus styles are used.
Required tests
blur(), settling, and proving old source leaves focus off the origin.Explicit exclusions
Account.css, client services, availability, AdminGuard, route wiring, result/photo semantics, or copy outside named docs hunks.Migration and residual risk
No migration. Focus handoff is accessibility behavior, not authorization, provider acknowledgement, audit proof, result correctness, or live evidence. Live #623 remains inert; #507 retains all connection/release gates.
Claim protocol
Assign and post a timestamped CLAIMED marker with exact branch/base before edits. Claim stays active through reviewed merge, exact-main audit, closure, and explicit release.