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 My Account interface, a confirmed profile-photo Save or removal will return keyboard focus only when that exact focused initiating control was displaced; it will not steal focus that the user deliberately moved to another connected control while work was pending. 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 needed because page topology, permissions, and data movement do not change.
Deployment evidence: None at issue creation. This is source-only accessibility/state 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
Contain confirmed profile-photo upload/removal focus handoffs so they restore only focus displaced from the exact initiating Save or Remove control and preserve any other connected focus deliberately selected while the mutation or authoritative readback is pending.
The preserved connected Account branch currently sets postMutationFocusRef after every confirmed photo upload or removal and then focuses File, Remove, or Save unconditionally. That can avoid stranding focus when an initiating control disappears, but it also steals focus if the user deliberately selects another connected control while the mutation or authoritative profile readback is pending. A programmatic or outside-focused invocation can also create an unrelated handoff.
The released People-finder and rejected-removal paths already distinguish displaced focus from meaningful connected focus. Confirmed photo success needs the same containment without changing its established destination priority.
Invariants and transitions
Create a confirmed-photo focus intent only after secure request-ID creation and startMutation('upload'|'remove') admit the exact current operation.
Create it only when Save profile photo owns focus for upload or Remove current saved photo owns focus for removal.
Bind it to the mounted application/account lifetime, exact operation symbol, and action only. Store no name, profile, revision, request ID, photo bytes, data URL, provider value, response, or error.
Transfer only a matching current intent after mutation success and a current successful authoritative profile readback.
Confirmed upload keeps the existing destination: the persistent Add/Replace file input.
Confirmed removal keeps the existing priority: surviving Remove; otherwise enabled Save for the exact current ready draft; otherwise the persistent file input.
Leave an already-focused destination alone.
Restore only from absent focus, document.body, document.documentElement, or a disconnected element.
Preserve any other connected focus selected while pending.
Clear or fail the intent on request-ID failure, rejected mutation admission, definitive rejection, unknown outcome, failed readback, application change, UID change, unmount, or obsolete completion.
docs/officers/EVENTS_SHOP_MEMBERS.md: only the optional-directory one-sentence text alternative and one no-terminal 001N evidence procedure; no Mermaid or unrelated procedure change.
No other path is in scope.
Trustworthy RED and required tests
On unchanged runtime, demonstrate that a deliberately selected connected outside or in-profile control is overwritten by confirmed upload/removal settlement.
Focused Save with modeled native eviction returns to the persistent file input after confirmed upload and authoritative readback.
Focused Remove with modeled eviction returns to the file input when no photo/draft remains, to exact current ready Save when a draft remains, or to surviving Remove when the photo remains.
An already-focused destination gets no redundant .focus() call.
Deliberately connected outside and in-profile focus remains focused for both upload and removal.
Outside-focused/programmatic Save or Remove creates no focus handoff.
Request-ID failure creates no intent, extra ID, or service call.
Application change, UID change, unmount, stale mutation completion, and stale readback are focus-inert.
Preserve exact request/read counts, upload content type and bytes, expected revisions, draft retention/disposal, and confirmation copy.
Render/log no raw value, filename, photo byte, provider detail, or caught error.
Default unavailable rendering still obtains no directory-service context, creates no request ID, and calls no directory service.
Update older confirmed-success tests that use bare fireEvent.click to focus the initiating control first; do not remove their destination, revision, draft, byte, or call-count assertions.
Run the named tests, full component and frontend suites, TypeScript, scoped ESLint, unchanged lint baseline, repository Node tests, diagnostic build, workflow checks, and diff-check.
Explicit exclusions
No CSS, Account.tsx/profile-name editing, People finder, visibility-toggle behavior, Reload-success behavior, service contract, Function, Rule, index, schema, repair, package/lockfile, workflow/release control, privacy/capability policy, Firebase/provider configuration, deployment, account/sign-in, production data, real name/photo, connected/live action, or #616 path/hunk.
Migration and residual risk
No migration. Programmatic focus is interface accessibility state, not server acknowledgement, upload/removal proof, authorization, reconciliation, provider evidence, or live proof. #507 retains every privacy, authorization, staging, backend-first deployment/readback, availability-flip, publication, and connected-live gate.
Stop conditions
Stop if the diff leaves the six paths, changes availability, request counts/bytes/revisions/confirmations, weakens #643/#637, restores stale focus, stores personal/service values in the 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 edit. The claim remains active through reviewed merge, exact-main/deployment audit, closure, and explicit release.
Parent: #504. Connected release remains owned by #507.
Officer impact: No live officer workflow changes. In the preserved future My Account interface, a confirmed profile-photo Save or removal will return keyboard focus only when that exact focused initiating control was displaced; it will not steal focus that the user deliberately moved to another connected control while work was pending. 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 is needed because page topology, permissions, and data movement do not change.Deployment evidence: None at issue creation. This is source-only accessibility/state 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
Contain confirmed profile-photo upload/removal focus handoffs so they restore only focus displaced from the exact initiating Save or Remove control and preserve any other connected focus deliberately selected while the mutation or authoritative readback is pending.
Exact base
6b6a597914b3322275a1afe3e5a3c7133ab2d0a9a07d391b8e23e28dd39785329be444f452fa2953295909b0df8dd7c54a0f164f99d4943656aece4bDefect
The preserved connected Account branch currently sets
postMutationFocusRefafter every confirmed photo upload or removal and then focuses File, Remove, or Save unconditionally. That can avoid stranding focus when an initiating control disappears, but it also steals focus if the user deliberately selects another connected control while the mutation or authoritative profile readback is pending. A programmatic or outside-focused invocation can also create an unrelated handoff.The released People-finder and rejected-removal paths already distinguish displaced focus from meaningful connected focus. Confirmed photo success needs the same containment without changing its established destination priority.
Invariants and transitions
startMutation('upload'|'remove')admit the exact current operation.document.body,document.documentElement, or a disconnected element.false; the default branch and live WEB-002C — Publish the bounded inert member-directory interface preview #623 preview remain inert.Exact ownership
src/pages/account/MemberDirectoryProfile.tsx: only exact-operation confirmed upload/remove focus intent, cleanup guards, transfer, and no-steal ready handoff.src/pages/account/MemberDirectoryProfile.test.tsx: one separately namedMEMBERS-DIRECTORY-001Nblock plus minimum directly affected assertions.SYSTEM_DESIGN.md: one separately named 001N source-only paragraph.IMPLEMENTATION_PLAN.md: one separately named 001N current-source paragraph.SECURITY.md: one separately named 001N/RISK-042 row immediately after released 001M; preserve active OAUTH-001A2L — Bound Strava activity/statistics JSON and cancel the unread statistics body #616's future OAUTH-001A2L/RISK-024 hunk.docs/officers/EVENTS_SHOP_MEMBERS.md: only the optional-directory one-sentence text alternative and one no-terminal 001N evidence procedure; no Mermaid or unrelated procedure change.No other path is in scope.
Trustworthy RED and required tests
.focus()call.fireEvent.clickto focus the initiating control first; do not remove their destination, revision, draft, byte, or call-count assertions.Run the named tests, full component and frontend suites, TypeScript, scoped ESLint, unchanged lint baseline, repository Node tests, diagnostic build, workflow checks, and diff-check.
Explicit exclusions
No CSS,
Account.tsx/profile-name editing, People finder, visibility-toggle behavior, Reload-success behavior, service contract, Function, Rule, index, schema, repair, package/lockfile, workflow/release control, privacy/capability policy, Firebase/provider configuration, deployment, account/sign-in, production data, real name/photo, connected/live action, or #616 path/hunk.Migration and residual risk
No migration. Programmatic focus is interface accessibility state, not server acknowledgement, upload/removal proof, authorization, reconciliation, provider evidence, or live proof. #507 retains every privacy, authorization, staging, backend-first deployment/readback, availability-flip, publication, and connected-live gate.
Stop conditions
Stop if the diff leaves the six paths, changes availability, request counts/bytes/revisions/confirmations, weakens #643/#637, restores stale focus, stores personal/service values in the 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 edit. The claim remains active through reviewed merge, exact-main/deployment audit, closure, and explicit release.