Skip to content

MEMBERS-DIRECTORY-001O — Preserve visibility-toggle focus after authoritative settlement #647

Closed

Description

@daliu

Parent: #504. Connected release remains owned by #507.

Officer impact: No live officer workflow changes. In the preserved future My Account interface, a keyboard or screen-reader user who changes the officer-finder checkbox can return to that same checkbox after the current save and authoritative readback settle, instead of being stranded when the checkbox is disabled during loading. Any other connected control deliberately focused while the request is pending keeps focus. 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 is required because element structure, page topology, permissions, ownership, and data movement do not change.

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, publication, or connected-live action is authorized.

Atomic outcome

Restore otherwise-lost focus to the exact officer-finder checkbox that owned focus when one current visibility mutation was admitted, after confirmed success or definitive rejection plus successful authoritative readback, without stealing any other connected focus.

Exact base

  • Source: 0f421e6d1ffc454aa1de09d342d7b70d3fbd2388
  • Tree: 292cc0cd87e3246d1b2976a15f2d48bc7b3dce93
  • Availability blob: 295909b0df8dd7c54a0f164f99d4943656aece4b

Defect

The preserved connected Account branch disables the officer-finder checkbox during every pending visibility mutation. Browsers may evict focus when that focused native checkbox becomes disabled. Current settlement re-enables the checkbox and renders an authoritative result or fixed rejection, but records no focus destination; keyboard and screen-reader users can be left on the document body. Confirmed upload/removal and People-finder search already have bounded operation-owned focus handoffs, while visibility does not.

Invariants and transitions

  • Capture a visibility focus intent only after request-ID creation and admitted startMutation('visibility'), and only when the exact rendered checkbox owns focus.
  • Store only the mounted application/account lifetime and exact operation identity. Store no query, name, profile, revision, request ID, result, error, provider value, photo byte, or data URL.
  • Keep the existing native pending disablement and duplicate-mutation gate unchanged.
  • Transfer the intent only after that exact current operation reaches a guarded ready state through either:
    • confirmed mutation success plus successful authoritative readback; or
    • definitive rejection plus successful confirming readback.
  • Consume the transferred intent once after the matching ready render.
  • Use the same persistent officer-finder checkbox as the only destination.
  • Leave the checkbox alone if it already owns focus.
  • Restore only from absent focus, document.body, document.documentElement, or a disconnected element, and only when the checkbox is connected and enabled.
  • Preserve any other connected outside or in-profile focus deliberately selected while pending.
  • If current name eligibility makes the returned off checkbox disabled, consume the intent without focusing it.
  • An outside-focused or programmatic checkbox invocation creates no intent and cannot steal focus later.
  • Request-ID construction failure and rejected mutation admission never enter pending and remain focus-inert beyond natural browser behavior.
  • Ordinary unknown outcomes and all post-mutation/confirming-read failures create no visibility result focus; they retain MEMBERS-DIRECTORY-001J — Preserve profile-recovery keyboard focus #637's Reload recovery and uncertainty truth.
  • Application change, UID change, unmount, cleanup, a newer load, or stale completion clears or fails the lifetime/operation guards.
  • Focus creates no request ID, read, mutation, retry, audit, result, draft, photo byte, data URL, provider action, or data action beyond the already admitted operation.
  • Preserve MEMBERS-DIRECTORY-001M — Restore surviving photo-control focus after rejected removal #643 rejected-removal focus, MEMBERS-DIRECTORY-001N — Preserve deliberate focus during confirmed photo changes #645 confirmed-photo focus, MEMBERS-DIRECTORY-001J — Preserve profile-recovery keyboard focus #637 Reload recovery, current error association, exact revisions, and existing confirmation copy.
  • Availability stays literal false; the default branch and live WEB-002C — Publish the bounded inert member-directory interface preview #623 preview remain inert and zero-call.
  • This remains name-prefix search plus human visual comparison of voluntary thumbnails. Add no photo query, facial recognition, matching, embedding, similarity, biometric processing, total, export, roster authority, or membership proof.

Exact ownership

  • src/pages/account/MemberDirectoryProfile.tsx
    • only an operation-bound focused-visibility pending/result intent, checkbox ref, cleanup/failure guards, and guarded ready-state focus handoff.
  • src/pages/account/MemberDirectoryProfile.test.tsx
    • one separately named MEMBERS-DIRECTORY-001O block plus the minimum directly affected focus assertions/helpers.
  • SYSTEM_DESIGN.md
    • one separately named 001O source-only paragraph.
  • IMPLEMENTATION_PLAN.md
    • one separately named 001O current-source paragraph.
  • SECURITY.md
  • docs/officers/EVENTS_SHOP_MEMBERS.md
    • only the optional-directory one-sentence text alternative and one separately named no-terminal 001O source-evidence procedure; no Mermaid or unrelated procedure change.

