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, clearly mislabeled saved-thumbnail response bytes will be rejected before reaching the page, while structurally WebP bytes that the browser cannot display will keep the existing recoverable Photo unavailable fallback and Remove action.
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. The data-flow diagram does not change.
Deployment evidence: None at issue creation. This is source-only response-boundary 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
Validate structurally WebP saved-photo responses at the actual Account component→service boundary without changing outbound photo-upload semantics.
Defect
On exact released main 7877babc96c78f54d11685b4ffb91496c3bf6945, memberDirectoryService.ts validates returned profile photos for exact fields, image/webp, canonical bounded base64, 256×256 dimensions, and UUID version, but accepts arbitrary decoded bytes. The server stored-photo boundary and officer-search client additionally require at least 12 bytes with RIFF at bytes 0–3 and WEBP at bytes 8–11. Existing profile component tests mock the service, so they cannot prove malformed callable bytes stop before the Account DOM.
Invariant
Only an exact returned photo object with canonical decoded bytes between 12 and 65,536 bytes, RIFF at bytes 0–3, and WEBP at bytes 8–11 may become a MemberDirectoryProfile.photo.
Failure uses only the fixed Invalid member directory response. error; no raw bytes, provider values, filename, or caught detail is rendered or logged.
Structural admission is not full image decoding. Header-valid bytes may still fail browser decode; the existing version-scoped byte-free Photo unavailable fallback must replace the image while Remove current saved photo remains available.
The structural check applies only to returned saved-photo state. Outbound JPEG, PNG, and WebP upload admission and exact bytes remain unchanged.
The actual component→actual service→mocked firebase/functions bridge is tested in the existing service test file; no real Firebase/network/account/data access.
Availability stays false; the default branch remains inert and zero-call.
No photo query, facial recognition, matching, embedding, similarity, biometric processing, roster authority, or membership proof.
Exact ownership
src/services/account/memberDirectoryService.ts
only its private canonical-base64 helper return value and inbound returned-photo RIFF/WEBP structural admission.
one separately named MEMBERS-DIRECTORY-001K block covering the response matrix and a real MemberDirectoryProfile→actual service→mocked firebase/functions bridge; reuse this existing file, with no rename/new test file.
SYSTEM_DESIGN.md
one separately named 001K source-only paragraph.
IMPLEMENTATION_PLAN.md
one separately named 001K current-source paragraph.
Prove canonical non-RIFF outbound WebP upload bytes still reach the callable unchanged.
Through the real component and real service with only firebase/functions mocked, prove mislabeled bytes render the generic unavailable state and never create a saved-thumbnail img or data URL.
Through that bridge, prove admitted-but-browser-undecodable bytes initially reach the fixed-type saved image; a synthetic error then removes its data URL, renders the accessible Photo unavailable fallback, keeps Remove enabled, and creates no extra callable.
Default unavailable branch remains zero-context, zero-ID, and zero-call.
MemberDirectoryProfile.tsx and its mocked unit test, Account wiring/tests, CSS/layout, admin finder/search service, outbound upload semantics, or new test/lint-baseline files.
Functions, Rules, indexes, schemas, repair/backfill, packages, workflows, or release controls.
No migration. Client magic validation is structural admission, not full decoding, authenticity, server-state proof, provider authorization, or deployment evidence. Browser decode fallback remains necessary. #507 retains all connection/release gates.
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 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, clearly mislabeled saved-thumbnail response bytes will be rejected before reaching the page, while structurally WebP bytes that the browser cannot display will keep the existing recoverable Photo unavailable fallback and Remove action.
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. The data-flow diagram does not change.Deployment evidence: None at issue creation. This is source-only response-boundary 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
Validate structurally WebP saved-photo responses at the actual Account component→service boundary without changing outbound photo-upload semantics.
Defect
On exact released main
7877babc96c78f54d11685b4ffb91496c3bf6945,memberDirectoryService.tsvalidates returned profile photos for exact fields,image/webp, canonical bounded base64, 256×256 dimensions, and UUID version, but accepts arbitrary decoded bytes. The server stored-photo boundary and officer-search client additionally require at least 12 bytes withRIFFat bytes 0–3 andWEBPat bytes 8–11. Existing profile component tests mock the service, so they cannot prove malformed callable bytes stop before the Account DOM.Invariant
RIFFat bytes 0–3, andWEBPat bytes 8–11 may become aMemberDirectoryProfile.photo.Invalid member directory response.error; no raw bytes, provider values, filename, or caught detail is rendered or logged.Photo unavailablefallback must replace the image whileRemove current saved photoremains available.firebase/functionsbridge is tested in the existing service test file; no real Firebase/network/account/data access.Exact ownership
src/services/account/memberDirectoryService.tssrc/services/account/memberDirectoryService.test.tsMemberDirectoryProfile→actual service→mockedfirebase/functionsbridge; reuse this existing file, with no rename/new test file.SYSTEM_DESIGN.mdIMPLEMENTATION_PLAN.mdSECURITY.mddocs/officers/EVENTS_SHOP_MEMBERS.mdRequired tests
firebase/functionsmocked, prove mislabeled bytes render the generic unavailable state and never create a saved-thumbnailimgor data URL.Photo unavailablefallback, keeps Remove enabled, and creates no extra callable.Explicit exclusions
MemberDirectoryProfile.tsxand its mocked unit test, Account wiring/tests, CSS/layout, admin finder/search service, outbound upload semantics, or new test/lint-baseline files.Migration and residual risk
No migration. Client magic validation is structural admission, not full decoding, authenticity, server-state proof, provider authorization, or deployment evidence. Browser decode fallback remains necessary. #507 retains all connection/release gates.
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 audit, closure, and explicit release.