From 9becaadc91b75790bdc00dda1fbd9976ae448394 Mon Sep 17 00:00:00 2001 From: Dave Liu <7david12liu@gmail.com> Date: Wed, 22 Jul 2026 05:00:45 -0700 Subject: [PATCH] CI-001B4C: retire stale hook lint directives (#449) --- .github/lint-baseline.json | 58 +------------------ GITHUB_ISSUES.md | 4 +- GITHUB_ISSUE_SLICES.md | 2 +- OPERATIONS_RUNBOOK.md | 2 +- SECURITY.md | 4 +- .../admin/events/AdminEventRegistrations.tsx | 2 +- src/pages/admin/shop/AdminOrders.tsx | 2 +- src/pages/events/EventRegister.tsx | 2 +- src/pages/shop/ProductDetail.tsx | 2 +- tests/ci-workflow.test.js | 2 +- 10 files changed, 14 insertions(+), 66 deletions(-) diff --git a/.github/lint-baseline.json b/.github/lint-baseline.json index 54e7a4d..c1b2e7a 100644 --- a/.github/lint-baseline.json +++ b/.github/lint-baseline.json @@ -17,13 +17,13 @@ ".ts": 38, ".tsx": 26 }, - "errorCount": 117, + "errorCount": 113, "warningCount": 6, "errorsByExtension": { ".js": 2, ".jsx": 26, ".ts": 2, - ".tsx": 87 + ".tsx": 83 }, "warningsByExtension": { ".js": 0, @@ -31,7 +31,7 @@ ".ts": 0, ".tsx": 6 }, - "fingerprint": "sha256:56b52a74434e910548d72c741ab21b634274d3cc9c36fe9983d8942b34eebddf", + "fingerprint": "sha256:80b91bb22c70f5f0d400703f8d79cda64c7b42ba3e2a33c91f67435d7a8adf52", "scannedFiles": [ "src/App.jsx", "src/App.test.jsx", @@ -627,19 +627,6 @@ "nodeType": "ConditionalExpression", "fatal": false }, - { - "file": "src/pages/admin/events/AdminEventRegistrations.tsx", - "line": 430, - "column": 3, - "endLine": 430, - "endColumn": 58, - "severity": 2, - "ruleId": "react-hooks/exhaustive-deps", - "message": "Definition for rule 'react-hooks/exhaustive-deps' was not found.", - "messageId": null, - "nodeType": null, - "fatal": false - }, { "file": "src/pages/admin/events/AdminEventRegistrations.tsx", "line": 586, @@ -718,19 +705,6 @@ "nodeType": "JSXOpeningElement", "fatal": false }, - { - "file": "src/pages/admin/shop/AdminOrders.tsx", - "line": 85, - "column": 3, - "endLine": 85, - "endColumn": 58, - "severity": 2, - "ruleId": "react-hooks/exhaustive-deps", - "message": "Definition for rule 'react-hooks/exhaustive-deps' was not found.", - "messageId": null, - "nodeType": null, - "fatal": false - }, { "file": "src/pages/admin/shop/AdminOrders.tsx", "line": 102, @@ -1121,19 +1095,6 @@ "nodeType": "JSXSpreadAttribute", "fatal": false }, - { - "file": "src/pages/events/EventRegister.tsx", - "line": 127, - "column": 3, - "endLine": 127, - "endColumn": 58, - "severity": 2, - "ruleId": "react-hooks/exhaustive-deps", - "message": "Definition for rule 'react-hooks/exhaustive-deps' was not found.", - "messageId": null, - "nodeType": null, - "fatal": false - }, { "file": "src/pages/events/EventRegister.tsx", "line": 276, @@ -1628,19 +1589,6 @@ "nodeType": "JSXText", "fatal": false }, - { - "file": "src/pages/shop/ProductDetail.tsx", - "line": 51, - "column": 3, - "endLine": 51, - "endColumn": 58, - "severity": 2, - "ruleId": "react-hooks/exhaustive-deps", - "message": "Definition for rule 'react-hooks/exhaustive-deps' was not found.", - "messageId": null, - "nodeType": null, - "fatal": false - }, { "file": "src/pages/shop/ProductDetail.tsx", "line": 142, diff --git a/GITHUB_ISSUES.md b/GITHUB_ISSUES.md index e704158..8b31e99 100644 --- a/GITHUB_ISSUES.md +++ b/GITHUB_ISSUES.md @@ -140,12 +140,12 @@ Do not redesign routing or hosting in this issue; WEB-001 owns that. Optimized p ## CI-001 — Repair test gates and secure the deployment pipeline **Labels:** `priority:P0`, `type:security`, `type:testing`, `area:ci`, `size:L`, `needs-external-config` -**Status:** Published as tracker [#105](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/105). [#103](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/103), [#124](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/124), and [#126](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/126) provide the local/hosted frontend and SPA baselines. CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) owns the dedicated hosted command-journal Firestore transaction gate. 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 exact main `bec7d5e365eacb418563a172029f241f660d9768`; exact PR run `29291402007` and post-merge run `29291515653` passed. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) and CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) are focused reductions of that exact lint ledger. PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) removes one obsolete prompt warning and two label errors with the unsafe controls themselves. The gate now records 108 files, 121 configured errors, and 6 warnings. [#135](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/135) owns the manual exact-commit, backend-first source gate and Git-triggered Netlify production containment. [#133](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/133) owns protected OIDC/environment configuration, and [#136](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/136) owns the actual profile-recovery release. Branch-required-check configuration, scanning, staging/live evidence, remaining lint-debt cleanup, and protected Netlify publication remain open, so the pipeline is still non-compliant overall. +**Status:** Published as tracker [#105](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/105). [#103](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/103), [#124](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/124), and [#126](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/126) provide the local/hosted frontend and SPA baselines. CI-001B3 [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167) owns the dedicated hosted command-journal Firestore transaction gate. 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 exact main `bec7d5e365eacb418563a172029f241f660d9768`; exact PR run `29291402007` and post-merge run `29291515653` passed. 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) are focused reviewed reductions of that ledger. [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 functional work. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) retires four stale unknown-rule directive records through comment-only same-line substitutions. The gate now records 111 files, 113 configured errors, and 6 warnings. [#135](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/135) owns the manual exact-commit, backend-first source gate and Git-triggered Netlify production containment. [#133](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/133) owns protected OIDC/environment configuration, and [#136](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/136) owns the actual profile-recovery release. Branch-required-check configuration, scanning, staging/live evidence, remaining lint-debt cleanup, and protected Netlify publication remain open, so the pipeline is still non-compliant overall. **Depends on:** SAFETY-001 ### Problem -Before #103, frontend tests failed because the Jest environment lacked `TextEncoder`. That child repaired the local baseline, and #124 adds it to hosted CI. #167 adds a separate named Node 20/Java 17 job for the PAY-002B2A Firestore transaction suite and makes both protected-release CI reads require it. The job uses one explicit demo project, Firestore only, committed lockfiles, and no cloud/provider authority. CI-001B4/#186 replaces the mutating, ignored `lint:fix` step with a blocking exact-record check that initially covered 102 JS/JSX/TS/TSX files. The same gate now scans 108 files. It disables the repository-wide severity-masking `eslint-plugin-only-warn` hook inside the lint process. CI-001B4A/#227 removes exactly one reviewed `arrow-body-style` record without changing the rule or gate. CI-001B4B/#239 removes exactly one stale `AdminMembers` unknown-rule suppression record without changing executable statements, the rule set, or the gate. PAY-004C1/#359 removes one `no-alert` warning and two label-association errors by removing the obsolete reusable-link prompt and amount/tier controls, leaving 121 configured errors and 6 warnings as reviewable individual records. Any added, removed, moved, or changed record and every fatal parser/configuration failure rejects with one fixed diagnostic. The checker runs directly before application tests in an exact prefix that pins the hosted runner, read-only permission, credential-free checkout, Node version, lifecycle-disabled install, lint, and adjacent clean check. Global overrides and prefix changes reject. The clean check compares tracked files with `HEAD` plus non-ignored untracked files; ignored dependency/build paths are outside that proof. This is an explicit debt baseline, not a clean-lint claim. #135 removes the automatic/fail-open release source defects: merge and release are separate, exact CI checks are re-read, release targets are fixed, OIDC replaces JSON-key wiring, lockfile tooling is used, backend precedes Pages, and Git-triggered Netlify production builds stop. The protected identity/environments and actual staged/live release remain outside that source slice. +Before #103, frontend tests failed because the Jest environment lacked `TextEncoder`. That child repaired the local baseline, and #124 adds it to hosted CI. #167 adds a separate named Node 20/Java 17 job for the PAY-002B2A Firestore transaction suite and makes both protected-release CI reads require it. The job uses one explicit demo project, Firestore only, committed lockfiles, and no cloud/provider authority. CI-001B4/#186 replaces the mutating, ignored `lint:fix` step with a blocking exact-record check that initially covered 102 JS/JSX/TS/TSX files. It disables the repository-wide severity-masking `eslint-plugin-only-warn` hook inside the lint process. CI-001B4A/#227 removes exactly one reviewed `arrow-body-style` record without changing the rule or gate. CI-001B4B/#239 removes exactly one stale `AdminMembers` unknown-rule suppression record without changing executable statements, the rule set, or the gate. PAY-004C1/#359 removes one `no-alert` warning and two label-association errors by removing the obsolete reusable-link prompt and amount/tier controls. Intervening reviewed source additions expanded coverage from 102 to 108 files by #359. PR #391 then adds one TypeScript file and removes two TSX errors; PR #392 adds two TypeScript files and removes two more TSX errors. CI-001B4C/#449 replaces the four remaining stale `react-hooks/exhaustive-deps` directives with ordinary same-line comments, preserving every executable statement and dependency array. The gate therefore scans 111 files and records 113 configured errors and 6 warnings as reviewable individual records. Any added, removed, moved, or changed record and every fatal parser/configuration failure rejects with one fixed diagnostic. The checker runs directly before application tests in an exact prefix that pins the hosted runner, read-only permission, credential-free checkout, Node version, lifecycle-disabled install, lint, and adjacent clean check. Global overrides and prefix changes reject. The clean check compares tracked files with `HEAD` plus non-ignored untracked files; ignored dependency/build paths are outside that proof. This is an explicit debt baseline, not a clean-lint claim. #135 removes the automatic/fail-open release source defects: merge and release are separate, exact CI checks are re-read, release targets are fixed, OIDC replaces JSON-key wiring, lockfile tooling is used, backend precedes Pages, and Git-triggered Netlify production builds stop. The protected identity/environments and actual staged/live release remain outside that source slice. ### Scope diff --git a/GITHUB_ISSUE_SLICES.md b/GITHUB_ISSUE_SLICES.md index a5ba1da..f7144da 100644 --- a/GITHUB_ISSUE_SLICES.md +++ b/GITHUB_ISSUE_SLICES.md @@ -21,7 +21,7 @@ An agent-ready child has one observable outcome, one trust boundary, explicit de | CI-001B1A | merged/closed as #126; #99 and CI-001B1 | Run the standalone same-origin SPA callback suite as a separate blocking hosted frontend step. | Local deliberate-failure proof plus the named hosted step passing on the exact pull-request and post-merge commits; no provider callback claim. | | CI-001B2 | published as #135; CI-001B1 | Provide the tested manual exact-commit source gate: fixed Rules/Functions, lockfile CLI, pinned Actions, short-lived-auth wiring, backend-first Pages dependency, missing-config failure, no frontend credential, and Netlify Git-production containment. | Source/static negative tests and exact PR evidence. #133 separately owns protected OIDC/environment configuration; #136 owns staged/target release; WEB-001 owns protected Netlify publication. | | CI-001B3 | source/tests tracked in live [#167](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/167); PAY-002B2A/#165 | Run the dedicated command-journal Firestore transaction suite as one named blocking Node 20/Java 17 job with exact demo project, explicit opt-in, Firestore-only scope, committed tooling, and no secrets/provider authority; require it at both protected-release CI reads. | Static negative workflow tests plus exact pull-request and post-merge hosted six-test evidence; no Firebase deployment, Stripe, website, or live claim. | -| CI-001B4 | merged/closed through [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) / [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`; focused debt reductions tracked in [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227), [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239), and functional removal in [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359); CI-001B1 | Replace the mutating fail-open frontend lint line with a named blocking JS/JSX/TS/TSX exact-record gate. The original gate covered 102 files with 125 configured errors and 7 warnings; it now scans 108 files. #227 removes one reviewed `arrow-body-style` error, #239 removes one stale `AdminMembers` suppression error, and #359 removes one prompt warning plus two label errors by deleting the unsafe reusable-link controls, leaving 121 errors and 6 warnings. Disable the repository-wide severity-masking hook inside the lint process. Any added, removed, moved, or changed record and every fatal parser/configuration failure rejects with a fixed diagnostic; lint may not rewrite tracked files or create non-ignored untracked files. | Exact #186 PR run `29291402007` and post-merge run `29291515653` passed lifecycle-disabled install, direct lint, clean proof, tests, and build; #227, #239, and #359 record their separate source/hosted evidence on their live issues. Ignored dependency/build paths remain outside this proof, with no clean-lint, branch-protection, deployment, website, Firebase, or provider claim. | +| CI-001B4 | merged/closed through [#186](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/186) / [PR #189](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/189) as `bec7d5e365eacb418563a172029f241f660d9768`; focused debt reductions tracked in [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227), [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239), functional removal in [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359), functional/file-count 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), and CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449); CI-001B1 | Replace the mutating fail-open frontend lint line with a named blocking JS/JSX/TS/TSX exact-record gate. The original gate covered 102 files with 125 configured errors and 7 warnings. #227 removes one reviewed `arrow-body-style` error, #239 removes one stale `AdminMembers` suppression error, and #359 removes one prompt warning plus two label errors by deleting the unsafe reusable-link controls. Intervening reviewed source additions expanded coverage to 108 files by #359. PR #391 adds one TypeScript file and removes two TSX errors; PR #392 adds two TypeScript files and removes two more TSX errors. #449 replaces the four remaining stale `react-hooks/exhaustive-deps` directives with ordinary comments on the same lines. The gate now scans 111 files with 113 errors and 6 warnings. Disable the repository-wide severity-masking hook inside the lint process. Any added, removed, moved, or changed record and every fatal parser/configuration failure rejects with a fixed diagnostic; lint may not rewrite tracked files or create non-ignored untracked files. | Exact #186 PR run `29291402007` and post-merge run `29291515653` passed lifecycle-disabled install, direct lint, clean proof, tests, and build; each later focused issue records its separate source/hosted evidence. Ignored dependency/build paths remain outside this proof, with no clean-lint, branch-protection, deployment, website, Firebase, or provider claim. | | SUPPLY-001A | published as [#127](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/127); CI-001A | Prove `gpxparser` unused and remove its obsolete transitive chain. | `rg`/tree proof, before/after audits, root lockfile diff, full frontend checks. | | SUPPLY-001B | source/test delivery tracked in [#192](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/192); CI-001A | Pin React Router DOM/Router 6.30.4 and `@remix-run/router` 1.23.3; opt the declarative routers into `v7_startTransition` and `v7_relativeSplatPath` without a route redesign. | Exact three-node lock diff; Node 20 production audit 22→19 and high 8→5 with no router finding; focused route/future-flag tests, standalone callback suite, full CI, and build. | | SUPPLY-001C | source/tests tracked in live [#202](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/202); CI-001A | Pin the Firebase browser SDK to 11.10.0 and its Rules test helper to 4.0.1; bridge Node 20's native web APIs into the isolated Jest Rules environment without changing application behavior or provider settings. | Root production audit 19→6, critical 1→0, and high 5→3; focused Firebase/Auth/App Check tests, full frontend/Functions/Rules suites, standalone callback and safety suites, diagnostic build, dependency tree, and bundle comparison. Website publication, Firebase deployment, provider configuration, and live behavior remain unproven. | diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index 5e0b7e7..d1bb421 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. The checker now covers 108 frontend files: 12 JS, 35 JSX, 35 TS, and 26 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, and CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record without changing either rule or the gate. PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) removes one prompt warning and two label-association errors with the unsafe reusable-link controls; the current baseline contains 121 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; #227, #239, and #359 record their separate source and hosted evidence on their live issues. 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 and does not prove 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. The checker now covers 111 frontend files: 12 JS, 35 JSX, 38 TS, and 26 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, 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 and does not prove 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. ### Firestore Rules diff --git a/SECURITY.md b/SECURITY.md index b29d722..22abaf8 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -82,7 +82,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. The gate now scans 108 JS/JSX/TS/TSX files. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` error, and CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record without changing executable statements, the rule set, or the gate. PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) removes the obsolete reusable-link prompt and amount/tier controls, retiring one `no-alert` warning and two label-association errors as part of that reviewed functional containment. The current baseline records 121 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. The current baseline scans 111 files and 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 Git-triggered Netlify production containment. Protected environments/OIDC, isolated staging, live-Netlify publication, and rollback evidence are still absent. | Complete #133 and #136, provision isolated staging, protect the Netlify release path under WEB-001, and rehearse rollback/safe roll-forward before production. | | 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. | @@ -132,7 +132,7 @@ These entries are implementation evidence, not a production risk-acceptance deci | RISK-009, part of RISK-024 | OAUTH-001C1H [#441](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/441) replaces browser-generated/session-storage-authoritative Strava OAuth state with a 32-byte server-issued challenge. Source stores only a SHA-256 digest in one browser-denied per-UID secret record, binds it to exact UID and decoded Auth `auth_time`, expires it after ten minutes, and transactionally deletes one match before provider exchange or connection writes. A later begin overwrites the older record; mismatch, expiry, replay, and the concurrent loser stop with one fixed result before Strava. Synthetic tests use mocks and no real callback or provider value. | This source does not deploy either Function or the website, configure Strava, prove the custom App Check guard is enabled, enable native runtime App Check enforcement, inspect production data, or prove live OAuth behavior. #443 separately supplies only the source/test clean-page readiness handoff while preserving initial callback suppression. Scope/account policy, refresh concurrency, provider/local reconciliation, revoke/audit, IAM/encryption, configured Enterprise evidence, native enforcement, and provider/live evidence remain open under [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88). | | RISK-008, RISK-009, part of RISK-024 | OAUTH-001C1I [#443](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/443) preserves initial capability-callback App Check suppression, then permits only a document that began on a normalized Strava callback to initialize the existing Enterprise provider after both current callback locations are clean, Router page state is `null`, and native history state is absent or the exact matching BrowserRouter index/key/empty-user-state record. One single-flight readiness attempt precedes one existing exchange. Before exchange admission, the callback rechecks the clean path, Router entry key, and exact UID, service, Firebase resources, app, attempt, and page lifecycle; dirty or reinjected paths, extra or mismatched history state, missing configuration, provider/readiness failure, or stale mounted context use one fixed failure and make no exchange, while an unmounted completion is inert. Authentication, registration, and shop callbacks are ineligible and keep their existing flow. The method never receives callback values or returns, inspects, logs, or stores the token-ready result. Local/test remain off and ordinary production startup remains eager. | This is source and synthetic-test ordering evidence only. It does not configure an Enterprise key or domains, prove a provider-backed token or Firebase acceptance, enable native `enforceAppCheck`, change a Function or Rule, publish the website, deploy Firebase, configure or contact Strava, inspect production data, or prove live OAuth behavior. App Check initialization is not reversible; later reinjection is scrubbed/discarded but earlier browser, hosting, provider, and network copies are not erased. A lifecycle or reinjection change after exchange admission cannot cancel server or provider work already started; it blocks another exchange and obsolete UI, but reconciliation may still be required. Complete ABUSE-001A2 only after protected provider and exact-revision staging evidence. Account/scope policy, refresh concurrency, reconciliation, revoke/audit, IAM/encryption, deployment, and live proof keep [#88](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/88) open. | | 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) source routes the remaining render, Auth-email, members-only, and App Check browser diagnostics through five fixed outcome identifiers and prohibits direct console calls elsewhere in application/public runtime source. 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. The checker now scans 108 frontend files; CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) and CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) each retire exactly one reviewed finding. PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retires two label errors and one prompt warning by removing those unsafe controls. | The reviewable lint baseline deliberately records 121 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. | The checker now scans 111 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. | | RISK-026, RISK-036 | #135 merged through PR #138 as `9eafab1217aff7058c42240aaba72d7b93f8ed24`, replacing automatic frontend-first/fail-open GitHub deployment with a tested manual exact-current-commit gate. Post-merge staging and synthetic production probes failed closed before authentication or mutation, and published neither Firebase nor Pages. | #133 must configure protected environments and least-privilege OIDC/WIF; #136 must prove staged/target deployment and clearing/readback of the existing Pages `runmprc.com` claim; a protected WEB-001 child must establish Netlify publication and rollback. No Firebase, Pages, live-host, or provider-setting change is proven by source/static tests alone. | | RISK-039 | The #118 source slice uses an empty authenticated callable request, bounded Firebase Auth identity fields, one transactional create-only helper shared with signup, constant responses, generic failures, and a UI that hides Edit until setup and the Rules-protected read succeed. Signup and recovery never change custom claims; browser profile creation remains denied. | Source review/merge is not deployment. Under #105, deploy the exact #100 Rules plus both `createMemberOnSignUp` and `ensureMemberProfile` before the website, prove App Check policy, use a synthetic staged account, verify rollback, then record website, Function, Rules, and live behavior separately. Never repair a real profile manually. | diff --git a/src/pages/admin/events/AdminEventRegistrations.tsx b/src/pages/admin/events/AdminEventRegistrations.tsx index 956e269..4d125cd 100644 --- a/src/pages/admin/events/AdminEventRegistrations.tsx +++ b/src/pages/admin/events/AdminEventRegistrations.tsx @@ -427,7 +427,7 @@ function Inner({ if (!firestore || !slug) return () => undefined; reload(true); return () => { requestSequence.current += 1; }; - // eslint-disable-next-line react-hooks/exhaustive-deps + // Firebase app, Firestore, and slug changes are the deliberate reload boundary. }, [firebaseApp, firestore, slug]); async function downloadCsv() { diff --git a/src/pages/admin/shop/AdminOrders.tsx b/src/pages/admin/shop/AdminOrders.tsx index 03f2fb6..10b671d 100644 --- a/src/pages/admin/shop/AdminOrders.tsx +++ b/src/pages/admin/shop/AdminOrders.tsx @@ -82,7 +82,7 @@ function Inner() { } reload(); return () => { requestSequence.current += 1; }; - // eslint-disable-next-line react-hooks/exhaustive-deps + // Firestore changes are the deliberate reload boundary. }, [firestore]); async function run(orderId: string, action: AdminOrderAction, payload?: Record) { diff --git a/src/pages/events/EventRegister.tsx b/src/pages/events/EventRegister.tsx index f1d1486..aa45c78 100644 --- a/src/pages/events/EventRegister.tsx +++ b/src/pages/events/EventRegister.tsx @@ -124,7 +124,7 @@ function EventRegister() { if (user?.email && !runner.email) { setRunner((r) => ({ ...r, email: user.email || '' })); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // Current user projection changes retrigger prefill; local email edits do not. }, [user]); useEffect(() => { diff --git a/src/pages/shop/ProductDetail.tsx b/src/pages/shop/ProductDetail.tsx index d35f989..7f46796 100644 --- a/src/pages/shop/ProductDetail.tsx +++ b/src/pages/shop/ProductDetail.tsx @@ -48,7 +48,7 @@ function ProductDetail() { useEffect(() => { if (user?.email && !email) setEmail(user.email); - // eslint-disable-next-line react-hooks/exhaustive-deps + // Current user projection changes retrigger prefill; local email edits do not. }, [user]); if (loading) return
Loading...
; diff --git a/tests/ci-workflow.test.js b/tests/ci-workflow.test.js index 5b94b2b..ee6163e 100644 --- a/tests/ci-workflow.test.js +++ b/tests/ci-workflow.test.js @@ -36,7 +36,7 @@ const CLEAN_COMMANDS = Object.freeze([ ]); const LINT_SCRIPT = 'node .github/scripts/check-frontend-lint.cjs'; const EXPECTED_LINT_FILES = 111; -const EXPECTED_LINT_ERRORS = 117; +const EXPECTED_LINT_ERRORS = 113; const EXPECTED_LINT_WARNINGS = 6; const YAML_TO_JSON = [ 'require "yaml"',