No other path is in scope.

Trustworthy RED and required tests

  • On unchanged runtime, focus the checkbox, admit a deferred visibility mutation, assert pending disablement, model native disabled-control focus eviction, settle authoritative readback, and prove focus is not restored.
  • Matrix requested on, requested off, and changed-again authoritative results after confirmed mutation success.
  • Definitive rejection plus successful confirming read restores lost focus and retains the fixed rejection alert/checkbox association.
  • Already-retained checkbox focus causes no redundant .focus() call.
  • Connected outside and in-profile focus deliberately selected while pending remains focused across both success and definitive rejection.
  • Outside-focused/programmatic invocation creates no later focus handoff; remove/blur the outside node before settlement to prove no hidden intent was captured.
  • Request-ID failure remains enabled, generic, zero-call, and focus-inert.
  • Unknown outcome and post-mutation/confirming-read failure focus only Reload through existing recovery; never the checkbox.
  • A name eligibility change that disables the returned checkbox consumes the intent without focusing it.
  • Application change, UID change, unmount, stale mutation completion, and stale authoritative readback cannot move focus in another context.
  • One-shot consumption cannot refocus on a later ready-state rerender.
  • Preserve exact existing profile-read, request-ID, and visibility-call counts; create no upload/removal call, retry, draft, or data URL.
  • Default unavailable rendering remains zero directory-service context, zero request ID, and zero directory call.
  • Existing profile photo, result disposal, accessibility, mobile, stale-context, response-contract, and privacy tests remain green.

Then run the full component and frontend suites, TypeScript, scoped ESLint, unchanged lint baseline, repository Node/workflow/security tests, diagnostic build, and diff-check.

Explicit exclusions

Migration and residual risk

No migration. Programmatic focus is an accessibility handoff, not authorization, provider acknowledgement, audit proof, mutation correctness, saved-state proof, or live evidence. Live #623 remains the inert preview, and #507 retains every privacy, authorization, staging, backend-first deployment/readback, availability-flip, publication, and live-proof gate.

Stop conditions

Stop if the diff leaves the six paths, changes availability, adds a read/mutation/retry, changes payloads/revisions/bytes, weakens #637/#643/#645, focuses a disabled checkbox, steals connected focus, lets a stale operation move focus, stores private/service values in an intent, changes CSS/Mermaid, overlaps #616, connects/deploys the backend, uses real data, or implies source/tests/preview are live.

Claim protocol

Assign the issue and post a timestamped CLAIMED marker naming the exact branch and released base before any source edit. The claim remains active through reviewed merge, exact-main/non-publication audit, closure, and explicit release.

