Skip to content

MEMBERS-DIRECTORY-001H — Preserve a reviewed replacement across saved-photo removal #633

Closed

Description

@daliu

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

Officer impact: In the preserved future My Account interface, removing the current saved photo will no longer silently discard a replacement photo the person is still reviewing, and keyboard focus will move to the next relevant photo action. This connected interface source remains unavailable on production.

Officer documentation: Update SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, SECURITY.md, and the existing optional-directory diagram, one-sentence text alternative, and source-review procedure in docs/officers/EVENTS_SHOP_MEMBERS.md.

Deployment evidence: None at issue creation. This is source-only interface hardening. memberDirectoryAvailability.ts must remain byte-for-byte false; no Firebase, provider, account, production-data, sign-in, or live website action is authorized. Closure must distinguish source/test/merge evidence from the unchanged inert #623 production preview.

Atomic outcome

Preserve a local selected-photo review across a confirmed removal of the current saved photo, and restore keyboard focus to a useful persistent or next-step control.

Invariants and transitions

  • Rename the destructive action to Remove current saved photo so it cannot be confused with the selected local replacement.
  • Selecting/reading/reviewing a replacement remains local and creates no request ID or service call until explicit Save profile photo.
  • A confirmed remove with authoritative readback preserves the current local reading or ready draft and its identity. It updates only the current saved-photo state and revision.
  • A later explicit Save of the preserved ready draft creates one new request ID, sends the preserved bytes once, and uses the authoritative revision returned after removal.
  • A confirmed remove does not change the officer-finder visibility setting.
  • A definitive rejected remove with successful authoritative readback keeps the local draft available for review/retry and associates the fixed error with the remove control.
  • An unknown remove outcome or any post-mutation authoritative readback failure clears the local draft/data URL, hides connected controls, and exposes the existing unknown/unavailable recovery state. It must not invite a duplicate mutation.
  • After confirmed removal, focus moves to Save profile photo when the preserved draft is ready; otherwise it moves to the persistent Add/Replace file input. If authoritative readback says a current saved photo still exists, the visible remove action remains a valid focus target.
  • App, UID, unmount, reselection, Cancel, FileReader, image-render, mutation, and readback generations remain fenced. A stale completion cannot restore bytes, focus, state, or a service call into another context.
  • The source-controlled availability boundary stays false. The default My Account branch remains an inert zero-context, zero-request-ID, zero-call preview.
  • Photo upload remains independent of visibility. Do not add photo-as-query, recognition, matching, embeddings, similarity, biometrics, roster authority, or membership proof.

Exact ownership

  • src/pages/account/MemberDirectoryProfile.tsx
    • preserve only the current local draft/read identity across a confirmed remove;
    • rename the remove action and add bounded post-remove focus intent.
  • src/pages/account/MemberDirectoryProfile.test.tsx
    • one separately named MEMBERS-DIRECTORY-001H block and the minimum expectation updates for the renamed action.
  • SYSTEM_DESIGN.md
    • one separately named MEMBERS-DIRECTORY-001H source-only paragraph.
  • IMPLEMENTATION_PLAN.md
    • one separately named MEMBERS-DIRECTORY-001H current-source paragraph.
  • SECURITY.md
  • docs/officers/EVENTS_SHOP_MEMBERS.md
    • only the existing optional-directory Mermaid/one-sentence text alternative and one separately named source-review procedure for this change.

Required tests

  • Capture trustworthy RED on the old runtime for draft loss and/or focus loss.
  • A ready reviewed draft survives one successful remove; no upload happens before Save.
  • The subsequent Save sends the exact preserved content once with the refetched revision.
  • A FileReader completion that remains current across a confirmed remove can finish locally; stale/reselected/context completions remain inert.
  • A definitive rejected remove with successful readback preserves the draft and fixed remove error.
  • Unknown remove outcome and post-success readback failure discard the draft/data URL and expose no Save retry.
  • Confirmed remove restores focus correctly with a ready draft, a reading/no-ready draft, no draft, and authoritative readback that still has a saved photo.
  • Visibility and saved-thumbnail fallback behavior remain unchanged.
  • The default unavailable branch still obtains no directory context and creates no request ID or service call.
  • Existing profile races, upload review, accessibility, mobile, privacy, and error tests remain green.

Explicit exclusions

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 audit, closure, and explicit release.

