Skip to content

WEB-002D — Publish the bounded keyboard-navigation and SPA-focus chain #659

Description

@daliu

Foundations: released WEB-UX-002 [#291 / PR #294], released mobile-navigation fix [#490 / PR #491], and merged WEB-UX-004 [#657 / PR #658]. Prior live artifact: [#623]. Reusable hosting remains [#460], [#133], and [#136]. Connected directory behavior remains [#507].

Officer impact: Publish a bounded accessibility-only website artifact. Keyboard users receive the reviewed visible-focus treatment, the phone menu closes deterministically with truthful disclosure state, and client-side path navigation moves otherwise-stale focus into the destination main content. No officer duty, sign-in workflow, member-directory action, backend, or production data changes.

Officer documentation: Update the exact one-shot release/current-truth sections in OFFICER_START_HERE.md, root design/security/operations documents, docs/officers/README.md, docs/officers/PUBLISH_AND_CHECK.md, and the existing public-navigation/current-live continuity sections that must name the new verified deploy after publication. No officer runs terminal commands or uses a real account.

Deployment evidence: This issue owns one bounded Netlify web-only publication with exact source/tree/artifact provenance, signed-out desktop/phone checks, rollback, immediate repause, temporary-ref retirement, and final-truth readback. Firebase, Rules, Functions, indexes, DNS, outside-provider configuration, accounts/sign-in, production data, payments, and connected directory behavior remain unchanged and excluded.

Outcome

Publish the complete reviewed WEB-UX-004 behavior from a frozen accessibility projection based directly on current live source c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec / tree 411aa6ec9a9459f5d923030533ffc7c007fe6908, without publishing accumulated current main.

The live source predates two explicit WEB-UX-004 prerequisites. Therefore the projection includes only the exact released #291 visible-focus source, exact released #490 phone-menu source, and exact released #657 route-focus source/tests. It does not cherry-pick or copy the rest of current main.

Current canonical main at issue creation is merge 95880748e15c03b0ee58da6e1ed11ac6c9526529 / tree eac1fe8b86f0e871d2fc41e5338dceace38a04ec. Current production remains Netlify deploy 6a7e072f8f346b0008510d29, control 9d5cc8612b4321172370bd949d307e7e4ac0ec7d, source c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec, 62 files, digest d837272a1e5efc1575809e87f532276b38d1a63f1dd79ec1aef0533f6da8afb1. Directory availability remains literal false.

Frozen-source invariant

  • Preserve every live-source byte except the six exact paths below.
  • Apply WEB-UX-002 — Restore visible keyboard focus across the site #291’s exact accessible skip-link inset, removal of the global outline suppression, and one reviewed global :focus-visible rule.
  • Apply WEB-UX-003 — Make mobile navigation state explicit and deterministic #490’s exact idempotent phone-menu close plus aria-controls and aria-expanded semantics; do not change routes, links, animation, layout, or authentication copy.
  • Apply WEB-UX-004 — Move focus to main content after SPA path navigation #657’s exact main#main-content programmatic focusability, pathname-bound layout capture/passive-frame settlement, no-steal/cancellation fences, and scoped bounded main cue.
  • The route handoff retains initial/same-path inertness, preventScroll, consume-before-check, exact connected-target identity, destination/user focus preservation, and stale/unmount fencing.
  • The scoped main cue stays fixed, pointer-inert, two-tone, fully inside the viewport below navigation, z98 below navigation z99, and layout-neutral.
  • No new route, request, retry, analytics event, log, storage, auth decision, membership behavior, directory action, photo/search behavior, provider call, or production-data path enters the projection.

Exact frozen-source ownership

Create codex/netlify-source-659-keyboard-focus from exact live source c2d87d1f69f15e128a0bc9b1b9f915b7c8417aec. Own only:

No package/lock, public content, image, service, route page, Account, directory, Function, Rule, index, schema, environment, workflow, provider, or data path may enter the frozen source. The frozen source ref must never merge to main.

Exact release-control ownership

After the frozen source is immutable and current main/claims are reread, create a release-control branch from exact then-current main. Own only:

  • a new rollback ref pinned to current live source c2d87d1f...;
  • config/netlify-production-release.json: one canonical active manifest with a unique release ID, exact expected first parent, pinned source ref/commit/tree, exact artifact count/digest, predecessor source c2d87d1f..., and rollback deploy 6a7e072f8f346b0008510d29;
  • tests/release-workflow.test.js: only exact active/repause manifest expectations;
  • netlify.toml: only the current-truth active/inactive preview comment;
  • separately named pending/current-truth hunks in SYSTEM_DESIGN.md, IMPLEMENTATION_PLAN.md, SECURITY.md, OPERATIONS_RUNBOOK.md, OFFICER_START_HERE.md, docs/officers/README.md, docs/officers/PUBLISH_AND_CHECK.md, and docs/officers/UPDATE_PUBLIC_CONTENT.md as required by direct release review;
  • after verified publication/repause, only existing current-live statements in README.md, docs/officers/ACCESS_CONTINUITY.md, docs/officers/REQUEST_A_CHANGE.md, docs/officers/SYSTEM_MAPS.md, and docs/officers/EVENTS_SHOP_MEMBERS.md that otherwise name obsolete WEB-002C — Publish the bounded inert member-directory interface preview #623 production truth.

Prepare the exact three-file repause (active:false, matching test, inactive comment) before publication. Do not merge final-truth documentation until production and repause are independently read back.

Active #616 owns functions/strava.js, functions/strava.test.js, and its separately named OAUTH-001A2L/RISK-024 SECURITY.md hunk; preserve them byte-for-byte. #507 owns every connected directory/backend/availability gate. #460/#133/#136 retain reusable release automation.

Required proof before publication

  1. Exact live-to-projection diff contains only the six frozen-source paths.
  2. Each projected runtime hunk is byte-semantic-equivalent to its reviewed WEB-UX-002 — Restore visible keyboard focus across the site #291, WEB-UX-003 — Make mobile navigation state explicit and deterministic #490, or WEB-UX-004 — Move focus to main content after SPA path navigation #657 source and introduces no accumulated-main route/content feature.
  3. Focused tests prove WEB-UX-002 — Restore visible keyboard focus across the site #291 visible focus/skip link, WEB-UX-003 — Make mobile navigation state explicit and deterministic #490 phone-menu close/ARIA, and WEB-UX-004 — Move focus to main content after SPA path navigation #657 initial/no-steal/redirect/stale/missing/unmount/POP behavior.
  4. Full projection-compatible frontend tests, TypeScript, targeted lint, diagnostic build, SPA/navigation checks, release tests, and diff-check pass under Node 20.
  5. A clean remote-fetch build reproduces the exact artifact file count and digest; safety scanning finds no credential material.
  6. Synthetic/local production-build checks at 1280×900 and 390×844 prove initial body focus/no cue, path navigation main focus at scroll (0,0), visible bounded cue, deterministic phone-menu close, correct next-Tab order, no clipping/overflow/layout shift, and no console error.
  7. Pinned active-control Deploy Preview marker exactly matches control/source/tree/previous source/rollback/count/digest and has no-store/nosniff/HSTS/noindex headers.
  8. Preview immutable assets contain only the expected accessibility/runtime delta and no connected directory callable/service/availability symbols.
  9. Signed-out public routes and guards work. Do not sign in, enter data, submit a form, or use a real name/photo/account.
  10. Exact rollback ref and a separately reviewed repause are ready before the active-control merge.
  11. Independent runtime/accessibility, security/privacy, release-governance, artifact-delta, and backup-officer reviews are GO.

Publication and verification

  • Freeze unrelated main merges after the active control candidate is finalized.
  • Merge the active release-control PR with a two-parent GitHub merge commit only. Never squash, rebase, directly promote a preview, call netlify deploy --prod, or use a build hook.
  • Stop unless the first parent is the exact manifest parent and Netlify’s production attempt uses that exact merge.
  • Verify the provider’s published deploy is ready, context=production, branch=main, and exact release merge.
  • Verify runmprc.com/.well-known/run-mprc-release.json, HTTPS headers, immutable assets, public routes, and signed-out route focus/cue at 1280×900 and 390×844.
  • Verify WEB-UX-002 — Restore visible keyboard focus across the site #291 focus treatment and WEB-UX-003 — Make mobile navigation state explicit and deterministic #490 phone-menu ARIA/close behavior on the served artifact.
  • Verify no member-directory request, no connected callable/service symbol, no Firebase deployment, no outside-provider configuration, and no account/data action.
  • Immediately merge the pre-reviewed repause. Prove its main attempt publishes nothing and the new deploy/marker remain live.
  • Retire temporary source/control/repause refs, retain the new rollback ref, then land final-truth documentation.

Stop conditions

Stop for any seventh frozen-source path; accumulated-main route/content/code; source/tree/parent/count/digest/marker mismatch; #291 or #490 behavior missing or altered; clipped/absent cue; focus steal/trap/wrong Tab order; phone menu left open or falsely announced; missing rollback/repause; main advance; unexpected Function/edge/backend/provider/DNS action; production sign-in; real data; directory request; direct preview promotion; or live behavior differing from the pinned preview. Disabling the manifest alone is not rollback.

Migration and undo

No data, schema, backend, provider, or account migration. If publication does not occur, retain current live deploy 6a7e072f8f346b0008510d29. If any new live check fails, atomically restore deploy 6a7e072f8f346b0008510d29, verify its #623 marker, and stop. If provider restore is unavailable, use only a newly reviewed exact-parent rollback pinned to source c2d87d1f....

Acceptance criteria

  • Frozen six-path live-based accessibility projection is exact, tested, built, and independently reviewed.
  • Active manifest/control candidate, exact marker preview, rollback, and pre-reviewed repause are ready.
  • Exact-parent two-parent release publishes only the pinned artifact.
  • Public marker/assets/routes/focus/cue/phone-menu checks pass signed out at both widths.
  • Firebase, providers, accounts/sign-in, production data, directory availability, and connected behavior remain unchanged.
  • Repause is merged/read back; temporary refs are retired; final truth lands.
  • Final evidence distinguishes source, tests, merge, preview, Netlify publication, runmprc.com, Firebase, outside providers, account/sign-in, production data, and live accessibility behavior.

Claim protocol

Issue creation is not a claim. Before any source/control/doc edit, reread current main, open PRs, active claims, live marker/provider state, #291/#490/#657/#623 records, and #616/#507 boundaries; post coordination notices; create the two unique branches/worktrees; assign this issue; set status:in-progress; and post a timestamped exact source/control/final-truth claim. Hold all claims through verified publication, repause, final-truth merge, closure, and explicit release.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:ciContinuous integration and deploymentarea:webWeb application and hostingpriority:P1High-priority follow-upsize:MMedium multi-file issuetype:operationsOperational setup or runbooktype:reliabilityReliability and recoverytype:securitySecurity or privacy boundarytype:testingTest infrastructure and quality gates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions