From 137d8a8721339a6ca1079283cc34c1bd7cc2706c Mon Sep 17 00:00:00 2001 From: Dave Liu <7david12liu@gmail.com> Date: Fri, 14 Aug 2026 00:47:55 -0700 Subject: [PATCH] WEB-002D: arm bounded Netlify accessibility release --- IMPLEMENTATION_PLAN.md | 2 + OFFICER_START_HERE.md | 2 + OPERATIONS_RUNBOOK.md | 2 + SECURITY.md | 1 + SYSTEM_DESIGN.md | 5 +- config/netlify-production-release.json | 22 ++--- docs/officers/PUBLISH_AND_CHECK.md | 95 ++++++++++++++++++++-- docs/officers/README.md | 2 + docs/officers/UPDATE_PUBLIC_CONTENT.md | 6 +- netlify.toml | 2 +- tests/release-workflow.test.js | 108 +++++++++++++++++++++---- 11 files changed, 210 insertions(+), 37 deletions(-) diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index 9a8b376..dd3230a 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -34,6 +34,8 @@ MPRC can open a race or merchandise item for sale only when the platform can: 9. Do not trade payment integrity for UI responsiveness. Confirmation may say “processing”; it must not guess “paid.” 10. Legal/tax/insurance questions are escalated to qualified owners, not decided by an implementation agent. +**WEB-002D pending release boundary:** [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is one active exact-artifact Netlify exception under review and is not published. It projects only the released #291 visible-focus behavior, #490 deterministic phone-menu disclosure/close behavior, and merged #657 route-focus handoff onto live source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. Pinned source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7` must match an exact two-parent merge whose first parent is `95880748e15c03b0ee58da6e1ed11ac6c9526529`. Until the exact preview, signed-out public checks, and immediate repause all pass, #623 deploy `6a7e072f8f346b0008510d29` remains production and the rollback target. #659 does not publish accumulated `main`, deploy Firebase, configure a provider, use an account, change production data, or connect the directory. Directory availability stays literal `false`; reusable hosting remains open under #460/#133/#136. + ## 3. Dependency map ```mermaid diff --git a/OFFICER_START_HERE.md b/OFFICER_START_HERE.md index ebdb60c..a1c6e15 100644 --- a/OFFICER_START_HERE.md +++ b/OFFICER_START_HERE.md @@ -48,6 +48,8 @@ Use the club's approved password manager for access. Share only a public link or As of **2026-08-13**, a merge runs checks but does not start the GitHub release. The protected release is **NOT AVAILABLE YET** until its short-lived cloud identity and named environment approvers are configured under issue #133. Ordinary Git-triggered Netlify production builds are paused. An overbroad #473 web artifact was published and immediately rolled back; its bounded replacement remains the recorded rollback. #623 then completed one separate, exact-artifact release of the inert member-directory interface. Netlify deploy `6a7e072f8f346b0008510d29` is live from source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. Signed-out route and guard checks passed, no member-directory request was observed, and repause merge `c8678c623afdd9becf77d596b71f36f26f04b746` made the temporary manifest inactive without replacing that deploy. Shop remains the static in-person catalog, while Events and Calendar show a fixed retry-later notice instead of a raw provider error. Event records are still unavailable because no Firebase repair was deployed. This does not change sign-in, expose protected event offers, add officer editing, or make commerce safe. GitHub Pages still reports `runmprc.com` as its custom domain even though Netlify serves that name; source removal is not provider proof. A green test or workflow does **not** by itself prove that GitHub Pages, `runmprc.com`, Firebase, or that domain setting changed. +As of **2026-08-14**, [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is one accessibility-only Netlify release under review and is not published. It pins one frozen 62-file artifact from source `7496fe0881fb52908c4ff2f40f488df09c94c908` and combines only the reviewed visible keyboard focus, phone-menu close/disclosure, and client-side route-focus behavior. Production remains #623 deploy `6a7e072f8f346b0008510d29`, which is also the rollback target. Officers do not run commands, sign in, enter data, change Firebase or a provider, or approve this as a reusable release. A named observer may perform the safe signed-out browser checks only after the platform owner supplies the exact preview, marker, and approval record. Follow [Review, merge, release, and check a change](./docs/officers/PUBLISH_AND_CHECK.md) and stop on any mismatch. + 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). For the concise handbook, see [OFFICER_HANDBOOK.md](./OFFICER_HANDBOOK.md). The expanded task index is [docs/officers/README.md](./docs/officers/README.md). diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index 26db2f3..d548c59 100644 --- a/OPERATIONS_RUNBOOK.md +++ b/OPERATIONS_RUNBOOK.md @@ -691,6 +691,8 @@ WEB-002A [#473](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/473) compl WEB-002C [#623](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/623) completed its bounded inert member-directory interface release on 2026-08-13. Pinned Deploy Preview `6a7e05febf8fde00084cf9e0` matched release-control head `1fdb31f71fcaf01c33b5e57a4cd28fc473a4a737`, and PR CI run `31728469418` passed. Exact two-parent merge `9d5cc8612b4321172370bd949d307e7e4ac0ec7d`, parents `019353361210021483f23003e09ee6924b78e67c` and `1fdb31f71fcaf01c33b5e57a4cd28fc473a4a737`, tree `41b6d024d369d93f28ea49940b4f4e5710d3ab52`, passed exact-main CI run `31728908486`. Netlify deploy `6a7e072f8f346b0008510d29` became ready and published at `2026-08-13T18:05:35.983Z`. Its marker matched frozen source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, tree `411aa6ec9a9459f5d923030533ffc7c007fe6908`, previous source `39ab8649df411262c8109a3c81a57bc38f1e168b`, rollback deploy `6a6dc9ea588b0c0008036312`, 62 files, and digest `d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1`. Signed-out `/account` and `/admin/member-directory` checks retained the normal guards; route and bundle review found no connected member-directory symbol or request. Protected Account and administrator layouts remain proved only with synthetic local artifacts. Repause head `d401daa409176dce0906c245adf3f20310cb513b` passed PR CI run `31728977578`; exact two-parent repause merge `c8678c623afdd9becf77d596b71f36f26f04b746`, parents `9d5cc8612b4321172370bd949d307e7e4ac0ec7d` and `d401daa409176dce0906c245adf3f20310cb513b`, passed all five exact-main jobs in run `31729248865`. Its Netlify attempt `6a7e081e73fdd60009f7ba57` errored unpublished; provider and marker readback retained deploy `6a7e072f8f346b0008510d29`. The manifest is inactive, the release source ref is absent, and rollback ref `codex/netlify-source-623-rollback` remains. #623 deployed no Firebase, Rules, Functions, or indexes; changed no outside-provider configuration, account, sign-in, or production data; and made no connected directory behavior available. Connected behavior remains **NOT AVAILABLE YET** under [#507](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/507). Do not reuse this exception as a general release button. +WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is an active one-shot Netlify accessibility release under review and is not published. Release ID `WEB-002D-KEYBOARD-FOCUS-2026-08-14` pins remote source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and artifact digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`; the exact six-path diff from previous/current live source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec` has digest `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`. The manifest expects exact first parent `95880748e15c03b0ee58da6e1ed11ac6c9526529`, release branch `codex/issue-659-netlify-release`, source ref `codex/netlify-source-659-keyboard-focus`, and rollback deploy `6a7e072f8f346b0008510d29`; rollback ref `codex/netlify-source-659-rollback` pins the current live source. The frozen source changes only `src/App.jsx`, `src/App.test.jsx`, `src/components/Navbar.jsx`, `src/components/ScrollToTop.jsx`, `src/headerClearance.test.jsx`, and `src/index.css`, combining exact reviewed #291 visible focus, #490 phone-menu disclosure/close behavior, and #657 path-navigation focus. Until the pinned preview, exact two-parent merge, production marker, signed-out desktop/phone focus and menu checks, and immediate repause all pass, #623 deploy `6a7e072f8f346b0008510d29` remains production and the rollback target. Stop for any source, tree, path, count, artifact, parent, marker, focus, menu, network, or repause mismatch. #659 has no authority for Firebase, Rules, Functions, indexes, outside-provider configuration, accounts, sign-in, production data, content, routes, payments, or connected directory behavior; directory availability remains literal `false`. Follow the pending no-terminal procedure in `docs/officers/PUBLISH_AND_CHECK.md`; never use this exception as a general release button. + 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 81eb8e0..03293ce 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -86,6 +86,7 @@ The findings below describe the repository at the start of the 2026-07-12 assess | RISK-034 | Webhook error response includes the Stripe library's signature error detail. | Return generic client errors; keep sanitized structured diagnostics server-side. | | RISK-035 | The deterministic frontend Jest suite and standalone SPA callback suite run as separate blocking hosted CI steps. CI-001B4/#186 merged a non-mutating frontend lint gate as `bec7d5e365eacb418563a172029f241f660d9768`; exact PR and post-merge runs passed. CI-001B4A [#227](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/227) removes one reviewed `arrow-body-style` error, CI-001B4B [#239](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/239) removes one stale `AdminMembers` unknown-rule suppression record, and PAY-004C1 [#359](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/359) retires one `no-alert` warning plus two label-association errors with the unsafe reusable-link controls. Reviewed functional changes in [PR #391](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/391) and [PR #392](https://github.com/Run-MPRC/Run-MPRC.github.io/pull/392) add one and two TypeScript files respectively while retiring two TSX errors each. CI-001B4C [#449](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/449) replaces the four remaining stale `react-hooks/exhaustive-deps` directives with ordinary same-line comments, without changing executable code or the gate. MEMBERS-CONTENT-001B [#492](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/492) removes one finding-free dormant JSX file. MEMBERS-DIRECTORY-001A [#505](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/505) adds four finding-free TypeScript/TSX files, 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, isolated staging, a reusable live-Netlify path, and provider-owned atomic rollback remain unverified. | Require a final blocker re-read and an executable delta from the live artifact before every release merge. Preserve the exact #473 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, provision isolated staging, protect the reusable Netlify release path under WEB-001, and rehearse provider rollback before broader production work. | +| WEB-002D pending exact-artifact containment for RISK-036 | [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is an active accessibility-only release under review and is not published. Its frozen source `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7` project only reviewed #291 visible-focus, #490 phone-menu, and #657 route-focus behavior over live source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. The exact six-path diff digest is `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`. Production remains #623 deploy `6a7e072f8f346b0008510d29`, which is also the rollback target. Literal-false directory availability, Firebase, providers, accounts, sign-in, production data, and connected directory behavior are unchanged. | Require the pinned preview, exact parent `95880748e15c03b0ee58da6e1ed11ac6c9526529`, exact two-parent merge, signed-out marker/focus/menu checks, separately reviewed rollback, and immediate repause. Stop for any source, tree, scope, count, digest, parent, marker, focus, menu, directory-request, backend, provider, account, data, or repause mismatch. Treat #659 as one temporary exception, not reusable authority. Preserve active #616 OAUTH-001A2L files and its RISK-024 wording byte-for-byte. | | 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. | | RISK-039 | Some authenticated accounts can lack `members/{uid}` after the Firebase cutover; the account screen hid the read failure and exposed an update that could only fail. Manual database/account repair could corrupt roles or private data. | Use an authenticated create-once server bootstrap, keep browser creation denied, fail the UI closed, and prove backend-first deployment with synthetic accounts. | diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md index efac33a..cca886f 100644 --- a/SYSTEM_DESIGN.md +++ b/SYSTEM_DESIGN.md @@ -95,6 +95,8 @@ The former workflow automatically published Pages before attempting Firebase and #623 completed the same fail-closed pattern for one inert member-directory interface artifact. Deploy Preview `6a7e05febf8fde00084cf9e0` matched control head `1fdb31f71fcaf01c33b5e57a4cd28fc473a4a737`. Exact merge `9d5cc8612b4321172370bd949d307e7e4ac0ec7d`, with first parent `019353361210021483f23003e09ee6924b78e67c`, published deploy `6a7e072f8f346b0008510d29` from source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, tree `411aa6ec9a9459f5d923030533ffc7c007fe6908`, 62 files, and digest `d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1`. Its marker also records previous source `39ab8649df411262c8109a3c81a57bc38f1e168b` and rollback deploy `6a6dc9ea588b0c0008036312`. Signed-out route, guard, and bundle checks found no connected member-directory request or symbol. Repause merge `c8678c623afdd9becf77d596b71f36f26f04b746` made the manifest inactive; attempt `6a7e081e73fdd60009f7ba57` stopped unpublished and retained the verified deploy and marker. The release source ref is absent and the rollback ref remains. The release changed no Firebase, outside-provider configuration, sign-in state, or production data. Build hooks and a reusable protected Netlify publication path remain unverified. No source test clears the current Pages custom-domain claim, configures #133, or deploys #136; those remain separate provider states. The App Engine synchronization script is another surface that must be documented as active or retired. +WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is one active exact-artifact exception under review, not a completed publication. It freezes only the reviewed #291 visible-focus treatment, #490 deterministic phone-menu disclosure/close behavior, and #657 client-side route-focus handoff over current live source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`. Its pinned source is `7496fe0881fb52908c4ff2f40f488df09c94c908`, tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`, 62 files, and artifact digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`; the exact six-path live-source diff digest is `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`, and the expected production first parent is `95880748e15c03b0ee58da6e1ed11ac6c9526529`. Until its pinned preview, exact two-parent merge, signed-out public focus checks, and immediate repause all pass, #623 deploy `6a7e072f8f346b0008510d29` remains production and the rollback target. #659 changes no route, content, Firebase surface, outside-provider configuration, account, sign-in state, production data, or directory behavior; directory availability remains literal `false`. Stop on any source, tree, file-count, artifact, parent, focus, menu, marker, or repause mismatch. + ```mermaid flowchart TD Merge["Merge to main"] --> CI["Exact main-push CI"] @@ -113,9 +115,10 @@ flowchart TD WebOnly --> Netlify Netlify --> WebReadback["Exact marker and signed-out guards verified"] WebReadback --> WebRepause["Temporary authority inactive; verified deploy retained"] + Pending["#659 exact focus artifact under review"] -. "Not published" .-> Netlify ``` -Text alternative: ordinary merges run CI and do not publish Netlify. #623 completed one exact-parent exception and production now serves its pinned inert artifact. Signed-out marker and guard 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. #623 completed one exact-parent exception and production now serves its pinned inert artifact. #659 is a separate exact focus-artifact release under review and has not published. Signed-out marker and guard checks passed for #623, then its temporary authority was disabled without replacing the verified deploy. 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 83e505d..31a645c 100644 --- a/config/netlify-production-release.json +++ b/config/netlify-production-release.json @@ -1,16 +1,16 @@ { "schemaVersion": 1, - "active": false, - "releaseId": "WEB-002C-MEMBER-DIRECTORY-PREVIEW-2026-08-13", - "issueNumber": 623, - "previewBranch": "codex/issue-623-netlify-release", - "expectedProductionParent": "019353361210021483f23003e09ee6924b78e67c", + "active": true, + "releaseId": "WEB-002D-KEYBOARD-FOCUS-2026-08-14", + "issueNumber": 659, + "previewBranch": "codex/issue-659-netlify-release", + "expectedProductionParent": "95880748e15c03b0ee58da6e1ed11ac6c9526529", "sourceRepository": "https://github.com/Run-MPRC/Run-MPRC.github.io.git", - "sourceRef": "refs/heads/codex/netlify-source-623-member-directory-preview", - "sourceCommit": "c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec", - "sourceTree": "411aa6ec9a9459f5d923030533ffc7c007fe6908", - "previousSourceCommit": "39ab8649df411262c8109a3c81a57bc38f1e168b", - "rollbackDeployId": "6a6dc9ea588b0c0008036312", + "sourceRef": "refs/heads/codex/netlify-source-659-keyboard-focus", + "sourceCommit": "7496fe0881fb52908c4ff2f40f488df09c94c908", + "sourceTree": "ccac4c189c195db8ab594e0eefe256ea9fa04996", + "previousSourceCommit": "c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec", + "rollbackDeployId": "6a7e072f8f346b0008510d29", "expectedSiteFileCount": 62, - "expectedSiteFilesSha256": "d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1" + "expectedSiteFilesSha256": "e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7" } diff --git a/docs/officers/PUBLISH_AND_CHECK.md b/docs/officers/PUBLISH_AND_CHECK.md index f4abd20..eea3c27 100644 --- a/docs/officers/PUBLISH_AND_CHECK.md +++ b/docs/officers/PUBLISH_AND_CHECK.md @@ -12,6 +12,8 @@ **Live Netlify publication status:** a reusable protected release is **NOT AVAILABLE YET**. Ordinary Git-triggered production builds are paused by repository configuration. An overbroad #473 artifact was published and then rolled back on 2026-08-01; bounded #473 deploy `6a6dc9ea588b0c0008036312`, source `39ab8649df411262c8109a3c81a57bc38f1e168b`, remains the recorded rollback. #623 completed one separate exact-artifact release. Deploy `6a7e072f8f346b0008510d29`, source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, is production now. Its signed-out marker, guard, route, and no-directory-request checks passed. The manifest is inactive, the release source is absent, and the rollback ref remains. Shop is the static catalog; Events and Calendar show a fixed retry-later notice instead of a raw provider error. Event records remain unavailable because this did not deploy Firebase. GitHub Pages currently still claims the same custom domain; future source omits that claim, but #136/WEB-001 must publish and verify its removal. +**Pending #659 exception:** WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is one active exact-artifact accessibility release under review and is not published. The frozen source contains only reviewed #291 visible focus, #490 phone-menu disclosure/close behavior, and #657 client-side route focus. Production remains #623 deploy `6a7e072f8f346b0008510d29`, which is also #659's rollback target. This is not an officer-operated or reusable control. The no-terminal procedure below permits only signed-out public checks after exact source, preview, merge, and marker proof. + ## The release gate ```mermaid @@ -57,7 +59,7 @@ As of **2026-07-13**, with the internal tooling note below checked from source o - `runmprc.com` is served by Netlify, not GitHub Pages. - GitHub Pages currently reports `runmprc.com` as its custom domain and redirects its normal address there. It is not an independently reachable copy today. - Future source stops writing that Pages domain claim. Only provider readback after #136/WEB-001 can prove it cleared. -- Ordinary Git-triggered Netlify production builds are paused. The completed #473 exception used one exact two-parent merge and pinned source/tree/artifact; its release source is retired. #623 completed a second exact-parent one-shot, published only its frozen inert artifact, passed signed-out readback, and was immediately re-paused. Its release source is retired; its rollback ref remains. +- Ordinary Git-triggered Netlify production builds are paused. The completed #473 exception used one exact two-parent merge and pinned source/tree/artifact; its release source is retired. #623 completed a second exact-parent one-shot, published only its frozen inert artifact, passed signed-out readback, and was immediately re-paused. Its release source is retired; its rollback ref remains. #659 is a separate exact accessibility artifact under review and is not published; #623 deploy `6a7e072f8f346b0008510d29` remains live and is #659's rollback target. - Live race signup, merchandise payments, and refunds remain unavailable. - CONFIG-001B1 [#151](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/151) adds source enforcement for a server-only commerce pause. It is not in the fixed profile-recovery release plan, is not deployed, and has no approved officer control. A future reviewed plan must deploy the complete guarded Function set with the deploy ceiling and every runtime/resource flag off, then prove signed webhooks still work. Do not widen the current plan by hand. @@ -163,6 +165,87 @@ If a member or officer sees **Server configuration is unavailable**: 6. Do not expect GitHub Pages, Firebase, Netlify, or `runmprc.com` to change from a merge unless a separate exact temporary release is explicitly armed and reviewed. 7. For any other merge, if Netlify unexpectedly publishes, stop and treat it as a hosting incident. +## Temporary #659 keyboard-navigation and route-focus release — UNDER REVIEW, NOT PUBLISHED + +**Purpose:** publish one frozen accessibility-only website artifact. Keyboard users receive the reviewed visible-focus treatment, truthful phone-menu disclosure and closing, and a one-time focus move into new main content after client-side path navigation. This does not change public content, routes, sign-in, Firebase, providers, accounts, production data, payments, or connected directory behavior. + +**Approver:** Dave Liu as platform owner, plus the accessibility reviewer. This is not an officer-operated or reusable release control. + +**Prerequisites:** approved issue [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) with no newer blocker; release ID `WEB-002D-KEYBOARD-FOCUS-2026-08-14`; green exact-head checks; successful pinned Deploy Preview; source commit `7496fe0881fb52908c4ff2f40f488df09c94c908`; source tree `ccac4c189c195db8ab594e0eefe256ea9fa04996`; 62-file digest `e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7`; exact six-path live-to-source diff digest `462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c`; exact first parent `95880748e15c03b0ee58da6e1ed11ac6c9526529`; current production and rollback deploy `6a7e072f8f346b0008510d29`; current live source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`; current live tree `411aa6ec9a9459f5d923030533ffc7c007fe6908`; current live 62-file digest `d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1`; release source `codex/netlify-source-659-keyboard-focus`; rollback source `codex/netlify-source-659-rollback`; an executable six-path diff; reviewed #291, #490, and #657 equivalence evidence; synthetic desktop and phone proof; a prepared manifest-disable change; a named signed-out public observer; and no other `main` merge until verification and repause finish. + +**Specialist dependency:** the platform maintainer supplies the exact GitHub, Netlify, marker, artifact, and rollback records. The officer uses reviewed links and a private browser only. The officer does not run a command, sign in, change a provider, inspect private data, or handle a secret. + +```mermaid +flowchart TD + Source["Frozen six-path source"] --> Preview["Pinned #659 Deploy Preview"] + Preview --> Match{"Source, tree, count, digest, and marker match?"} + Match -- "No" --> Keep["Stop — keep #623 deploy live"] + Match -- "Yes" --> Merge["Exact-parent two-parent merge"] + Merge --> Public["Signed-out desktop and phone checks"] + Public --> Good{"Focus, menu, marker, and network checks pass?"} + Good -- "No" --> Rollback["Restore #623 deploy"] + Good -- "Yes" --> Repause["Disable temporary authority"] + Repause --> Verify["Confirm no replacement; retire temporary refs"] +``` + +In words: the preview must match the exact six-path frozen artifact. Only the exact-parent merge may publish it. Signed-out desktop and phone checks then verify the marker, visible focus, phone-menu behavior, and absence of a directory request. A mismatch leaves or restores the current #623 deploy. A success is immediately re-paused, and the temporary refs are retired. + +1. Open the #659 release pull request. +2. Confirm its destination is `main`. +3. Confirm its head is the exact reviewed control commit. +4. Confirm every required check for that head is green. +5. Ask the platform maintainer for the frozen source identity. +6. Confirm the source commit and tree match the prerequisites. +7. Confirm the artifact count and digest match the prerequisites. +8. Confirm the six-path diff digest matches the prerequisites. +9. Confirm the six changed paths are `src/App.jsx`, `src/App.test.jsx`, `src/components/Navbar.jsx`, `src/components/ScrollToTop.jsx`, `src/headerClearance.test.jsx`, and `src/index.css`. +10. Confirm the review found only #291 visible-focus behavior, #490 phone-menu behavior, and #657 route-focus behavior. +11. Confirm the review found no new route, content, service, Firebase, provider, account, data, payment, or connected-directory behavior. +12. Confirm the directory availability value remains literal `false`. +13. Read the synthetic desktop result at 1280 by 900 CSS pixels. +14. Confirm the first load kept body focus and showed no main-content cue. +15. Confirm a client-side path change focused main content at scroll position zero. +16. Confirm the scoped cue was visible, unclipped, layout-neutral, and below the navigation layer. +17. Read the synthetic phone result at 390 by 844 CSS pixels. +18. Confirm a public phone-menu choice closed the menu and reported its collapsed state. +19. Confirm phone navigation focused the new main content with the same bounded cue. +20. Confirm the next Tab movement followed the normal destination order. +21. Open the pinned Deploy Preview marker. +22. Confirm its control, source, tree, previous source, rollback deploy, count, and digest match the prerequisites. +23. Confirm the preview marker uses HTTPS, JSON, no-store, nosniff, and HSTS. +24. Confirm preview pages carry `X-Robots-Tag: noindex`. +25. Stay signed out and open safe public preview pages at both checked widths. +26. Confirm direct load keeps body focus and the skip link appears on the first Tab. +27. Confirm public path navigation moves focus into the new main content once. +28. Confirm the phone menu closes and reports its collapsed state. +29. Confirm the preview network record contains no member-directory request. +30. Confirm the rollback ref and prepared repause are ready. +31. Re-read the issue and pull-request comments. +32. Stop for any unresolved blocker posted after the last review. +33. Confirm `main` is still exact commit `95880748e15c03b0ee58da6e1ed11ac6c9526529`. +34. Have the platform owner merge with a merge commit. +35. Confirm the production attempt identifies that exact two-parent merge on `main`. +36. Read the live public marker before checking behavior. +37. Confirm the live marker matches the preview's stable source, tree, previous source, rollback deploy, count, and digest. +38. Stay signed out and repeat the safe focus and phone-menu checks at both widths. +39. Confirm the production network record contains no member-directory request. +40. Record Firebase, providers, accounts, sign-in, and production data as unchanged. +41. Have the platform owner merge the prepared manifest-disable change immediately. +42. Confirm its Netlify attempt does not replace the verified deploy. +43. Read the public marker again and confirm the verified deploy remains live. +44. Confirm the release, control, and repause refs are retired. +45. Confirm the rollback ref remains pinned to the prior live source. + +**Expected result:** if every gate passes, Netlify serves exactly the frozen accessibility artifact. A direct load keeps body focus and the skip link remains first. A client-side path change moves otherwise-stale focus into main content once with a visible bounded cue. A phone-menu destination closes the menu with truthful disclosure state and leaves normal next-Tab order. The release deploys no Firebase, Rules, Functions, or indexes; configures no provider; uses no account; changes no production data; and does not connect the directory. Until the production and repause proof exists, #659 remains under review and not published, while #623 deploy `6a7e072f8f346b0008510d29` remains live. + +**Stop conditions:** stop if `main` advances; a branch, context, source, tree, six-path scope, count, digest, parent, marker, asset, page, focus, cue, menu, network record, rollback, or repause result differs; a seventh source path appears; accumulated `main` behavior appears; the cue is absent or clipped; focus is stolen, trapped, stale, or out of order; the phone menu remains open or reports the wrong state; a protected control is enabled; a public check asks for sign-in or private data; a directory request appears; Firebase or a provider changes; another production attempt starts; or any blocker remains open. + +**Success proof:** keep the issue and pull-request links; exact control, source, tree, parent, and six-path diff identities; artifact count and digest; preview deploy and marker; required checks; signed-out desktop and phone page/focus/menu/network results; release merge; production deploy and marker; repause merge and unpublished attempt; retained-deploy readback; retired temporary refs; retained rollback ref; check date; browser; widths; and two redacted public screenshots. Record source, tests, merge, preview, website publication, `runmprc.com` revision, Firebase, outside providers, accounts/sign-in, production data, and live focus behavior as separate states. + +**Undo:** before publication, leave deploy `6a7e072f8f346b0008510d29` live. If the wrong result publishes, ask the Netlify team owner to atomically restore that same deploy. If provider restore is unavailable, use only a newly reviewed exact-parent rollback pinned to source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, then repeat its exact preview and marker checks. Disabling the manifest alone does not roll back an already published deploy. + +**Escalation:** platform owner first; accessibility reviewer second; security/privacy owner if an unexpected request, private value, account boundary, or provider action appears. Use the private incident path for any private data or secret. Do not copy that value into GitHub, a screenshot, email, or an AI tool. + ## Temporary #623 inert member-directory interface release — COMPLETED 2026-08-13 **Purpose:** record the completed publication of only the visibly disabled My Account profile-photo/finder-choice interface and the administrator-guarded People finder layout. This is an interface preview. It does not connect the private backend, read or save a setting, accept or upload a photo, search a name, or show a person. @@ -385,13 +468,13 @@ Do not use this section until #133 records that both GitHub environments are pro 9. Use made-up data only. Do not inspect or change a real member record. 10. Complete the delivery record. -### Check keyboard focus after an approved website publication — NOT AVAILABLE YET +### Check keyboard focus after an approved website publication — #659 EXACT-ARTIFACT CHECK UNDER REVIEW **Purpose:** prove that a person using a keyboard can see which public link, button, or navigation control is active. **Approver:** the named release observer, with the platform owner or accessibility reviewer available if the check fails. -**Prerequisites:** protected website publication must be available; the exact approved commit must be live and identified by the host; the public site must be safe to open without signing in; and the observer must use a normal computer with a keyboard. Publication is still **NOT AVAILABLE YET** under #133/#136, so do not record live proof from this procedure until those prerequisites are met. +**Prerequisites:** the exact approved commit must be live and identified by the host; the public site must be safe to open without signing in; and the observer must use a normal computer with a keyboard. The reusable protected website release is still **NOT AVAILABLE YET** under #133/#136. #659 is one exact-artifact exception under review and is not published. Use this check for #659 only after its public marker matches the approved release; until then, #623 deploy `6a7e072f8f346b0008510d29` remains the verified host record. 1. Open the public website in a private browser window. 2. Confirm the host identifies the exact approved commit. @@ -413,13 +496,13 @@ Do not use this section until #133 records that both GitHub environments are pro **Escalation:** platform owner first, then the accessibility reviewer or backup release officer. Treat an unexpected live publication as a hosting incident. -### Verify focus after a client-side page change — WEB-UX-004 SOURCE CHECK AVAILABLE; LIVE CHECK NOT AVAILABLE YET +### Verify focus after a client-side page change — WEB-UX-004 MERGED; #659 LIVE CHECK UNDER REVIEW **Purpose:** prove that a keyboard user who opens another page without a full browser reload moves from the old navigation control into the new main content. The source must not move focus on the first page load or take focus that the new page or user already chose. A client-side page change replaces the page content while the website stays open. **Approver:** the pull-request accessibility reviewer approves the source evidence. The named release observer approves a later public check, with the platform owner available if the revision or publication record is unclear. -**Prerequisites:** issue #657; one exact reviewed pull request and commit; the recorded old-source failure; the named green WEB-UX-004 and full App results; and a reviewed undo. The source check uses GitHub and test summaries only. It needs no terminal, account, sign-in, private page, or real data. The later public check also requires a separately approved exact commit, host readback for that commit, a private browser window, a keyboard, and safe signed-out public pages. Protected publication is still **NOT AVAILABLE YET** under #133/#136. At the time this procedure was added, #623 Netlify deploy `6a7e072f8f346b0008510d29`, source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, remained live. Do not call WEB-UX-004 live while that remains the host record. +**Prerequisites:** issue #657; reviewed PR #658 and exact head `a411cb4ebcfb4f1f05b3883721aa55f3d72bc701`; the recorded old-source failure; the named green WEB-UX-004 and full App results; and a reviewed undo. The source check uses GitHub and test summaries only. It needs no terminal, account, sign-in, private page, or real data. #659 now pins the equivalent route-focus behavior with its #291/#490 prerequisites in source `7496fe0881fb52908c4ff2f40f488df09c94c908`, but that one-shot release is under review and is not published. The later public check requires the exact #659 marker, a private browser window, a keyboard, and safe signed-out public pages. Reusable protected publication remains **NOT AVAILABLE YET** under #133/#136. #623 Netlify deploy `6a7e072f8f346b0008510d29`, source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, remains live. Do not call WEB-UX-004 live while that remains the host record. **Specialist dependency:** the platform maintainer must supply the exact issue, pull request, commit, test record, and later host readback. The officer can perform every browser step without a terminal. No Firebase or provider specialist action belongs to this check because those surfaces do not change. @@ -441,7 +524,7 @@ Do not use this section until #133 records that both GitHub environments are pro 14. Read the full App result and the hosted required checks for the same exact commit. 15. Record source changed, tests passed, and merge state separately. -**Later signed-out public check — NOT AVAILABLE YET:** +**Later signed-out public check — ONLY AFTER THE EXACT #659 MARKER IS LIVE:** 16. Open the approved public page in a private browser window at 1280 CSS pixels wide. 17. Confirm the host identifies the exact approved commit. diff --git a/docs/officers/README.md b/docs/officers/README.md index 9a9ee89..8c49c2e 100644 --- a/docs/officers/README.md +++ b/docs/officers/README.md @@ -65,6 +65,8 @@ Never shorten several of these states to “done.” Independent officer publishing to the live Netlify host is **NOT AVAILABLE YET**. An overbroad #473 artifact was published and rolled back on 2026-08-01; bounded #473 deploy `6a6dc9ea588b0c0008036312` remains the recorded rollback. #623 completed one separate, exact-artifact release of the inert member-directory interface. Deploy `6a7e072f8f346b0008510d29`, source `c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec`, is live. Signed-out guard and no-request checks passed. The temporary manifest is inactive, and its repause attempt did not replace the verified deploy. Shop remains the static pickup catalog, and Events/Calendar show a fixed retry-later notice instead of a raw provider error. Event records remain unavailable. This is not a reusable officer control. Use a platform maintainer until the Netlify connection and rollback path are documented and tested. +WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) is one temporary accessibility artifact under review and is not published. It pins source `7496fe0881fb52908c4ff2f40f488df09c94c908` and only the reviewed visible-focus, phone-menu, and client-side route-focus behavior. Production remains #623 deploy `6a7e072f8f346b0008510d29`; that deploy is #659's rollback target. Officers perform no terminal, account, Firebase, provider, or production-data action. A named signed-out observer follows [Review, merge, release, and check a change](./PUBLISH_AND_CHECK.md) only after the platform owner supplies the exact preview and marker. A preview, green check, or merged release control does not prove the website changed. + The protected GitHub release is also **NOT AVAILABLE YET** until #133 configures the environment approvers and short-lived cloud identity. Missing authority stops the release with a red failure before Firebase or website publication. GitHub Pages currently still claims `runmprc.com`, so its normal address redirects to the Netlify-served name. The source stops adding that claim, but #136/WEB-001 must publish and verify the provider setting before officers call Pages an independent copy. diff --git a/docs/officers/UPDATE_PUBLIC_CONTENT.md b/docs/officers/UPDATE_PUBLIC_CONTENT.md index ad85b14..0d6d50c 100644 --- a/docs/officers/UPDATE_PUBLIC_CONTENT.md +++ b/docs/officers/UPDATE_PUBLIC_CONTENT.md @@ -112,13 +112,13 @@ Do not publish photos of minors, private events, name badges, addresses, license 4. Check spelling, title, photo, order, and old-officer removal. 5. Ask AI to confirm no account permissions changed. Website display and GitHub/Firebase access are separate. -## Phone navigation preview check — NOT LIVE YET +## Phone navigation preview check — SOURCE AVAILABLE; #659 LIVE CHECK UNDER REVIEW **Purpose:** confirm that the small-screen menu is predictable before a website release. **Approver:** communications lead or platform owner. -**Before you start:** have the reviewed preview link. Stay signed out and use no private information. +**Before you start:** have the reviewed preview link. Stay signed out and use no private information. WEB-002D [#659](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/659) freezes the reviewed #490 phone-menu behavior with the related visible-focus and route-focus source for one exact-artifact release, but it is under review and is not published. Production remains #623 deploy `6a7e072f8f346b0008510d29`, which is also #659's rollback target. 1. Open the preview at a phone-sized width. 2. Select the MPRC logo while the menu is closed. @@ -141,7 +141,7 @@ Do not publish photos of minors, private events, name badges, addresses, license **Escalation:** platform owner first; accessibility reviewer second. -This check describes #490 source and preview behavior only. It is **NOT LIVE YET** until an approved exact website release is published and the same checks pass on `runmprc.com`. +This check describes #490 source and preview behavior. The #659 signed-out live observer may repeat the phone-menu check only after the public marker identifies the exact approved release. On production, use safe public destinations only; do not choose Sign in, enter data, open a private page, or submit a form. Until the exact #659 publication and repause records pass, this behavior is **NOT LIVE YET** and #623 remains the verified host record. Follow the full no-terminal procedure in [Review, merge, release, and check a change](./PUBLISH_AND_CHECK.md). ## Success check diff --git a/netlify.toml b/netlify.toml index 29b3ecd..9c4cafe 100644 --- a/netlify.toml +++ b/netlify.toml @@ -16,7 +16,7 @@ command = "node ./scripts/netlify-release-build.js" [context.deploy-preview] - # The temporary #623 production authority is inactive again. Ordinary + # The #659 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 2d5c895..f41181e 100644 --- a/tests/release-workflow.test.js +++ b/tests/release-workflow.test.js @@ -33,6 +33,16 @@ const FINAL_RELEASE_TRUTH_PATHS = [ 'docs/officers/REQUEST_A_CHANGE.md', 'docs/officers/SYSTEM_MAPS.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, @@ -54,6 +64,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 }; @@ -226,58 +242,58 @@ test('Netlify production is an exact-artifact release while previews remain avai }); }); -test('Netlify manifest pins the inactive bounded #623 interface release', () => { +test('Netlify manifest pins the active bounded #659 keyboard-focus 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-002C-MEMBER-DIRECTORY-PREVIEW-2026-08-13', + 'WEB-002D-KEYBOARD-FOCUS-2026-08-14', ); - assert.equal(loaded.manifest.issueNumber, 623); + assert.equal(loaded.manifest.issueNumber, 659); assert.equal( loaded.manifest.expectedProductionParent, - '019353361210021483f23003e09ee6924b78e67c', + '95880748e15c03b0ee58da6e1ed11ac6c9526529', ); assert.equal( loaded.manifest.sourceCommit, - 'c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec', + '7496fe0881fb52908c4ff2f40f488df09c94c908', ); assert.equal( loaded.manifest.sourceTree, - '411aa6ec9a9459f5d923030533ffc7c007fe6908', + 'ccac4c189c195db8ab594e0eefe256ea9fa04996', ); assert.equal( loaded.manifest.previousSourceCommit, - '39ab8649df411262c8109a3c81a57bc38f1e168b', + 'c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec', ); assert.equal( loaded.manifest.rollbackDeployId, - '6a6dc9ea588b0c0008036312', + '6a7e072f8f346b0008510d29', ); assert.equal( loaded.manifest.sourceRef, - 'refs/heads/codex/netlify-source-623-member-directory-preview', + 'refs/heads/codex/netlify-source-659-keyboard-focus', ); assert.equal( loaded.manifest.previewBranch, - 'codex/issue-623-netlify-release', + 'codex/issue-659-netlify-release', ); assert.equal(loaded.manifest.expectedSiteFileCount, 62); assert.equal( loaded.manifest.expectedSiteFilesSha256, - 'd837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1', + 'e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7', ); }); -test('completed #623 records are live while #473 remains rollback history', () => { +test('completed #623 records stay live while #659 is pending', () => { assert.match( netlifyConfig, - /temporary #623 production authority is inactive again/i, + /#659 control-branch preview verifies its exact pinned source/i, ); assert.match( netlifyConfig, - /Ordinary[\s\S]{0,20}previews use their checked-out tree/i, + /Other[\s\S]{0,20}previews use their checked-out tree/i, ); finalReleaseTruth.forEach((contents, relativePath) => { @@ -371,6 +387,68 @@ test('completed #623 records are live while #473 remains rollback history', () = }); }); + const expectedPendingTruth = new Map([ + [ + 'IMPLEMENTATION_PLAN.md', + /\*\*WEB-002D pending release boundary:\*\* \[#659\][^\n]*under review and is not published/i, + ], + [ + 'OFFICER_START_HERE.md', + /As of \*\*2026-08-14\*\*, \[#659\][^\n]*under review and is not published/i, + ], + [ + 'OPERATIONS_RUNBOOK.md', + /WEB-002D \[#659\][^\n]*active one-shot Netlify accessibility release under review and is not published/i, + ], + [ + 'SECURITY.md', + /WEB-002D pending exact-artifact containment for RISK-036 \| \[#659\][^\n]*under review and is not published/i, + ], + [ + 'SYSTEM_DESIGN.md', + /WEB-002D \[#659\][^\n]*active exact-artifact exception under review, not a completed publication/i, + ], + [ + 'docs/officers/PUBLISH_AND_CHECK.md', + /^## Temporary #659 keyboard-navigation and route-focus release — UNDER REVIEW, NOT PUBLISHED$/m, + ], + [ + 'docs/officers/README.md', + /WEB-002D \[#659\][^\n]*under review and is not published/i, + ], + [ + 'docs/officers/UPDATE_PUBLIC_CONTENT.md', + /WEB-002D \[#659\][^\n]*under review and is not published/i, + ], + ]); + expectedPendingTruth.forEach((expectedTruth, relativePath) => { + const contents = pendingReleaseTruth.get(relativePath); + assert.match( + contents, + expectedTruth, + `${relativePath} must bind #659 to its exact pending status`, + ); + assert.match(contents, /#659/); + assert.match(contents, /6a7e072f8f346b0008510d29/); + assert.doesNotMatch( + contents, + /#659 (?:has )?completed (?:one|its)|#659 published deploy|#659 is production/i, + `${relativePath} must not claim that #659 is live`, + ); + }); + [ + '7496fe0881fb52908c4ff2f40f488df09c94c908', + 'ccac4c189c195db8ab594e0eefe256ea9fa04996', + 'e4c26e6f0fbcd086663d86238675f0be228fb649a00628c1c97d1166612f49c7', + '95880748e15c03b0ee58da6e1ed11ac6c9526529', + '462eeb01e7a9858678802464f7dd4b76cd2fcb3c13be827efb4f98fa53ca809c', + ].forEach((identifier) => { + [ + pendingReleaseTruth.get('OPERATIONS_RUNBOOK.md'), + pendingReleaseTruth.get('docs/officers/PUBLISH_AND_CHECK.md'), + ].forEach((record) => assert.match(record, new RegExp(identifier))); + }); + const canonicalRecords = [ finalReleaseTruth.get('OPERATIONS_RUNBOOK.md'), finalReleaseTruth.get('docs/officers/PUBLISH_AND_CHECK.md'),