Activity

  1. added
    bugSomething isn't working
    priority:P1High-priority follow-up
    type:securitySecurity or privacy boundary
    area:membershipMembership lifecycle and reconciliation
    area:webWeb application and hosting
    size:SSmall focused issue
    status:readyDependencies complete and ready to claim
    type:testingTest infrastructure and quality gates
    area:privacyPersonal data, consent, minimization, retention, and privacy operations
    status:in-progressClaimed and actively being implemented
    and removed
    status:readyDependencies complete and ready to claim
    on Aug 14, 2026
  2. self-assigned this
    on Aug 14, 2026
  3. daliu commented on Aug 14, 2026

    @daliu
    ContributorAuthor

    CLAIMED by /root at 2026-08-14T02:03:42Z. Branch: codex/issue-647-visibility-focus. Exact released base: 0f421e6d1ffc454aa1de09d342d7b70d3fbd2388, tree 292cc0cd87e3246d1b2976a15f2d48bc7b3dce93.

    Ownership is exactly the six paths/hunks named in the issue: MemberDirectoryProfile.tsx and its existing test; separate 001O current-source hunks in SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, and SECURITY.md; and only the optional-directory one-sentence text alternative plus one no-terminal 001O evidence procedure in docs/officers/EVENTS_SHOP_MEMBERS.md. Availability stays byte-for-byte false; #616's two Strava files and its OAUTH-001A2L/RISK-024 SECURITY hunk are immutable. No source edit preceded this marker. No backend, deployment, provider, account/sign-in, production-data, or live action is authorized. The claim remains active through reviewed merge, exact-main/non-publication audit, closure, and explicit release.

  4. daliu commented on Aug 14, 2026

    @daliu
    ContributorAuthor

    #647 candidate evidence — 2026-08-14

    Exact released base and current remote main: 0f421e6d1ffc454aa1de09d342d7b70d3fbd2388 (tree 292cc0cd87e3246d1b2976a15f2d48bc7b3dce93).

    The reviewed working diff is exactly the six claimed paths:

    • src/pages/account/MemberDirectoryProfile.tsx
    • src/pages/account/MemberDirectoryProfile.test.tsx
    • SYSTEM_DESIGN.md
    • IMPLEMENTATION_PLAN.md
    • SECURITY.md
    • docs/officers/EVENTS_SHOP_MEMBERS.md

    Exact binary diff SHA-256: 1d06e5f300c3e5362009881d6bfd28dce0e029cee510ec93f8eee283244ce961.

    Trustworthy RED on unchanged runtime: the initial MEMBERS-DIRECTORY-001O matrix had 5 exact focus-restoration failures and 14 containment controls passing. Corrected source: 21/21 named tests and 152/152 full MemberDirectoryProfile tests pass.

    Node 20 verification is green:

    • full frontend: 18 suites, 1,237 tests;
    • TypeScript --noEmit;
    • scoped ESLint;
    • lint baseline: 120 files, 113 reviewed legacy errors, 6 reviewed warnings;
    • repository Node/workflow/security tests: 105/105;
    • diagnostic production build;
    • git diff --check.

    Independent focus/race, security/privacy, frontend/accessibility, and backup-officer/operations reviews all report GO with no findings. The officer procedure is no-terminal; its text alternative is one sentence; all 52 Mermaid blocks are unchanged.

    The source-controlled availability file remains literal false at blob 295909b0df8dd7c54a0f164f99d4943656aece4b. Active #616 files remain byte-identical: functions/strava.js blob 2eb48945061ab5ad2a896c6835f308cefd7fe63a and functions/strava.test.js blob d1792d390bd57608fecab84341a6e5916fcf8196; its separate RISK-024/OAUTH hunk is untouched.

    This is SOURCE ONLY and NOT LIVE. Live production remains the inert #623 deploy 6a7e072f8f346b0008510d29; no website, Firebase, provider, account/sign-in, production-data, or connected behavior was changed or tested. #507 retains every connection and release gate.

  5. added a commit that references this issue on Aug 14, 2026
  6. daliu commented on Aug 14, 2026

    @daliu
    ContributorAuthor

    COMPLETE / CLOSED / CLAIM RELEASED — MEMBERS-DIRECTORY-001O

    Merged PR #648 as exact main 161ebb80f951651484a7592fd0e504649d3d1035 (parent 0f421e6d1ffc454aa1de09d342d7b70d3fbd2388, tree f5f598aab4efb8a4ad7d8668be2ad2e4b6a9ad7f). The tree is identical to reviewed head c930dcd88aa46d654305cc9aec1ad743fe4fa95f; the exact six-path binary diff SHA-256 remains 1d06e5f300c3e5362009881d6bfd28dce0e029cee510ec93f8eee283244ce961.

    Outcome: a focused officer-finder visibility checkbox now gets one lifetime/operation-bound focus handoff after confirmed success or definitive rejection plus current authoritative readback. It restores only genuinely lost focus to the same connected and enabled checkbox, preserves deliberately selected connected focus, consumes a disabled/name-ineligible result without delay, and keeps unknown/readback failures on existing Reload recovery. No request, read, callable, retry, payload, revision, photo byte, backend, provider, account, sign-in, or production-data behavior changed.

    Evidence:

    • trustworthy old-source RED: 5 exact restoration failures with 14 containment controls already passing;
    • final MEMBERS-DIRECTORY-001O: 21/21; full profile: 152/152; full frontend: 1,237/1,237;
    • TypeScript, scoped lint, lint baseline, repository Node tests 105/105, diagnostic build, and diff-check passed;
    • independent focus/race, security/privacy, frontend/accessibility, and backup-officer reviews returned GO;
    • exact-head CI 31763516255 and exact-main CI 31763730376 each passed all five jobs;
    • exact-head Netlify preview 6a7e7bd690347c0008f4aac7 was ready and unpublished with no Netlify or Edge Functions;
    • exact-main Netlify attempt 6a7e7cd247875d0007e4d37a is error/unpublished;
    • the published pointer remains inert WEB-002C — Publish the bounded inert member-directory interface preview #623 deploy 6a7e072f8f346b0008510d29, and the public marker remains byte-identical SHA-256 b74498854585346aa66c0341e29c829245445ce986806c3864cad526b267876f;
    • memberDirectoryAvailability.ts remains literal false; OAUTH-001A2L — Bound Strava activity/statistics JSON and cancel the unread statistics body #616's two Strava blobs remain byte-identical.

    No Firebase, Rules, indexes, Functions, provider configuration, account/sign-in, production-data, or live connected action occurred. #507 retains every connection and release gate.

    The exact #647 source, test, and separately named documentation hunks are now released for later work. Any later child must refresh from exact current main and preserve #616's active paths and SECURITY hunk.

  7. removed their assignment
    on Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:membershipMembership lifecycle and reconciliationarea:privacyPersonal data, consent, minimization, retention, and privacy operationsarea:webWeb application and hostingbugSomething isn't workingpriority:P1High-priority follow-upsize:SSmall focused issuetype:reliabilityReliability and recoverytype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions