Files
ytplayer/plans/phase4-verification.md

6.2 KiB
Raw Permalink Blame History

Phase 4 verification

The served frontend is build c3dbdd7039db, source delivery commit 2c50035. phase4-final-2026-10-08.json records parent b335f95 because the review fix was uncommitted when its scratch tree was copied; that tree includes exactly the frontend subsequently committed as 2c50035. The isolated cold result records both 2c50035 and the build tag. Earlier phase result files were restored after harnesses wrote their default paths; Phase 4 copies retain the actual new run evidence.

Six green seams

Commit Seam Original bytes moved Frontend tests Server tests Both-engine cached smoke / hidden timers
3c9a24a Eager shell/views/section rail 98,378 192 183 Pass
5fb9564 Presenter 9,492 193 183 Pass
8e7fa19 Remote client 30,421 194 183 Pass
94ea211 Watch party 22,833 195 183 Pass
0475a18 Share/External 13,334 196 183 Pass
b335f95 Stats view 7,074 197 183 Pass
2c50035 Lazy-entry rejection handling — 198 183 Pass

After every seam, node --test frontend/*.test.js, bun install then bun run test in server, node perf/hidden-timers.mjs, and node perf/seams.mjs --browser all ran. Server tests used PATH="$PWD/../perf/.tmp/test-venv/bin:$PATH" so yt-dlp worker tests also ran, without skips. Logs are in gitignored perf/.tmp; representative actual output:

ℹ tests 198
ℹ pass 198
ℹ fail 0
ℹ skipped 0

Server totals across its isolated test processes: 183 pass, 0 fail, 0 skip.

chromium {"browser":"chromium","checked":["shell","presenter","remote","party","share","stats"],"offlineNetworkRequests":0,"errors":[]}
webkit {"browser":"webkit","checked":["shell","presenter","remote","party","share","stats"],"offlineNetworkRequests":0,"errors":[]}
Result: ALL ASSERTIONS PASSED

The cache smoke stops Bun and blocks its proxy, then tests home playlists and eager Settings, Presenter blank/pair validation, Remote pair form/close, Party local UI, Share timestamp editing, External uploaded-media sheet/M3U, populated Stats view, and a rejected entry action. Network relays are still required to connect parties or remotes; offline verification proves cached code/UI, not offline relay service. Existing lazy harness passes offline layouts, first-use, Settings extensions, contract guards, pinned instances and update-during-playback on both engines.

One review smoke WebKit process terminated during concurrent browser checks; an isolated rerun and the final expanded both-engine smoke passed. Initial harness fixture errors (incorrect Settings selector, absent VM helper, timestamp format, hidden list pane) were corrected to exercise actual UI; no product tests were removed or weakened.

Measurements

Actual commands:

node perf/baseline.mjs --runs 1 --browser all --profile lte --scenario all --out perf/results/phase4-final-2026-10-08.json --compare perf/results/after-phase0-2026-10-07.json
node perf/baseline.mjs --runs 3 --browser chromium --profile lte --scenario cold --out perf/results/phase4-cold-isolated-2026-10-08.json --compare perf/results/after-phase0-2026-10-07.json

Full reduced run overlapped other checks; its Chromium long tasks were 495 ms. Repeat cold-only runs with no concurrent tests produced 297/274/275 ms (median 275). Keep both results: neither is rewritten. WebKit lacks the long-task API. Historical Phase 0 is five-run data; these reduced measurements are directional.

Metric Phase 0 Chromium / WebKit Phase 3 Chromium / WebKit Phase 4 Chromium / WebKit
Initial compressed JS/CSS 276,414 / 338,940* 221,307 / 274,813 210,419 / 255,200
Cold boot ms 10,480 / 3,290 7,193 / 3,293 7,010** / 2,977
Cold FCP ms 1,572 / 1,100 1,356 / 2,467 1,352** / 2,401
Cold long-task ms 454 / unavailable 287 / unavailable 275** / unavailable
Warm boot ms 692 / 139 419 / 81 467 / 132
Offline boot ms 259 / 137 166 / 84 180 / 90
Core app update wire bytes 611,338 / 680,822 159,905 / 194,026 125,795 / 147,259
Inactive CSS blocking-readiness bytes 611,476 / 680,831 29,724 / 28,082 30,263 / 28,713
Feature edit through actual idle cache fill — — 33,408 / 41,364

*Matched Phase 0 source reconstructed in Phase 3; historical JSON lacks initial bytes. **Isolated three-run Chromium cold median. Other Phase 4 numbers are the one-run both-browser suite. Warm counters include unfinished initial idle caching. CSS readiness excludes its later background payload; it is not full update cost. WebKit first paint still fails the master no-regression target. Full five-run comparisons belong to Phase 5. Native iPhone timing/audio/quota is unverified.

Actual feature-update output:

run 1/1: 33408 bytes, 8 reqs, dur=1376ms
run 1/1: 41364 bytes, 7 reqs, dur=1358ms

Only presenter.js application payload transfers (3,118 / 3,587 compressed bytes). Totals include changed stamped index, manifest, version checks, sw.js checks and WebKit's 1,954-byte sync-core worker import. No app.js, unchanged core views, fonts, icons or CSS transfer. The benchmark asserts this rather than inferring it from the lower total. Final app.js is 408,473 versus 587,029 bytes: −178,556, −30.4169%; original code moved totals 181,532, facade overhead 2,976 bytes.

Migration, rollback and owner checks

Both engines pass b77938a migration with lossy/stalling and unthrottled proxies: 122 cached SHELL entries, one banner and exactly one user-initiated reload, 21 legacy URL checks, N-1 open-tab continuity, offline boot, playback guard, eviction repair and incremental refresh. Result JSON records the real runs. No automatic activation/reload or live singleton replacement is added.

Rollback ASSET_SYNC=0 and ASSET_HASHING=0 use the existing legacy path; commands and results are in perf/README.md and perf/results. No new feature flag. Revert an individual seam to restore its previous parsing behavior.

Owner must verify a real iPhone PWA: warm feature first-use, selected/offline layout, Presenter/Remote/Party sessions, update guard/override, locked audio 30 minutes, interruption/resume, saved OPFS music surviving cache quota pressure. Nothing was pushed, merged or deployed.