diff --git a/.github/lint-baseline.json b/.github/lint-baseline.json index b2019cb8..ca82b437 100644 --- a/.github/lint-baseline.json +++ b/.github/lint-baseline.json @@ -10,10 +10,10 @@ "targets": [ "src" ], - "scannedFileCount": 118, + "scannedFileCount": 119, "scannedFilesByExtension": { ".js": 12, - ".jsx": 34, + ".jsx": 35, ".ts": 42, ".tsx": 30 }, @@ -31,7 +31,7 @@ ".ts": 0, ".tsx": 6 }, - "fingerprint": "sha256:3eecd570ba0c4ada1a62f8a05be593a2ab81fa33d042654cfed303c7ac271791", + "fingerprint": "sha256:bda71336dd9fbb242334c9aaf7f2be6d58bc55814540f730d90fe4809ec7e829", "scannedFiles": [ "src/App.jsx", "src/App.test.jsx", @@ -106,6 +106,7 @@ "src/pages/shop/Shop.tsx", "src/pages/shop/merchCheckoutRequest.test.ts", "src/pages/shop/merchCheckoutRequest.ts", + "src/pages/suggestions/Suggestions.jsx", "src/reportWebVitals.js", "src/services/ServiceLocatorContext.ts", "src/services/ServiceLocatorProvider.tsx", diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index d046c1c2..e73e6dfd 100644 --- a/OPERATIONS_RUNBOOK.md +++ b/OPERATIONS_RUNBOOK.md @@ -267,7 +267,7 @@ node .github/scripts/check-frontend-lint.cjs node --test tests/test-artifact-safety.test.js ``` -The frontend Jest command is a dependable local baseline and hosted CI runs it as the blocking `Run frontend Jest tests` step under [#124](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/124). Hosted CI also runs the separate Node SPA suite as `Run SPA callback safety tests` under [#126](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/126). CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) adds the blocking `Commerce command journal emulator` job. That job uses exact demo project `demo-pay002b2-test`, Firestore only, an explicit opt-in, and the focused transaction suite. CI-001B4 [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) merged through [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`. It adds the named blocking `Run non-mutating frontend lint` step using the checker directly, before application tests can change its process environment. Its trusted prefix pins the hosted runner, read-only job permission, credential-free checkout, Node 20 setup, install with lifecycle scripts disabled, lint, and the immediately following clean check. With MEMBERS-DIRECTORY-001B [#506](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/506), the checker covers 118 frontend files: 12 JS, 34 JSX, 42 TS, and 30 TSX. The lint process disables the repository-wide `eslint-plugin-only-warn` hook so the original configured severities remain visible. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` record, CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record, and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) removes one prompt warning plus two label-association errors with the unsafe reusable-link controls. Reviewed functional changes in [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add three TypeScript files and retire four TSX errors. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) replaces exactly four stale `react-hooks/exhaustive-deps` directives with ordinary comments on the same lines and changes no executable code. MEMBERS-CONTENT-001B [#492](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/492) removes one finding-free dormant JSX file, #505 adds four finding-free TypeScript/TSX files, and #506 adds four more finding-free TypeScript/TSX files, leaving 113 configured errors and 6 warnings. This is accepted debt, not a clean-lint claim. Any finding added, removed, moved, or changed must be understood and the exact record updated in the same reviewed pull request; a fatal parser, configuration, or unexpected process failure always stops with one fixed diagnostic. Never regenerate the baseline only to make a check green. The clean-checkout step compares tracked files with `HEAD` and rejects non-ignored untracked files. Ignored dependency and build paths are outside this proof. The original #186 PR run `29291402007` and post-merge run `29291515653` passed the install, lint, clean, test, workflow-validation, build, Functions, Rules, commerce, and artifact jobs; each later focused issue records its separate source and hosted evidence. These runs prove source execution only: branch protection, production publication, Firebase, Stripe, and provider state remain unchanged. TEST-001A2 [#177](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/177) adds the exact `Test artifact scrubber` job. It deliberately creates bounded synthetic output and proves that the dependency-free scanner accepts reserved examples, rejects the documented recognizable sensitive patterns with fixed messages, ignores source outside an explicit output root, and protects both release job lists. Current CI uploads no test report. Later report-producing work must scan its explicit output before upload. A green scrubber proves only that this deliberate source test ran. It is not a general data-loss-prevention guarantee or proof that an unknown or newly obfuscated sensitive value is absent, that an artifact was uploaded, that all runtime logs are safe, or that Firebase, Stripe, the website, or another provider changed. The manual-release source invariants remain under [#135](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/135). Protected environment/OIDC configuration, actual staged/live deployment, branch-required-check configuration, and controlled Netlify publication remain **NOT AVAILABLE YET** under [#105](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/105), [#133](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/133), [#136](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/136), and WEB-001. +The frontend Jest command is a dependable local baseline and hosted CI runs it as the blocking `Run frontend Jest tests` step under [#124](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/124). Hosted CI also runs the separate Node SPA suite as `Run SPA callback safety tests` under [#126](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/126). CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) adds the blocking `Commerce command journal emulator` job. That job uses exact demo project `demo-pay002b2-test`, Firestore only, an explicit opt-in, and the focused transaction suite. CI-001B4 [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) merged through [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`. It adds the named blocking `Run non-mutating frontend lint` step using the checker directly, before application tests can change its process environment. Its trusted prefix pins the hosted runner, read-only job permission, credential-free checkout, Node 20 setup, install with lifecycle scripts disabled, lint, and the immediately following clean check. With WEB-SUGGESTIONS-001A [#618](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/618), the checker covers 119 frontend files: 12 JS, 35 JSX, 42 TS, and 30 TSX. The lint process disables the repository-wide `eslint-plugin-only-warn` hook so the original configured severities remain visible. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` record, CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record, and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) removes one prompt warning plus two label-association errors with the unsafe reusable-link controls. Reviewed functional changes in [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add three TypeScript files and retire four TSX errors. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) replaces exactly four stale `react-hooks/exhaustive-deps` directives with ordinary comments on the same lines and changes no executable code. MEMBERS-CONTENT-001B [#492](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/492) removes one finding-free dormant JSX file, #505 adds four finding-free TypeScript/TSX files, #506 adds four more finding-free TypeScript/TSX files, and #618 adds one finding-free JSX page, leaving 113 configured errors and 6 warnings. This is accepted debt, not a clean-lint claim. Any finding added, removed, moved, or changed must be understood and the exact record updated in the same reviewed pull request; a fatal parser, configuration, or unexpected process failure always stops with one fixed diagnostic. Never regenerate the baseline only to make a check green. The clean-checkout step compares tracked files with `HEAD` and rejects non-ignored untracked files. Ignored dependency and build paths are outside this proof. The original #186 PR run `29291402007` and post-merge run `29291515653` passed the install, lint, clean, test, workflow-validation, build, Functions, Rules, commerce, and artifact jobs; each later focused issue records its separate source and hosted evidence. These runs prove source execution only: branch protection, production publication, Firebase, Stripe, and provider state remain unchanged. TEST-001A2 [#177](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/177) adds the exact `Test artifact scrubber` job. It deliberately creates bounded synthetic output and proves that the dependency-free scanner accepts reserved examples, rejects the documented recognizable sensitive patterns with fixed messages, ignores source outside an explicit output root, and protects both release job lists. Current CI uploads no test report. Later report-producing work must scan its explicit output before upload. A green scrubber proves only that this deliberate source test ran. It is not a general data-loss-prevention guarantee or proof that an unknown or newly obfuscated sensitive value is absent, that an artifact was uploaded, that all runtime logs are safe, or that Firebase, Stripe, the website, or another provider changed. The manual-release source invariants remain under [#135](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/135). Protected environment/OIDC configuration, actual staged/live deployment, branch-required-check configuration, and controlled Netlify publication remain **NOT AVAILABLE YET** under [#105](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/105), [#133](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/133), [#136](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/136), and WEB-001. ### CI-001B5 Functions job credential boundary — SOURCE ONLY diff --git a/SECURITY.md b/SECURITY.md index 694413b7..98716425 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -84,7 +84,7 @@ The findings below describe the repository at the start of the 2026-07-12 assess | RISK-032 | `auditLog` arrays grow within primary documents and are editable by broad admins. | Move to append-oriented, immutable-by-client audit records with retention/export rules. | | RISK-033 | CSV export mitigates formula injection, but roster export has no explicit re-auth, download audit, row limit/streaming limit, or data-minimization profiles. | Add scoped exports, reason/re-auth, audit, minimum columns, safe filename IDs, and large-export controls. | | RISK-034 | Webhook error response includes the Stripe library's signature error detail. | Return generic client errors; keep sanitized structured diagnostics server-side. | -| RISK-035 | The deterministic frontend Jest suite and standalone SPA callback suite run as separate blocking hosted CI steps. CI-001B4/#186 merged a non-mutating frontend lint gate as `bec7d5e365eacb418563a172029f241f660d9768`; exact PR and post-merge runs passed. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` error, CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record, and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retires one `no-alert` warning plus two label-association errors with the unsafe reusable-link controls. Reviewed functional changes in [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add one and two TypeScript files respectively while retiring two TSX errors each. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) replaces the four remaining stale `react-hooks/exhaustive-deps` directives with ordinary same-line comments, without changing executable code or the gate. MEMBERS-CONTENT-001B [#492](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/492) removes one finding-free dormant JSX file. MEMBERS-DIRECTORY-001A [#505](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/505) adds four finding-free TypeScript/TSX files, and MEMBERS-DIRECTORY-001B [#506](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/506) adds four more. The current baseline scans 118 files and still records 113 configured errors and 6 warnings after the lint process disables the repository's severity-masking `eslint-plugin-only-warn` hook. Branch protection, remaining lint-debt cleanup, and broader domain/integration coverage remain incomplete. | Continue reducing the reviewed finding baseline in focused changes, prove required branch checks, and add domain/integration coverage. Never regenerate the baseline merely to make CI green. | +| RISK-035 | The deterministic frontend Jest suite and standalone SPA callback suite run as separate blocking hosted CI steps. CI-001B4/#186 merged a non-mutating frontend lint gate as `bec7d5e365eacb418563a172029f241f660d9768`; exact PR and post-merge runs passed. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` error, CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record, and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retires one `no-alert` warning plus two label-association errors with the unsafe reusable-link controls. Reviewed functional changes in [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add one and two TypeScript files respectively while retiring two TSX errors each. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) replaces the four remaining stale `react-hooks/exhaustive-deps` directives with ordinary same-line comments, without changing executable code or the gate. MEMBERS-CONTENT-001B [#492](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/492) removes one finding-free dormant JSX file. MEMBERS-DIRECTORY-001A [#505](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/505) adds four finding-free TypeScript/TSX files, and MEMBERS-DIRECTORY-001B [#506](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/506) adds four more. WEB-SUGGESTIONS-001A [#618](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/618) adds one finding-free JSX page. The current baseline scans 119 files and still records 113 configured errors and 6 warnings after the lint process disables the repository's severity-masking `eslint-plugin-only-warn` hook. Branch protection, remaining lint-debt cleanup, and broader domain/integration coverage remain incomplete. | Continue reducing the reviewed finding baseline in focused changes, prove required branch checks, and add domain/integration coverage. Never regenerate the baseline merely to make CI green. | | RISK-036 | #135 adds a manual exact-commit source gate, fixed profile-recovery targets, backend-first order, missing-config failure, and ordinary Git-triggered Netlify production containment. WEB-UX-001A [#457](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/457) used a temporary exact-artifact exception. On 2026-08-01 an overbroad WEB-002A artifact was merged after a late blocker and published; exact rollback merge `1099ee8` restored source `ed1b0833`, and `dee7951` paused the manifest. Bounded replacement [#473](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/473) then published exact source `39ab8649` as deploy `6a6dc9ea588b0c0008036312`; its delta is only Shop and Events/Calendar failure containment, and its public checks passed. Final control `cb6a8f0` made the manifest inactive; Netlify attempt `6a6dcdd47bc81e000859a249` stopped unpublished and left the bounded deploy live. Protected environments/OIDC, isolated staging, a reusable live-Netlify path, and provider-owned atomic rollback remain unverified. | Require a final blocker re-read and an executable delta from the live artifact before every release merge. Preserve the exact #473 marker and rollback evidence, keep ordinary publication paused, and keep the reviewed Git rollback projection available. Complete #133 and #136, provision isolated staging, protect the reusable Netlify release path under WEB-001, and rehearse provider rollback before broader production work. | | RISK-037 | Account/registration deletion, export, retention, backup, and restore procedures are incomplete. | Approve retention matrix, automate minimization, support access/deletion requests, and test backup restoration. | | RISK-038 | Source-controlled secret scan is ad hoc; no continuous secret scanner, dependency update bot, SBOM, provenance, or branch protection is documented. | Add secret/dependency/code scanning, reviewed lockfile updates, protected environments/branches, and artifact provenance appropriate to project scale. | @@ -145,7 +145,7 @@ These entries are implementation evidence, not a production risk-acceptance deci | RISK-009, part of RISK-024 | OAUTH-001C1J [#612](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/612) browser source admits a fulfilled Strava exchange result only when it presents exactly two own fields, each an enumerable data field: primitive `ok` equal to `true` and a positive safe-integer `athleteId`. It returns a fresh frozen confirmation. Every other fulfillment or exceptional result inspection throws one fixed local response error; a current callback uses the existing fixed failure screen without navigating, while existing lifecycle guards keep obsolete completions inert. Callable transport rejection remains uninspected and identity-preserving. Browser JavaScript cannot distinguish a transparent Proxy that faithfully presents the contract, so the received object is never retained. The check relies on the page realm's built-in reflection, numeric, and freeze methods; code that replaces those methods before admission can change what this browser-only boundary observes. Synthetic tests use no real callback, account, token, provider, or Firebase project. | This client acknowledgement check does not prove Strava origin, provider exchange, paired Firestore persistence, athlete ownership, approved scopes, server integrity, Firebase or website deployment, or live behavior. A compromised server or browser realm can forge the exact result. Provider response-byte and timeout limits, scope/account policy, provider/local reconciliation, audit, IAM/encryption, configured Enterprise evidence, native enforcement, release order, and provider/live proof remain open under [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88). | | RISK-017, part of RISK-024 | OAUTH-001A2K [#614](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/614) Function source admits a successful Strava authorization-exchange or refresh body only through the captured native Node `Response`, `Headers`, and stream-reader methods. It permits at most 65,536 content-decoded bytes and 4,096 chunks before copy, treats a valid `Content-Length` only as an early ceiling check, counts the actual chunks even when that header is missing or lower, best-effort cancels an unfinished failure without awaiting or exposing cleanup, then uses fatal UTF-8 decoding and captured JSON parsing before the existing strict projector. It never calls the response's `json`, `text`, `arrayBuffer`, or `bytes` method, clone, or tee. Invalid body transport/parsing keeps the existing fixed unavailable result; a bounded invalid schema keeps the fixed internal result. Exchange state stays consumed but no token/connection write follows a body failure; refresh keeps the prior secret and starts no bearer data request. The direct projector seam remains absent from `functions/index.js` and preserves hostile-JavaScript tests that real JSON bytes cannot construct. Synthetic tests use no real token, account, provider, or Firebase project. | This application ceiling covers only content-decoded chunks consumed by this source. It does not bound headers, compressed-wire bytes, Undici buffers, one already-allocated provider chunk, parsed-object heap growth, CPU, or request/connect/read time. Cancellation cannot undo a provider exchange or rotation, so a lost acknowledgement can still require reconciliation and must not be retried blindly. Activities/statistics response bounds and their concurrently started body cleanup remain open, as do scope/account policy, refresh/revoke reconciliation, audit, IAM/encryption, Firebase deployment, provider configuration, production data, and provider/live proof under [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88). | | Part of RISK-027 | #99 blocks App Check, Firebase Analytics, and Sentry in local/test and on initial capability-callback startup. OBS-001A1 [#134](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/134) source disables Sentry replay, tracing, browser session tracking, client reports, member user context, breadcrumbs, attachments, transactions, and unapproved default integrations. OBS-001A2 [#139](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/139) source removes every application runtime Firebase Analytics import, initialization, and emission, preserves existing wrapper calls as provider-free no-ops, and removes the direct Waiver SDK bypass. OBS-001A3 [#142](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/142) routed the remaining render, Auth-email, members-only, and App Check browser diagnostics through five fixed outcome identifiers and prohibited direct console calls elsewhere in application/public runtime source. OBS-001A5 [#494](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/494) removes the dormant members-only identifier after its sole caller was retired, leaving the current helper with four fixed outcomes and requiring the old literal to be dropped as unknown input. Synthetic tests use mocks/canaries and make no provider call. | #110/#111 still own any future approved telemetry purpose, consent, event/parameter schema, provider settings, and residual hosted boundary. Source/tests and merge evidence do not prove website publication, the exact `runmprc.com` revision, provider transport/collection, IP/cookie behavior, console history, historical data deletion, retention, access, consent, deletion, or vendor terms. Sentry provider behavior is likewise unverified. #443 completes only the source/test Strava client handoff; native enforcement and the DATA-001A confirmation handoffs remain with ABUSE-001A and their canonical trackers. | -| Part of RISK-035 | The Jest environment is repaired, #124 adds the complete frontend suite as a named blocking hosted step, and #126 adds the standalone SPA callback suite. CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) merged the lockfile-bound Node 20/Java 17 `Commerce command journal emulator` job using exact demo project `demo-pay002b2-test`, Firestore only, and explicit opt-in. CI-001B4 [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) merged through [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`, adding the no-new-dependency exact-record checker, named blocking lint step, and clean-checkout step. Exact PR run `29291402007` and post-merge run `29291515653` passed every GitHub job. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227), CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239), and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retire four errors and one warning in focused reviewed changes. [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add three TypeScript files while retiring four TSX errors during reviewed functional work. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) retires exactly four stale unknown-rule directive records with comment-only same-line substitutions. #492 removes one finding-free dormant JSX file, #505 adds four finding-free TypeScript/TSX files, and #506 adds four more. | The checker now scans 118 frontend files. Its reviewable baseline deliberately records 113 configured errors and 6 warnings as individual file/line/column/rule/message records; it is not a clean-lint claim. Any added, removed, moved, or changed record requires review, every fatal parser/configuration failure rejects with a fixed diagnostic, and the baseline must not be regenerated just to pass. The clean check covers tracked and non-ignored untracked files; ignored dependency/build outputs are outside this proof. Hosted source checks do not configure branch protection, deploy Firebase, or prove Stripe/live behavior. #169, #173, #182, #206, #226, #232, and #238 expand the focused commerce suite; configure/prove branch-required checks and add the broader TEST-001 suite. | +| Part of RISK-035 | The Jest environment is repaired, #124 adds the complete frontend suite as a named blocking hosted step, and #126 adds the standalone SPA callback suite. CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) merged the lockfile-bound Node 20/Java 17 `Commerce command journal emulator` job using exact demo project `demo-pay002b2-test`, Firestore only, and explicit opt-in. CI-001B4 [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) merged through [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`, adding the no-new-dependency exact-record checker, named blocking lint step, and clean-checkout step. Exact PR run `29291402007` and post-merge run `29291515653` passed every GitHub job. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227), CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239), and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retire four errors and one warning in focused reviewed changes. [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add three TypeScript files while retiring four TSX errors during reviewed functional work. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) retires exactly four stale unknown-rule directive records with comment-only same-line substitutions. #492 removes one finding-free dormant JSX file, #505 adds four finding-free TypeScript/TSX files, and #506 adds four more; #618 adds one finding-free JSX page. | The checker now scans 119 frontend files. Its reviewable baseline deliberately records 113 configured errors and 6 warnings as individual file/line/column/rule/message records; it is not a clean-lint claim. Any added, removed, moved, or changed record requires review, every fatal parser/configuration failure rejects with a fixed diagnostic, and the baseline must not be regenerated just to pass. The clean check covers tracked and non-ignored untracked files; ignored dependency/build outputs are outside this proof. Hosted source checks do not configure branch protection, deploy Firebase, or prove Stripe/live behavior. #169, #173, #182, #206, #226, #232, and #238 expand the focused commerce suite; configure/prove branch-required checks and add the broader TEST-001 suite. | | DATA-001A3 / registration confidentiality | DATA-001A3 [#374](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/374) limits the My Account registration callable to one exact stored-UID query. Source no longer reads token email or verification claims and no longer searches registrations by runner email. Matching-email records with no UID or another account's UID are excluded; exact-UID records retain their existing sanitized summary, event lookup, and sort. The page's empty result says only that no upcoming registration is linked and that a signed-out registration may not appear. Synthetic tests use getter and Proxy canaries and make no write or provider call. | This source containment is not deployed or live and does not associate, migrate, repair, or change a registration. Anonymous, historical, mistyped-email, shared-email, and differently owned records stay hidden until a separately approved, audited server association under [#115](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/115). Keep the email index until separate inventory and migration review. Complete protected Function deployment/readback, website publication, exact `runmprc.com` verification, and a made-up account check before describing the boundary as live. | | DATA-001A4 / registration response minimization | DATA-001A4 [#553](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/553) removes the unused nested runner projection from the exact-UID My Account registration response and its browser type. Source does not access the matching document's `runner` property or serialize runner name, email, or shirt size; it preserves every non-runner registration field, the event summary, event reads, registration-created sort, and empty result. A synthetic accessor-backed record proves the runner property is untouched and invented canaries do not cross the response. | This source is not deployed or live. The Function still retrieves the complete matching registration document from Firestore, and stored runner data plus separate event, admin, and confirmation contracts remain unchanged. This slice makes no retention, deletion, field-mask, schema, association, or migration decision. Complete a protected Function deployment/readback and made-up account check before describing the narrower response as live. | | DATA-001A5 / registration-query failure containment | DATA-001A5 [#560](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/560) catches without binding any exceptional Firestore construction, collection-group, exact-UID `where`, or query `get` outcome and returns only fixed `unavailable / Registration data could not be loaded.` before registration projection or event reads. Synthetic stage failures prove that no caught-value getter, coercion, serialization, formatting hook, or application logger is reached while App Check/Auth and successful query behavior stay unchanged. | This source is not deployed or live. It does not contain exceptional registration snapshot iteration/projection or event-document reads, change stored data or field retrieval, add retries, or prove Firebase logging outside application code. Complete a protected Function deployment/readback and made-up account check before describing the fixed boundary as live; harden later data/event failure stages separately. | diff --git a/docs/CONTENT_GUIDE.md b/docs/CONTENT_GUIDE.md index e3c494b8..4b59ff00 100644 --- a/docs/CONTENT_GUIDE.md +++ b/docs/CONTENT_GUIDE.md @@ -16,6 +16,7 @@ | Shop | Firestore product records plus `src/pages/shop/` | Live commerce is not approved. | | Committee | `src/text/Committee.js`, `src/pages/officers/Committee.jsx`, `src/images/committee/` | Names/titles and duplicate search metadata live in the component. | | Contact | `src/text/ContactUs.js`, `src/pages/contact/Contact.jsx`, `src/images/contact/` | Some text and email parts are hardcoded. | +| Suggestions — **SOURCE ONLY, NOT LIVE** | `src/pages/suggestions/Suggestions.jsx`, `src/pages/suggestions/suggestions.css` | Information page only: no suggestion form, record, or suggestion-specific service or provider. It opens Contact; any email is a separate existing channel. Exact copy requires communications and privacy/security approval. | | Footer | `src/text/Footer.js`, footer components | Legal/privacy-style wording requires an approved source. | | Forms, map, and social links | `src/text/externalLinks.js` | Use public view/submission links, never private edit links. | | Terms and Privacy | `src/pages/legal/` | Do not ask AI to invent policy. Require approved owner text. | diff --git a/docs/officers/SYSTEM_MAPS.md b/docs/officers/SYSTEM_MAPS.md index fb09d3d8..ac0cdf74 100644 --- a/docs/officers/SYSTEM_MAPS.md +++ b/docs/officers/SYSTEM_MAPS.md @@ -17,6 +17,8 @@ flowchart TD Site --> Shop["Shop pickup catalog — LIVE; no online ordering"] Site --> Committee["Committee"] Site --> Contact["Contact Us"] + Site --> Suggestions["Suggestions — source only, not live"] + Suggestions --> Contact Site --> Account["Login and Account"] Account --> AuthAction["Verification link page — source only, not live"] Site --> Legal["Terms and Privacy"] @@ -24,8 +26,11 @@ flowchart TD ``` In words: public information, account/admin pages, and unfinished commerce -screens share one website; the live Shop pickup catalog creates no order or -payment, and seeing any screen does not mean it is approved for live commerce. +screens share one website; in source only, Suggestions is a public information +page with no form or suggestion record, opens the existing Contact page, and +treats any later email as a separate existing channel, while the live Shop +pickup catalog creates no order or payment and seeing any screen does not mean +it is approved for live commerce. ## Where information lives diff --git a/docs/officers/UPDATE_PUBLIC_CONTENT.md b/docs/officers/UPDATE_PUBLIC_CONTENT.md index 64e10961..ad85b146 100644 --- a/docs/officers/UPDATE_PUBLIC_CONTENT.md +++ b/docs/officers/UPDATE_PUBLIC_CONTENT.md @@ -29,6 +29,69 @@ Helpful request: 5. Ask AI to find every visible place using the old link. 6. Test each changed button from the preview. +## Suggestions page no-form preview — SOURCE ONLY, NOT LIVE + +**Purpose:** confirm that the Suggestions source shows only approved public +information and opens the existing Contact page without adding an intake form. +This procedure checks display of approved wording. It does not approve or change +privacy or security policy. + +**Approver:** communications lead and privacy/security owner. + +**Before you start:** have the exact #618 pull request and preview link, plus the +approved Suggestions wording. Stay signed out. Use phone and computer widths. +Use no real suggestion, security evidence, or private information. Do not +activate the email control on Contact. + +1. Open the exact `/suggestions` preview while signed out at a phone-sized width. +2. Confirm that the address ends in `/suggestions`. +3. Confirm that the page has one **Suggestions** heading. +4. Confirm that the browser title identifies Suggestions. +5. Compare the safety wording with the approved text. +6. Confirm that the page says it has no suggestion form and submits no idea. +7. Confirm that the email-retention disclosure identifies Contact as a separate existing channel. +8. Confirm that the page promises no anonymity, confidentiality, reply, or implementation. +9. Confirm that there is no textbox, upload, submit button, vote, or public idea list. +10. Use Tab to reach **Go to Contact**. +11. Confirm that focus is visible. +12. Press Enter. +13. Confirm that `/contact` opens. +14. Do not activate the email control on Contact. +15. Open the same preview at a normal computer width. +16. Use the footer **Suggestions** link. +17. Confirm that `/suggestions` opens. +18. Confirm that no content is clipped or hidden. + +**Expected result:** the source preview shows fixed public information and one +internal Contact action only. It creates no suggestion intake. This check does +not prove that the mailbox is monitored, that an email is delivered or retained +for a defined period, that a reply occurs, or that the page is live. + +**Stop conditions:** stop if the Suggestions page adds a form, external intake, +or direct email link; makes an anonymity, confidentiality, reply, or +implementation promise; requests private information or security evidence; +diverges from the current `SECURITY.md` first-contact direction; requires +sign-in; performs a provider action; opens the wrong route; hides keyboard +focus; clips content; or changes the public website unexpectedly. + +**Success proof:** record the exact reviewed head, preview URL, check date, +phone and computer widths, route, heading, title, no-form checklist, keyboard +result, and pass or fail. Use redacted screenshots only. + +**Undo:** reject the pull request before merge, or ask the platform maintainer +for one revert pull request after merge. No provider action or data cleanup is +needed for this source-only page. + +**Escalation:** communications lead for wording; privacy/security owner for +safety language; platform owner and accessibility reviewer for route, focus, or +layout failures. + +Source, tests, merge, website publication, `runmprc.com` verification, +Firebase deployment, outside-provider configuration, and production behavior +are separate states. This procedure describes #618 source and preview behavior +only. It is **NOT LIVE** until an approved exact website release is published +and the same checks pass on `runmprc.com`. + ## Photos 1. Get permission to publish the photo. diff --git a/public/index.html b/public/index.html index 1fd92068..341bc276 100644 --- a/public/index.html +++ b/public/index.html @@ -7,28 +7,28 @@ -
Help improve the club
++ We welcome short ideas about club runs, events, communications, + accessibility, and the website. +
+ ++ This page does not submit or store your suggestion. It has no + suggestion form or suggestion-specific tracking. Open Contact and + choose its email link if you want to send an idea. +
++ If you send an email, your email service and the club's existing + email service may retain your address and message. The Contact email + is not anonymous or confidential. +
++ Do not include passwords or verification codes, payment details, + private member information, health information, emergency-contact + details, or vulnerability evidence. +
++ For a security or privacy problem, use Contact and write + {' '} + security report + . Ask for a secure reply. Keep secrets, private records, payment + references, and exploit details out of an ordinary suggestion. +
++ We may not reply, and sending an idea does not promise that it will be + implemented. +
+ + + Go to Contact + +