Activity

  1. added
    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 13, 2026
  2. self-assigned this
    on Aug 13, 2026
  3. daliu commented on Aug 13, 2026

    @daliu
    ContributorAuthor

    CLAIMED by /root at 2026-08-13T21:33:15Z on branch codex/issue-633-preserve-photo-draft, exact released base d5a218a3ceebdfa758067ae7510803c75564c3c0.

    Exact ownership is limited to:

    • src/pages/account/MemberDirectoryProfile.tsx: reviewed/reviewing draft preservation across confirmed saved-photo removal, the exact remove label, and bounded post-remove focus intent only.
    • src/pages/account/MemberDirectoryProfile.test.tsx: one separately named MEMBERS-DIRECTORY-001H block plus minimum exact-label expectation updates.
    • one separately named 001H current-source hunk in each of SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, and SECURITY.md;
    • only the existing optional-directory Mermaid/one-sentence text alternative and one separately named 001H source-review procedure in docs/officers/EVENTS_SHOP_MEMBERS.md.

    Everything else is immutable: Account wiring/tests/CSS, admin finder, client services including the separate inbound-WebP finding, availability, Functions, Rules, indexes, packages, workflows, release controls, providers, data, sign-in, production/live behavior, #507 gates, and both #616 Strava files plus its OAUTH-001A2L/RISK-024 SECURITY hunk. No source edit preceded this marker. The claim remains active through reviewed merge, exact-main audit, closure, and explicit release.

  4. daliu commented on Aug 13, 2026

    @daliu
    ContributorAuthor

    RED/GREEN implementation evidence on exact base d5a218a3ceebdfa758067ae7510803c75564c3c0:

    • Trustworthy RED on the old runtime: the new ready-draft case failed because a confirmed saved-photo removal erased the separate local replacement preview.
    • GREEN current six-file candidate: the same current ready/reading draft identity survives only a confirmed remove plus authoritative readback; no upload occurs before explicit Save; later Save creates a new request and sends the same content type/bytes once with the refreshed revision. Unknown outcomes and failed post-mutation readbacks discard the draft/data URL and hide connected controls.
    • The action is now Remove current saved photo; one-shot focus resolves to current Remove, current ready Save, or the persistent file input.
    • Named MEMBERS-DIRECTORY-001H focused suite: 80/80 passed.
    • Full frontend Jest: 18 suites / 1,125 tests passed under Node 20.
    • TypeScript --noEmit, scoped ESLint, lint baseline (120 files / 113 reviewed legacy errors / 6 warnings), diagnostic production build, diff-check, and repository workflow/security/SPA Node suites (105/105) passed.
    • Three independent reviews are running/completing; frontend and security/privacy reviews are already GO with no findings.

    Availability remains byte-identical literal false; production remains the inert #623 release. No Firebase, provider, account, sign-in, production-data, deployment, or live connected action occurred.

  5. daliu commented on Aug 13, 2026

    @daliu
    ContributorAuthor

    CANDIDATE / PR MARKER: PR #634 is open at exact three-review-approved head 38fb2b79665510317aa8ab889627f6b89ece7ea4, tree 2cbc73167092d83a3d81155e9d3f520cc32b41e0, sole parent/base d5a218a3ceebdfa758067ae7510803c75564c3c0.

    Exact six-path binary diff SHA-256: e57f4962c73851f10f4a3e813e76fe6c8136e09fcfb958e0c15e055bfb7454e9.

    Local focused/full/type/lint/build/workflow gates are green. Independent security/privacy, frontend/accessibility, and backup-officer/operations reviews are GO with no findings. Hosted exact-head CI and preview checks are now pending.

    Availability remains hard false; live remains inert #623. No Firebase/provider/account/sign-in/data/deployment/connected action. #616 protected files/hunk are byte-identical. Claim remains active through exact-head CI, reviewed merge, exact-main/production-boundary audit, closure, and explicit release.

    PR: #634

  6. daliu commented on Aug 13, 2026

    @daliu
    ContributorAuthor

    COMPLETE/CLOSED/CLAIM RELEASED.

    PR #634 was admin squash-merged from exact reviewed head 38fb2b79665510317aa8ab889627f6b89ece7ea4 as exact main fd0988afc8f55869db3bd8e5f0a391de83b8c816. The reviewed and merged trees are identical at 2cbc73167092d83a3d81155e9d3f520cc32b41e0; the exact six-path binary diff SHA-256 remains e57f4962c73851f10f4a3e813e76fe6c8136e09fcfb958e0c15e055bfb7454e9.

    PR CI 31748099236 and exact-main CI 31748394119 passed all five required jobs. Netlify preview 6a7e3e66f69c0b00083c3301 is ready and unpublished; the exact-main production attempt 6a7e3f53a5cd00000855ffc6 errored unpublished. Netlify site readback still reports both deploy pointers at inert #623 deploy 6a7e072f8f346b0008510d29 / control 9d5cc8612b4321172370bd949d307e7e4ac0ec7d. The public #623 marker remains valid JSON with no-store/nosniff/HSTS and byte SHA-256 b74498854585346aa66c0341e29c829245445ce986806c3864cad526b267876f. GitHub deployment records contain no #633 deployment.

    The source-controlled availability boundary remains byte-identical and literal false. No Firebase, Functions, Rules, indexes, provider, account, sign-in, production-data, website publication, or connected/live member-directory action occurred. #507 retains every connection/release gate. Active #616 Strava blobs and its separate SECURITY OAUTH-001A2L/RISK-024 hunk remain byte-identical.

    All six #633 claims are released. The remote feature branch is absent.

  7. removed their assignment
    on Aug 13, 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 hostingpriority:P1High-priority follow-upsize:SSmall focused issuetype:featureProduct capabilitytype: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