Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions docs/accessibility/audit-23-25-26-manual-closure-runbook.md
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions docs/accessibility/audit-25-26-mobile-a11y-matrix.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
86 changes: 86 additions & 0 deletions docs/security/next-postcss-advisory-runbook.md
Original file line number Diff line number Diff line change
@@ -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@<stable-version> @next/bundle-analyzer@<stable-version> --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:
```
9 changes: 9 additions & 0 deletions tests/guards/mobile-a11y-audit-issues-262-263.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,21 @@ 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")
expect(doc).toContain("Axe serious and critical violations must be zero")
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")
})
})
25 changes: 25 additions & 0 deletions tests/guards/next-postcss-advisory-runbook.test.ts
Original file line number Diff line number Diff line change
@@ -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"')
})
})
14 changes: 14 additions & 0 deletions tests/guards/pwa-install-offline-issue-260.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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")
})
})