From f0c2d2378fd30b684ecb2fede447a184a414ab1c Mon Sep 17 00:00:00 2001 From: Dave Liu <7david12liu@gmail.com> Date: Mon, 14 Sep 2026 21:03:33 -0700 Subject: [PATCH] WEB-CONTENT-001: arm September meeting notice release --- IMPLEMENTATION_PLAN.md | 4 ++ OFFICER_START_HERE.md | 4 ++ OPERATIONS_RUNBOOK.md | 4 ++ SECURITY.md | 1 + SYSTEM_DESIGN.md | 15 ++++--- config/netlify-production-release.json | 22 ++++----- docs/officers/PUBLISH_AND_CHECK.md | 57 +++++++++++++++++++++++ docs/officers/README.md | 4 ++ docs/officers/UPDATE_PUBLIC_CONTENT.md | 46 +++++++++++++++++++ netlify.toml | 2 +- tests/release-workflow.test.js | 62 +++++++++++++++++--------- 11 files changed, 184 insertions(+), 37 deletions(-) diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index 414985b..af620d6 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -36,6 +36,10 @@ MPRC can open a race or merchandise item for sale only when the platform can: **WEB-002D completed release boundary:** [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one exact-artifact Netlify exception on 2026-08-14. Exact release merge `46e23647d8e0bf9fa3a574ea5c5f993be10a419d` published deploy `6a7ece87c5ca4d0007c1a3fc` from source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`. Signed-out desktop route-focus and phone menu/route-focus checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` passed exact-main CI run `31783808994`; attempt `6a7ed0ddb00a46000818878d` remained unpublished and retained the verified deploy. The manifest is inactive, the temporary source/control/repause refs are absent, and rollback ref `codex/netlify-source-659-rollback` remains pinned to #623 source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. #659 published only the reviewed #291 visible-focus, #490 phone-menu, and #657 route-focus behavior. It deployed no Firebase, Rules, Functions, or indexes; changed no outside-provider configuration, account, sign-in state, production data, payment, or connected directory behavior; and left directory availability literal `false`. Reusable hosting remains open under #460/#133/#136, and #507 still owns every connected-directory gate. +**WEB-CONTENT-001 pending release boundary:** [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) arms one exact-artifact Netlify exception for the temporary Sept. 19 and Sept. 26 meeting-location banner. It is under review and is not published. Frozen source `41a9ae4ebc719212df610ff5cdcf9ca4eab18e71`, tree `7f75ebda7b9d295c5be26acc11b06b452dcc20c6`, and 62-file digest `cb4eba76c65c3501b37f9a0ad3cf00b6eefbc5a9c2e653f2b3c03607cfe64850` contain only the banner and its expiry tests on top of current live source `7496fe0881fb52908c4ff2f40f488df09c94c908`. Production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc` unless the exact-parent release, marker, phone/desktop checks, and immediate repause all succeed. No Firebase, provider, account, sign-in, private data, payment, route, or permission change is included. + +**Historical source-ref correction:** a 2026-09-14 remote read found the exact hot source refs for #473, #623, and #659 still present despite older absent/retired wording. Their manifests are inactive, so ordinary `main` merges remain paused, but an authorized manual rebuild of a historical active merge is a latent retry path. Do not treat that residual as resolved; retire those hot refs separately only after confirming their rollback refs. + **WEB-001A1 Firebase Hosting source foundation:** [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) is the first bounded child of #460. It makes controlled optimized builds environment-explicit, keeps local/test on the demo emulators, requires complete staging-named public Firebase configuration, rejects production identities in staging, scans the executable synthetic CI artifact, changes the unqualified CLI default to `demo-mprc-local`, and adds the inert `build/` Hosting rewrite. It deliberately does not provision staging, configure short-lived authority or branch/environment protection, deploy Hosting/Firebase, automate `production-web`, add release readback/rollback/headers, alter Netlify/Pages, or touch DNS/TLS. Source/tests/merge and a synthetic build are not staging or production evidence. **WEB-001A2 isolated static staging:** [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) creates the club-owned `run-mprc-staging` Firebase project, one web app, and the static [run-mprc-staging.web.app](https://run-mprc-staging.web.app) Hosting site from exact merged source `a614c68d9a1a2be631a3be874a686d61e5d170a0`. The executable artifact scanner found the staging identity and rejected known production identities; provider, direct-route, desktop, and phone readback passed. This is signed-out visual staging only. It does not configure App Check, Auth test users, Firestore, Functions, Rules, indexes, Storage data, provider sandboxes, protected short-lived authority, a release marker, tested predecessor rollback, security headers, `production-web`, custom domains, DNS/TLS, or production publication. diff --git a/OFFICER_START_HERE.md b/OFFICER_START_HERE.md index 1e74b8b..6a59bda 100644 --- a/OFFICER_START_HERE.md +++ b/OFFICER_START_HERE.md @@ -51,6 +51,10 @@ As of **2026-08-13**, a merge runs checks but does not start the GitHub release. As of **2026-08-14**, [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one accessibility-only Netlify release. Deploy `6a7ece87c5ca4d0007c1a3fc` is live from frozen source `7496fe0881fb52908c4ff2f40f488df09c94c908`; its exact 62-file marker and signed-out desktop/phone route-focus and menu checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` made the manifest inactive. Its attempt `6a7ed0ddb00a46000818878d` published nothing and retained the verified deploy. #623 deploy `6a7e072f8f346b0008510d29` is the recorded rollback, not current production. #659 changed no Firebase, provider configuration, account, sign-in state, production data, payment, or connected directory behavior. Officers do not run commands, sign in, enter data, or approve this as a reusable release. Follow the completed record in [Review, merge, release, and check a change](./docs/officers/PUBLISH_AND_CHECK.md). +As of **2026-09-14**, [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) is a temporary meeting-location notice under review and is not published. The reviewed banner gives the Sept. 19 Seal Point dog-park restroom pin and the Sept. 26 Baywinds Park meeting point, both at 8:45 AM, and removes each item after its Saturday in Pacific time. Production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc` until an exact frozen preview, exact-parent merge, public marker, phone/desktop readback, and immediate repause all pass. Officers do not run commands, sign in, enter data, or reuse this one-shot release control. + +Remote readback on 2026-09-14 found the old #473, #623, and #659 hot source refs still present; this supersedes older absent/retired wording. Their manifests are inactive and ordinary merges remain paused, but the latent manual-rebuild path is not yet retired. Officers do not remove refs; the platform owner must verify rollback refs before a separate cleanup. + As of **2026-08-26**, WEB-001A1 [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) is merged, and WEB-001A2 [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created the club-owned `run-mprc-staging` project. CI-001C1 [#667](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/667) adds a separate protected read-only identity check: Dave Liu or Jeff Chang reviews exact `main`, and a keyless five-minute identity may read only the staging project identity. It cannot deploy Firebase. CI-001D1 [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) adds an empty, delete-protected staging Firestore database and the exact reviewed Rules/index definitions. Anonymous reads of three fixed server-only paths were denied, and the database still had zero root collections after verification. CI-001D2 [#671](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/671) deploys password-required email/password Auth from exact merged source and proves it with disposable API and browser sign-in/sign-out checks. Readback shows improved email privacy, only the two staging domains, no other provider, billing disabled, and zero users/records after cleanup. CI-001D3 [#674](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/674) adds a code guard for a future deployment of only the two profile Functions. It does not deploy them, and billing remains unapproved. CI-001D4 [#676](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/676) now enforces App Check on staging Authentication and Firestore: exact source `bce911a7083201cfe2141edaa9660f210287bf57` is live at [run-mprc-staging.web.app](https://run-mprc-staging.web.app) as Hosting version `8556fc51210bdc66`; one score-based key is restricted to only the two staging hosts and registered to the one web app for one-hour tokens; and both services read `ENFORCED` with replay protection `OFF`. A made-up browser account completed create, sign-out, fresh sign-in, and post-enforcement sign-in; token-bearing empty Events reads worked signed in and signed out without browser warnings/errors. Requests without App Check were denied by Auth and Firestore, and cleanup returned users and root collections to zero. This remains an **ENGINEERING STAGING SITE ONLY**: Functions, outside-provider sandboxes, protected automatic release, release marker, tested rollback, complete security headers, custom domain, and officer publish control are still **NOT AVAILABLE YET**. The account page therefore shows a safe unavailable profile state. Officers do not sign in, enter data, run commands, configure providers, attach billing, or treat App Check as a complete member backend. Netlify still answers `runmprc.com`; production Firebase Hosting remains empty; and DNS, GitHub Pages, Netlify, production Firebase, production data, and live website behavior are unchanged. The optional profile-photo and officer People-finder functions are still **NOT AVAILABLE YET**. #621 makes the frontend default an inert preview: My Account shows the future photo and separate finder-choice controls disabled, while the People finder stays behind the administrator guard and shows its name field and Search button disabled. The preview reads no saved photo or setting, accepts or uploads no photo, searches no name, and saves nothing; it shows no people or sample results. #623 published exactly that disabled interface as deploy `6a7e072f8f346b0008510d29`. Officers inspect the protected layouts only in synthetic local artifacts. The completed signed-out production review proved only the exact revision, normal sign-in and administrator guards, and absence of a member-directory network request. Do not sign in to production, choose a real photo, enter a real name, or treat the preview as a directory. #623 changed no Firebase, provider configuration, account, sign-in, or production data. #507 must later prove the privacy, authorization, staging, backend-first deployment, and readback gates before a separate reviewed source change may connect it. Follow the preview and source-review procedure in [Events, shop, members, and money](./docs/officers/EVENTS_SHOP_MEMBERS.md). diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index 7f5aeed..00d7248 100644 --- a/OPERATIONS_RUNBOOK.md +++ b/OPERATIONS_RUNBOOK.md @@ -741,6 +741,10 @@ WEB-002C [#623](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/623) compl WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed its one-shot Netlify accessibility release on 2026-08-14. Release ID `WEB-002D-KEYBOARD-FOCUS-2026-08-14` used pinned Deploy Preview `6a7ec998bf8fde00086d2bfe`, matched release-control head `137d8a8721339a6ca1079283cc34c1bd7cc2706c`, and passed PR CI run `31781730576`. Exact two-parent release merge `46e23647d8e0bf9fa3a574ea5c5f993be10a419d`, parents `95880748e15c03b0ee58da6e1ed11ac6c9526529` and `137d8a8721339a6ca1079283cc34c1bd7cc2706c`, tree `3ef47ed0f664e1e9a2c703332ca9071cfda27ad2`, passed exact-main CI run `31783141914`. Netlify deploy `6a7ece87c5ca4d0007c1a3fc` became ready and published at `2026-08-14T08:16:09.268Z`. Its marker and all 62 artifact paths matched source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, previous source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, rollback deploy `6a7e072f8f346b0008510d29`, and digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`; the exact six-path live-source diff digest was `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`. Signed-out desktop `/shop` and phone `/events` checks passed: route changes left main focused at the top without horizontal overflow, and the phone menu exposed truthful open state before destination selection closed it and preserved normal route focus. Repause preview `6a7ecfbc90347c000804901c` matched head `94c949abed3759c15cdaa98afc6896343e8a6edd`, which passed PR CI run `31783487885`; exact repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7`, parents `46e23647d8e0bf9fa3a574ea5c5f993be10a419d` and `94c949abed3759c15cdaa98afc6896343e8a6edd`, tree `c4667394dc9a2286c3a2eda028728314e925c22f`, passed all five exact-main jobs in run `31783808994`. Its attempt `6a7ed0ddb00a46000818878d` errored unpublished; provider and marker readback retained deploy `6a7ece87c5ca4d0007c1a3fc`. The manifest is inactive, the release/control/repause refs are absent, and rollback ref `codex/netlify-source-659-rollback` remains pinned to source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. #659's frozen source differed from its predecessor only at `src/App.jsx`, `src/App.test.jsx`, `src/components/Navbar.jsx`, `src/components/ScrollToTop.jsx`, `src/headerClearance.test.jsx`, and `src/index.css`. It deployed no Firebase, Rules, Functions, or indexes; changed no outside-provider configuration, account, sign-in state, production data, content, route set, payment, or connected directory behavior; and left directory availability literal `false`. Follow the completed no-terminal audit record in `docs/officers/PUBLISH_AND_CHECK.md`; never use this exception as a general release button. +WEB-CONTENT-001 [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) is one active Netlify content exception under review and is not published. Release ID `WEB-CONTENT-001-SEPTEMBER-LOCATIONS-2026-09-14` pins source `41a9ae4ebc719212df610ff5cdcf9ca4eab18e71`, tree `7f75ebda7b9d295c5be26acc11b06b452dcc20c6`, 62 files, digest `cb4eba76c65c3501b37f9a0ad3cf00b6eefbc5a9c2e653f2b3c03607cfe64850`, exact expected first parent `925a677cd807dad1f925b4a85e89fc317b7a38b7`, and current production/rollback deploy `6a7ece87c5ca4d0007c1a3fc`. The source differs from current live source `7496fe0881fb52908c4ff2f40f488df09c94c908` only in `src/components/AnnouncementBanner.jsx` and `src/components/AnnouncementBanner.test.jsx`. Before merge, require the pinned preview marker, public notice/map checks at 390×844 and 1280×900, all hosted checks, an unchanged `main`, and a prepared manifest-disable branch. Stop and rebuild the control if `main` advances or any identity differs. After a successful live marker/readback, merge the disable change immediately and verify its attempt publishes nothing. This exception changes no Firebase, provider configuration, account, sign-in state, private data, payment, route, permission, or reusable release authority. + +Remote-ref correction recorded 2026-09-14: the exact hot source refs for #473, #623, and #659 remain present, superseding older absent/retired statements in this record. Inactive manifests block ordinary `main` publication, but an authorized manual rebuild of a historical active merge remains a latent retry path. Do not call the refs retired. Confirm each rollback ref, then use a separate approved cleanup before removing the corresponding hot ref. + Incident record: on 2026-08-01, overbroad source `094af1096ed8721597561cd59bf695d4c4a9d210` was published by merge `40728ff6141e34a279b70cc41d983c22ac5f0daa` as deploy `6a6dc0167fbe68000816b448` after a release-blocker comment. Exact rollback merge `1099ee8e6fdb81141fd9460de175b6d854cbcfdd` published deploy `6a6dc219a8136300081811db`, restoring source `ed1b0833`, tree `878c6628d961f4484cb49208aef53f1e9f2e3b47`, 60 files, and digest `7570955c2a00926e5813aef135f1799172cfd046072ac89fb4e492bed0797092`. Safety merge `dee79511b6e371329aa129139729e112e7a51aad` re-paused the manifest; its Netlify attempt `6a6dc35767a4ef000877e74b` did not publish, and provider readback left the rollback deploy live. The overbroad release ref was deleted and verified absent. This incident changed no Firebase, outside-provider configuration, account, payment, or production data. ### Production approvals diff --git a/SECURITY.md b/SECURITY.md index c819528..b993dcb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -87,6 +87,7 @@ The findings below describe the repository at the start of the 2026-07-12 assess | 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, 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, and MEMBERS-DIRECTORY-001D [#621](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/621) adds one finding-free TypeScript availability module. The current baseline scans 120 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 that bounded deploy as #623's rollback. WEB-002C [#623](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/623) then completed one exact-artifact release: merge `9d5cc8612b4321172370bd949d307e7e4ac0ec7d` published frozen inert source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, tree `411aa6ec9a9459f5d923030533ffc7c007fe6908`, 62 files, and digest `d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1` as deploy `6a7e072f8f346b0008510d29`. Signed-out marker, route, guard, and no-connected-symbol/request checks passed. Repause merge `c8678c623afdd9becf77d596b71f36f26f04b746` made the manifest inactive; attempt `6a7e081e73fdd60009f7ba57` stopped unpublished and retained the verified deploy. The release source is absent and the rollback ref remains. Protected environments/OIDC, backend/provider staging, a reusable live-Netlify path, and provider-owned atomic rollback remain unverified; #665 proves only the static host. | Require a final blocker re-read and an executable delta from the live artifact before every release merge. Preserve the exact #473 rollback evidence, keep ordinary publication paused, and keep the reviewed Git rollback projection available. Treat #623 as a completed one-off, not a reusable control. Complete #133 and #136, extend #665 into protected backend/provider staging, protect the reusable Netlify release path under WEB-001, and rehearse provider rollback before broader production work. | | WEB-002D completed exact-artifact containment for RISK-036 | [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one accessibility-only release on 2026-08-14. Exact release merge `46e23647d8e0bf9fa3a574ea5c5f993be10a419d` published deploy `6a7ece87c5ca4d0007c1a3fc`; its marker and all 62 artifact paths matched frozen source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`, and exact six-path diff digest `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`. Signed-out desktop and phone route-focus/menu checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` passed exact-main CI run `31783808994`; attempt `6a7ed0ddb00a46000818878d` stayed unpublished and retained the verified deploy. Literal-false directory availability, Firebase, Rules, Functions, indexes, outside-provider configuration, accounts, sign-in, production data, payments, and connected directory behavior were unchanged. | The manifest is inactive; source/control/repause refs are absent; rollback ref `codex/netlify-source-659-rollback` remains pinned to #623 source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. Treat #659 as a completed one-off, not reusable authority. Keep ordinary publication paused, preserve #507 connected-directory gates, and preserve active #616 OAUTH-001A2L files and its RISK-024 wording byte-for-byte. | +| WEB-CONTENT-001 pending exact-artifact containment for RISK-036 | [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) is a content-only banner release under review and is not published. The frozen two-file delta names two public meeting locations and has Pacific-time expiry tests; production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc`. A 2026-09-14 remote read found the old #473, #623, and #659 hot source refs still present, superseding older absent/retired wording; inactive manifests block ordinary merges, but the manual-rebuild residual remains. | Permit only the pinned source/tree/artifact and exact first-parent merge. Require signed-out phone/desktop preview and live readback, then immediate repause. Stop on any identity, content, link, expiry, artifact, or `main` mismatch. The release must not change Firebase, providers, accounts, sign-in, private data, payment, routes, permissions, or reusable authority. Retire historical hot refs only in a separate approved cleanup after rollback refs are confirmed. | | WEB-001A1/A2 boundary for RISK-010 and RISK-036 | [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) adds the dependency-free hosted-build contract and Hosting rewrite. [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) adds one club-owned staging project, web app, finalized static Hosting release, provider readback, and signed-out desktop/phone route checks from exact source `a614c68`. | This proves static engineering staging only. It creates no staging backend/provider isolation, App Check, WIF/IAM identity, protected branch/environment, automatic deployment, release marker, tested predecessor rollback, complete header policy, custom domain, DNS/TLS change, production Hosting, `runmprc.com` publication, or live protection. Complete #113/#133 and the remaining #460 children before any end-to-end staging or production claim. | | CI-001D1 boundary for RISK-006 and RISK-010 | [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) creates empty Native/Standard staging Firestore in `us-west2`, enables delete protection, keeps PITR off, and deploys exact Rules SHA-256 `fe3f53302db76df5febf7e9d242d82a6b6bec0c0b574ecc8253f1034f1a77dba`, four composite indexes, and 28 field overrides from source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7`. The 418-case emulator suite passed; active Rules content matched; fixed anonymous server-only reads returned denial; root collection count remained zero. | This proves only an empty staging data boundary. It creates no Auth test user/provider, Function, App Check enforcement, provider sandbox, protected Firebase deploy role, application record, website release, production Rules change, or production behavior. | | 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. | diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md index e3e14f9..3b6efd3 100644 --- a/SYSTEM_DESIGN.md +++ b/SYSTEM_DESIGN.md @@ -103,6 +103,10 @@ The former workflow automatically published Pages before attempting Firebase and WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one exact-artifact exception on 2026-08-14. Pinned preview `6a7ec998bf8fde00086d2bfe` matched control `137d8a8721339a6ca1079283cc34c1bd7cc2706c`. Exact release merge `46e23647d8e0bf9fa3a574ea5c5f993be10a419d` published deploy `6a7ece87c5ca4d0007c1a3fc` from source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and artifact digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`; the exact six-path predecessor diff digest was `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`. Signed-out desktop route-focus and phone menu/route-focus checks passed. Repause merge `3138a00c1c48e1d5d1dcda0b44722b09a2194ff7` passed exact-main CI `31783808994`; attempt `6a7ed0ddb00a46000818878d` stayed unpublished and retained the verified deploy. The manifest is inactive; temporary refs are absent; #623 deploy `6a7e072f8f346b0008510d29` is the rollback target. #659 changed no route set, content, Firebase surface, outside-provider configuration, account, sign-in state, production data, payment, or directory behavior; directory availability remains literal `false` and #507 still owns connection. +WEB-CONTENT-001 [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) arms a fourth bounded exact-artifact exception for one temporary public banner. It is under review and is not published. The pinned source adds only the two meeting-location notices and their automatic Pacific-time expiry tests to live #659 source; production remains deploy `6a7ece87c5ca4d0007c1a3fc` until exact preview, exact-parent merge, marker, signed-out phone/desktop readback, and repause proof all pass. Firebase, providers, accounts, private data, routes, payments, permissions, and the reusable release boundary do not change. + +Remote source-ref readback on 2026-09-14 found the old #473, #623, and #659 hot refs still present, superseding older absent/retired wording. Their inactive manifests keep ordinary `main` merges from publishing, but a manual rebuild of a historical active merge remains latent. A separate reviewed cleanup must confirm the matching rollback refs before retiring those hot refs. + **WEB-001A1/A2 Firebase Hosting foundation and isolated static staging:** [#663](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/663) makes every controlled optimized browser build select `staging` or `production` explicitly. Local/test still use only `demo-mprc-local` and all three loopback emulators. A staging build requires a complete public Firebase web configuration whose project name has a `staging` boundary; both the browser startup boundary and build contract reject production-equal identities, and CI scans executable JavaScript for every selected staging field and absence of known production Firebase identities. Production requires the exact reviewed public web configuration. `firebase.json` describes `build/`, a missing-path rewrite to `/index.html`, and a predeploy chain that binds the selected web configuration to Firebase CLI's exact `GCLOUD_PROJECT`, rebuilds, and scans the artifact before upload. `.firebaserc` defaults to the non-deployable demo namespace. On 2026-08-26, [#665](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/665) created club-owned project `run-mprc-staging`, one web app, and finalized Hosting version `3ffadcf2ac8cc760` from exact merged source `a614c68d9a1a2be631a3be874a686d61e5d170a0`. Provider and rendered checks passed for [run-mprc-staging.web.app](https://run-mprc-staging.web.app), static assets, direct `/events`, desktop, and phone navigation. **CI-001D1 empty staging Firestore boundary:** [#669](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/669) provisioned the empty `(default)` Firestore Native, Standard database in `us-west2` with delete protection enabled and point-in-time recovery disabled. Exact `main` source `ee16bd16220ab58bd3a2add80dd2f39a1d514dd7` supplied Rules SHA-256 `fe3f53302db76df5febf7e9d242d82a6b6bec0c0b574ecc8253f1034f1a77dba`, four composite indexes, and 28 field overrides. Provider readback matched those definitions; fixed anonymous reads of `mail`, `stripeEvents`, and `auditEvents` were denied, and root collection count remained zero. This is a protected empty data boundary, not a usable application backend. Auth test configuration, Functions, App Check, Storage data, outside-provider sandboxes, protected Firebase deployment authority, `production-web`, a release marker, tested predecessor rollback, response-header policy, custom domains, DNS/TLS, Netlify/Pages, production Hosting, and `runmprc.com` were unchanged. @@ -121,14 +125,15 @@ flowchart TD Verify -- "No" --> Stop Verify -- "Yes" --> Pages["Publish Pages branch without a CNAME"] Merge -. "Ordinary Git production build paused" .-> Netlify["Netlify / runmprc.com\nreusable protected publication not available"] - Predecessor["#623 inert artifact retained as rollback"] --> Completed["#659 exact-parent one-shot completed"] - Completed --> WebOnly["Pinned accessibility artifact live"] - WebOnly --> Netlify + Predecessor["#623 inert artifact retained as older history"] --> Completed["#659 exact-parent one-shot completed"] + Completed --> WebOnly["#659 accessibility artifact remains live"] + WebOnly --> Pending["#685 temporary notice under review"] + Pending -. "Only the exact reviewed parent may publish" .-> Netlify Netlify --> WebReadback["Exact marker and signed-out route/menu checks verified"] - WebReadback --> WebRepause["Temporary authority inactive; #659 deploy retained"] + WebReadback --> WebRepause["Temporary authority inactive; last verified deploy retained"] ``` -Text alternative: ordinary merges run CI and do not publish Netlify. #659 completed one exact-parent accessibility exception, and production now serves deploy `6a7ece87c5ca4d0007c1a3fc` over the inert #623 predecessor. Its exact marker and signed-out route/menu checks passed, then the temporary authority was disabled without replacing the verified deploy. The separate protected workflow still requires approval and verified Firebase before publishing its Pages copy. +Text alternative: ordinary merges run CI and do not publish Netlify. #659 completed one exact-parent accessibility exception, and production still serves deploy `6a7ece87c5ca4d0007c1a3fc`. #685 is under review and is not published; only its exact reviewed parent, frozen banner artifact, marker, public checks, and repause may replace #659. The separate protected workflow still requires approval and verified Firebase before publishing its Pages copy. ### GitHub Pages callback handoff diff --git a/config/netlify-production-release.json b/config/netlify-production-release.json index bc86a25..1a91c30 100644 --- a/config/netlify-production-release.json +++ b/config/netlify-production-release.json @@ -1,16 +1,16 @@ { "schemaVersion": 1, - "active": false, - "releaseId": "WEB-002D-KEYBOARD-FOCUS-2026-08-14", - "issueNumber": 659, - "previewBranch": "codex/issue-659-netlify-release", - "expectedProductionParent": "95880748e15c03b0ee58da6e1ed11ac6c9526529", + "active": true, + "releaseId": "WEB-CONTENT-001-SEPTEMBER-LOCATIONS-2026-09-14", + "issueNumber": 685, + "previewBranch": "codex/issue-685-netlify-release", + "expectedProductionParent": "925a677cd807dad1f925b4a85e89fc317b7a38b7", "sourceRepository": "https://github.com/Run-MPRC/Run-MPRC.github.io.git", - "sourceRef": "refs/heads/codex/netlify-source-659-keyboard-focus", - "sourceCommit": "7496fe0881fb52908c4ff2f40f488df09c94c908", - "sourceTree": "ccac4c189c195db8ab594e0eefe256ea9fa04996", - "previousSourceCommit": "c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec", - "rollbackDeployId": "6a7e072f8f346b0008510d29", + "sourceRef": "refs/heads/codex/netlify-source-685-september-locations", + "sourceCommit": "41a9ae4ebc719212df610ff5cdcf9ca4eab18e71", + "sourceTree": "7f75ebda7b9d295c5be26acc11b06b452dcc20c6", + "previousSourceCommit": "7496fe0881fb52908c4ff2f40f488df09c94c908", + "rollbackDeployId": "6a7ece87c5ca4d0007c1a3fc", "expectedSiteFileCount": 62, - "expectedSiteFilesSha256": "e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7" + "expectedSiteFilesSha256": "cb4eba76c65c3501b37f9a0ad3cf00b6eefbc5a9c2e653f2b3c03607cfe64850" } diff --git a/docs/officers/PUBLISH_AND_CHECK.md b/docs/officers/PUBLISH_AND_CHECK.md index 3ec67d1..d24646b 100644 --- a/docs/officers/PUBLISH_AND_CHECK.md +++ b/docs/officers/PUBLISH_AND_CHECK.md @@ -16,6 +16,63 @@ **Completed #659 exception:** WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one exact-artifact accessibility release on 2026-08-14. The frozen source contains only reviewed #291 visible focus, #490 phone-menu disclosure/close behavior, and #657 client-side route focus. Production is deploy `6a7ece87c5ca4d0007c1a3fc`; #623 deploy `6a7e072f8f346b0008510d29` is its rollback target. This is not an officer-operated or reusable control. The no-terminal section below is retained as the audit record. +## Temporary #685 meeting-location release — UNDER REVIEW, NOT PUBLISHED + +**Purpose:** publish one frozen public banner that tells prospective members where the 8:45 AM runs meet on Sept. 19 and Sept. 26, 2026. The Sept. 19 item disappears at midnight after that run. The whole banner disappears at midnight after Sept. 26. Both cutoffs use Pacific time. + +**Approver:** Dave Liu as platform owner and the communications owner who supplied the notice. Officers observe the public result only; they do not run commands, handle credentials, or reuse this exception. + +**Prerequisites:** issue [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685); exact approved public wording and map links; frozen source `41a9ae4ebc719212df610ff5cdcf9ca4eab18e71`; tree `7f75ebda7b9d295c5be26acc11b06b452dcc20c6`; 62-file digest `cb4eba76c65c3501b37f9a0ad3cf00b6eefbc5a9c2e653f2b3c03607cfe64850`; source ref `codex/netlify-source-685-september-locations`; exact expected first parent `925a677cd807dad1f925b4a85e89fc317b7a38b7`; current deploy `6a7ece87c5ca4d0007c1a3fc`; rollback ref `codex/netlify-source-685-rollback`; all required checks; a signed-out pinned preview; and a prepared manifest-disable change. + +```mermaid +flowchart LR + Live["#659 deploy remains live"] --> Preview["Review exact #685 frozen preview"] + Preview --> Parent{"main still equals the recorded parent?"} + Parent -- "No" --> Stop["Stop and rebuild the control"] + Parent -- "Yes" --> Merge["One exact two-parent merge"] + Merge --> Marker{"Marker and public banner match?"} + Marker -- "No" --> Rollback["Keep or restore #659 deploy"] + Marker -- "Yes" --> Repause["Merge prepared disable change"] + Repause --> Quiet["Later merges publish nothing"] +``` + +In words: #659 stays live while the exact #685 preview is reviewed. Only an unchanged recorded `main` parent may merge the control. The public marker and banner must match before the prepared disable change makes ordinary publication inactive again. Any mismatch stops or restores #659. + +1. Stay signed out. Use no member, account, payment, or private information. +2. Confirm the source diff contains only `src/components/AnnouncementBanner.jsx` and `src/components/AnnouncementBanner.test.jsx` on top of source `7496fe0881fb52908c4ff2f40f488df09c94c908`. +3. Confirm all four expiry tests, the full frontend suite, the SPA safety suite, the diagnostic build, lint, and artifact checks passed under Node 20. +4. Open the pinned Deploy Preview. Confirm its marker names issue 685, the frozen source/tree, 62 files, the exact digest, and the preview control head. +5. At 390×844, confirm the banner is below the blue navigation, fits without horizontal overflow, and leaves the page heading visible below it. +6. Confirm Sept. 19 says **8:45 AM**, names the restrooms next to the Seal Point dog park, warns that parking may be limited, and opens the approved exact restroom pin. +7. Confirm Sept. 26 says **8:45 AM**, names The Kite School in Baywinds Park, gives 30 Lakeside Drive, Foster City, says run and social, identifies the artificial turf south of the restrooms toward the San Mateo Bridge, and opens the approved map. +8. Repeat the content and layout check at 1280×900. +9. Confirm production still reports deploy `6a7ece87c5ca4d0007c1a3fc`. A preview is not live proof. +10. Confirm all hosted checks are green and no unrelated pull request merged after expected parent `925a677cd807dad1f925b4a85e89fc317b7a38b7`. +11. Confirm the manifest-disable branch and rollback ref are already prepared and independently reviewed. +12. Merge with a merge commit only. Confirm its first parent is the expected production parent and its second parent is the exact reviewed control head. +13. Wait for the Netlify production attempt. Do not promote a preview, use a build hook, or deploy with a local CLI. +14. Read `/.well-known/run-mprc-release.json`. Confirm every identity and artifact field matches the approved record. +15. Repeat the signed-out 390×844 and 1280×900 content, link, visibility, and overflow checks on `runmprc.com`. +16. Confirm Firebase, GitHub Pages, DNS, accounts, sign-in, private data, payments, routes, and permissions did not change. +17. Merge the prepared disable pull request immediately. +18. Confirm its production attempt publishes nothing and the verified #685 deploy remains live. +19. Retire only the #685 hot source, control, and repause refs after readback. Retain the exact rollback ref. +20. Record exact commits, checks, preview, deploy, marker, public checks, repause, retained rollback, and any residual risk before closing #685. + +**Expected result:** one exact public artifact shows both notices through Sept. 19, only the Sept. 26 notice from Sept. 20 through Sept. 26, and no banner from Sept. 27. Ordinary production publication is inactive again. Firebase and every other named surface are unchanged. + +**Stop conditions:** stop if `main` advances; a required check fails; any source/tree/file-count/digest/parent/ref/deploy/marker value differs; either location, time, link, city, parking note, social note, or cutoff is wrong; layout clips or covers content; an account or private route is requested; any unrelated source enters the artifact; the disable change or rollback ref is absent; or Netlify attempts to build accumulated `main` instead of the frozen source. + +**Success proof:** record the exact source/tree/digest, control head, PR and hosted run, pinned preview and marker, phone/computer dimensions and results, exact two-parent merge, production attempt/deploy time, public marker, both public map links, no-overflow result, manifest-disable PR/merge/attempt, retained rollback ref, and separate unchanged statements for Firebase, Pages, DNS, providers, accounts, data, and payments. Redact screenshots and include the check date. + +**Undo:** before publication, reject the control PR. If publication fails before replacing production, keep #659 live. If a bad #685 artifact becomes live, ask a Netlify team owner to atomically restore deploy `6a7ece87c5ca4d0007c1a3fc`; if that control is unavailable, use a newly reviewed exact-parent Git projection of rollback source `7496fe0881fb52908c4ff2f40f488df09c94c908`. A manifest-disable commit alone is not rollback. + +**Escalation:** communications owner for wording or location; platform owner for source, CI, Netlify, marker, or rollback; security owner for any unexpected account, data, credential, provider, or permission behavior. + +#685 is under review and is not published. Production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc` until every step above passes. + +Remote readback on 2026-09-14 found the old #473, #623, and #659 hot source refs still present; this supersedes older absent/retired wording in this guide. Their manifests are inactive, so ordinary merges remain paused, but the manual-rebuild residual is not retired. Officers do not remove refs. The platform owner must confirm the rollback refs and use a separate approved cleanup. + ## The release gate ```mermaid diff --git a/docs/officers/README.md b/docs/officers/README.md index 88754f2..c7e6a8d 100644 --- a/docs/officers/README.md +++ b/docs/officers/README.md @@ -68,6 +68,10 @@ Independent officer publishing to the live Netlify host is **NOT AVAILABLE YET** WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) completed one temporary accessibility artifact release on 2026-08-14. Deploy `6a7ece87c5ca4d0007c1a3fc` is live and pins source `7496fe0881fb52908c4ff2f40f488df09c94c908` with only the reviewed visible-focus, phone-menu, and client-side route-focus behavior. Signed-out route/menu checks passed. Repause attempt `6a7ed0ddb00a46000818878d` published nothing, retained the deploy, and left the manifest inactive. #623 deploy `6a7e072f8f346b0008510d29` is the rollback target. Officers performed no terminal, account, Firebase, provider-configuration, or production-data action. The completed audit record is in [Review, merge, release, and check a change](./PUBLISH_AND_CHECK.md). A preview, green check, or merged release control alone does not prove the website changed. +WEB-CONTENT-001 [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685) is a two-date public meeting-location banner under review and is not published. Production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc`. The banner must pass exact frozen preview, 390×844 and 1280×900 checks, exact-parent publication, public marker/readback, and immediate repause before anyone calls it live. Officers do not run commands, sign in, enter data, or reuse this one-shot release control. + +A 2026-09-14 remote check found the old #473, #623, and #659 hot source refs still present, superseding older absent/retired wording. Ordinary merges remain paused because their manifests are inactive, but a latent manual-rebuild path remains. Officers do not remove refs; a separate platform-owner cleanup must confirm rollback refs first. + The general protected GitHub release is still **NOT AVAILABLE YET**. #667 configures only a separate staging read-only identity check: Dave Liu or Jeff Chang reviews exact `main`, and a keyless five-minute identity may read only the staging project identity. It cannot deploy Firebase or publish a website. #133 still owns backend deployment roles and production protection. Missing authority stops the release with a red failure before Firebase or website publication. The empty staging Firestore boundary is available after #669. Project `run-mprc-staging` has a delete-protected empty database with the exact reviewed Rules and indexes. Fixed signed-out requests to server-only paths were denied, and the final root collection count was zero. #671 deploys and verifies password-required email/password Auth from exact merged source. Improved email privacy is on; only the two staging domains are authorized; every other provider is absent; billing is disabled; disposable API/browser checks passed; and cleanup returned Auth and Firestore to zero users/records. #674 adds a code guard for a future deployment of only the two profile Functions; no Function or related API is live because billing remains unapproved. #676 configured one restricted score-based App Check provider, registered it to the one staging web app for one-hour tokens, published exact merged source `bce911a7083201cfe2141edaa9660f210287bf57` as Hosting version `8556fc51210bdc66`, and set Authentication plus Firestore to `ENFORCED` with replay protection `OFF`. A made-up browser account proved create, sign-out, fresh sign-in, post-enforcement sign-in, and signed-in/signed-out empty Events reads; tokenless Auth and Firestore requests were denied, and cleanup returned users and root collections to zero. This is still not a usable member backend: Functions, provider sandboxes, reusable deployment authority, role/private-data proof, and officer operation remain **NOT AVAILABLE YET**, and the account profile fails closed while Functions are absent. Officers do not sign in, enter records, run commands, edit the database, deploy Auth/Hosting, configure App Check, or attach billing. Use the no-terminal [staging Firestore review](./PUBLISH_AND_CHECK.md#review-the-empty-staging-firestore-boundary--available-after-669), [staging Auth review](./PUBLISH_AND_CHECK.md#review-the-staging-auth-boundary--available-after-671), and [App Check enforcement review](./PUBLISH_AND_CHECK.md#review-staging-app-check-enforcement--available-after-676). diff --git a/docs/officers/UPDATE_PUBLIC_CONTENT.md b/docs/officers/UPDATE_PUBLIC_CONTENT.md index ca0ff5d..923b9d5 100644 --- a/docs/officers/UPDATE_PUBLIC_CONTENT.md +++ b/docs/officers/UPDATE_PUBLIC_CONTENT.md @@ -92,6 +92,52 @@ 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`. +## Temporary September 2026 meeting locations — UNDER REVIEW, NOT PUBLISHED + +**Purpose:** show prospective members the two temporary Saturday meeting points, then remove each notice automatically after it is no longer useful. + +**Approver:** communications lead or the officer who owns Saturday-run announcements, plus the platform owner for the one-shot release. + +**Before you start:** have issue [#685](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/685), the approved wording below, both public map links, the exact pinned preview, and a signed-out browser. Use Pacific time. Do not sign in or enter any information. + +Approved public notice: + +- **Sept. 19, 8:45 AM:** meet at the restrooms next to the Seal Point dog park. Parking may be limited, so allow extra time. Use the [exact restroom pin](https://www.google.com/maps/search/?api=1&query=37.5733685%2C-122.3007770), not the site's usual Seal Point restroom pin. +- **Sept. 26, 8:45 AM:** meet at [The Kite School in Baywinds Park](https://maps.app.goo.gl/eWoXjkF2Brt8ujh88), 30 Lakeside Drive, Foster City, for the run and social. Gather on the artificial turf south of the restrooms, toward the San Mateo Bridge. + +```mermaid +flowchart LR + A["Through Sept. 19\nboth notices"] --> B["Sept. 20–26\nSept. 26 only"] + B --> C["From Sept. 27\nno banner"] +``` + +In words: both notices show through the end of Sept. 19 Pacific time; only the Sept. 26 notice shows from Sept. 20 through Sept. 26; the whole banner is gone from Sept. 27. + +1. Open the exact pinned preview while signed out at 390×844. +2. Confirm the red banner begins below the blue navigation and does not cover the page heading. +3. Compare every date, time, landmark, city, parking note, social note, and map link with the approved notice. +4. Open each map. Confirm Sept. 19 points to the dog-park-adjacent south restroom and Sept. 26 points to The Kite School at Baywinds Park in Foster City. +5. Confirm no private address, member information, account control, registration, payment, or form appears. +6. Confirm there is no horizontal overflow and all link text remains readable. +7. Repeat steps 2–6 at 1280×900. +8. Review the automated tests showing both notices before Sept. 20, only Sept. 26 afterward, Sept. 26 through the end of that Saturday, and no banner from Sept. 27. +9. After publication, repeat the same checks on `runmprc.com` and verify the release marker identifies #685's exact frozen artifact. +10. Confirm the release is immediately re-paused and its follow-up attempt publishes nothing. + +**Expected result:** prospective members see the correct temporary place and time without signing in. The page stays usable at phone and computer sizes. Stale text disappears automatically on the documented Pacific-time boundaries. + +**Stop conditions:** stop if a date, time, city, landmark, link, parking note, social note, or expiry is wrong; the ordinary Seal Point pin is used; text is clipped or hidden; the page requires sign-in; unrelated content changed; or the marker does not identify the exact reviewed artifact. + +**Success proof:** record the exact source and preview, check date, both viewport sizes, both map destinations, banner and page-heading visibility, no-overflow result, four expiry-test results, exact public marker, and the repause attempt. A green workflow alone is not website proof. + +**Undo:** before publication, reject the pull request. After publication, ask the platform owner to restore the recorded #659 deploy or use the reviewed rollback projection. Do not remove the banner by editing production directly; the automatic cutoff is the normal content undo. + +**Escalation:** communications owner for wording or meeting-place questions; platform owner for layout, expiry, release, marker, or rollback; security owner for any unexpected account, private-data, or provider behavior. + +#685 is under review and is not published. Production remains #659 deploy `6a7ece87c5ca4d0007c1a3fc` until the exact release and live checks pass. + +Remote readback on 2026-09-14 also found the old #473, #623, and #659 hot source refs still present, superseding older absent/retired wording. Their inactive manifests keep ordinary merges paused, but the manual-rebuild residual still needs a separate approved cleanup after rollback refs are confirmed. + ## Photos 1. Get permission to publish the photo. diff --git a/netlify.toml b/netlify.toml index 663bef0..9675b9a 100644 --- a/netlify.toml +++ b/netlify.toml @@ -16,7 +16,7 @@ command = "node ./scripts/netlify-release-build.js" [context.deploy-preview] - # The temporary #659 production authority is inactive again. Ordinary + # The #685 control-branch preview verifies its exact pinned source. Other # previews use their checked-out tree; production still needs the exact gate. command = "node ./scripts/netlify-release-build.js --preview" diff --git a/tests/release-workflow.test.js b/tests/release-workflow.test.js index ce4d66d..745884e 100644 --- a/tests/release-workflow.test.js +++ b/tests/release-workflow.test.js @@ -34,6 +34,16 @@ const FINAL_RELEASE_TRUTH_PATHS = [ 'docs/officers/SYSTEM_MAPS.md', 'docs/officers/UPDATE_PUBLIC_CONTENT.md', ]; +const PENDING_RELEASE_TRUTH_PATHS = [ + 'IMPLEMENTATION_PLAN.md', + 'OFFICER_START_HERE.md', + 'OPERATIONS_RUNBOOK.md', + 'SECURITY.md', + 'SYSTEM_DESIGN.md', + 'docs/officers/PUBLISH_AND_CHECK.md', + 'docs/officers/README.md', + 'docs/officers/UPDATE_PUBLIC_CONTENT.md', +]; const { authorizeProductionRelease, evaluateProductionRelease, @@ -56,6 +66,12 @@ const finalReleaseTruth = new Map( fs.readFileSync(path.join(ROOT, relativePath), 'utf8'), ]), ); +const pendingReleaseTruth = new Map( + PENDING_RELEASE_TRUTH_PATHS.map((relativePath) => [ + relativePath, + fs.readFileSync(path.join(ROOT, relativePath), 'utf8'), + ]), +); function runNetlifyGate(context) { const env = { ...process.env }; @@ -228,60 +244,68 @@ test('Netlify production is an exact-artifact release while previews remain avai }); }); -test('Netlify manifest pins the inactive bounded #659 keyboard-focus release', () => { +test('Netlify manifest pins the active bounded #685 meeting-location release', () => { const loaded = loadManifest(NETLIFY_MANIFEST_PATH); assert.equal(loaded.ok, true); - assert.equal(loaded.manifest.active, false); + assert.equal(loaded.manifest.active, true); assert.equal( loaded.manifest.releaseId, - 'WEB-002D-KEYBOARD-FOCUS-2026-08-14', + 'WEB-CONTENT-001-SEPTEMBER-LOCATIONS-2026-09-14', ); - assert.equal(loaded.manifest.issueNumber, 659); + assert.equal(loaded.manifest.issueNumber, 685); assert.equal( loaded.manifest.expectedProductionParent, - '95880748e15c03b0ee58da6e1ed11ac6c9526529', + '925a677cd807dad1f925b4a85e89fc317b7a38b7', ); assert.equal( loaded.manifest.sourceCommit, - '7496fe0881fb52908c4ff2f40f488df09c94c908', + '41a9ae4ebc719212df610ff5cdcf9ca4eab18e71', ); assert.equal( loaded.manifest.sourceTree, - 'ccac4c189c195db8ab594e0eefe256ea9fa04996', + '7f75ebda7b9d295c5be26acc11b06b452dcc20c6', ); assert.equal( loaded.manifest.previousSourceCommit, - 'c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec', + '7496fe0881fb52908c4ff2f40f488df09c94c908', ); assert.equal( loaded.manifest.rollbackDeployId, - '6a7e072f8f346b0008510d29', + '6a7ece87c5ca4d0007c1a3fc', ); assert.equal( loaded.manifest.sourceRef, - 'refs/heads/codex/netlify-source-659-keyboard-focus', + 'refs/heads/codex/netlify-source-685-september-locations', ); assert.equal( loaded.manifest.previewBranch, - 'codex/issue-659-netlify-release', + 'codex/issue-685-netlify-release', ); assert.equal(loaded.manifest.expectedSiteFileCount, 62); assert.equal( loaded.manifest.expectedSiteFilesSha256, - 'e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7', + 'cb4eba76c65c3501b37f9a0ad3cf00b6eefbc5a9c2e653f2b3c03607cfe64850', ); }); -test('completed #659 records are live while #623 remains rollback history', () => { +test('pending #685 records keep #659 live until exact publication', () => { assert.match( netlifyConfig, - /temporary #659 production authority is inactive again/i, - ); - assert.match( - netlifyConfig, - /Ordinary[\s\S]{0,20}previews use their checked-out tree/i, + /#685 control-branch preview verifies its exact pinned source/i, ); + pendingReleaseTruth.forEach((contents, relativePath) => { + assert.match(contents, /#685/); + assert.match(contents, /under review and is not published/i); + assert.match(contents, /6a7ece87c5ca4d0007c1a3fc/); + assert.doesNotMatch( + contents, + /#685[^\n]{0,180}(?:completed|is live|published deploy)/i, + `${relativePath} must not claim the pending #685 release is live`, + ); + }); +}); +test('completed #659 records are live while #623 remains rollback history', () => { finalReleaseTruth.forEach((contents, relativePath) => { assert.match(contents, /#659/); assert.match(contents, /6a7ece87c5ca4d0007c1a3fc/); @@ -297,8 +321,6 @@ test('completed #659 records are live while #623 remains rollback history', () = /#473's narrower replacement is \*\*NOT AVAILABLE YET\*\*/i, /WEB-002D pending/i, /Temporary #659[^\n]*— (?:UNDER REVIEW|PENDING)/i, - /#659[^\n]{0,180}(?:under review|is not published|not published|not live yet)/i, - /(?:under review|not published)[^\n]{0,180}#659/i, /#659 LIVE CHECK UNDER REVIEW/i, /ONLY AFTER THE EXACT #659 MARKER IS LIVE/i, /production remains #623/i,