From 0ff39a86eef9b2bcdeb2ed1ee7f4dc12c1b46cac Mon Sep 17 00:00:00 2001 From: baixiangcpp Date: Sat, 27 Jun 2026 16:31:30 +0800 Subject: [PATCH] Document manual audit closure runbooks --- .../audit-23-25-26-manual-closure-runbook.md | 198 ++++++++++++++++++ .../audit-25-26-mobile-a11y-matrix.md | 2 + .../security/next-postcss-advisory-runbook.md | 86 ++++++++ .../mobile-a11y-audit-issues-262-263.test.ts | 9 + .../next-postcss-advisory-runbook.test.ts | 25 +++ .../pwa-install-offline-issue-260.test.ts | 14 ++ 6 files changed, 334 insertions(+) create mode 100644 docs/accessibility/audit-23-25-26-manual-closure-runbook.md create mode 100644 docs/security/next-postcss-advisory-runbook.md create mode 100644 tests/guards/next-postcss-advisory-runbook.test.ts diff --git a/docs/accessibility/audit-23-25-26-manual-closure-runbook.md b/docs/accessibility/audit-23-25-26-manual-closure-runbook.md new file mode 100644 index 00000000..42701678 --- /dev/null +++ b/docs/accessibility/audit-23-25-26-manual-closure-runbook.md @@ -0,0 +1,198 @@ +# Audit 23/25/26 Manual Closure Runbook + +This runbook covers the remaining manual checks for: + +- Issue #260: PWA install, offline state, cache clearing, and update UX. +- Issue #262: mobile layout and real-device usability. +- Issue #263: accessibility, screen-reader output, keyboard paths, and Lighthouse accessibility. + +Automated browser coverage already runs through `npm run test:e2e:smoke`, `npm run test:e2e:pwa`, representative axe checks, mobile overflow checks, and touch-target checks. Do not close #260, #262, or #263 from automation alone. Close them only after this runbook has real-device or assistive-technology evidence attached to the issue. + +## Required Environment + +Use the latest production build from `main` or a preview deploy for the PR being validated. + +Required browsers and devices: + +- Chrome Desktop on Windows, macOS, or Linux. +- Microsoft Edge Desktop on Windows or macOS. +- Android Chrome on a physical Android phone. +- iOS Safari on a physical iPhone. +- At least one desktop screen reader: NVDA on Windows or VoiceOver on macOS. +- At least one mobile screen reader: TalkBack on Android or VoiceOver on iOS. +- Chrome Lighthouse in a clean profile, with extensions disabled. + +Record the exact date, build commit, browser version, OS/device model, and tester initials in each issue comment. + +## PWA Checks For #260 + +Chrome Desktop: + +- Open `/en/install-app`. +- Confirm Chrome-specific install instructions are visible. +- Trigger install from the browser UI or the in-app install CTA when available. +- If the install CTA is unavailable, confirm the UI explains the browser limitation and gives manual next steps. +- Open the installed app window and verify `/en/json-formatter` loads. +- Warm cache online, then turn network offline in DevTools. +- Confirm `/en/json-formatter` still runs a local JSON format flow. +- Confirm `/en/har-viewer-sanitizer` still runs a local scrub flow. +- Confirm Pipeline Builder can run a local sample pipeline while offline. +- Confirm an external-request tool shows a clear offline-required message. +- Clear cached app files from Install App and from Local Data Controls. + +Microsoft Edge: + +- Repeat the Chrome Desktop install, installed-window, offline local-tool, external-request offline, and cache-clear checks. +- Confirm Edge-specific install guidance is visible. + +Android Chrome: + +- Open `/en/install-app` on a physical Android phone. +- Confirm Android guidance is visible. +- Install to home screen where supported. +- Launch from the home-screen icon. +- Warm cache online, enable airplane mode, and run `/en/json-formatter`. +- Confirm external-request tools show offline-required messaging. +- Clear cached app files after returning online. + +iOS Safari: + +- Open `/en/install-app` on a physical iPhone. +- Confirm iOS Safari Add to Home Screen guidance is visible. +- Add to Home Screen. +- Launch from the home-screen icon. +- Warm cache online, enable airplane mode, and run `/en/json-formatter`. +- Confirm external-request tools show offline-required messaging. +- Confirm cache-clear instructions are still discoverable from Install App and Local Data Controls. + +Update behavior: + +- With a waiting service worker available, confirm update availability is communicated as a user-triggered action. +- Confirm active tool input is not silently discarded before the user chooses to refresh. + +## Mobile Checks For #262 + +Run on Android Chrome and iOS Safari. + +Routes: + +- `/en` +- `/en/all-tools` +- `/en/data-code-formats` +- `/en/json-formatter` +- `/en/base64-encode-decode` +- `/en/jwt-decoder` +- `/en/regex-tester` +- `/en/pipeline-builder` +- `/en/trust-center` +- `/en/install-app` + +For each route: + +- Confirm there is no page-level horizontal scrolling. +- Confirm header navigation opens, closes, and restores focus. +- Confirm primary buttons and icon buttons are easy to tap. +- Confirm copy/export actions show visible feedback. +- Rotate between portrait and landscape where practical. + +Software keyboard: + +- On `/en/json-formatter`, focus the input, type invalid JSON, fix it, and run format. +- Confirm the keyboard does not hide the active input or primary action in a way that prevents completion. +- On `/en/base64-encode-decode`, enter a long URL-like value and copy output. +- On `/en/regex-tester`, edit pattern and sample text with the keyboard open. + +Pipeline Builder: + +- Open `/en/pipeline-builder`. +- Confirm the mobile diagnostics are readable without forcing page-level horizontal scrolling. +- Run the default sample or a local sample. +- Confirm run status and output are visible. +- If the workflow is too dense on a specific device, record the device/browser and exact blocker instead of marking pass. + +## Accessibility Checks For #263 + +Desktop keyboard: + +- Tab to the skip link, activate it, and confirm focus moves to main content. +- Open the command palette with Control/Command+K, search for `json`, select a result, and close with Escape. +- Navigate header language controls with keyboard only. +- Complete JSON Formatter input, run, copy, and clear with keyboard only. +- Complete Pipeline Builder sample run with keyboard only. +- Open and close modal/dialog surfaces with Escape and confirm focus restoration. + +Screen reader: + +Use NVDA or VoiceOver for desktop checks and TalkBack or iOS VoiceOver for mobile checks. + +JSON Formatter: + +- Confirm the input has a clear accessible name. +- Confirm invalid JSON exposes an error announcement or associated alert. +- Confirm copy success is announced. + +All Tools: + +- Confirm search field has a clear accessible name. +- Confirm result-count changes are announced through a polite status. +- Confirm mobile filter drawer has a dialog name and description, traps focus, closes with Escape, and restores focus. + +Pipeline Builder: + +- Confirm initial input and final output have clear accessible names. +- Confirm run status updates are announced. +- Confirm run-log table or mobile cards are understandable by the screen reader. +- Confirm failures expose an alert. + +External-request flow: + +- Confirm destination, purpose, data sent, and offline behavior are read before confirmation. +- Confirm preview/download actions remain disabled until explicit confirmation. + +Lighthouse: + +- Run Lighthouse accessibility in Chrome with a clean profile and extensions disabled. +- Representative URLs: + - `/en` + - `/en/all-tools` + - `/en/json-formatter` + - `/en/pipeline-builder` + - `/en/trust-center` + - `/en/install-app` +- Required result: each representative page has accessibility score >= 90. +- Attach the score table or report links to #263 before closing. + +## Closure Comment Template + +Use this template when all required checks pass: + +```text +Manual closure verification for #260/#262/#263 + +Build commit: +Date: +Tester: + +PWA: +- Chrome Desktop: +- Edge Desktop: +- Android Chrome: +- iOS Safari: + +Mobile: +- Android Chrome device/browser: +- iOS Safari device/browser: +- Routes checked: +- Software keyboard result: +- Pipeline Builder result: + +Accessibility: +- Desktop keyboard result: +- Desktop screen reader: +- Mobile screen reader: +- Lighthouse score table: + +Residual notes: +``` + +If any item fails, keep the issue open and create a follow-up bug with the exact device/browser, route, steps, expected behavior, and observed behavior. diff --git a/docs/accessibility/audit-25-26-mobile-a11y-matrix.md b/docs/accessibility/audit-25-26-mobile-a11y-matrix.md index d86ef4d1..d1be8be5 100644 --- a/docs/accessibility/audit-25-26-mobile-a11y-matrix.md +++ b/docs/accessibility/audit-25-26-mobile-a11y-matrix.md @@ -69,3 +69,5 @@ The following checks still require real device or assistive-technology verificat - Lighthouse accessibility score verification on representative pages in a stable Chrome/Lighthouse environment. - Screen-reader output in NVDA, VoiceOver, or TalkBack for Pipeline Builder and external-request confirmation flows. - Software keyboard overlap on physical mobile devices for multiline tool inputs. + +Use `docs/accessibility/audit-23-25-26-manual-closure-runbook.md` for the required closure procedure and issue comment template. diff --git a/docs/security/next-postcss-advisory-runbook.md b/docs/security/next-postcss-advisory-runbook.md new file mode 100644 index 00000000..f212636a --- /dev/null +++ b/docs/security/next-postcss-advisory-runbook.md @@ -0,0 +1,86 @@ +# Next Bundled PostCSS Advisory Runbook + +This runbook tracks issue #7: GHSA-qx2v-qp2m-jg93 through Next.js bundled `postcss`. + +The issue must stay open until a stable Next.js release bundles `postcss >= 8.5.10`, or an upstream non-applicable determination is documented. + +## Current Stable Evidence + +Checked on 2026-06-27: + +- `npm view next version`: `16.2.9` +- `npm view @next/bundle-analyzer version`: `16.2.9` +- `npm view next@latest dependencies --json`: bundled `postcss` is `8.4.31` +- Project dependency: `next@16.2.9` +- Project dev dependency: `@next/bundle-analyzer@16.2.9` + +This does not meet the closing requirement because `8.4.31 < 8.5.10`. + +## Stable Remediation Check + +Run on a dedicated branch: + +```bash +git checkout main +git pull --ff-only origin main +git checkout -b chore/next-postcss-stable-check +npm view next version +npm view @next/bundle-analyzer version +npm view next@latest dependencies --json +``` + +If stable Next bundles `postcss >= 8.5.10`, update Next and bundle analyzer together: + +```bash +npm install next@ @next/bundle-analyzer@ --package-lock-only +npm ci +node -p "require('./node_modules/next/package.json').version" +node -p "require('./node_modules/next/node_modules/postcss/package.json').version" +npm audit --omit=dev --json +``` + +Required validation before closing #7: + +```bash +npm run check:audit:prod-high +npm run lint +npm test +npm run test:coverage +npm run validate +npm run build:app +npm run build:post +npm run test:e2e:smoke +npm run test:e2e:pwa +``` + +## Non-Goals + +- Do not run `npm audit fix --force` if it downgrades Next. +- Do not merge Next canary into `main` without an explicit project decision. +- Do not suppress the advisory without upstream evidence. +- Do not loosen production audit gates. + +## Closure Comment Template + +```text +Next bundled PostCSS advisory closure evidence + +Build commit: +Date: +Tester: + +Stable Next version: +Bundled postcss version: +npm audit --omit=dev result: +check:audit:prod-high: +lint: +test: +test:coverage: +validate: +build:app: +build:post: +test:e2e:smoke: +test:e2e:pwa: + +Residual notes: +``` diff --git a/tests/guards/mobile-a11y-audit-issues-262-263.test.ts b/tests/guards/mobile-a11y-audit-issues-262-263.test.ts index 3d813363..6f4c087b 100644 --- a/tests/guards/mobile-a11y-audit-issues-262-263.test.ts +++ b/tests/guards/mobile-a11y-audit-issues-262-263.test.ts @@ -47,6 +47,7 @@ describe("issues #262/#263 mobile and accessibility audit coverage", () => { it("keeps the audit matrix documented with automated and manual boundaries", () => { const doc = read("docs/accessibility/audit-25-26-mobile-a11y-matrix.md") + const runbook = read("docs/accessibility/audit-23-25-26-manual-closure-runbook.md") expect(doc).toContain("360x740") expect(doc).toContain("/en/pipeline-builder") @@ -54,5 +55,13 @@ describe("issues #262/#263 mobile and accessibility audit coverage", () => { expect(doc).toContain("Android Chrome PWA install") expect(doc).toContain("iOS Safari Add to Home Screen") expect(doc).toContain("Screen-reader output") + expect(doc).toContain("audit-23-25-26-manual-closure-runbook.md") + expect(runbook).toContain("Issue #262") + expect(runbook).toContain("Issue #263") + expect(runbook).toContain("Lighthouse") + expect(runbook).toContain("NVDA") + expect(runbook).toContain("VoiceOver") + expect(runbook).toContain("TalkBack") + expect(runbook).toContain("Software keyboard") }) }) diff --git a/tests/guards/next-postcss-advisory-runbook.test.ts b/tests/guards/next-postcss-advisory-runbook.test.ts new file mode 100644 index 00000000..273bf125 --- /dev/null +++ b/tests/guards/next-postcss-advisory-runbook.test.ts @@ -0,0 +1,25 @@ +import { readFileSync } from "node:fs" +import { describe, expect, it } from "vitest" + +function read(path: string) { + return readFileSync(path, "utf8") +} + +describe("issue #7 Next bundled PostCSS advisory runbook", () => { + it("keeps stable remediation evidence and closure criteria documented", () => { + const doc = read("docs/security/next-postcss-advisory-runbook.md") + const packageJson = read("package.json") + + expect(doc).toContain("issue #7") + expect(doc).toContain("GHSA-qx2v-qp2m-jg93") + expect(doc).toContain("postcss >= 8.5.10") + expect(doc).toContain("Checked on 2026-06-27") + expect(doc).toContain("16.2.9") + expect(doc).toContain("8.4.31") + expect(doc).toContain("npm run check:audit:prod-high") + expect(doc).toContain("npm run test:e2e:pwa") + expect(doc).toContain("Do not run `npm audit fix --force`") + expect(packageJson).toContain('"next": "16.2.9"') + expect(packageJson).toContain('"@next/bundle-analyzer": "16.2.9"') + }) +}) diff --git a/tests/guards/pwa-install-offline-issue-260.test.ts b/tests/guards/pwa-install-offline-issue-260.test.ts index 8eb7f47f..0a1a3914 100644 --- a/tests/guards/pwa-install-offline-issue-260.test.ts +++ b/tests/guards/pwa-install-offline-issue-260.test.ts @@ -66,4 +66,18 @@ describe("issue #260 PWA install, offline state, cache, and update UX", () => { expect(appRuntime).toContain('navigator.serviceWorker.addEventListener("controllerchange"') expect(appRuntime).toContain("window.location.reload()") }) + + it("keeps the remaining real-device PWA closure checklist documented", () => { + const runbook = read("docs/accessibility/audit-23-25-26-manual-closure-runbook.md") + + expect(runbook).toContain("Issue #260") + expect(runbook).toContain("Chrome Desktop") + expect(runbook).toContain("Microsoft Edge") + expect(runbook).toContain("Android Chrome") + expect(runbook).toContain("iOS Safari") + expect(runbook).toContain("Add to Home Screen") + expect(runbook).toContain("Clear cached app files") + expect(runbook).toContain("Update behavior") + expect(runbook).toContain("Do not close #260, #262, or #263 from automation alone") + }) })