Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ Exit gate:

**MEMBERS-DIRECTORY-001K current source boundary:** [#639](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/639) changes only inbound returned saved-photo admission in the preserved connected Account service. A photo's exact canonical base64 must decode to 12 through 65,536 bytes with `RIFF` at bytes 0–3 and `WEBP` at bytes 8–11, in addition to the existing exact object, MIME, dimensions, and version contract. A malformed response becomes only **Invalid member directory response.** without raw-byte, provider-value, or caught-detail output. The actual Account component-to-actual-service path, with only Firebase Functions mocked, proves mislabeled bytes stop before a saved-thumbnail image or data URL. Structurally admitted but browser-undecodable bytes retain the version-scoped, byte-free **Photo unavailable** fallback and **Remove current saved photo** action. Outbound JPG, PNG, and WebP upload admission and exact bytes remain unchanged. Availability stays `false`, so the default branch and live #623 preview remain inert. #639 changes no Account component, People finder, Function, Rule, index, schema, package, workflow, backend, provider, account, sign-in, production data, deployment, biometric processing, or connected/live behavior. #507 still owns privacy approval, scoped authorization, isolated staging, backend-first deployment/readback, the reviewed availability flip, connected publication, and live proof.

**MEMBERS-DIRECTORY-001L current source boundary:** [#641](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/641) changes only search-settlement keyboard focus in the preserved connected officer People finder. A valid explicit search records an intent only after request-ID creation admits `pending`, only when the persistent name input or Search button owns focus, and only as the exact operation symbol plus that origin. On that current operation's result-card, empty-result, or fixed-failure render, the intent is consumed: the already-focused origin is left alone; body, root, absent, or disconnected focus returns to the same now-enabled origin; and any other connected focus chosen during the request is preserved. Programmatic or outside-focused submit creates no intent. Editing and Clear remove obsolete intent; validation and request-ID failure never enter `pending`; and application change, administrator change, unmount, or stale resolution or rejection cannot move focus. Clear retains its existing zero-ID, zero-call disposal and input focus. The handoff creates no request ID, search, retry, Clear action, result, audit, service call, or data URL. Existing normalization, native pending controls, response and result behavior, privacy bounds, `AdminGuard`, and stale fences remain unchanged. Availability stays `false`, so the default branch and live #623 preview remain inert. #641 changes no data movement, page structure, Account path, service contract, Function, Rule, index, package, workflow, backend, provider, account, sign-in, production data, deployment, biometric processing, or connected/live behavior. #507 still owns privacy approval, scoped authorization, isolated staging, backend-first deployment/readback, the reviewed availability flip, connected publication, and live proof.

### Phase 5 — End-to-end qualification

**Issue:** TEST-001 plus final closure evidence from all prior phases
Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ These entries are implementation evidence, not a production risk-acceptance deci
| Source-only uncertain-change recovery containment for RISK-042 | MEMBERS-DIRECTORY-001I [#635](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/635) gives the preserved connected Account branch a component-lifetime uncertainty marker for an ordinary mutation failure or failed authoritative post-mutation readback. Failed and repeated **Reload settings** reads retain the fixed **We could not confirm that change** warning, keep photo and finder mutation controls hidden, and cannot restore discarded draft bytes or data URLs. A successful guarded authoritative profile read clears uncertainty and displays the returned state. Initial load failures and failed confirming reads after definitive mutation rejection remain generic unavailable; that generic message no longer globally promises **No setting was changed**. Reload creates no request ID or visibility, upload, or removal mutation. Generated-only tests cover repeated failures, eventual authoritative success, generic failures, zero mutation retries, discarded bytes, and stale application/account reload fences. | The marker preserves truthful uncertainty only within one mounted application-and-account component lifetime; it is not provider acknowledgement, durable mutation evidence, reconciliation, deletion proof, or authorization. Generic unavailable state deliberately does not infer whether a prior change occurred. The source-controlled availability value stays `false`, and live #623 remains inert. No data movement, page structure, service/server contract, Firebase, provider, account, sign-in, production data, deployment, or connected/live behavior changes. #507 still owns notice/retention approval, scoped authorization, protected authority, isolated staging, backend-first deployment/readback, the availability flip, connected publication, and live proof. Use no real name or photo. |
| Source-only recovery-focus containment for RISK-042 | MEMBERS-DIRECTORY-001J [#637](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/637) gives the preserved connected Account branch one explicit recovery-focus intent for a user-initiated uncertain mutation, failed authoritative post-mutation readback, or failed confirming read after definitive rejection. The intent is tied to the current mounted application-and-account lifetime. A Reload-created intent is additionally bound by the next load effect to that exact load identity. Only the matching current unavailable or unknown transition focuses the rendered **Reload settings** action. Repeated failed reloads focus each replacement action. Initial or background load failure has no intent and does not steal focus; successful authoritative reload clears the intent without redirecting focus to an unrelated ready control. Application change, account change, unmount, and stale completion remain focus-inert. Generated-only tests cover all three mutations, both readback-failure classes, repeated uncertain and generic reload failures, successful reload, outside focus, application/account changes, unmount, zero retry or request-ID creation, and the unchanged unavailable default. | Programmatic focus is accessibility state, not provider acknowledgement, authorization, durable reconciliation, deletion proof, or evidence that a stale load became current. It creates no service call, mutation, automatic retry, draft restoration, data URL, or new data flow. The source-controlled availability value stays `false`, and live #623 remains inert. No page structure, service/server contract, Function, Rule, index, Firebase or provider configuration, account, sign-in, production data, deployment, or connected/live behavior changes. #507 still owns notice/retention approval, scoped authorization, protected authority, isolated staging, backend-first deployment/readback, the availability flip, connected publication, and live proof. Use no real name or photo. |
| Source-only saved-photo response containment for RISK-042 | MEMBERS-DIRECTORY-001K [#639](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/639) makes the preserved connected Account service admit an inbound returned saved photo only when the existing exact object, `image/webp`, 256×256 dimensions, and UUID version contract contains canonical base64 that decodes to 12 through 65,536 bytes with `RIFF` at bytes 0–3 and `WEBP` at bytes 8–11. Any failure returns only **Invalid member directory response.** without rendering or logging raw bytes, a provider value, or caught detail. A real Account component-to-real-service test with only `firebase/functions` mocked proves mislabeled bytes stop before a saved-thumbnail image or data URL. Structurally admitted but browser-undecodable bytes retain the version-scoped, byte-free **Photo unavailable** fallback and enabled **Remove current saved photo** action without another callable. Outbound JPG, PNG, and WebP admission and exact bytes remain unchanged. | RIFF/WEBP markers are structural admission, not full decoding, safe image proof, authenticity, server-state proof, authorization, or provider acknowledgement; header-shaped hostile bytes can still reach the browser decoder, so the byte-free render fallback remains required. The source-controlled availability value stays `false`, and live #623 remains inert. No Function, Rule, index, schema, package, workflow, photo query, facial recognition, matching, embedding, similarity, biometric processing, Firebase or provider configuration, account, sign-in, production data, deployment, or connected/live behavior changes. #507 still owns notice/retention approval, scoped authorization, protected authority, isolated staging, backend-first deployment/readback, the availability flip, connected publication, and live proof. Use only generated non-face test bytes; do not inspect or upload a real photo. |
| Source-only search-focus containment for RISK-042 | MEMBERS-DIRECTORY-001L [#641](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/641) gives the preserved connected People finder one exact-operation focus intent after a valid query and request ID admit `pending`, and only when the persistent name input or Search button owns focus. Current result-card, empty-result, and fixed-failure settlement consumes the intent after render. The already-focused origin is left alone; body, root, absent, or disconnected focus returns to the same now-enabled origin; and another connected element focused during the request retains focus. Programmatic or outside-focused submit creates no intent. Editing, Clear, local validation failure, request-ID failure, application or administrator change, unmount, and stale resolution or rejection clear or fail the guards. Generated-only tests cover both origins and all three outcomes, deliberate outside focus, retained-origin focus, local failures, Clear, context changes, unmount, one exact request, and the unavailable default. | Programmatic focus is accessibility state, not authorization, search correctness, provider acknowledgement, audit proof, membership evidence, or live behavior. It stores no query, name, result, photo, account ID, request ID, or service value and creates no request ID, search, retry, Clear action, result, audit, service call, or data URL. Existing response/privacy bounds and name-only search plus human comparison of voluntary thumbnails remain unchanged; never add a photo query, face recognition, matching, embedding, similarity, biometric processing, totals, export, or roster authority. The source-controlled availability value stays `false`, and live #623 remains inert. No data movement, page structure, service/server contract, Function, Rule, index, Firebase or provider configuration, account, sign-in, production data, deployment, or connected/live behavior changes. #507 still owns notice/retention approval, scoped authorization, protected authority, isolated staging, backend-first deployment/readback, the availability flip, connected publication, and live proof. Use no real name or photo. |
| Immediate Product-binding containment part of RISK-031 | PAY-PRODUCT-001A is tracked in live [#353](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/353). One dependency-free projection is used by the paid race and Shop checkout paths. A present stored Product link must be an own primitive non-empty string from 1 through 255 JavaScript code units and is copied without trimming, conversion, character restrictions, or `prod_` inference. Only a genuinely missing own field retains the compatibility Product-create path. Before any mapping write, a resolved Product must provide a bounded custom ID, exact Product kind, expected declared mode, and an installed-SDK 2xx response marker. Malformed stored links stop before token, registration/order identifier, Product-link or business-record write, or Stripe work; earlier access and request-count checks and their safety-counter writes may already have run. Malformed created results stop after at most one Product attempt but before mapping, Checkout Session, or business-record writes. | This structural containment does not prove provider origin, Stripe account ownership, intended catalog identity, metadata binding, Product status, price, dispatch, delivery, or reconciliation. A rejected create result may leave an orphaned Product; do not retry automatically. Anonymous clean-missing creation remains concurrency-prone and reachable from public traffic. Complete #113 inventory/disposition, authenticated idempotent catalog synchronization, Product-specific plan/pre-send/result/lost-acknowledgement/reconciliation controls, isolated staging, protected Firebase deployment, and provider proof before live commerce. |
| Immediate current-handler containment part of RISK-003 | PAY-SESSION-001A is tracked in live [#357](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/357). The current paid race and Shop handlers build one immutable expectation before the Session call, catch rejection without opening it, and immediately project only a closed installed-SDK result. A result must match declared test/live mode, payment/open/unpaid state, exact cents, USD, buyer email, exact closed metadata, exact callbacks, a mode-compatible bounded Session ID, one canonical HTTPS capability at the hard-coded default `checkout.stripe.com` origin, and an installed-SDK 200 marker. Only copied ID/URL values continue; records store the ID but never the URL. Invalid results create no registration/order record and return one fixed unknown-result message. The website makes rejection or a missing paid URL terminal for that page visit, retains the form, and blocks a second direct handler call. | This is a narrow legacy compatibility stop, not trusted provider/account origin, deterministic business idempotency, dispatch/delivery proof, durable result evidence, payment proof, or adoption of the unused C4 chain. The Session call occurs first, so a rejected result may leave a payable orphan; earlier rate-counter, token/identifier, and lazy Product-mapping effects may remain. Reload, another tab/device, or a scripted caller bypasses the page lock. A configured Stripe custom checkout domain is blocked until #113 and a protected configuration boundary approve it. Complete PAY-002C/D persistence-first sagas, trusted C4 controller/result persistence, reconciliation, protected staging/deployment, provider readback, and exact website/Firebase/live proof. |
| Immediate pre-render browser containment part of RISK-003 | PAY-SESSION-001B is tracked in live [#503](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/503). Each current public race and Shop page now keeps one component-local in-memory marker. After existing local checks admit a request, the handler sets that marker synchronously before analytics or its first Checkout promise can settle. A same-action or later submission on that mounted page is inert, including the gap before React renders the existing pending disabled button. Focused actual-route tests prove one service/analytics attempt across same-action and post-render repeats; preserve free-participant, volunteer-without-price-tier, and both paid-link navigation branches; and prove local waiver/native-disabled paths do not consume an attempt. | This browser marker is not a server boundary, durable idempotency key, provider dispatch/result record, business-state lock, payment proof, or reconciliation. It never releases during the mounted page visit because the admitted result must navigate or enter #357's terminal unknown-result state. Existing form controls other than the submit button remain editable. Reload, a remount, another tab/device, a script, or a direct service caller can bypass it. A same-mounted route change instead stays locked, and this slice does not fence an older pending result from that changed route. Complete PAY-002C/D persistence-first deterministic commands, durable replay/reconciliation, protected deployment, and exact website/Firebase/Stripe/live proof. |
Expand Down
Loading