# Device check baseline 2026-10: iOS 18.6.2 (pre-iOS 26 reference) - protocol: `PROTOCOL.md` (environment block, recording fields, citation string) - status: partial (T1 and T1-WI by the owner; Safari-tab values automated 2026-10-20, see "Safari tab (automated)"; Home Screen tests pending the human-tap list) - purpose: control for `2026-10-ios27.md` T1. Shows what a manifest-less Home Screen icon did before iOS 26 changed the default. It does not replace the iOS 27 run. - target devices: the owner's iPhone --- ## Human-tap list (2026-10-20) One pass, about 37 min, ordered so nothing is installed twice. Phone: iPhone 16 Pro (iPhone17,1), iOS 18.6.2 (22G100). **Before starting:** close any Mac Safari Web Inspector windows attached to the iPhone (the agent reads values itself through `ios_webkit_debug_proxy`; an open Inspector window locks that page). Keep the phone unlocked and on USB. Say "ready N" in chat after each numbered step that ends with **[agent reads]**; the agent reads the foreground page and answers before you move on. Screenshots: side + volume up, AirDrop to the Mac, names as given (`2026-10-20_iphone16pro_ios18.6.2_.png`). The lab and demo pages show no personal data; skip or crop any shot that shows other apps' notifications. **Do not delete the installed apps at the end**: leaving them installed through the iOS 27 upgrade gives a free extra test (what an iOS 18-installed app looks like after the upgrade). ### A. Safari tab first (markers must exist before install), 3 min 1. Safari → `https://openpwa.net/demo/` → tap the **中文** button in the header so the page is Chinese. **[agent reads]** (T6 marker) 2. Safari → `https://openpwa.net/lab/device-tests/#t6` → tap **Write marker here** (value starts `TAB-`). **[agent reads]** (T6 lab marker) 3. Safari → `https://openpwa.net/demo/push/` (don't tap anything). **[agent reads]** (T7 step 1) ### B. Installs, 5 min 4. Still in Safari on `https://openpwa.net/lab/device-tests/` → Share → **Add to Home Screen**. Screenshot the sheet **before** tapping Add (`T3_0`: name field, any switch). Add. (T3, used by T4/T6/T7/T8) 5. Safari → `https://openpwa.net/lab/device-tests/t3/manifest-only/` → Share → Add to Home Screen → Add ("Lab no-ATI"). 6. If an "OpenPWA" demo icon exists, delete it first. Safari → `https://openpwa.net/demo/` → Share → Add to Home Screen. Screenshot the sheet (`T2_1`: prefilled name; is there any "Open as Web App" switch?). Add. 7. Safari → `https://openpwa.net/lab/device-tests/t1/no-manifest/` → Share → Add to Home Screen. Screenshot the sheet before Add (`T1_0`: name, any switch). Add. (T1 probe page: no manifest, no icon, no SW) 8. Home Screen screenshot showing PWA Lab, Lab no-ATI, OpenPWA and the existing "iOSAddtoHom…" icon (`T3_1`, include the T1 probe icon). Say what number/colour each lab icon shows (180 red / 192 blue / 512 green / M192 / M512 / FAV / screenshot / letter). ### C. Demo app (T2, T5, T6, T9, T10), 5 min 9. Launch **OpenPWA** from the icon. Screenshot top of page (`T2_2`, includes the "Running as an installed app" line and the language shown). **[agent reads]** (display-mode, standalone, install APIs, pushManager, safe-area, storage, language) 10. In the app, tap the language button once (switch it). Go to Safari, reload the `/demo/` tab. **[agent reads]** (T6 step 3; or tell me the tab's language) 11. In the Safari tab tap the language button again. Fully close the OpenPWA app (app switcher, swipe up), relaunch it. **[agent reads]** (T6 step 4) ### D. PWA Lab app and T1 probe app (T1, T5, T6 lab, T9, T10), 3 min 12. Launch **PWA Lab**. **[agent reads]** (full results JSON, marker: `null` = isolated, `TAB-…` = copied) 13. In the app tap **Write marker here** (`APP-…`). Go to Safari, reload `https://openpwa.net/lab/device-tests/`. **[agent reads]** (tab marker must still be `TAB-…`). Return to the PWA Lab app. 14. Launch the T1 probe icon (from step 7). Screenshot the page (`T1_4`: summary line, display-modes, whether a service worker controls it). **[agent reads]** (url substring `t1/no-manifest`) ### E. Status bar (T4), 6 min (portrait, in the PWA Lab app) 15. PWA Lab app → T4 table → **baseline**. Scroll so "Line 05" is under the status bar. Screenshot `T4_1`. **[agent reads]** (variant probe block) 16. Back → **fixed**, same scroll, `T4_2`. Back → **sticky**, `T4_3`. Back → **safe-area**, `T4_4`. Say whether fixed shows a solid bar. 17. Safari tab → `https://openpwa.net/lab/device-tests/t4/baseline/`, same scroll, `T4_5`. Back in the app's baseline page rotate to landscape, `T4_6`, rotate back. 18. Only if 15 and 16 look different: **threshold** page, h6/w100/top0 `T4_7`, h5 `T4_8`, h6+w79 `T4_9`, h6+top5 `T4_10`. 18b. (added 10-20, follow-up to N30-a: is the strip colour theme-color or the page's top colour, and does it re-sample?) PWA Lab app → T4 table → open each new variant **inside the app**, screenshot at the top and again with "Line 05" under the status bar, and say the strip colour for each: - **white-top** (no header, white page, theme-color #161616) `T4_11a` / `T4_11b` - **theme-red** (as white-top, theme-color #d00000) `T4_12a` / `T4_12b` - **bg-green** (green html/body, theme-color #161616) `T4_13a` / `T4_13b` - **dynamic** (blue header): screenshot on load `T4_14_0`, then after **A** (theme-color → red) `T4_14_A`, after **B** (header → orange) `T4_14_B`, after **C** (remove header) `T4_14_C`. Keep strip, probe block and change log in each shot. Optional: background the app and return after C, screenshot `T4_14_C2` (re-sample on resume?). **[agent reads]** 18c. (added 10-20, manifest vs meta theme-color: theme-red in the lab app showed "black" with meta #d00000 but manifest #161616, no screenshot.) Three separate apps, each with its own manifest/scope and a grey icon labelled M1/M2/M3, white page, no header, default status-bar style. In **Safari** (not the lab app), for each URL: Share → **Add to Home Screen**. For **M1 only, screenshot the add sheet before tapping Add** (`T4_18c_sheet`; this also fills the missing `T3_0`: is there an "Open as Web App" switch, and what is in the name field?). Add. Then launch each from its Home Screen icon, screenshot the top of the screen with the time strip visible (`T4_18c_M1`, `T4_18c_M2`, `T4_18c_M3`), say the strip colour, and keep each app open 20 s for an agent read. **[agent reads]** - **M1** `https://openpwa.net/lab/device-tests/t4/theme-m1/`: manifest `theme_color` #d00000 (red), page meta theme-color #00a050 (green) - **M2** `https://openpwa.net/lab/device-tests/t4/theme-m2/`: manifest without `theme_color`, page meta #d00000 (red) - **M3** `https://openpwa.net/lab/device-tests/t4/theme-m3/`: manifest `theme_color` #00a050 (green), no meta theme-color | Observation | Reading | |---|---| | M1 strip red | manifest `theme_color` wins over the page meta | | M1 strip green | page meta theme-color wins over the manifest | | M1 strip other (black/white) | neither colour is used for the strip in this mode | | M2 strip red | page meta is used when the manifest has no colour | | M2 strip other | page meta is ignored even without a manifest colour | | M3 strip green | manifest colour is used when the page has no meta | | M3 strip other | manifest colour is ignored even without a page meta | ### F. Push and notifications (T7, T8), 10 min (PWA Lab app) 19. PWA Lab app → **1. Request permission**. Screenshot the system prompt (`T7_2`, note its exact text). Tap **Allow**. 20. Tap **Subscribe to push**. **[agent reads]** (result line and endpoint host only) 21. Tap **Probe worker exposure**. **[agent reads]** (T8 exposure values) 22. Tap **2b. Show in 5 s (then go Home)**, swipe Home at once. Banner? Screenshot it (`T8_1`, crop other apps). Tap it. Screenshot the event log in the app (`T8_2`). **[agent reads]** (records, `via`, `navigation.outcome`) 23. Tap **2a. Show notification now**, stay in the app, pull down Notification Centre, tap it. **[agent reads]** 24. Fully close PWA Lab (app switcher). Launch it, tap **2b**, go Home, tap the banner. **[agent reads]** (cold-start record) 25. OpenPWA demo app → Push page (`/demo/push/` link) → **Request permission and subscribe** → Allow. Screenshot (`T7_3`, scroll the endpoint away). **[agent reads]** 26. Settings → Notifications: screenshot the list area showing "PWA Lab" / "OpenPWA" (`T7_4`, crop others). 25c. (added 10-20, recorded permission retest for anomaly A7; a clean app that has never been asked) Start a **screen recording** (Control Centre). In Safari open `https://openpwa.net/lab/device-tests/t7/perm/` → Share → **Add to Home Screen** (name "Perm Test", yellow **P7** icon) → launch **Perm Test** from the icon. Tap **1. Read state (no request)**, then send **"ready 25c-pre"**. **[agent reads]** Then, with the recording still running, tap **2. Request permission**: say whether a system prompt appears (and its exact text), tap **Allow**. Stop the recording, then send **"ready 25c-post"**. **[agent reads]** (the page shows start / end / elapsed ms and the resolved value; Copy JSON if asked) ### G. Badging (T11), 2 min 27. OpenPWA app → Badging → **Increment and set badge** three times → go Home. Screenshot the icon (`T11_1`). Back in the app **Clear badge**. **[agent reads]** (result line) ### H. Optional, if time is left (about 8 min) 28. T4b: in Safari add each of `https://openpwa.net/lab/device-tests/t4/sbs-default/`, `.../t4/sbs-black/`, `.../t4/sbs-black-translucent/` to the Home Screen, launch each from its icon, scroll so lines pass under the status bar, screenshot `T4b_1..3`. Keep them installed. 29. T1 steps 4–6 with the existing "iOSAddtoHom…" icon: launch it, tap the site logo (stays in Safari?), tap any webkit.org link, then close and relaunch from the icon: which URL opens? Screenshot `T1_3`. 30. T5b only if Chrome for iOS is installed: Chrome → `https://openpwa.net/demo/` → Share → is "Add to Home Screen" there? Screenshot `T5b_1`. 31. Settings → General → About: tell me Model Name / Model Number, and Settings → General → Language & Region (language / region). Also: any VPN / iCloud Private Relay on? (Environment block.) --- ## Environment ``` - date / time / timezone: 2026-10-20 ~14:45 CST (China time, as reported by the owner); automated tab run 2026-10-20 06:54 UTC (14:54 CST) - tester: owner (T1); agent over USB (Safari tab, automated) - device: iPhone 16 Pro (ProductType iPhone17,1, HardwareModel D93AP, order number MYLU3CH/A; read with libimobiledevice `ideviceinfo`, not from Settings). Model Number (A-number) not read: Settings → General → About → Model Number (tap to toggle) - OS: iOS 18.6.2 (22G100). Source: `ideviceinfo` ProductVersion/BuildVersion and the safaridriver session capabilities (safari:platformVersion 18.6.2, safari:platformBuildVersion 22G100) - release channel: release (public) - Safari: 18.6 (safaridriver browserVersion "18.6"). UA string from T0-WI: Mozilla/5.0 (iPhone; CPU iPhone OS 18_6_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1 - device language / region: navigator.language "zh-CN", navigator.languages ["zh-CN"]; region CH/A hardware (mainland China). Settings language/region not reported by the owner - appearance: Light (Settings → Display & Brightness, owner, ~17:19; `prefers-color-scheme: dark` false in all agent reads 06:54–09:06Z). Switched to Dark for N48 only - Safari feature flags changed from default: TBD (not reported) - Content blockers / VPN / Private Relay: at least one Safari Web Extension is installed (a `safari-web-extension://…/background/background.html` page is listed by the inspector); which one, and VPN / Private Relay state: TBD (not reported) - Mac for Web Inspector: macOS 26.3 (25D125), Safari 26.3 (safaridriver "Included with Safari 26.3 (21623.2.7.11.6)"); ios_webkit_debug_proxy 1.9.2 (Homebrew) for scripted Web Inspector reads. First pairing needed one retry after "pairing denied" ``` --- ## Methods Written for reuse in an article or paper; it describes the procedure as run on 2026-10-20. **Device under test.** Apple iPhone 16 Pro (ProductType iPhone17,1, HardwareModel D93AP, order number MYLU3CH/A, mainland-China hardware), iOS 18.6.2 build 22G100, release channel, Safari 18.6 (WebKit 605.1.15 frozen UA token). Device time zone Asia/Hong_Kong (UTC+8). Browser language zh-CN. Settings → Apps → Safari → Advanced: Web Inspector on and Remote Automation on (both set by the owner before the run). At least one Safari Web Extension installed. Feature flags, VPN and iCloud Private Relay state: not yet reported (see Threats to validity). **Host.** MacBook Pro, macOS 26.3 (25D125), Safari 26.3. USB connection, device paired and trusted. Node.js 26.0.0. Tools: - `safaridriver` "Included with Safari 26.3 (21623.2.7.11.6)", W3C WebDriver, capabilities `{"browserName":"safari","platformName":"iOS","safari:useSimulator":false}`. User-level `~/Library/WebDriver/com.apple.Safari.plist` already had `AllowRemoteAutomation = true` (file modified 14:36:42 CST, before this agent ran); no `sudo safaridriver --enable` was needed. - `ios_webkit_debug_proxy` 1.9.2 (Homebrew; libimobiledevice 1.4.0, libplist 2.8.0, libusbmuxd 2.1.1), installed 2026-10-20 ~14:56 CST. Speaks the WebKit remote inspector protocol over usbmux; on iOS 18 each page requires the `Target.sendMessageToTarget` wrapper. - `ideviceinfo` (libimobiledevice 1.4.0) for ProductType, BuildVersion, ModelNumber, TimeZone. - Scripts in `tools/` (copies, with `tools/SHA256SUMS`): `probe.mjs` (WebDriver driver; navigates and runs the probe with `/execute/async`), `probe-t1.mjs` (same, T1 page only), `probe-wi.js` (the probe expression used for inspector reads; same probe body as `probe.mjs` plus localStorage dump, cookie names and the lab page's on-screen output), `wi-eval.mjs` (inspector client; starts the async probe, stores its JSON on `window`, polls for it, deletes it), `wi-read.sh` (restarts the proxy, selects a page by URL substring and optionally process id, runs `wi-eval.mjs`, saves raw JSON and, from v3, a `.meta.json` sidecar with tool hashes and the redacted inspectable-page list). **Probe.** Read-only. It evaluates feature-detection expressions (`'x' in navigator/window`, `typeof`), `matchMedia` for seven `display-mode` values (browser, minimal-ui, standalone, fullscreen, window-controls-overlay, picture-in-picture, application), `CSS.supports`, computed `env(safe-area-inset-*)` via a temporary hidden element (removed immediately), screen / window / visualViewport geometry, `navigator.storage.estimate()` and `persisted()` (never `persist()`), `navigator.serviceWorker.getRegistrations()` (read only), `canShare()` with a synthetic URL and a 1-byte in-memory text File (no share sheet), page declarations from the DOM, `localStorage` contents (values truncated to 200 chars), cookie **names** only, and visible page text. It never calls `requestPermission`, `subscribe`, `share`, `install` or `register`. The lab page registers its own service worker on load; that is the page's behaviour, not the probe's. **Two data paths.** (1) *Automated tab* (WebDriver): Safari runs an automation window; no human taps. Used only for tab-side values. (2) *Human-tap + inspector read*: the owner performs the tap list on the phone in the normal Safari profile and in Home Screen apps; after each step the agent reads the foreground page through `ios_webkit_debug_proxy` with `wi-read.sh`. Home Screen web apps appear as a separate process (separate `appId`) from Safari while foregrounded. **Records.** Raw JSON per read in `raw/`, named `2026-10-20-ios18.6.2---.json` (`tab` = Safari tab, `app` = Home Screen app). Owner screenshots go to `screenshots/2026-10-ios18-baseline/` (naming per PROTOCOL.md). Owner-reported observations relayed by the coordinating session are quoted verbatim and marked "owner report". **Verdicts.** `as-expected` = matches the expectation written in `2026-10-ios27.md` or in this file before the read; `differs` = contradicts it; `inconclusive` = the step cannot discriminate between the hypotheses (reason given). --- ## Results summary (one line per test; details in the Lab notebook) | Test | Context | Verdict | Finding | Evidence | |---|---|---|---|---| | T0-WI | tab | as-expected | UA `…iPhone OS 18_6_2… Version/18.6 Mobile/15E148 Safari/604.1` | N03, raw tab-*.json | | T1 / T1-WI | manifest-less icon (owner, 14:45) | as-expected for pre-26 | opens as Safari bookmark: standalone false, display-mode browser; sheet has no "Open as Web App" switch | T1 section below | | T1 probe | tab + icon | as-expected | `t1/no-manifest/` in tab: standalone false, browser only; from its icon: opens in Safari's process with Safari's storage (TAB-07:45:25 marker) and the lab SW controlling | N06, N23 | | T2 | demo app | as-expected | standalone true, display-mode standalone only | N13 | | T3 | Home Screen icons | as-expected | PWA Lab = 180 (apple-touch-icon wins over manifest); Lab no-ATI = 192 (manifest any 192); demo = its artwork; T1 probe = black letter tile | N11, N12 | | T5 | tab vs app | as-expected | tab: browser / standalone false; app: standalone / standalone true | N03, N13 | | T6 (demo) | tab vs app | as-expected | app did not inherit tab's `zh` at add time; tab → English did not change app (`zh` after cold relaunch); app's later `zh` write did not reach the tab (`en`) | N08, N13, N16, N17 | | T7 tab | tab | as-expected | no Notification, no PushManager in tab; `/demo/push/` reports 4 unmet prerequisites | N10 | | T8 tab-side | tab SW | as-expected | `'onnotificationclick' in self` false in a tab-controlled worker | N03 | | T8 notificationclick | app: banner (warm, after relaunch, after swipe-away) and Notification Centre | **both handler paths fire (6/6)**; always `focused existing window`; `openWindow` path not reached (the window survives a swipe-away) | N35, N36, N38, N40 | | T8 app-side exposure | app SW | differs from tab (no prior expectation) | same worker in the Home Screen app: `'onnotificationclick' in self` true, `onpush` true, `Notification` in self true, `showNotification`/`pushManager` on registration true | N18 | | T6 (lab, 3 stores) | tab ↔ app | differs (cookie) | localStorage, IndexedDB isolated, never copied; **cookie copied Safari → app once, apparently at Add to Home Screen (N21–N22, moderate), then independent both ways**; each Home Screen app has its own cookie store | N09, N18–N22 | | T9 | tab + app | as-expected | no `navigator.install`, no `BeforeInstallPromptEvent` in either | N03, N13 | | T10 | tab + app | as-expected | `window.pushManager` present in tab and app; in tab without `PushManager`/`Notification` | N03, N13 | | T4 (app, portrait, Light) | baseline, fixed, sticky, safe-area, white-top, theme-red, bg-green | as-expected (pre-26): **strip solid black, no content or blur behind the time, independent of theme-color, page top colour and viewport-fit**; Dark unconfirmed (N48) | N47, N47-a, N47-b, N48 | | T4 (superseded row) | | **visual results retracted (N46, A9)**; superseded text follows: as-expected (pre-26), notable | status-bar area solid **blue (matches the page's top/header colour, not theme-color #161616)** on all four, incl. scrolled static-header baseline; no blur, content never under it; viewport starts below the bar (812 of 874), inset-top 0 even with `viewport-fit=cover` (bottom 34) | N25–N30, N30-a | | T7 app | lab + demo + Perm Test | as-expected (A7 resolved: probable observer miss) | both granted, Apple push host, both listed in Settings → Notifications; lab: owner saw no prompt, demo: prompt seen | N32–N33, N41, N44 | | T11 | demo app | **uncertain (conflicting owner reports)** | N44 "badge shown" vs N56 "no Badge"; tie-breaker: screenshot T11_1 | N43, N44, N44-a, N56 | | T4b | SBS transl (app) | as-expected, **agent-confirmed** | `black-translucent` + cover: viewport 402×874, inset-top 62 px, blue header behind white status-bar text; SBS default/black not observed | N51, N55 | | T7 25c | Perm Test (clean app) | as-expected | prompt shown (screen-recorded), `requestPermission` pending 2068 ms, `default` → `granted`, both permissionStates `prompt` → `granted` | N53, N54 | | T5b | | pending | | | | T11 (17:52 update) | demo app | **as-expected** | badge "3" on the OpenPWA icon (screenshot T11_1); supersedes the "uncertain" row | N60 | | T7 prompt (17:47 update) | PWA Lab, Perm Test | as-expected | prompt shown in both, wording “”想给你发送通知 / 通知可能包括提醒、声音和图标标记。可在“设置”中配置相关功能。 / 不允许 / 允许; A7 closed | N58, N59 | | T4 strip (17:56 update) | app + tab | as-expected (pre-26) | strip pixels #161616 (= theme-color and manifest theme_color), never #000000; source (meta vs manifest) untested | N62 | | T4 strip (19:05 update, T4 18c) | M1/M2/M3 apps + theme-red in PWA Lab | as-expected (theme-color drives the strip) | strip pixels = the **page meta theme-color** whenever one is present (M1 #00a050 over manifest #d00000; M2 #d00000; theme-red #d00000 over lab manifest #161616), = manifest `theme_color` when the page has none (M3 #00a050); supersedes the "source untested" row and N62's manifest hypothesis | N64–N66 | --- ## Lab notebook (chronological, append-only) Times are 2026-10-20, local = CST (UTC+8). Entries N01–N14 were written retroactively at 15:26–15:40 CST from tool output in the agent session, raw-file timestamps (`collectedAt` and file mtime) and the coordinator's relays; the time of each entry is the time of the event. Later entries are written at the time of the step. Corrections are appended as new entries, never by editing old ones. **N01 · 14:36:42 (06:36:42Z) · setup (pre-agent).** `~/Library/WebDriver/com.apple.Safari.plist` last modified; contains `AllowRemoteAutomation = true`. Owner had turned on Remote Automation on the phone. **N02 · ~14:45 · T1 / T1-WI (owner, pre-agent).** Recorded in the "T1" section below (manifest-less `/reference/installation/ios-add-to-home-screen/` added to Home Screen; Web Inspector console output). Not repeated here. **N03 · ~14:50–14:55 (06:50–06:55Z) · automated Safari tab run (WebDriver session 1).** State before: phone unlocked, USB, Safari open. Action: agent started `safaridriver -p 4723`, created a session (returned `safari:platformVersion 18.6.2`, `safari:platformBuildVersion 22G100`, `browserVersion 18.6`, `safari:deviceUDID` present), then `probe.mjs` navigated the automation window to `/lab/device-tests/` (06:54:33Z), `/reference/installation/ios-add-to-home-screen/` (06:54:43Z) and `/demo/` (06:54:50Z), 6 s settle each, probe + page screenshot; on the lab page it also read the lab's own results JSON (textarea) and worker exposure output after 3 s. Session deleted afterwards. Raw: `raw/2026-10-20-ios18.6.2-tab-{lab,ios-a2hs,demo}.json`; screenshots `screenshots/2026-10-ios18-baseline/2026-10-20_iphone_ios18.6.2_tab-{lab,ios-a2hs,demo}_1.png`. Observed: see "Safari tab (automated)" section. Expected (2026-10-ios27.md T0/T5/T9/T10 tab side): browser display mode, standalone false, no install APIs, `window.pushManager` present (BCD Safari 18.4). Verdict: as-expected. Note: in session 1 the `/demo/` page showed two registrations (lab and demo), both created inside that session. **N04 · 14:56–15:05 · tooling: ios_webkit_debug_proxy.** Installed via Homebrew. Findings, each reproduced at least twice: (a) the proxy lists Safari pages with `appId` PID:24364, including a `safari-web-extension://…/background/background.html` page (a Safari Web Extension is installed); (b) a page that a Mac Safari Web Inspector window is attached to cannot be evaluated (log line `Taking page 9222/1 from remote …`); (c) background tabs (`about:blank`) do not answer `Runtime.evaluate`; (d) the proxy serves only **one** inspector connection per page per proxy run; a second connection gets no messages, so `wi-read.sh` restarts the proxy before every read; (e) an early client using `Runtime.evaluate` with `awaitPromise` returned no usable value (cause not isolated; possibly a client bug), so `wi-eval.mjs` uses a store-on-window-and-poll design instead. **N05 · 15:00 · tap list sent** to the coordinator (numbering later shifted; see N07). **N06 · 15:08 (07:08:43Z) · automated tab run on the T1 probe page (WebDriver session 2).** Action: new session, `probe-t1.mjs` → `https://openpwa.net/lab/device-tests/t1/no-manifest/`. Raw: `raw/2026-10-20-ios18.6.2-tab-t1-no-manifest.json`; screenshot `…_tab-t1-no-manifest_1.png`. Observed: standalone false; display-mode browser only; no manifest, no icons, no theme-color; `serviceWorker.controller` false; `getRegistrations()` = **[]**; page summary line `T1 standalone=false dm=browser iOS 18.6.2`. Verdict: as-expected (tab). Session deleted; `safaridriver` stopped. **Anomaly A1 (discovered here):** the lab worker registered in session 1 (N03) was absent in session 2, although its scope covers this page. Interpretation: each WebDriver session on iOS gets a fresh, isolated website-data store. Consequence: automation must not be used for storage markers (T6) or anything that must be visible to the owner's Safari profile or Home Screen apps. Corroborated by N09 (real profile quota 41231686042 vs automation quota 1048576000). **N07 · 15:10 · protocol change.** Coordinator inserted two steps into the owner's list (7 = install T1 probe, 14 = launch it); the tap list in this file was renumbered to match (1–31). **N08 · 15:12:14 (07:12:14Z) · step 1, T6 demo tab marker.** Owner action: Safari (normal profile) → `https://openpwa.net/demo/` → tapped the header **中文** button once. Read: `wi-read.sh openpwa.net/demo/` (v1, no sidecar). Pages listed (all PID:24364): extension background page, `/demo/`, two `about:blank`. Raw: `raw/2026-10-20-ios18.6.2-step01-tab-demo.json`. Observed: `localStorage["openpwa-demo-lang"]="zh"`, page in Chinese (toggle now labelled "English"), standalone false. Expected: zh stored. Verdict: as-expected (precondition for T6). **N09 · 15:14:17 (07:14:17Z) · step 2, T6 lab tab marker.** Owner action: Safari → `https://openpwa.net/lab/device-tests/#t6` → **Write marker here**. Read: `wi-read.sh lab/device-tests/`. Pages: `/lab/device-tests/#t6`, extension page, two `about:blank` (PID:24364). Raw: `raw/2026-10-20-ios18.6.2-step02-tab-lab.json`. Observed: marker `TAB-2026-10-20T07:13:46Z` in localStorage, IndexedDB and cookie `openpwa_lab_marker`; lab SW registered and controlling; a `/demo/` registration also present (created by step 1); storage quota 41231686042. Expected: marker in all three stores. Verdict: as-expected (precondition for T6 lab variant). **N10 · 15:15:21 (07:15:21Z) · step 3, T7 step 1 (tab).** Owner action: Safari → `https://openpwa.net/demo/push/`, no taps. Raw: `raw/2026-10-20-ios18.6.2-step03-tab-demo-push.json`. Observed (page UI in Chinese because of step 1): prerequisites met = secure context, SW for `/demo/`, user gesture; not met = Notification API ("缺少 window.Notification,无法请求权限。"), PushManager ("没有 window.PushManager,此处无法创建推送订阅。"), permission ("Notification.permission: unavailable"), "iOS:已添加到主屏幕" ("Safari 标签页中不暴露 Push API;请先添加到主屏幕。"). Probe: `Notification` false, `PushManager` false, `window.pushManager` true. Expected: tab = Notification/Push unavailable. Verdict: as-expected. Note N10a: the page's sentence that a Safari tab does not expose the Push API is accurate for the service-worker Push API only; Declarative Web Push's `window.pushManager` is exposed in the same tab (content-wording follow-up, not changed here). **N11 · ~15:16–15:20 · steps 4–8, installs and T3 icons (owner report via coordinator).** Owner actions: Safari → `/lab/device-tests/` → Share → Add to Home Screen → Add ("PWA Lab"); Safari → `/lab/device-tests/t3/manifest-only/` → Add ("Lab no-ATI"); Safari → `/demo/` → Add ("OpenPWA"); Safari → `/lab/device-tests/t1/no-manifest/` → Add (T1 probe); Home Screen screenshot. Exact times not captured. Owner report, verbatim: "180 热点,192 blue, T- 7step is black". Interpretation (coordinator, accepted): PWA Lab icon = red **180** ("热点" read as a typo for 红 "red"; the 180 icon is the only red one, so the number alone identifies it); Lab no-ATI = blue **192**; T1 probe = black letter tile. Expected (2026-10-ios27.md T3): PWA Lab = 180; Lab no-ATI = 192 or 512; T1 = screenshot or letter tile. Verdict: as-expected for all three. Sheet contents (name, presence of any switch): pending screenshots T3_0, T2_1, T1_0. **N12 · ~15:20 · step 6, demo icon (owner report).** Verbatim: "black with blue square". Matches the demo artwork (`/demo/icons/icon.svg`: #161616 square, white outline, blue #0f62fe square). Every declared demo icon (apple-touch-icon `/demo/icons/icon-192.png`; manifest any 192/512; maskable 192/512) carries this artwork. Verdict: as-expected; cannot identify which asset (by design; N11 answers that question). **N13 · 15:21:34 (07:21:34Z) · step 9, demo launched from Home Screen (T2, T5 app, T6 step 2, T9/T10 app).** State before: demo installed in N11, never launched. Owner action: tapped the OpenPWA icon. Read: `wi-read.sh openpwa.net/demo/`. Pages listed: **PID:24500** (not Safari's 24364): one page of another origin (a Home Screen shortcut of another site; not read, URL not recorded, see A3) and `https://openpwa.net/demo/`. Raw: `raw/2026-10-20-ios18.6.2-step09-app-demo.json`. Observed: standalone true; display-mode standalone true, all six others false; page line "Running as an installed app: display-mode: standalone (iOS navigator.standalone)"; page in **English**; localStorage `{}`; no cookies; `Notification` true (permission `default`); `PushManager` true; `window.pushManager` true; `setAppBadge` true; `navigator.install` false; `BeforeInstallPromptEvent` false; registrations: only `/demo/` (activated, controlling); quota 41231686042, usage 86499, persisted false; screen 402×874, inner and visualViewport 402×812, safe-area insets 0/0/0/0. Expected: standalone; English if isolated. Verdict: as-expected; T6 step 2 = isolated (nothing copied at add time: not localStorage, and the lab registration from Safari is not visible either). **N14 · 15:24:36 (07:24:36Z) · step 10, T6 step 3.** Owner action: in the OpenPWA app tapped the language button once (app → 中文/zh), switched to Safari, reloaded the `/demo/` tab. Read: `WIPID=PID:24364 wi-read.sh openpwa.net/demo/` (v2: process filter added because tab and app share the URL). Pages listed at 15:24 (all PID:24364): `t3/manifest-only/`, extension page, `about:blank`, `/lab/device-tests/#t6`, `about:blank`, `t1/no-manifest/`, `/demo/`. The app process was not listed (app in background), so the app value is the owner's report. Raw: `raw/2026-10-20-ios18.6.2-step10-tab-demo.json`. Observed: tab `openpwa-demo-lang="zh"`, page Chinese; app zh (owner report). Expected: tab unaffected by the app. Verdict: **inconclusive**: the app's new value equals the tab's existing value, so the step cannot distinguish isolation from sharing. Step 11 (tab → English, app fully closed and relaunched, app should stay zh) is the discriminating step. **N15 · 15:25–15:40 · tooling and record-keeping change.** `wi-read.sh` v3: writes a `.meta.json` sidecar per read (UTC/local time, sha256 of expression/`wi-eval.mjs`/`wi-read.sh`, proxy version, selected page, redacted page list). Scripts copied to `tools/` and run from there via symlinks in `/tmp/ios18probe/`; hashes in `tools/SHA256SUMS`. `wi-eval.mjs` differs from the copy used in N08–N14 only by a header comment line; `probe-wi.js` is byte-identical to the one used in N08–N14; `wi-read.sh` v1 (N08–N13) and v2 (N14) differ from v3 only in page selection/sidecar output, not in what is evaluated. Reads from step 11 onward carry sidecars. **N16 · 15:29:13 (07:29:13Z) · step 11, T6 step 4 (discriminating step).** State before: tab `zh`, app `zh` (N14). Owner actions: Safari `/demo/` tab → tapped the language button (tab → English); app switcher → swiped OpenPWA away; launched OpenPWA from its icon; app in foreground. Reads: `WIPID=PID:24500 wi-read.sh openpwa.net/demo/` with `probe-wi.js`, then with `tools/timing.js` (`performance.timeOrigin`, navigation type). Pages listed: PID:24500 only (one other-origin page, A3, and `/demo/`); Safari's process not listed (backgrounded), so the tab value is the owner's report. Raw: `raw/2026-10-20-ios18.6.2-step11-app-demo.json` (+ `.meta.json`), `raw/2026-10-20-ios18.6.2-step11-app-demo-timing.json` (+ `.meta.json`). Observed: app `localStorage["openpwa-demo-lang"]="zh"`, page in Chinese, standalone true; document `timeOrigin` 2026-10-20T07:28:22.926Z, navigation type `navigate`, `history.length` 1, i.e. a fresh page load after the relaunch, later than the N14 change (07:24). Tab: English (owner report). The host process id was the same as in N13 (PID:24500), so swiping the app away did not end that process (it also hosts another site's shortcut, A3); the page itself was reloaded. Expected (isolation): app keeps `zh` regardless of the tab switching to English. Verdict: **as-expected**. T6 (demo marker) overall: isolated in both directions observed so far (N13: nothing copied at add time; N16: a tab change does not reach the app). Still to check: whether the app's change reached the tab (N14 inconclusive; can be retested by setting the app to English and reading the tab, optional). **N16-c · 15:31 · correction to N16 (appended).** The optional retest suggested at the end of N16 ("set the app to English and read the tab") would itself be inconclusive, because the tab already holds `en`. Replaced by the coordinator's design: in the app tap the language button twice (zh → en → zh) so the app's last write is `zh` while the tab holds `en`; then foreground the Safari `/demo/` tab without reloading and read its `localStorage` (a same-origin `localStorage` read returns the current stored value without a reload). Isolation predicts the tab still reads `en`. Recorded as N17 ("ready 11b"). **N17 · 15:31:16 (07:31:16Z) · step 11b, T6 app → tab (discriminating).** State before: tab `en` (N16), app `zh`. Owner actions: in the OpenPWA app tapped the language button twice (zh → en → zh), so the app's last write was `zh`; switched to Safari; the `/demo/` tab was foregrounded and **not reloaded**. Read: `WIPID=PID:24364 wi-read.sh openpwa.net/demo/`. Pages listed: Safari PID:24364 (seven pages: `t3/manifest-only/`, `about:blank`×2, extension, `/lab/device-tests/#t6`, `t1/no-manifest/`, `/demo/`) and the app process PID:24500 (other-origin page, `/demo/`). Raw: `raw/2026-10-20-ios18.6.2-step11b-tab-demo.json` (+ `.meta.json`). Observed: tab `localStorage["openpwa-demo-lang"]="en"`, page in English (toggle labelled 中文), standalone false. A follow-up read of the app ~1 min later found no `/demo/` page in PID:24500 (app no longer listed/foreground), so the app's `zh` rests on the owner's report. Expected (isolation): tab stays `en` despite the app's later `zh` write. Verdict: **as-expected**. T6 (demo marker) now covers all three directions: add-time copy (N13: none), tab → app (N16: none), app → tab (N17: none). **N18 · 15:34:15 (07:34:15Z) · step 12, PWA Lab app first launch (T5 app, T6 lab variant, T8 app-side exposure, T9/T10 app).** State before: PWA Lab installed in N11 (step 4), never launched; Safari profile holds marker `TAB-2026-10-20T07:13:46Z` in localStorage, IndexedDB and cookie (N09). Owner action: tapped the PWA Lab icon; app in foreground. Read: first attempt without a process filter selected the backgrounded Safari tab `/lab/device-tests/#t6` and timed out (A5); repeated with `WIPID=PID:24500 wi-read.sh lab/device-tests/`. Pages listed: Safari PID:24364 (seven pages as in N17) and PID:24500: other-origin page (A3), `/lab/device-tests/`, `/demo/`, i.e. **the PWA Lab and OpenPWA Home Screen apps are hosted in the same process** (PID:24500). Raw: `raw/2026-10-20-ios18.6.2-step12-app-lab.json` (+ `.meta.json`). Observed: - context `app (display-mode: standalone; navigator.standalone: true)`; display-mode standalone only; inner 402×812; safe-area insets 0/0/0/0 (lab has no `viewport-fit=cover`). - **Storage marker: localStorage `null`, IndexedDB `null`, cookie `TAB-2026-10-20T07:13:46Z`.** `document.cookie` names: `openpwa_lab_marker`. localStorage `{}`. Storage usage 30 bytes, quota 41231686042. - SW: registration ok (registered on this launch), scope `/lab/device-tests/`, activated, controlling; only this registration visible (the demo's is not, although it lives in the same process). - Window: `Notification` true (permission `default`), `PushManager` true, `window.pushManager` true, `setAppBadge` true; push not subscribed; no notification event records. - **Worker exposure (app-controlled worker, `lab-sw-v2`, captured at worker start before the property is assigned): `'onnotificationclick' in self` true, `typeof self.onnotificationclick` `object` (null), `'onnotificationclose' in self` true, `'onpush' in self` true, `'onpushsubscriptionchange' in self` true, `'Notification' in self` true, `'showNotification' in registration` true, `'pushManager' in registration` true, `clients.openWindow` function.** Expected: localStorage/IndexedDB/cookie all `null` if isolated (2026-10-ios27.md T6 lab variant); worker exposure: no documented expectation for the app context. Verdict: localStorage and IndexedDB **as-expected** (not copied). **Cookie: differs**: the Safari cookie value is visible in the Home Screen app. Two hypotheses: (H1) cookies are copied from Safari into the app's store when the icon is added (or at first launch); (H2) the app and Safari share one cookie jar live. Step 13 discriminates: the app writes `APP-…` to all three stores, then the Safari tab is reloaded: tab cookie `APP-…` ⇒ H2; tab cookie still `TAB-…` ⇒ H1 (copy at add time). Worker exposure: **differs from the Safari-tab-controlled worker** (N03: all of these false). The same worker script exposes the notification/push event handler properties and `Notification` only when controlled by the Home Screen app. Relevance: BCD #22959 marks `notificationclick_event` unsupported on Safari iOS based on `"onnotificationclick" in self`; in a Home Screen app on iOS 18.6.2 that check is **true**, so the BCD result reflects the browser-tab context it was collected in. This goes into the Discrepancies table once T8 (does the handler fire) is done. **N19 · 15:38:39–15:39:56 (07:38:39–07:39:56Z) · step 13, T6 lab: app → tab, cookie copy vs shared.** State before: app holds cookie `TAB-…` (N18). Owner actions (relayed): in the PWA Lab app tapped **Write marker here** (`APP-…`); switched to Safari; opened and reloaded the lab; tab in foreground. Reads (Safari process PID:24364): (a) `wi-read.sh openpwa.net/lab/device-tests/` with `probe-wi.js` matched the first lab-origin page, which was the foreground tab `https://openpwa.net/lab/device-tests/t3/manifest-only/` (not the lab root; this page has no results panel, so the probe's lab fields are null) → `raw/…-step13-tab-lab.json`; (b) an attempt on the backgrounded `/lab/device-tests/#t6` tab timed out (A5); (c) new expression `tools/marker.js` (imports `/lab/device-tests/lab.js` and calls its `readMarker()`; adds `performance.timeOrigin`, navigation type, visibility) on the foreground t3 tab → `raw/…-step13-tab-t3-marker.json` (+ `.meta.json`). The marker cookie is set with `path=/lab/device-tests/`, so it is visible on the t3 page; localStorage and IndexedDB are origin-wide. Observed (c): visibility `visible`; `timeOrigin` 07:38:18.212Z, navigation type `reload`; marker localStorage `TAB-2026-10-20T07:13:46Z`, IndexedDB `TAB-2026-10-20T07:13:46Z`, **cookie `TAB-2026-10-20T07:13:46Z`**. Expected: under H2 (shared live jar) the tab cookie would read `APP-…`; under H1 (copy at add/launch) `TAB-…`. Verdict: consistent with **H1: Safari cookies were copied into the Home Screen app's cookie store when the app was added or first launched, and are not shared afterwards**; localStorage and IndexedDB were not copied (N18) and stay separate. Pending control: read the app to confirm its cookie now reads `APP-…` (i.e. that the app's write happened); without it, "app write did not happen" is an alternative explanation. **N20 · 15:41:08 (07:41:08Z) · step 13b, control read of the app.** Owner action: returned to the PWA Lab app, no taps. Read: `WIPID=PID:24500 wi-read.sh openpwa.net/lab/device-tests/ tools/marker.js`. Raw: `raw/2026-10-20-ios18.6.2-step13b-app-lab-marker.json` (+ `.meta.json`). Observed: href `/lab/device-tests/`, standalone true, visible; document `timeOrigin` 07:32:47.060Z (same document since launch, N18); marker localStorage, IndexedDB and cookie all **`APP-2026-10-20T07:37:40Z`**. So the app wrote `APP-…` at 07:37:40Z, 38 s before the Safari tab reload (07:38:18Z, N19), and the tab still read `TAB-…` in all three stores. Verdict for T6 (lab, three stores): localStorage and IndexedDB isolated in both directions and not copied at add time; **cookie copied from Safari into the Home Screen app once (at add time or first launch), then independent in both directions** (app write not visible in Safari; the Safari value was present in the app before any app write). Not yet determined: whether the copy happens at Add to Home Screen or at first launch, and whether it applies to cookies with other attributes (this one: `path=/lab/device-tests/; max-age=31536000; SameSite=Lax; Secure`, first-party, set by `document.cookie`). For iOS 27: repeat the same sequence. **N21 · 15:46:16 (07:46:16Z) · step 13c, cookie copy timing (add vs first launch).** Design (coordinator): "Lab no-ATI" (`/lab/device-tests/t3/manifest-only/`; manifest id/start_url/scope all `/lab/device-tests/t3/manifest-only/`, display standalone; no service worker; covered by the cookie's `path=/lab/device-tests/`) was added in step 5 (~15:16, when Safari's cookie was `TAB-2026-10-20T07:13:46Z`) and never launched. Owner actions: in the Safari `/lab/device-tests/` tab tapped **Write marker here** (new `TAB-…`, value not yet read); then launched Lab no-ATI for the first time; app in foreground. Read: `WIPID=PID:24500 wi-read.sh t3/manifest-only tools/marker.js`. Pages: PID:24500 only (`t3/manifest-only/`, `/demo/`, `/lab/device-tests/`, other-origin page); the Safari process was not listed at read time (backgrounded), so the new TAB value could not be read (two attempts, no matching page). Raw: `raw/2026-10-20-ios18.6.2-step13c-app-noati-marker.json` (+ `.meta.json`). Observed: href `/lab/device-tests/t3/manifest-only/`, standalone true, `timeOrigin` 07:45:32.575Z, navigation `navigate` (first launch); marker localStorage `null`, IndexedDB `null`, **cookie `TAB-2026-10-20T07:13:46Z`** (the value Safari held when the icon was added, not the newer one). Interpretation (pre-registered by the coordinator): old value ⇒ **copied at Add to Home Screen**. Verdict: consistent with copy-at-add, pending confirmation that Safari really held a newer `TAB-…` at launch time (control read of the Safari tab requested as step 13d). Alternative explanation to keep in view: the copy happens at first launch but from a persisted snapshot of Safari's cookie store that had not yet been flushed with the newer write (the newer write was seconds to minutes old). Also noted: each Home Screen app has its own cookie store: Lab no-ATI does not see PWA Lab's `APP-…` cookie (N20) even though both run in PID:24500 and the path covers both. **N22 · 15:47:52 (07:47:52Z) · step 13d, control read of Safari after N21.** Owner action: Safari `/lab/device-tests/` tab in foreground, no taps. Read: `WIPID=PID:24364 wi-read.sh openpwa.net/lab/device-tests/ tools/marker.js`. Raw: `raw/2026-10-20-ios18.6.2-step13d-tab-lab-marker.json` (+ `.meta.json`). Observed: href `/lab/device-tests/#t3`, `timeOrigin` 07:45:14.204Z; marker localStorage, IndexedDB and cookie all **`TAB-2026-10-20T07:45:25Z`**. Timeline: Safari cookie `TAB-…07:13:46Z` (N09) → Lab no-ATI added (~15:16) → Safari writes `TAB-…07:45:25Z` → Lab no-ATI first document load 07:45:32.575Z (N21), **7 s after the Safari write** → app cookie = `TAB-…07:13:46Z`. Verdict: **consistent with copy at Add to Home Screen** (the app got the value Safari held at add time, not the value Safari held at first launch). Strength: moderate. With only ~7 s between the Safari write and the first launch, a first-launch copy from a not-yet-persisted Safari cookie store cannot be excluded. Proposed stronger retest (optional, folds into T4b): add `t4/sbs-default/` (under the cookie path) without launching; write a new TAB marker in Safari; wait ≥ 2 min and background Safari; then first launch the SBS app and read its cookie (old value ⇒ add time; new value ⇒ first launch). **N23 · 15:49:47 (07:49:47Z) · step 14, T1 probe launched from its Home Screen icon.** State before: icon added in step 7 (black letter tile, N11); a Safari tab on the same URL had existed since step 7. Owner action: tapped the T1 probe icon; owner screenshot T1_4 taken. Reads: `wi-read.sh t1/no-manifest tools/probe-wi.js`, then `tools/timing.js`. Pages listed: all openpwa.net pages in Safari's process PID:24364 (7 pages, same set as N22 plus this one); **no new process, nothing for this URL in the web-app process PID:24500**. Raw: `raw/2026-10-20-ios18.6.2-step14-t1probe.json`, `raw/…-step14-t1probe-timing.json` (+ `.meta.json` each). Observed: page in Safari's process; standalone false; display-mode browser only; inner 402×678 (the Safari-tab size, vs 402×812 in the web apps); insets 0; document `timeOrigin` 07:48:59.035Z, navigation `navigate`, `history.length` 1 (a fresh load when the icon was tapped; whether Safari reused the existing tab or opened a new one cannot be told from the page list, which has the same number of pages); the lab SW (scope `/lab/device-tests/`) **controls** the page; registrations in this context: `/demo/` and `/lab/device-tests/` (Safari's set); localStorage `openpwa-lab-marker` = `TAB-2026-10-20T07:45:25Z` and `openpwa-demo-lang` = `en` (Safari's current values, N17/N22); cookie name `openpwa_lab_marker` present. On-page summary line: `T1 standalone=false dm=browser iOS 18.6.2`. Expected (pre-26 control, consistent with N02): opens as a Safari bookmark. Verdict: **as-expected**: on iOS 18.6.2 a manifest-less, icon-less Home Screen item opens in Safari, with Safari's storage and service workers, not as a separate web app. This matches the owner's 14:45 T1-WI result on the other manifest-less page. **N24 · 15:53:52 (07:53:52Z) · step 15, T4 baseline: where did the in-scope link open?** Owner action (relayed): in the PWA Lab app → T4 table → tapped **open** on the `baseline` row (``, a plain same-origin link inside the manifest scope `/lab/device-tests/`; the baseline page links the same manifest); scrolled so "Line 05" was under the status bar; screenshot T4_1 taken. New expression `tools/t4.js` (variant-probe block, top-element geometry, insets, metas, scroll, element at the top centre). `wi-read.sh` v4 (exact-URL match with a leading `=`; needed because `/lab/device-tests/` is a prefix of other lab URLs; an earlier substring read hit the backgrounded `t3/manifest-only/` page and timed out). Pages listed (PID:24500 only): `t3/manifest-only/`, `/demo/`, `/lab/device-tests/`, other-origin page. **No page for `/t4/baseline/` in any listed process**; Safari's process not listed. Read of the PWA Lab document: href `/lab/device-tests/` (no hash), standalone true, `scrollY` 1283, element at top centre = `H2#t4` ("T4: status bar and top blur va…"), insets 0, theme-color `#161616`, no status-bar-style meta, `viewport` `width=device-width, initial-scale=1`, inner 402×812; document `timeOrigin` 07:32:47.174Z, navigation `navigate`, `history.length` 1, i.e. the **same document since the app launched at N18; the app window never navigated to the baseline page.** Raw: `raw/2026-10-20-ios18.6.2-step15-app-t4-baseline.json`, `raw/…-step15-app-lab-timing.json` (+ `.meta.json`). Interpretation: the baseline page the owner screenshotted was shown outside the app window, most likely an in-app browser sheet (SFSafariViewController-style, separate process not exposed to the proxy) or Safari. 2026-10-ios27.md T4 anticipated this ("If any of them opens in a sheet or Safari instead, record that"). Verdict: **differs from the checklist's assumption** that same-scope variant pages open inside the lab app; the owner is asked to confirm what UI showed the page (Done button / address bar at top = sheet; Safari tabs UI = Safari). Consequence for T4: the T4_1 screenshot shows the baseline page in that container, not in the installed app's own window. **N24-a · 15:56 · harness check for N24 (appended; coordinator asked whether this is a link artefact).** Checked the live `https://openpwa.net/lab/device-tests/` (curl, 07:55Z) and the repo source `site/public/lab/device-tests/index.html`/`lab.js`: the T4 links are plain relative anchors `open`; **no `target` attribute anywhere on the live page (0 matches), no `rel`, no ``, no `window.open`, no click handler on links** (the only click handlers are on the lab's buttons). `https://openpwa.net/lab/device-tests/t4/baseline/` answers `HTTP/2 200` directly (no redirect to another host or path) and links the same manifest `/lab/device-tests/manifest.webmanifest`. So the N24 behaviour is **not** a `target=_blank` / cross-host harness artefact. Explanation still pending the owner's description of the screen (sheet with Done vs Safari vs in-app). Note: N24's inference rests on the app document's `history.length` 1 and unchanged `timeOrigin`; if the owner had navigated to baseline and then used a Back control, the app document would have a new `timeOrigin` (it does not), so an in-app round trip is excluded. **N25 · 15:59:32 (07:59:32Z) · step 15 redo: T4 baseline opens inside the app; correction of N24.** Owner actions (relayed): launched PWA Lab from the Home Screen → T4 table → tapped **open** on the baseline row. The coordinator reports that the first attempt (N24) most likely never tapped the link. Reads: `wi-read.sh t4/baseline tools/t4.js` (no process filter; first match), then `tools/timing.js`. Pages listed: PID:24500 only: `t3/manifest-only/`, `/demo/`, **`/lab/device-tests/t4/baseline/`**, other-origin page; the PWA Lab entry `/lab/device-tests/` is gone from the list (replaced by baseline). Raw: `raw/2026-10-20-ios18.6.2-step15r-t4-baseline.json`, `raw/…-step15r-t4-baseline-timing.json` (+ `.meta.json`). Observed: baseline document in the **web-app process PID:24500**, standalone true, display-mode standalone; `timeOrigin` 07:58:53.462Z, navigation `navigate`, **`history.length` 2** (lab page → baseline in the same window); variant probe: `context: app (display-mode: standalone; navigator.standalone: true)`, `top element: static, top 0px, height 56px, width 402px of 402px` (HEADER "Normal-flow header", blue rgb(15, 98, 254)), `safe-area-inset-top: 0px`, `status-bar-style meta: absent`, `theme-color: #161616`, `viewport: width=device-width, initial-scale=1`; scrollY 0; inner 402×812. Verdict: **as-expected**: a same-scope link opens inside the installed app's window. **Correction of N24 (N24 and N24-a are kept as written):** N24's "differs" verdict is withdrawn. The N24 evidence (app document unchanged since launch, `history.length` 1) is fully explained by the link never having been tapped, so it is not evidence of out-of-app navigation. Screenshot T4_1 from the first attempt therefore does not show the baseline variant; it is to be retaken now. **N25-c · 16:01 · correction to N24 / N24-a (appended; owner confirmation).** The owner confirms that in the first step-15 attempt the baseline link was **not tapped** (owner error, not iOS behaviour), and that on the redo the numbered-lines page opened with **no Done button**, i.e. in-app navigation, not a sheet. N24's "differs" verdict and its sheet/Safari interpretation are void; N24-a's harness check stands as a check. A follow-up read of the scrolled baseline page (~16:01) found no `t4/baseline` page listed (app not in the foreground at that moment); the scrolled state is documented by the owner's screenshot T4_1 (retaken). **N26 · 16:01:17 (08:01:17Z) · step 16 (opportunistic read), T4 fixed variant in the app.** The owner had already moved on to the fixed variant when the N25-c follow-up ran. Read: `WIPID=PID:24500 wi-read.sh t4/fixed tools/t4.js`. Pages: PID:24500 `t3/manifest-only/`, `/demo/`, `/lab/device-tests/t4/fixed/`, other-origin page. Raw: `raw/2026-10-20-ios18.6.2-step16-app-t4-fixed.json` (+ `.meta.json`). Observed: standalone true; `top element: fixed, top 0px, height 56px, width 402px of 402px` (HEADER "Fixed header (56 px)", blue rgb(15, 98, 254)); safe-area insets 0; no status-bar-style meta; theme-color `#161616`; viewport without `viewport-fit`; scrollY 0 at read time. Geometry matches the variant's design (fixed, ≥ 6 px high, ≥ 80% wide, within 4 px of the top: the iOS 27 claim's trigger condition). Visual result (solid bar vs blur): from the owner's screenshot T4_2. **N27 · 16:02–16:03 (08:02–08:03Z) · step 16 "r 16": reads missed (no data).** Three read attempts while the owner moved between variants: (1) 08:02:4x no `t4/*` page in PID:24500 (list: `t3/manifest-only/`, `/lab/device-tests/`, `/demo/`, other); (2) the lab root was gone by the next read; (3) 08:03 the list showed `t4/safe-area/`, but it was no longer present when the read started ~5 s later. No values recorded for sticky or safe-area from these attempts; the visual record is the owner's screenshots T4_3 / T4_4. Procedure change requested: the owner keeps each variant on screen for ~20 s after "ready" and names it. **N28 · 16:05:04 (08:05:04Z) · step 16, T4 sticky variant in the app.** Owner: "ready sticky", holding ~20 s. Read: `WIPID=PID:24500 wi-read.sh t4/sticky tools/t4.js`. Raw: `raw/2026-10-20-ios18.6.2-step16-app-t4-sticky.json` (+ `.meta.json`). Observed: standalone true; scrollY 289 (scrolled); `top element: sticky, top 0px, height 56px, width 402px of 402px` (HEADER "Sticky header (56 px)", blue), stuck at the top; element at the top centre = that header; safe-area insets 0; no status-bar-style meta; theme-color `#161616`; no `viewport-fit`. Visual (bar solid vs blur): owner screenshot T4_3. **N29 · 16:06:41 (08:06:41Z) · step 16, T4 safe-area variant in the app.** Owner: "ready safe-area", holding ~20 s. Read: `WIPID=PID:24500 wi-read.sh t4/safe-area tools/t4.js`. Raw: `raw/2026-10-20-ios18.6.2-step16-app-t4-safe-area.json` (+ `.meta.json`). Observed: standalone true; viewport `width=device-width, initial-scale=1, viewport-fit=cover`; scrollY 409; `top element: fixed, top 0px, height 56px, width 402px` (HEADER "Fixed header, safe-area padded", blue); **safe-area insets top 0px, right 0px, bottom 34px, left 0px**; inner and visualViewport 402×812 (same as without `viewport-fit=cover`; screen 874 tall). Interpretation: in an iOS 18.6.2 standalone app without `apple-mobile-web-app-status-bar-style: black-translucent`, `viewport-fit=cover` extends the layout viewport to the **bottom** edge (34 px home-indicator inset) but **not under the status bar**: the viewport still starts below it (874 − 812 = 62 px, the status-bar area), and `env(safe-area-inset-top)` is 0, so the header's top padding adds nothing. The "blue behind the status bar" that the checklist expects for this variant therefore depends on the system painting the status-bar area, not on page content (owner screenshot T4_4 shows which). Comparison point for iOS 27, where the status-bar/blur behaviour is claimed to change. **N30 · ~16:08 · T4 visual result, four in-app variants (owner report via coordinator).** Source: owner's visual report; screenshots T4_1 (baseline, retaken), T4_2 (fixed), T4_3 (sticky), T4_4 (safe-area) pending AirDrop. Report: on all four variants (baseline N25, fixed N26, sticky N28, safe-area N29) the status-bar area is a **solid colour; no blur; no page content visible under the bar**. Colour: not yet reported (asked). Consistent with the reads: in every variant the layout viewport starts below the status bar (inner height 812 of 874; `safe-area-inset-top` 0, including with `viewport-fit=cover`), so page content cannot reach that strip. Expected for pre-iOS 26 (no documented blur; the iOS 27 claim, Modern Web Weekly #80 / MacRumors 2489325, is about later releases). Verdict: **as-expected**; T4 iOS 18.6.2 baseline = "solid status bar, content never under it, fixed/sticky/cover make no difference". **N30-a · ~16:10 · colour of the status-bar strip (appended to N30; owner report).** The solid strip is **blue on all four variants** (baseline, fixed, sticky, safe-area): the colour of the pages' 56 px header (`#0f62fe`, rgb(15, 98, 254)), **not** `theme-color` `#161616` (black) and not the page background (`html` computed `rgb(255, 255, 255)`, lab.css `--background: #ffffff`). Pages declare no `apple-mobile-web-app-status-bar-style` (default). The owner states this also holds for **baseline**, whose header is `position: static` and scrolls away (N25: static, top 0 at scrollY 0); T4_1 was taken with "Line 05" scrolled under the bar, i.e. with the blue header off-screen. Finding (notable): on iOS 18.6.2, a Home Screen web app with the default status-bar style paints the strip above its viewport in a colour that matches the top of the page content (here the blue header), and `theme-color` did not determine it in these four pages. Open questions, not settled by this run: (a) whether the colour is sampled once (at load/launch, with the header at the top) or tracks the content currently at the top; baseline-scrolled staying blue suggests sampling at load or from the document's top, not live tracking; (b) whether theme-color is used when the top of the page has no distinct colour. A white-topped page would discriminate (not in the current lab). Evidence: owner report + T4_1…T4_4 (pending). For iOS 27: the same four pages are the comparison set; the claim to test there is a blur band instead of a solid strip. **N31 · 16:12:01 (08:12:01Z) · step 17, T4 baseline in a Safari tab (T4_5) and in the app in landscape (T4_6).** Owner actions (relayed): opened `https://openpwa.net/lab/device-tests/t4/baseline/` in a Safari tab, scrolled, screenshot T4_5; returned to the PWA Lab app on the baseline page, rotated to landscape, screenshot T4_6, holding ~20 s. Pages listed: PID:24500 `t3/manifest-only/`, `/demo/`, `t4/baseline/`, other-origin page; PID:24364 (Safari) `t4/baseline/`, `#t6`, `t1/no-manifest/`, `/demo/`, extension page, two `about:blank`. Reads: (a) app baseline `WIPID=PID:24500 … tools/t4.js` → ok; (b) Safari tab baseline `WIPID=PID:24364 …` → evaluation timed out (tab backgrounded, A5); the Safari-tab state rests on T4_5 and the owner's report. Raw: `raw/2026-10-20-ios18.6.2-step17-app-t4-baseline-landscape.json` (+ `.meta.json`). Observed (app, landscape): orientation `landscape-primary`; standalone true; inner and visualViewport **750×402** (screen 874×402 in landscape; 874 − 750 = 124 px not given to the page, i.e. ~62 px on each side); **safe-area insets 0/0/0/0** (no `viewport-fit=cover` on baseline, so the side areas are outside the viewport rather than reported as insets); header static, top 0, 56 × 750, blue; scrollY 0. Expected: no documented expectation for landscape. Verdict: recorded as the baseline; no comparison claim. Visual questions sent to the owner for T4_5 (Safari tab: status-bar/toolbar colour, any tint from the blue header or theme-color) and T4_6 (landscape: is there a status bar at all; colour of the side bands left/right of the page). **N31-a · ~16:14 · owner answers to the N31 visual questions (appended).** Verbatim: **"blue ,yes, still show"**. The questions, in order, were: (1) T4_5 Safari tab: colour of the status-bar/top area, and does it change when the header scrolls away; (2) T4_6 landscape: is a status bar shown at all, and the colour of the side bands. Coordinator's interpretation, recorded with its ambiguity: - "blue" → T4_5 Safari tab top/status area is **blue** (matches the header). Firm. - "yes" → most likely "yes, the colour changes when the header scrolls away". **Ambiguous**: it could also be a bare acknowledgement. Confirmation requested; do not cite until confirmed. - "still show" → T4_6 landscape: **the status bar is still shown** in the installed app in landscape. Moderately firm (the phrase fits question 2a only). - Side-band colours in landscape: **not reported**. If "yes" is confirmed, the Safari tab samples the top colour live (it changes on scroll), unlike the installed app's strip, which stayed blue with the header scrolled off-screen (N30-a). That would be a tab-vs-app difference worth recording for iOS 27. **N31-b · ~16:15 · landscape side bands (appended to N31-a; owner report).** T4_6 (PWA Lab app, baseline, landscape, no `viewport-fit=cover`): the ~62 px bands left and right of the 750 px viewport are **white** on both sides. White matches the page background (`html` rgb(255, 255, 255)); it is neither the blue header colour (which the top strip uses, N30-a) nor theme-color `#161616`. So in landscape the side areas outside the viewport take the page background, while the top strip takes the header colour. Still pending from N31-a: whether the Safari-tab top colour changes when the header scrolls away. **N32 · 16:18:29 (08:18:29Z) · step 19, T7 permission prompt in the installed app.** Owner actions (relayed): PWA Lab app → **1. Request permission** → system prompt shown (screenshot T7_2; exact wording asked, not yet reported) → **Allow**. New expression `tools/perm.js` (reads `Notification.permission`, `permissionState({userVisibleOnly:true})` on the SW registration's and on `window.pushManager`, `getSubscription()` host only, and the lab's result and event lines; it requests nothing). Read: `WIPID=PID:24500 wi-read.sh "=https://openpwa.net/lab/device-tests/#t4" tools/perm.js` (the app document's URL now carries `#t4` from the earlier Back link). Raw: `raw/2026-10-20-ios18.6.2-step19-app-lab-perm.json` (+ `.meta.json`). Observed: standalone true; lab result line **"Notification.requestPermission() → granted"**; `Notification.permission` **granted**; SW registration `/lab/device-tests/` activated; `registration.pushManager.permissionState` **granted**; `window.pushManager.permissionState` **granted** (one grant covers both the SW Push API and Declarative Web Push); no subscriptions yet (both `null`); notification event log "(none yet)". Expected (2026-10-ios27.md T7): prompt after a tap, `granted`. Verdict: **as-expected**. Prompt wording: pending owner report / T7_2. **N32-a · 16:22 · anomaly: permission granted with no prompt seen (appended to N32; see A7).** The owner now reports that **no system permission prompt appeared** at step 19. (The coordinator's earlier relay for step 19 said "system prompt shown (T7_2 screenshot), tapped Allow"; the two relays contradict each other, and the later one is the owner's direct statement.) Read-only evidence: - PWA Lab app, same origin and same app: `Notification.permission` was **`default`** at 07:34:15Z (N18, both the probe and the lab's own JSON); **`granted`** at 08:18:29Z (N32), with both `permissionState` values `granted`. - The lab calls `Notification.requestPermission()` only from the **1. Request permission** button (`lab.js` `requestPermission`, no automatic call on load); its result line reads "Notification.requestPermission() → granted", so the grant came from that call. - No other context requests permission for this app; the OpenPWA demo app was still `default` at N13 (07:21Z) and has not been asked since. - No timing evidence: the lab does not timestamp the call or its resolution, so whether it resolved instantly cannot be shown. Two explanations remain: (H-a) iOS 18.6.2 granted without showing a prompt (would be notable); (H-b) a prompt was shown and answered without being noticed or remembered (e.g. a quick tap on Allow, the earlier relay's version). Not decidable from the page. Discriminating retest planned: step 25 asks for permission in the OpenPWA demo app, which is still `default`; the owner should start a **screen recording** (Control Centre) before tapping, and the agent reads `Notification.permission` before and after. Step 26 (Settings → Notifications) shows whether "PWA Lab" is listed with alerts allowed. **N32-b · 16:24 · correction to N32 / N32-a (appended; coordinator).** The step-19 relay wording "system prompt shown (T7_2 screenshot), tapped Allow" was the coordinator's **paraphrase of the planned step, not the owner's report**; the owner sent only "r 19". It must not be used as evidence. The first and only owner report about the prompt is "no system prompt". N32's sentence "system prompt shown (screenshot T7_2 …) → Allow" is therefore void; N32-a's hypothesis H-b loses its support from the relay (it remains a possibility only as "prompt shown but not noticed"). The step-25 retest with screen recording and before/after reads stands. **N33 · 16:20:33 (08:20:33Z) · step 20, push subscription in the PWA Lab app (T7 step 3).** Owner action (relayed): **Subscribe to push**, holding ~20 s. New expression `tools/sub.js` (records endpoint **host only** plus endpoint path length, `expirationTime`, `options.userVisibleOnly`, whether `options.applicationServerKey` equals the lab's public key, and the names of the keys; never the endpoint path or key values). Read: `WIPID=PID:24500 wi-read.sh "openpwa.net/lab/device-tests/#" tools/sub.js`. Raw: `raw/2026-10-20-ios18.6.2-step20-app-lab-sub.json` (+ `.meta.json`; checked: no full endpoint in any raw file). Observed: lab result line **"subscribed; endpoint host web.push.apple.com"**; SW-registration subscription: endpoint host **`web.push.apple.com`**, path length 172, `expirationTime` **null**, `userVisibleOnly` true, applicationServerKey **matches** the lab VAPID key, keys `p256dh`, `auth`; `Notification.permission` granted. **`window.pushManager.getSubscription()` → `null`** while the SW registration holds a subscription: the Declarative Web Push manager on `window` does not return the service-worker subscription on the same origin and app. Expected (2026-10-ios27.md T7): subscribe succeeds with an Apple push host. Verdict: **as-expected**; the window/SW subscription separation is recorded as an observation (no prior expectation). **N34 · 16:21:46 (08:21:46Z) · step 21, worker exposure probe in the app (T8 step 1), after permission and subscription.** Owner action: **Probe worker exposure**, holding ~20 s. Expression `tools/exposure.js` (reads the lab's probe output and its JSON exposure block; no worker messages of its own). Raw: `raw/2026-10-20-ios18.6.2-step21-app-lab-exposure.json` (+ `.meta.json`). Observed (lab JSON collected 08:21:16Z; result line "probe answered"): `lab-sw-v2`, captured at worker start before the property is assigned: `'onnotificationclick' in self` **true**, `typeof self.onnotificationclick` **object**, `'onnotificationclose' in self` true, `'onpush' in self` true, `'onpushsubscriptionchange' in self` true, `'Notification' in self` true, `'showNotification' in registration` true, `'pushManager' in registration` true, `clients.openWindow` function; push subscribed, host `web.push.apple.com`. Identical to N18 (before permission was granted), so the exposure does not depend on permission state; it depends on the context (app vs tab, N03). Verdict: recorded for T8 values; the BCD #22959 check (`"onnotificationclick" in self`) is **true** in the Home Screen app context. **N35 · 16:25:26 (08:25:26Z) · step 22, `notificationclick` from a banner tap (T8 steps 2–3).** Owner actions: **2b. Show in 5 s (then go Home)** → Home Screen → banner appeared → tapped it. Owner report, verbatim: **"i tapped the banner, but still stay test page"**. Screenshots T8_1 / T8_2 presumably taken (pending). New expression `tools/events.js` (lab `readEvents()` from IndexedDB, the localStorage last event, page log, document timing). Read: `WIPID=PID:24500 wi-read.sh "openpwa.net/lab/device-tests/#"` (a first read without `#` matched the backgrounded `t3/manifest-only/` page and timed out, A5). Raw: `raw/2026-10-20-ios18.6.2-step22-app-lab-events.json` (+ `.meta.json`). Observed: page log "worker recorded notificationclick via addEventListener". **Six records = three banner taps, each firing both handler paths**: | tap | notification created | click recorded (addEventListener / property) | navigation (addEventListener path) | |---|---|---|---| | 1 | 08:22:57.000Z | 08:23:07.007Z / 08:23:07.008Z | windowsFound 1, **focused existing window** (`/lab/device-tests/#t4`) | | 2 | 08:23:21.253Z | 08:23:30.533Z / 08:23:30.534Z | windowsFound 1, focused existing window | | 3 | 08:24:38.479Z | 08:24:46.071Z / 08:24:46.072Z | windowsFound 1, focused existing window | All records: title "OpenPWA lab notification", body "shown by the worker after 5 s: tap me (T8)", tag `lab-t8`, `action` "", `data.url` `/lab/device-tests/?from=notification`, `swVersion` `lab-sw-v2`. No `notificationclose` records. Page document: `timeOrigin` 08:17:25.267Z (unchanged across the taps; loaded before the first notification), navigation `navigate`, `history.length` 3, visible, still at `/lab/device-tests/#t4`; SW controlling; permission granted. The owner's report that it "still stays on the test page" is the lab's designed behaviour: with a window already open, the worker calls `focus()` on it and does not navigate to `data.url`. Expected / hypotheses (2026-10-ios27.md T8): no record = handler did not fire (WebKit 268797); listener only = property path broken (BCD); both = both fire. Verdict: **both paths fire, every time (3/3)**; `clients.matchAll` finds the window and `focus()` succeeds. On iOS 18.6.2 in a Home Screen app, `notificationclick` works via `addEventListener` and via `self.onnotificationclick`; together with N18/N34 (`'onnotificationclick' in self` true) this contradicts BCD's "unsupported" for this context. Candidate for the Discrepancies table. The owner tapped more than once (three notifications in ~2 min); all are kept. **N35-a · 16:27 · owner visual cross-check of N35 (appended).** Owner reads the page's result line as, verbatim, "worker recorded not cliick via add eventlistener", i.e. the lab's line "worker recorded notificationclick via addEventListener" (matches the `notifyOut` value read in N35). That line shows only the most recent message from the worker; the property-path records are not shown there but **are present** in IndexedDB (ids 1, 3, 5, `via: "onnotificationclick property"`, each 1 ms after its listener record). **N36 · 16:27:20 (08:27:20Z) · step 23, notification shown while the app is in the foreground, tapped in Notification Centre (T8 step 4).** Owner actions: **2a. Show notification now**, stayed in the app, pulled down Notification Centre, tapped the notification, holding ~20 s. Read: `tools/events.js`. Raw: `raw/2026-10-20-ios18.6.2-step23-app-lab-events.json` (+ `.meta.json`). Observed: two new records, notification created 08:26:28.601Z (label "shown immediately"), clicked 08:26:49.588Z: id 7 `via: "onnotificationclick property"`, id 8 `via: "addEventListener"` with navigation windowsFound 1, **focused existing window** (`/lab/device-tests/#t4`); document `timeOrigin` unchanged (08:17:25.267Z), `history.length` 3; no `notificationclose`. Verdict: **both paths fire** from a Notification Centre tap as well (4/4 taps so far). Whether a banner was shown while the app was in the foreground: asked, not yet reported. **N37 · 16:28 · harness version change (lab).** The coordinator reports a deploy (39392356831; repo commit `1124b20d feat(lab): add T4 strip-colour variants (white-top, theme-red, bg-green, dynamic)`) that adds `/lab/device-tests/t4/{white-top,theme-red,bg-green,dynamic}/` and changes `lab.js` (the variant probe block now also prints the top-element colour, viewport-top colour, html/body background, and refreshes itself). Snapshots in `tools/site-snapshots/` (with `SHA256SUMS`): `lab.js` at b72fe9ca `849c0ac7…6502` (the version served during N03–N36), live `lab.js` fetched 08:28Z `eb7c4d5d…325c`; `sw.js` unchanged (`0e7e6f34…fc30`, `lab-sw-v2`, identical in both). Pages already open in the app keep the old module until reloaded; reads from N38 on note which `lab.js` the page loaded. Plan: new step 18b (added by another session to the tap list) runs after step 27. **N38 · 16:29:42 (08:29:42Z) · step 24, banner tap after a full close and relaunch (T8 step 5).** Owner actions: app switcher → swiped PWA Lab away; launched it from its icon; **2b**; went Home; tapped the banner; holding ~20 s. New expression `tools/events2.js` (= `events.js` plus a `lab.js` version check: whether the loaded module's `bootVariant` contains the new "colour at viewport top" line). Raw: `raw/2026-10-20-ios18.6.2-step24-app-lab-events.json` (+ `.meta.json`). Pages listed: **only one page in PID:24500, `/lab/device-tests/`** (the demo, Lab no-ATI and the other-origin page are no longer listed; same PID). Observed: document `timeOrigin` 08:28:29.978Z, navigation `navigate`, `history.length` 1 (the relaunch gave a fresh document; the `#t4` hash is gone); SW controlling (`/lab/device-tests/sw.js`). Two new records: notification created 08:28:40.822Z (2b), clicked 08:28:50: id 9 `via: "onnotificationclick property"` (08:28:50.061Z), id 10 `via: "addEventListener"` (08:28:50.048Z) with windowsFound 1, **focused existing window** (`/lab/device-tests/`). Verdict: both paths fire (5/5 taps). Caveat: this was a fresh launch, but the app window was still alive (backgrounded) when the banner was tapped, so it tests the same focus path as N35, not the "no window alive → `openWindow`" path the checklist aims at. A variant that closes the app between 2b and the tap is proposed as step 24b. Version note: the freshly loaded page reports the **old** `lab.js` (849c0ac7, pre-1124b20d) although the live file changed at ~08:28Z (N37). The lab SW has no fetch handler or cache (sw.js comment "No fetch handler and no caching"), so the old module came from the HTTP cache or from a load that preceded the deploy reaching this edge; it does not affect the notification records (the worker, `sw.js`, is unchanged). **N38-a · 16:31 · cause of the old `lab.js` (appended).** `curl -I https://openpwa.net/lab/device-tests/lab.js` (08:31Z): `cache-control: public, max-age=14400, must-revalidate, no-transform`. A 4-hour HTTP cache lifetime explains why the relaunched app still runs the pre-deploy module. To get the new probe lines for step 18b, the pages must bypass the cache (e.g. Settings → Apps → Safari → Advanced → Website Data is **not** acceptable here because it would also wipe the T6/T7/T8 state; preferred: the lab adds a version query to the module URL, or accept the old probe block and rely on `tools/t4.js` reads, which already capture top-element and html/body colours). **N36-a · 16:32 · foreground banner (appended to N36; owner report).** With the PWA Lab app in the foreground, tapping **2a. Show notification now** made a notification **banner appear on screen** (the owner then also found it in Notification Centre and tapped it there, N36). So on iOS 18.6.2 a `registration.showNotification()` from a Home Screen app's own worker is presented as a banner even while that app is frontmost. **N39 · 16:34 · decisions and tooling for steps 18b / 24b (coordinator).** (1) Step 24b approved: 2b → immediately swipe PWA Lab away in the app switcher → tap the banner → read; tests the "no window alive" path (`navigation.outcome` "opened new window" expected if `openWindow` runs). (2) No cache-bust or deploy for 18b. Instead new expression **`tools/t4b.js`** (sha256 `69d66f9c…bcb8`): everything `t4.js` reads plus, computed independently in the page, the colour fields the 1124b20d lab probe prints: top element computed background, colour at the viewport top via `elementFromPoint(innerWidth/2, 0)` walking up to the first non-transparent background (same algorithm as live `lab.js` `colourAtViewportTop`), the same at y = 1, html and body backgrounds, all `theme-color` metas (content and media), status-bar-style, viewport, and the dynamic page's log. Step 18b values come from `t4b.js`, not from the (cached, old) on-page probe block. The foreground-banner answer is in N36-a. **N40 · 16:43:47 (08:43:47Z) · step 24b, banner tap after swiping the app away (T8 "no window alive" attempt).** Owner actions: **2b**; immediately opened the app switcher and swiped PWA Lab away; banner appeared; tapped it; app in foreground, holding ~20 s. Read: `tools/events2.js`. Raw: `raw/2026-10-20-ios18.6.2-step24b-app-lab-events.json` (+ `.meta.json`). Pages: PID:24500, one page `/lab/device-tests/`. Observed: notification created 08:43:03.022Z; clicked 08:43:09: id 11 `via: "onnotificationclick property"` (08:43:09.245Z), id 12 `via: "addEventListener"` (08:43:09.236Z) with **windowsFound 1, "focused existing window"**. Document `timeOrigin` 08:28:30.036Z (the N38 document, 08:28:29.978Z; the 58 ms difference is within the rounding of `performance.timeOrigin` across reads, and `history.length` is 1 in both), navigation `navigate`; old `lab.js` (849c0ac7); SW controlling. Interpretation: swiping the app away in the switcher **did not end the page**: the same document was still alive ~6 s later and `clients.matchAll` found it, so the worker focused it instead of calling `openWindow`. Both handler paths fired (6/6 taps). Verdict for the `openWindow` path: **not reached** (could-not-run by this method). Swiping a Home Screen web app away on iOS 18.6.2 appears to hide the window rather than destroy the web content within seconds (consistent with N16, where the process id also survived a swipe, though there the page was reloaded at relaunch). **N41 · 16:49:29 (08:49:29Z) · step 25, OpenPWA demo: permission and push subscription (T7 steps 2–3, demo path).** Planned procedure (pre-tap read + screen recording, N32-a) was **not followed**: the owner skipped the pre-tap read and did not record the screen; tapped **Request permission and subscribe** on the demo's Push page, then sent "ready 25b". **Owner report: a system permission prompt did appear, and they tapped Allow.** (Contrast: step 19 in PWA Lab, owner reports no prompt, A7.) New expression `tools/demo-push.js` (permission states, subscription host only, page result text with endpoints/keys redacted). Pages at read time: PID:24500, one page, `https://openpwa.net/demo/` (not `/demo/push/`; document `timeOrigin` 08:49:06.706Z, `history.length` 1, i.e. a fresh document, so the result line of the Push page was not available). Raw: `raw/2026-10-20-ios18.6.2-step25b-app-demo-push.json`, `raw/…-step25b-app-demo-timing.json` (+ `.meta.json`; no endpoint path in either). Observed: standalone true; `Notification.permission` **granted** (was `default` at N13, 07:21Z); SW and window `permissionState` granted; SW registration `/demo/`; subscription endpoint host **`web.push.apple.com`**, `expirationTime` null; `window.pushManager.getSubscription()` null (as in the lab, N33). Verdict: **as-expected** (prompt after a tap, granted, Apple push host). A7 stays open. Pre-tap value for the demo is the N13 read (`default`, 88 min earlier); nothing in between asked for the demo's permission. Retest options for A7 (a never-prompted app with a permission button): none exists in the current harness. Lab no-ATI and the t4/sbs-* pages have no buttons (0 `