Blaze test: holding Down/Up through any list shows each item fully loaded #641
Open
opened 2026-10-01 16:22:29 +00:00 by kayg
·
100 comments
No Branch/Tag specified
dev
wip/nlpchip-1127
wip/morph-1104
wip/merge-round-7c5
wip/merge-round-7c4
wip/merge-round-7c3
wip/merge-round-7c2
wip/merge-round-7c
wip/mchrome-1084
wip/mailghost2-1094
wip/mailghost-1094
wip/kbpreview2-1118
wip/kbpreview-1118
wip/kanban-1092
wip/importhang-1121
wip/hiderev-1153
wip/hide4-1153
wip/hide3-1153
wip/hide2-1153
wip/hide-1153
wip/editreg-1132
wip/editorrail3-1113
wip/editorrail2-1113
wip/editorrail-1113
wip/e2e-b2-1071
wip/e2e-b-1071
wip/draw4-1101
wip/draw3-1101
wip/draw2-1101
wip/draw-1101
wip/directory-1199-r
wip/directory-1199
wip/delete-1119
wip/collabrev-1197
wip/collabloss-1197
wip/cards2-1083
wip/cards-1083
wip/canvas-visual
wip/canvasvis2-976
wip/calhdr-1112
wip/calcards-1115
wip/browserfix
wip/blocks-1125
wip/allday-1107
wip/agenda-decks
wip/agenda-1086
wip/adv7c-1105
wip/txentry-1198
wip/trayicons2-1095
wip/trayicons-1095
wip/tagperf-1186
wip/sidebar3-1094
wip/rev2-webperf
wip/rev2-money-ident
job/adv-1202
wip/restyle-notes
wip/previewcard-1098
wip/palette2-1123
wip/palette-1093
wip/onboard2-1141
wip/onboard-1141.aborted-early
wip/onboard-1141
job/merge30
job/notifloop-1194
job/collabloss-1197
job/onboard-1141
job/hide-1153
job/perf-1124
job/perf2-1124
job/tocrail-1191
job/restyle-settings
wip/restyle-settings
job/segmented-1200
wip/notifloop-1194
job/tagperf-1186
wip/segmented-1200
job/restyle-files
job/tagdnd-1187
job/cards-1179
wip/cards2-1179
wip/cards-1179
wip/tocrail-1191
wip/tagdnd-1187
wip/restyle-files
wip/perf-1124
wip/merge30j
job/restyle-notes
job/wizchoices-1140
wip/wizchoices-1140
wip/restyle-1190
job/moneyfmt-1180
job/txentry-1198
wip/moneyfmt2-1180
wip/moneyfmt-1180-r
wip/moneyfmt-1180
job/pillglass-1189
job/flags-1181
wip/flags-1181
job/restyle-1190
job/restyle-mailmoney
job/restyle-search
job/settingsreg-1195
job/wizard-1140
site/website
wip/wizardrev2-1140
wip/wizardrev-1140
wip/wizard5-1140
wip/wizard4-1140
wip/wizard3-1140
wip/wizard2-1140
wip/wizard-1140
wip/pillglass-1189
wip/settingsreg-1195
job/merge29
job/fu-1171
wip/merge29j
wip/fu-1171
job/fu-1166
job/directory-1199
job/proflog-1204
job/txresearch-1188
wip/fu-1166
job/merge28
job/search-1066
wip/search-1066
wip/merge28j
job/gateslot-1182
job/bulkimport-1157
job/mailnet-1160
wip/mailnetrev-1160
wip/mailnet-1160
wip/bulkrev-1157
wip/bulkimport-1157
job/startup-1161
wip/startup-1161
job/merge27
job/linkcards-1151
wip/linkcards3-1151
wip/linkcards2-1151
wip/linkcards-1151
job/traydate-1144
wip/traydate3-1144
wip/traydate2-1144
wip/traydate-1144
job/draw-1101
wip/merge27j
job/blockpill-1152
wip/blockpill3-1152
wip/blockpill2-1152
wip/blockpill-1152
job/minihover-1149
wip/minihover2-1149
wip/minihover-1149
job/merge25
wip/merge25-r
wip/merge25b
wip/merge25
job/inspector-1129
job/tags-1110
wip/inspector3-1129
wip/inspector2-1129
wip/inspector-1129
wip/tagsrev-1110
wip/tags2-1110
wip/tags-1110
job/dates-1148
wip/datesrev-1148
wip/dates2-1148
wip/dates-1148
job/licence-1145
wip/licence2-1145
wip/licence-1145
job/selfhost-1156
job/merge23
wip/merge23
job/tagfilter-1109
wip/tagfilter2-1109
wip/tagfilter-1109
job/kbd-1134
wip/kbd2-1134
wip/kbd-1134
job/palfoot-1137
wip/selfhost-1156
wip/palfoot2-1137
wip/palfoot-1137
job/toggle-1158
wip/toggle-1158
job/kbpreview-1118
job/docratchet-1155
job/perflint-1133
job/devtests-1159
wip/docratchet-1155
wip/devtests-1159
job/segv-1136
wip/toast-1142
wip/segv-1136
job/toast-1142
job/blockreload-1147
wip/blockreload-1147
job/font-1150
wip/font-1150
job/importui-1120
job/minimonth-1149
wip/importui-1120
wip/minimonth-1149
job/depcheck-1146
wip/perflint-1133
wip/depcheck-1146
job/calcards-1115
job/blocks-1125
job/plus-1128
job/shift-1138
wip/plus2-1128
wip/plus-1128
wip/shift-1138
job/moneyfid-1130
job/editorrail-1113
wip/moneyrev-1130
wip/moneyfid-1130
job/noext-851
wip/noext-851
wip/noext3-851
wip/noext2-851
job/week-1135
wip/week-1135
job/editreg-1132
job/smoke-1122
wip/smoke-1122
job/docs-1143
job/palette2-1123
job/calhdr-1112
job/nlpchip-1127
job/mailghost-1094
job/reconnect-1131
wip/reconnect-1131
job/trayicons-1095
job/delete-1119
job/importhang-1121
job/cards-1083
job/palette-1093
job/mchrome-1084
job/e2e-a-1071
job/canvas-visual
job/previewcard-1098
job/allday-1107
wip/e2e-a2-1071
wip/e2e-a-1071
job/e2e-b-1071
job/adv7c-1105
job/kanban-1092
job/agenda-1086
job/merge-round-7c
job/morph-1104
wip/surfaces-p2
job/merge-round-9
wip/merge-round-9
job/7cfix-small
wip/7cfix-small
job/mailui-1078
job/merge-round-8
wip/merge-round-8
wip/mailui-1078
job/mailround-1038
job/applemail-accept
wip/settitle-1068
wip/mailround2-1038
wip/mailround-1038
wip/e2e-7b
job/crash-1069
wip/crash-1069
job/searchlost-1066
wip/searchlost-1066
job/7b-reconcile
job/flake-1065
wip/flake-1065
wip/merge-round-7b7
wip/merge-round-7b6
wip/merge-round-7b5
wip/merge-round-7b4
wip/7b-reconcile
job/appupdate-1059
job/nfd-1044
wip/appupdate-1059
job/e2e-7b
job/loop-1062
wip/loop-1062
job/pdfprev-1045
job/invtoggle-1053
wip/pdfprev-1045
wip/nfd-1044
wip/invtoggle-1053
job/7bfix-e2e
job/mailstress-b
wip/7bfix-e2e
wip/mailstress-b
job/7bfix-adv
wip/7bfix-adv
job/mailstress-a
job/stack-1054
wip/stack-1054
wip/mailstress-a
job/mailstress-1038
wip/mailstress-1038
job/upload500-1051
wip/upload500-1051
job/share-1034
wip/share-1034
job/syncerr-1037
job/7bfix-photos
wip/7bfix-photos
job/paste-1036
job/setside-1039
wip/setside-1039
wip/paste-1036
job/lease-1042
wip/syncerr-1037
wip/lease-1042
job/7bfix-data
job/passkeybind-1043
wip/apprevoke-1041
job/invite-1035
wip/invite-1035
job/merge-round-7b2
wip/merge-round-7b2
job/mailproxy-486
job/apprevoke-1041
job/rebuild-1033
job/pillborder-1029
wip/pillborder-1029
wip/mailproxy-486
wip/applemail-486
job/headless-998
wip/headless-998
job/groups-1028
wip/groups-1028
job/rebuildwarn-1016
wip/rebuildwarn-1016
job/startup-1011
wip/startup-1011
job/monthpill-1009
job/bgthumb-1025
job/sharetitle-1012
wip/monthpill-1009
wip/bgthumb-1025
wip/sharetitle-1012
job/canvas-cards-977
wip/canvas-cards-977
job/canvas-pencil-978
job/canvas-sketch-990
wip/canvas-sketch-990
wip/canvas-pencil-978
job/canvas-files-989
wip/canvas-files-989
job/canvas-collab-991
wip/canvas-collab-991
job/weekscroll-1018
wip/weekscroll-1018
wip/canvas-core-976
job/canvas-core-976
job/round-drag
wip/round-drag
job/round-settings
job/browserfix
wip/oapi-974
job/oapi-974
job/hist2-integrate
job/mailhtml-726
wip/mailhtml-726
wip/hist2-integrate
job/moneyfu-984
job/drag-1015
wip/drag-1015
job/rename-1017
wip/rename-1017
job/hist2-api
wip/hist2-api
job/oneacct-1014
wip/oneacct-1014
wip/moneyfu-984
job/hist2-bench
job/hist2-restore
wip/hist2-bench
job/hist2-write
job/hotfix-724
wip/hotfix-724
wip/hist2-write
wip/hist2-restore
job/hist2-store
job/hist2-ui
wip/hist2-ui
wip/hist2-store
job/searchstarve-965
job/shutdown-963
wip/shutdown-963
wip/pubedit-981
job/pubedit-981
job/analytics-973
wip/searchstarve-965
job/authflash-850
job/weeklane-969
job/pvtitle-1004
job/hist-975
wip/authflash-850
job/voicepill-617
wip/pvtitle-1004
job/headring-1003
wip/weeklane-969
wip/voicepill-617
wip/headring-1003
wip/analytics-973
job/agentscope-980
wip/thumbsandbox-988
job/thumbsandbox-988
wip/hist-975
job/links-856
wip/links-856
job/davetag-966
wip/davetag-966
job/filesstorm-1000
job/hoverpad-725
wip/filesstorm-1000
job/ffmpegblas-993
job/merge-round-7a
wip/hoverpad-725
wip/ffmpegblas-993
job/nowdot-1002
wip/verify-7a
job/noteid-857
wip/nowdot-1002
wip/noteid-857
wip/merge-round-7a
wip/agentscope-980
job/imapedge
job/a11yfix2
wip/imapedge-941
wip/imapedge
wip/a11yfix2
job/notetask-986
job/logheading
wip/logheading-998
job/textthumb-652
job/photolive-987
wip/photolive-987
job/davactive-983
job/savefix-985
job/tabicons-607
wip/davactive-983
wip/tabicons-607
wip/notetask-986
wip/savefix-985
job/dirid-627
job/buildspeed-1007
wip/dirid-627
job/agenda-decks
job/perfguards-impl
job/undo-a11y
wip/undo-a11y
job/mailperf
job/wal-824
wip/settings-50
job/settings-50
job/notesfilter-606
wip/notesfilter-606
job/surfaces-p2
wip/wal-824
job/maillayouts
wip/mailperf
wip/maillayouts
job/taskmeta-659
job/money-ident
wip/money-ident
wip/taskmeta-659
job/errstates
wip/perfguards-impl
job/headings-881
wip/headings-881
wip/errstates
job/voice-619
job/gaps-827
job/notesperf
wip/notesperf
wip/voice-619
job/hddsql-549
job/perf-stream-668
wip/perf-stream-668
wip/deeplinks-fix
job/deeplinks-fix
job/authfix
job/docsfix-rust
wip/docsfix-rust
job/webperf
job/docsfix-web
job/datafix2
job/webdav-lock-476
job/copyfix
wip/copyfix
wip/webperf
job/focus-658
wip/protofix
job/mediafix
job/protofix
wip/mediafix
job/agentfix
job/hhmm-724
wip/agentfix
job/undo-722
job/reuse
wip/webdav-lock-476
wip/reuse
job/scopefix
job/datafix
wip/hhmm-724
wip/undo-722
job/surfaces-p1
wip/hddsql-549
job/voicememos-618
wip/datafix2
wip/surfaces-p1
job/fix-940
wip/fix-940
job/blaze-surfaces
wip/datafix
wip/blaze-surfaces
job/taskday-655
job/linknav-639
wip/linknav-639
wip/gaps-827
job/isolation-707
job/audiophotos-720
wip/audiophotos-720
job/advfind-664
wip/voicememos-618
wip/taskday-655
wip/isolation-707
wip/advfind-664
wip/scopefix
wip/focus-658
job/testgaps
wip/testgaps
job/overscroll-718
wip/authfix
job/deps
wip/overscroll-718
job/rev2-agentfix
job/rev2-money-ident
job/rev2-mailperf
wip/deps
job/hardening-728
wip/hardening-728
job/searchgen-832
wip/searchgen-832
job/photopw-849
job/mailsql-825
wip/photopw-849
job/sharefix
wip/sharefix
job/rev2-mailhtml-726
job/rev2-perfguards
job/copyval-723
job/lightglass-r2
wip/lightglass-r2
wip/docsfix-web
job/copy-audit
job/macinterop-staging-r2
job/design-sync
job/rev2-taskmeta-659
job/rev2-webperf
job/docs-audit
job/rev2-advfind-664
job/rev2-mailproxy-486
job/states-audit
job/rev2-datafix
job/design-drift
job/test-gaps
job/rev2-voicememos-618
job/rev2-mediafix
job/rev2-deps
job/rev2-datafix2
job/licence-audit
job/issue-hygiene
job/rev2-protofix
job/rev2-voice-619
job/rev2-isolation-707
job/rev2-surfaces-p1
job/deeplink-audit2
job/rev2-audiophotos-720
wip/test-gaps
job/rev2-overscroll-718
job/rev2-undo-722
wip/states-audit
job/rev2-dropmd-719
job/rev2-linknav-639
job/merge-7b-plan
wip/merge-7b-plan
job/rev2-taskday-655
wip/mailsql-825
job/rev2-webdav-lock-476
job/rev2-browserfix
wip/design-drift
job/rev2-hddsql-549
wip/deeplink-audit2
job/rev2-scopefix
job/rev2-authfix
job/rev2-hardening-728
job/rev2-wal-824
job/rev2-sharefix
job/calsidebar-638
job/chrome-audit
job/ioperf
wip/ioperf
wip/chrome-audit
wip/calsidebar-638
job/dropmd-719
wip/dropmd-719
job/ocr-build
wip/ocr-build
job/blaze-settings
wip/copyval-723
job/toastring-721
wip/toastring-721
job/deployfix-732
wip/deployfix-732
wip/blaze-settings
job/money-import-recheck
job/rev-a11y
job/perf-arch-db
job/rev-7b-data
wip/textthumb-652
wip/perf-arch-db
job/sec-protocols
job/sidehdr-660
job/rev-7b-security
job/research-surfaces
job/rev-design-gaps
job/rev-mcp-api
wip/sidehdr-660
job/perf-arch-memory
wip/sec-protocols
job/perf-arch-bundle
job/snapedge-714
wip/rev-mcp-api
job/sec-supplychain
wip/research-surfaces
job/perf-arch-sync
job/rev-consistency
job/perf-arch-server
wip/perf-arch-server
wip/perf-arch-memory
job/perf-arch-io
job/perf-arch-client
job/sec-fs
job/sec-mcp-scopes
job/sec-sharing
job/perf-guards
job/sec-browser
job/sec-admin-deploy
job/sec-auth
wip/snapedge-714
job/bgpicker-717
wip/perf-arch-bundle
wip/money-import-recheck
job/advsetup-654
wip/bgpicker-717
wip/advsetup-654
job/burst-709
job/kbdcaps-710
job/app-pw-chooser
wip/burst-709
wip/app-pw-chooser
job/imaptest-625
wip/kbdcaps-710
job/fix-499
wip/fix-499
job/perf-mut-667
job/calimg-589
job/perf-snap-666
wip/calimg-589
wip/perf-snap-666
wip/perf-mut-667
job/perf-cache-665
wip/perf-cache-665
job/voicefiles-620
wip/voicefiles-620
job/admin-burst-705
wip/admin-burst-705
job/voicememos-review
wip/voicememos-review
wip/ryw-653
job/ryw-653
job/writeonopen-661
job/instant-663
wip/writeonopen-661
job/money-import-review
wip/money-import-review
wip/importjs-610
review/integrations-407-round6
wip/integrations-review
job/dragghost-612
wip/dragghost-612
job/integrations
wip/integrations
job/decider-656
job/merge-round-6
job/perf-rerun
wip/merge-round-6
job/integrations-review-round5
job/selalign-576
wip/selalign-576
job/mcp-events-491
job/files-631
job/cal-e2e-569
wip/cal-e2e-569
job/reload-423
wip/reload-423
wip/mcp-events-491
wip/files-631
job/notesbridge-644
wip/notesbridge-644
job/editor-series
job/calcard-series
wip/calcard-series
job/mcp-events-review-491
wip/mcp-events-review
wip/editor-series
job/quirks-546
job/integrations-recheck
job/tocrail-636
wip/tocrail-636
wip/quirks-546
wip/reminders-643
job/reminders-643
wip/davscale-573
job/davscale-573
job/integrations-review
wip/ocr-eval-584
job/ocr-eval-584
job/esc-537
wip/esc-537
job/toastname-586
wip/toastname-586
job/submenu-579
wip/submenu-579
job/tasks-mode
wip/tasks-mode
job/agentdocs-630
job/dupwrite-634
wip/agentdocs-630
wip/dupwrite-634
job/lightglass-588
wip/lightglass-588
job/tabswitch-549
job/ghosttask-623
wip/ghosttask-623
job/toaststack-616
job/weekstate-609
job/mailsync-613
wip/mailsync-613
wip/weekstate-609
job/maildup-626
wip/tabswitch-549
wip/maildup-626
wip/toaststack-616
job/motion-611
wip/motion-611
job/tlstest-601
wip/tlstest-601
job/perf-495
job/floating-sheet
wip/floating-sheet
job/remdup-585
wip/remdup-585
job/fix-502
wip/fix-502
job/attachplay-622
job/perf-batch
wip/perf-batch-563
wip/perf-495
hotfix/mail-sync-diag
job/mail-m3
wip/mail-m3
job/attach-poof-603
job/calhover-608
job/editorbar-604
job/mentions-605
job/merge-round-4
job/allday-514
wip/merge-round-4
wip/allday-514
job/merge-round-4a
wip/merge-round-4a
job/sharestack-580
job/fix-501
wip/sharestack-580
wip/fix-501
job/perf-batch-563
job/apw-cache-review
wip/apw-cache-review
job/probe-520
wip/probe-520
job/mac-393
wip/mac-393
job/header-571
job/flake-513
wip/flake-513
job/docs-thumb-547
wip/header-571
job/webcal-572
wip/webcal-572
wip/shortcuts-542
job/shortcuts-542
wip/docs-thumb-547
job/caldav-stress
wip/caldav-stress
wip/sweep-478
job/apw-cache-512
wip/apw-cache-512
job/money-empty-540
wip/restart-505
wip/money-empty-540
wip/fix-510
job/restart-505
job/fix-503
job/perf-496
wip/perf-496
job/fix-498
wip/fix-498
job/info-inspector-465
wip/info-inspector-465
job/fix-510
job/fix-507
wip/fix-507
wip/fix-503
job/fix-493
job/money-kinds
wip/money-kinds
job/hygiene-548
job/merge-round-3
wip/fix-493
job/drag-snap-536
wip/merge-round-3
wip/merge-round-0930
wip/drag-snap-536
job/align-538
wip/align-538
job/bg-flash
wip/bg-flash
job/money-import
job/search-count-544
wip/search-count-544
wip/money-import
job/settings-key-541
wip/settings-key-541
job/toast-539
job/preview-421
wip/preview-421
wip/toast-539
job/tasks-500-531
job/title-plain-526
wip/title-plain-526
wip/tasks-500-531
job/notes-bridge
wip/parity-484
job/parity-484
job/files-slow
job/crash-525
wip/notes-bridge
wip/files-slow
wip/crash-525
job/kbd-motion-527
wip/bg-422
job/analytics-504
wip/analytics-504
wip/kbd-motion-527
job/upload-pill-523
wip/upload-pill-523
wip/tray-order
job/tray-order
wip/overflow-mid
wip/merge-round-2
job/perf-494
wip/perf-494
wip/mcp-fast-492
wip/motion-477
wip/asr-ab-489
wip/theme-variants-506
wip/overflow-511
wip/week-header-508
wip/attach-427
job/dav-delete-471
job/iso-435
wip/iso-435
wip/files-sel-keys
wip/dav-delete-471
job/align-253
job/siwc-490
wip/siwc-490
job/money-kinds-review
wip/align-253
wip/money-kinds-review
job/small-bugs-3
wip/overlay-title-487
wip/multiget-500
wip/hidden-420
wip/webcal-ui
wip/webcal-431
job/perf-367
job/location
wip/small-bugs-3
wip/location
wip/perf-367
wip/admin-deny-483
job/tag-unicode-473
wip/tag-unicode-473
job/blur-436
wip/photos-470
wip/blur-436
wip/small-bugs-4
wip/hunt-20260930
wip/settings-hdr-482
wip/chips-416
job/dedup-375
wip/dedup-375
job/doc-stack
wip/doc-stack
job/tokens-literals
wip/tokens-literals
job/jobs-leftovers
wip/send-fast
wip/paste-467
wip/money-numbers
job/money-plugin
wip/money-plugin
job/break-dav
wip/merge-batch
wip/crossday-469
wip/mac-verify
wip/mail-m2
wip/break-dav
wip/money-review2
job/money-md
job/modes-424
wip/money-md
wip/jobs-leftovers
job/agenda-413
wip/agenda-413
wip/modes-424
job/recog-417
wip/recog-417
wip/bounce-425
wip/ab-384-luna
job/webdav-perf
wip/webdav-perf
job/toast-ring
wip/toast-ring
job/money-review
wip/money-review
wip/micro-motion
wip/settings-card
wip/minical
job/notes-imap-428
job/least-priv
wip/ui-small-2
wip/flaky-426
wip/drag-end-418
job/jank
wip/jank
wip/least-priv
wip/docs-site
job/agenda
job/sec-batch
wip/sec-batch
wip/per-user-index
job/area-calendars
wip/area-calendars
job/parity
wip/parity
job/documents-research
wip/documents-research
job/test-infra
job/reminders-sync
wip/small-bugs-2
wip/reminders-sync
wip/gestures
job/google-oauth
wip/tags-merge
wip/tags
job/e2e-theme
wip/e2e-theme
job/icon-align
wip/test-infra
wip/select-align
wip/editor-385
job/voice
wip/webdav
job/webdav
job/app-pw-ui
job/editor-integrity
wip/editor-integrity
wip/voice
wip/quota
wip/cal-followups
wip/icon-align
job/composer-scale
wip/composer-scale
job/jobs-page
wip/jobs-page
job/hig-type
wip/hig-type
wip/app-pw-ui
job/motion-spring
job/mcp
wip/motion-spring
wip/mcp
job/small-bugs
wip/push-hosts
job/profile-sign
wip/touch-369
wip/profile-sign
job/mobile-focus
wip/mobile-focus
wip/ui-polish-354
wip/small-bugs
wip/dup-task
job/toast-polish
job/app-pw-scopes
wip/toast-polish
wip/app-pw-scopes
wip/cli-agent
wip/selection-pills
job/preview-attach
wip/preview-attach
job/dav-proppatch
wip/dav-proppatch
wip/cal-switcher
job/atomic-race
wip/atomic-race
job/photos-shared
wip/photos-shared
wip/cal-grid
wip/note-rewrite
wip/search-rebuild
job/mail-m1
job/paperless-import
wip/paperless-import
wip/mail-m1
wip/hidden-activity
wip/search-d
wip/pricing-research
wip/cursors
wip/auto-scheme
job/single-pills
wip/single-pills
wip/xuser-matrix
wip/money-format
wip/app-pw-setup
wip/purge-dos
wip/vault-health
wip/caldav-apple
wip/xuser-audit
wip/e2e-green
wip/tabbar
wip/adv-harness
wip/maple-mono
job/search-fix
wip/search-fix
wip/search-perf-c
job/adv-harness
wip/sidebar-headers
job/glass
wip/temp-index
job/polish
wip/polish
wip/file-protocols
wip/money-research
wip/glass
wip/voice-models
wip/collab-redo
job/voice-research
wip/hunt-20260928
wip/notes-actions-research
wip/search-pad
wip/search-perf
wip/search-sticky
wip/editor-undo
wip/chrome-rules
wip/motion
wip/appearance-research
wip/appearance
wip/audit-bugs
wip/cal-glass
wip/block-actions
wip/authz-order
wip/event-stripes
wip/chrome-sidebar
wip/auth-flaky
wip/robust-2
wip/gate-fix
wip/menu-blur
wip/import-calternaljs
wip/tray-fix
job/import-calternaljs
wip/index-order
wip/audit-fixes
wip/search-chevrons
research/mail
wip/phone-chrome
wip/dedup-break
wip/csp
wip/ui-audit
wip/select-toast
wip/perf
wip/flat-layout
wip/fonts
wip/event-tint
wip/sync-converge
wip/data-split
wip/glass-audit
wip/robustness
wip/sync-chaos
wip/search-thumbs
wip/fuzz
wip/menu-icons
wip/search-pill
wip/sync-changing
wip/heading-links
wip/date-formats
wip/a11y
wip/break-editor
wip/e2e-fix
wip/settings-sections
wip/sync-root-guard
wip/search-palette
wip/share-edit
job/toasts
wip/toasts
wip/cont-analytics
wip/authz-review
wip/popovers
wip/overlay-glass
wip/change-feed
wip/editor-modes
wip/composer-align
wip/cont-agenda
wip/agenda-merge
job/agent-conventions
wip/agent-conventions
wip/backend-misc
job/route-audit
wip/route-audit
wip/ui-batch
wip/heif-hardening
wip/grid-resize
wip/ask-page
wip/webmcp
job/deeplink-audit
wip/deeplinks
wip/shortcuts
wip/cont-tz-days
main
No results found.
Labels
Clear labels
No items
No labels
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
kayg/calternal#641
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Owner test (2026-10-01), now the main performance test. Put the cursor on the first item of a list and hold Down (or Up) at full keyboard repeat speed. The selection moves through the list at once. At every step, the content pane must show the selected item fully loaded. No skeleton, spinner, blank pane, half-rendered card or "Loading" text may appear while you move fast. When you release the key, the content of the last item is already there.
The owner calls this the "blaze test". It is the measure of whether calternal performance is good.
Where it applies
Approach rules (owner priorities: performance first, never at the cost of finesse)
Measurement (bench/blaze.mjs, shared by every surface)
Input.dispatchKeyEvent, key repeat at 33 ms (common default) and 15 ms (fastest macOS repeat). 200+ steps. Chromium and WebKit, 1440 px and 390 px where the surface exists on phones.[aria-busy=true], no skeleton/spinner class, expected content element present).root@10.69.69.63) with the HDD emulation from #549 (bench/hdd-emu.sh) andflock /root/perf.lock, cold and warm, with heavy data (the large fixtures).Sub-issues own the work per surface. This issue owns the harness and the targets.
Starting #641/#642 on job/blaze-settings at base
687ff70313. I will commit the shared blaze harness first, then implement and measure the Settings path.The shared harness is committed as 134158825e44c1b4c98140efefaf21a33c62c5fb (
bench: blaze harness for surface selection).node --check bench/blaze.mjspassed andbun run buildcompleted against the production web app. The worktree does not containbench/hdd-emu.sh(test -x bench/hdd-emu.shreturned false); I am checking the perf VM for the #549 helper before measuring.The runner and report are committed, but the required perf VM cannot currently be reached from this worktree:
ssh -o BatchMode=yes -o ConnectTimeout=5 root@10.69.69.63 ...returnedNo route to host. The worktree also has nobench/hdd-emu.sh. I will use the allowed local fallback and label its numberslocal; this does not claim HDD-emulated perf VM coverage.Status update for #641: I fetched
origin/job/blaze-settingsand checkedgit log --oneline job/blaze-settings; the branch still ends at687ff703and does not contain the expectedbench: blaze harnesscommit. I am continuing the Mail work and will recheck this ref before the profile run.Starting job/blaze-surfaces from origin/dev at
687ff70313. I am tracing and improving the Files, Photos, Money, and Tab switching blaze paths, using the shared bench/blaze.mjs harness when job/blaze-settings lands it.Baseline finding for #641. The production build is running locally because
bench/hdd-emu.shis absent from this worktree and SSH toroot@10.69.69.63returnsNo route to host. No perf-VM result is claimed.Exact command:
At desktop width, Settings ignores ArrowDown/ArrowUp. Each 200-step direction run therefore left selection at Account; every step was never painted complete. The list is not present in the phone drill-in layout, so those runs were recorded as skipped.
Full frame-level evidence:
artifacts/blaze/settings-before-641.json(local, not committed).Trace finding:
packages/ui/src/components/viewer/QuickLook.sveltemounted only the selected image and did not decode adjacent image sources. Files selection also had no neighbour thumbnail/full-preview warmup. I am adding one bounded decoded-image LRU for those existing paths. The first focused unit-test attempt is currently blocked becausevitestis not installed in this worktree (bun run test -- ../packages/ui/src/imageCache.test.ts: command not found).Progress on
job/blaze-surfaces(base687ff703136e71e89f8dfba139e93cd0788b25c1): committed319e353f158a65c5bc643ce17cb9c9e81e95ce0d(perf: predecode Files and Photos image neighbours). The shared viewer now waits forimg.decode()before declaring a full image ready, and Files and Quick Look warm a direction-aware bounded decoded-image cache.bun run checkcompleted withsvelte-check found 0 errors and 0 warnings; focused cache tests passed (3 tests). Next I am adding the Files/Photos/Money/tab configs to the shared blaze sampler and surface coverage.Finding while testing #641: SvelteKit's shallow
pushStatechanges the address bar but does not update$app/state.page.url. Reproduction in the production build: two ArrowDown presses changed the address to/settings/maintenancewhile every Settings row lostaria-current="page"and the Account content remained selected. I removed that approach and kept Settings' documented same-routegotobehavior so the URL, selected row and section body stay synchronized. The repeat-key e2e is rerunning against the corrected navigation.Progress on #641 — commits
2061200b5and69d192b28are onjob/blaze-surfaces.The shared Quick Look path now shares bounded decoded-image, text-response and PDF-document caches with directional neighbour prefetch. The Files/Photos/Money/Tabs configs use the same frame sampler; it records key-to-paint latency, long tasks, server CPU/RSS and load average, and asserts that every input has a complete matching view. The focused web suite passed: 5 files, 23 tests.
bun run checkreported 0 errors and 0 warnings. I am moving to production-build runs now.Production-build local follow-up after the Settings changes. The perf VM is still unreachable (
No route to host), andbench/hdd-emu.shis absent, so these are host-contended local numbers.Exact command:
Every sampled warm frame is complete and matches the selected section. The local traversal still has 24 input steps with no distinct frame before the next input; this is visible in the attached JSON and remains open for the required perf-VM matrix. The benchmark attributes a paint to the interval before the next key event, so later revisits cannot count for an earlier step.
Perf host access finding: the locked probe
ssh root@10.69.69.63returnedNo route to host, so the requested perf VM run is unavailable from this worker. I will run the profiles locally against the production build and label the measurements as local.git fetch origin && git merge origin/devreturnedAlready up to date.The shared blaze runner failed before recording Mail samples in its WebKit pass.
apps/web/e2e/harness.mjs::authenticatorcallscontext.newCDPSession, which is Chromium-only; the run exited withCDP session is only available in Chromium. I am updating the shared runner to register and sign in with Chromium, close that browser, then transfer the authenticated cookies to the WebKit measurement context. This keeps one browser active at a time and does not change app authentication.Harness finding: Playwright strict mode rejected Files readiness because the virtualized selector matched 27 rendered rows. The shared wait now uses the first matching row, and Files waits for an indexed row before opening Quick Look. The sampler now records per-key main-thread time through the queued UI flush, reports p95/max, and fails at 16 ms or above. Files is configured to traverse all 1,200 fixture rows in both directions; Photos and Money use 520 and 220 steps. This harness slice is committed as
2fe7a29bf; the full Files matrix is running locally.Finished #641 on branch job/blaze-settings. Head:
94a9433216.Built the shared surface-agnostic blaze runner and Settings coverage. The harness is in commit 134158825e44c1b4c98140efefaf21a33c62c5fb, the first commit on this branch. Settings now supports ArrowUp/ArrowDown rail traversal, paints the pending selection immediately, keeps visited sections mounted until the overlay closes, caches safe Settings resources per User, and preloads the Settings route. The warm E2E test asserts every sampled frame has matching, complete content.
Exact production-build measurement commands:
The table shows cold/warm pairs. Each cell is baseline → after. “Never complete” counts section steps with no distinct complete paint before the next input.
These are local results from production assets, not perf-VM results. The baseline load averages were 14.92/16.16/15.93; the after run recorded 26.18/25.23/24.95. Linux cache dropping was not run. SSH to root@10.69.69.63 returned “No route to host”; bench/hdd-emu.sh is absent. Warm runs had zero incomplete frames in both browsers, but fast-repeat inputs still skipped distinct section paints on this busy host. Chromium also recorded local long tasks above 50 ms. The Settings rail is not present at 390 px because the phone layout is a drill-in list; the harness records those runs as not applicable.
Visual screenshots cover Settings, its sidebar, and the account menu at 390, 820, and 1440 px in light and dark themes. They remain in ignored artifacts/settings-key-541/. The fj issue CLI has no attachment option, so they are not attached to this comment.
Final web gates, verbatim output excerpts:
Decisions not specified in DESIGN.md: preserve each visited Settings subtree only for the lifetime of the overlay; keep safe card snapshots in userStorage, but keep raw Admin TOML only in per-User memory until the overlay closes; and enable arrow navigation only for Settings while retaining nav/button semantics. The 2026-10-01 owner override makes keyboard actions use pointer motion timings; reduced-motion preferences still settle motion.
No Rust crate or server API changed, so no Rust gates or API adversarial probe were applicable. cargo clean removed 7237 files (4.6GiB), and apps/web/build was deleted.
Files profile finding: one local matrix case waited 120 seconds for the first indexed row from the disk-backed fixture and timed out, so the profile emitted no result table. The runner now logs the browser/viewport/cadence and retains only API paths/statuses, failed-request paths, visible row count, and server warning lines on readiness failure. Files gets one bounded five-minute scan window. The diagnostic change is committed as
a65d312a5; I am starting one full retry.The local 10k Mail run confirmed a warmup race. The Mail API returned 50 rows and a valid next cursor on both the first and second page. Before the fix, the 15 ms run reached list index 99 while later pages were still pending. The preloader now shares any in-flight page request and waits for 240 rows before sampling; the new run records 250 loaded rows in every pass.
On WebKit, the warm 15 ms pass recorded 0 selected/content mismatches and 0 incomplete frames. It still recorded 277 key steps with no complete painted frame, with p95 frame time 763 ms and host load average 35.88–39.38. The 33 ms pass recorded 17 mismatches. These are local results under heavy shared-host load, not a quiet-host baseline. The perf VM is unreachable from this worktree (
sshreportsNo route to host), so the required HDD-emulated comparison remains unavailable here.Local #641 Columns run completed with the shared harness and a 10,000-message mailbox (250 rows loaded). At load average 27–35, Chromium recorded 102–179 selected/content mismatch frames and 129–217 incomplete frames per 200-key pass; WebKit recorded up to 196 of each. Some frames showed the selected row one message ahead of the reader, and others had no reader frame. This host is too busy for an acceptance latency result, but it exposes a path that needs another pass: sustained input can outpace the current prefetch/reader updates. I am checking that before reporting final measurements. Perf VM access still returns
No route to host.The post-prefetch local Columns run cleared all selected/body mismatches in Chromium (0 across all four passes). WebKit exposed a second issue under repeated Down: in the 33 ms cold pass, the selected row stopped advancing at index 98 while the reader showed index 99; later repeat events continued to target the old focused row. The handler moves focus only after
tick(), which lets a repeat event arrive before the target row receives focus. I am updating the handler to base movement on the latest selected thread and to focus an already-rendered adjacent row synchronously. Local load was 8.9–22 average; this is functional race evidence, not a clean latency run.WebKit finding and fix: the session cookie was present in transferred storage state, but WebKit returned 401 for the Files APIs on the plain HTTP test origin because it does not send the
__Host-Secure cookie there. I added a temporary HTTPS localhost proxy to the shared E2E harness and routed WebKit matrix cases through it; the real local server remains the only writer. A focused WebKit Files check now reports identity 200 and one indexed row. The fix is committed asc9ca3774d.Round 2 traversal work starting on
job/blaze-settingsat94a9433216da2de7b0c57d1a03cfab6f1500df00, based onorigin/dev687ff703136e71e89f8dfba139e93cd0788b25c1. I will measure Settings rail traversal on the production build and post the per-key-step paint table before changing the traversal path.The keyboard focus fix removed the WebKit row-98 stall and allowed the 200-step sweep to reach index 199. The local WebKit profile still recorded frames with no selected row during scrolling, while the reader remained on a different body. The selection path updates the native scroll position, but the virtual list waits for the later scroll event to update its own scroll state. I am syncing the virtual scroll state in the same keyboard step so its rendered window follows the selected ID immediately. These frames were recorded at load average 18–25 and remain local stress evidence.
Production-build Settings traversal baseline, before application changes. Exact run:
The full run samples 400 keydowns per phase (200 Down, then 200 Up). Of those, 40 keydowns changed the selected section; the other 360 repeated at a list boundary and kept the same selected section. The table below reports every selection-changing keydown and whether a complete matching section appeared before the next keydown. Local load was 19.56 before and 27.80 after (1/5/15-minute averages 19.56/14.41/19.15 before).
Per-step warm 15 ms table (the 30
nonerows did not show a distinct complete paint before the next key):Artifact:
artifacts/blaze/settings-round2-before-641.json(local, ignored). The run is host-contended and is used to establish the per-step failure, not as quiet-host latency evidence.Sampler finding: the first Chromium desktop cold pass recorded 1,877 identity mismatch frames. The saved frames show
selectedValue: nullwhile the Quick Look content key is present after the selected Files row leaves the virtualized DOM. The sampler used.fc-item.focusfor selection, so this invalidated identity matching and paint latency. Files now reads selected identity/position from the mounted Quick Look viewer (.ql[data-viewer-key]/.ql[data-viewer-position]) and compares it with the stage identity/position. I will rerun the full matrix with corrected sampling.Blaze test result for #640
Extended the shared
bench/blaze.mjsharness with Mail Columns, Split, and Morph surfaces. It seeds 10,000 test messages, waits for 240 list rows and their bodies, then records 200 Down and 200 Up events at 33 ms and 15 ms. The sampler checks the selected ID, reader body ID, sanitized HTML frame readiness, frame loss, browser heap, server CPU/RSS, and host load.The initial run showed that the old 48-body cache and list-only warmup could not keep the reader warm through the sweep. I expanded the bounded cache, added one four-worker prefetch queue, warmed the first 240 bodies, and fixed repeat focus and virtual-scroll state races. Final Chromium profiles have zero selected/body mismatch and incomplete frames across all three layouts. WebKit still records incomplete frames under the overloaded local host; these results do not verify the every-step requirement.
Before / after
The before Columns profile averaged 337.9 key steps without a complete paint per pass. In the final run, Chromium still had missed intermediate animation-frame samples under load, but every sampled frame had the selected body ready. WebKit’s p95 frame intervals ranged from 289 to 690 ms. The local perf VM connection returned
No route to host, so these profiles did not usebench/hdd-emu.sh; the 50 ms warm target remains unverified. The current profile JSON is inartifacts/blaze/in the worktree.Warm observed paint latency, selected/body mismatch totals and p95 frame interval are summarized in #640. The final profiles all reached 250 rows from the 10,000-message test fixture.
Gate output:
Head:
68bd0b4999e4c21dc613f6d9b995b5d319653012.Frame-paced production-build follow-up for Settings. The opted-in arrow navigation now queues each intended section and applies one selection per rendered frame; focus and aria-current move together. Pointer picks remain immediate. The harness predicts each target from the prior key intent and attributes a complete frame in step order, with the opposite direction as a boundary so a later revisit cannot hide a miss. Each pass sent 200 Down and 200 Up keydowns at the requested cadence. Chromium was pinned to CPUs 0–1. This local host was busy: load average before the run was 18.53 / 16.86 / 16.45 (1/5/15 minutes).
Warm runs now paint all 40 distinct section changes at both cadences, with no mismatches or incomplete frames. The local p95 frame interval and >50 ms tasks remain load-sensitive and exceed the target in this run. Cold first-traversal has incomplete frames because the sections have no per-User cache yet; warm is the #641 merge target. SLOW-only timing is not conclusive on this host.
Per-step complete-paint latency table for the warm runs (ms from the key intent to its complete frame):
Progress (2026-10-02, commit
00bfbd93d): the Photos surface initially showed its real empty state while startup reconciliation was still building the disk fixture projection. The API later exposed all 520 items. I updated the shared harness to poll the real Photos bucket count and reload after it becomes nonzero, so it measures the indexed fixture rather than an early empty response.Focused local Chromium run (200 positions each way, 1440×900, 33 ms; full Photos fixture has 520 items): cold/warm had 8/10 incomplete frames and 39/27 steps never sampled complete. Main-thread key-handler p95 was 0.1 ms in both; longest browser task was 4,745 ms. Peak server RSS was 460.1/460.2 MiB. The local load average at start was 16.53, 14.39, 14.59. The profile failed its paint gate. The perf VM remains unreachable by SSH, so this is local evidence under a heavily loaded shared host, not the requested locked VM measurement.
Starting the WebKit blaze follow-up on
job/maillayoutsat68bd0b4999e4c21dc613f6d9b995b5d319653012, based onorigin/dev687ff703136e71e89f8dfba139e93cd0788b25c1. I will run the shared production-build harness locally for Columns, Split and Morph in Chromium and WebKit, then report the per-engine mismatch/incomplete-frame and timing table.Cold traversal follow-up
The production profile after the first frame-queue change has zero missed/incomplete steps on both warm passes, but the cold pass still advances before section content finishes. At 1440×900 on the local host (load
18.53, 16.86, 16.45before the profile), the 33 ms cold pass had 24 incomplete frames and 16 steps with no complete paint; the 15 ms cold pass had 27 incomplete frames and the same 16 missed steps. The first cold misses wereaccount → appsandapps → maintenance; later misses covered Notifications, Calendars, Mail, AI, Photos, Files, Plugins and Admin sections. The full per-step samples are inartifacts/blaze/settings-round2-frame-paced.jsonin the worktree.I am changing the queue to wait for the caller's selected route content to become complete and paint before it applies the next queued arrow step. The list still updates the selected route immediately; this wait only prevents a later repeat from replacing a section before its real content has painted.
Columns WebKit blaze finding (local shared build host): Chromium reported 0 mismatch and 0 incomplete frames for both cadences. WebKit reported:
The 33 ms WebKit passes also had 19,996–22,308 ms p95 paint latency on the busy local host, so I will report timings with load context. I am tracing whether repeated
srcdocnavigation while the first frame is loading leaves WebKit on a stale body.The WebKit body is not a
srcdocswap on warm selection:fitFramereuses the document, but its live update path writesinnerHTMLand immediately callsgetBoundingClientRect()to fit the iframe. That forces a synchronous layout inside the WebKit key handler. I am changing live updates to let the existing ResizeObserver measure the new root before paint; only a newly loaded document needs the initial synchronous fit. The long-to-short E2E will wait for the observer-driven shrink, and the blaze will be rerun.Tabs profile and screenshot update (#641)
The Tabs selector is now resolved against the real mode TabList. A focused production-build run (local host, Chromium 1440×900, 33 ms, 200 mode-shortcut steps, cold + warm) completed collection but failed the zero-incomplete gate:
Local load average at run start was 24.4, 19.35, 18.94. This is local-only evidence; the perf VM remains unreachable, so it is not a stable baseline. The frames show warm route transitions taking longer than the key interval, so the profile cannot establish a product regression without a quiet host run.
The screenshot-only path had not installed the userStorage test seam before calling setTheme. I fixed the harness and captured Tabs from the production SPA at 390, 820 and 1440 px in light and dark. Files, Photos and Money captures remain in progress. Screenshots stay in ignored artifacts and are not committed.
Round 2 cold-profile finding:
applyKeyboardStep()clears its RAF handle before it awaits the route callback. While that callback is still waiting for the selected Settings pane to complete, each repeated key sees a null handle and schedules another consumer. Those consumers run concurrently, advance routes while earlier panes still showaria-busy/Loading, and cancel the earlier paint waits. The captured 1440×900 Chromium trace at 33 ms showed 218 of 400 steps without a complete frame; the 15 ms pass showed 218 as well. The frame sequence advanced through Apps, Maintenance, Appearance, Editor, Notifications, Calendars, Mail, AI, Photos, Files, Plugins, and Admin while each visible pane was still busy. I am adding an explicit in-flight guard so one callback owns the queue until its complete paint resolves.The isolated frame update path no longer forces a parent layout read after each warm body update, and the long-to-short and image-heavy E2E checks pass with ResizeObserver sizing. That change alone did not clear the WebKit blaze: Columns still reports reader/selection mismatches (150–329 frames per pass before the focus guard; 227–436 after the guard). Chromium reports zero mismatches and zero incomplete frames in both runs. The mismatch traces show WebKit's
[aria-current=true]row disappearing while all 250 rows remain in the list, with the reader stuck on a prior message. I am instrumenting the virtual range, scroll position and active row to identify why WebKit loses the selected row before applying another fix.Finished #641 on
job/blaze-surfacesat head30f644436262f125d7ecbb5c246d85a0eb5fe52c.Built:
img.decode()before replacing the preview. Files also prefetches text and PDF neighbours through bounded caches.All 24 production-build screenshots are attached to this issue: Files, Photos, Money and Tabs at 390, 820 and 1440 px in light and dark.
Performance results are focused local runs only: Chromium, 1440×900, 33 ms cadence, cold and warm. No before baseline exists in
docs/perf/baseline.json. The perf VM atroot@10.69.69.63was unreachable (No route to host), so these numbers are not a quiet-host comparison.The blaze zero-incomplete gate did not pass these local profiles. Load averages at run start were 9.6–24.4 across the runs, and the frame cadence was also delayed by long tasks. This does not replace the requested Chromium/WebKit × desktop/phone × cold/warm matrix on the perf VM. No valid before/after comparison is available.
Web gate output (verbatim):
Decisions not specified in DESIGN: use 8 decoded images, 5 PDF documents, and 8 text entries/8 MiB per viewer cache; retain 12 Money registers and 2 month views; prefetch four previewable viewer neighbours and three Money accounts; cap queued Money navigation at 512 targets. Extend the existing registered Mod+Alt+1–9 bindings for all tray modes.
Known gaps: the full browser/viewport/cadence matrix and a before baseline need a perf-VM run. The focused local profiles still show incomplete frames and long tasks; no claim of a zero-incomplete pass is made. No Rust crate or server route changed, so Rust or adversarial API gates were not applicable.
cargo cleanremoved 7,237 files (4.6 GiB), andapps/web/buildwas removed after captures. Worktree is clean.Correction to the final gate excerpt above: these result lines preserve Vitest's output exactly, including indentation:
Columns now passes WebKit correctness after repeated-selection route updates were deferred until key release. The opt-in
BLAZE_TRACE_VIRTUAL=1trace recorded WebKit's selected index, reader ID, mounted row range, active row, scroll position and pathname. Before the fix, the selected index advanced while the path/body stayed on an earlier thread and the mounted range stopped moving. After the fix, all four WebKit Columns passes report 0 mismatches and 0 incomplete frames (cold/warm at 33 ms and 15 ms). The local diagnostic run was under shared-host load average 20–25 and tracing was enabled, so I will use separate uninstrumented runs for the report's timing table.#641 production traversal — local
Host
calternal-dev, load average21.48, 19.99, 17.97; Chromium, 1440×900, pinned to CPUs 0–1; 200 ArrowDown then 200 ArrowUp events per pass.All 400 key events were accounted for in each pass. The 20 route changes in each direction received their own complete painted frame. At each end of the list, boundary repeats kept the same complete section selected and did not enqueue a new route.
Per-route transition latency (input to its complete frame)
appsmaintenanceappearanceeditornotificationscalendarsmailaiphotosfilespluginsadmin/usersadmin/invitationsadmin/sign-inadmin/configurationadmin/backupsadmin/maintenanceadmin/appsadmin/pluginsadmin/systemadmin/pluginsadmin/appsadmin/maintenanceadmin/backupsadmin/configurationadmin/sign-inadmin/invitationsadmin/userspluginsfilesphotosaimailcalendarsnotificationseditorappearancemaintenanceappsaccountRaw per-key records: settings-round2-final.json
The queue defect was concurrent consumers: a repeated key scheduled another consumer after the RAF handle cleared while the prior route callback still awaited content paint. An explicit in-flight guard now serializes the queue. Fix commit:
b3fbeab57; current branch head:98bcdcdc2.Load caused slow frames in this local run; the non-SLOW correctness checks were clean: no selected/content mismatch and no unpainted route transition.
Round 2 #641 WebKit correction and final profile report
Root cause:
selectRowAtcalled SvelteKitreplaceStateonce per repeated Arrow key. On WebKit, the shallow route and reader update lagged behind the selected row. The optionalBLAZE_TRACE_VIRTUAL=1sampler recorded the selected index, reader ID, active row, mounted range, scroll position and pathname; the pathname/body stayed on an older thread while selection moved. Mail now follows every key repeat immediately and writes the stable thread URL once on key release. The frame bridge also avoids a synchronous layout read after same-document body writes; the existing frame ResizeObserver handles live body and image growth.Correctness compared with the previous
docs/perf/baseline.jsonprofile (commit88cb3c63d):Performance comparison (ranges across cold/warm 33 ms and 15 ms passes):
These are local measurements on the shared host, not a clean performance baseline. The current 1-minute load averages ranged from 13.6 to 33.1;
docs/perf/baseline.jsonalso marks the previous local Mail timing as unverified due to host load. The runner sends 400 Down and 400 Up inputs while loading 250 visible rows, sounpaintedincludes steps beyond a painted selection. WebKit does not report Long Tasks in this runner.Profiles:
artifacts/blaze/mail-columns-round2-final.json,artifacts/blaze/mail-split-round2-final.json, andartifacts/blaze/mail-morph-round2-final.json(local, ignored; not committed). All measured passes used a 10,000-message projection and 240 warmed bodies.Started #641 on
job/blaze-surfacesat30f644436262f125d7ecbb5c246d85a0eb5fe52c; baseline reforigin/devis687ff703136e71e89f8dfba139e93cd0788b25c. The worktree is clean. I have readCLAUDE.md,CONTEXT.md, anddocs/DESIGN.md. I am validating the shared blaze harness and setting up interleaved baseline runs before making code changes.Final head after the documentation audit:
357e2a12c422d8fb948d5c890b338611951856fa.Final verification after that documentation-only commit:
bun run check:svelte-check found 0 errors and 0 warningsgit diff --check: passedcargo clean:Removed 7238 files, 4.6GiB totalapps/web/build,apps/web/.svelte-kit, andtarget/tmpafter verification.The production measurements and attached screenshots in the report above remain unchanged. Known gap: the Settings warm-open target (≤100 ms p95 / about 50 ms main-thread work) is still not met in the local pinned run; the perf VM was offline and the local host load was high. No Rust source changed.
Baseline harness finding: the first
origin/devPhotos run failed before key sampling.waitForSurfaceCompletetimed out after 60 s because the runner queried.ql[data-viewer-key]and.ql-stage[data-content-key], which do not exist in theorigin/devQuickLook markup. That revision exposes the item name in.ql-title h2and.image-view[aria-label]; its image decoder is.image-view img.decoder. No baseline timing was recorded. I am updating the shared sampler to read these real accessible values and decode state in both revisions, then I will rebuild the same baseline SPA and restart A/B/A/B.origin/devbaseline A1 is measured with the same production build mode and 520-photo fixture. The perf VM probe still returnsNo route to host, so this is local. Profile: Chromium, 1440×900, 33 ms, 520 Down + 520 Up per cold/warm pass. The runner wroteartifacts/blaze/ab/photos-A1.jsonand exited non-zero on the expected blaze gate.This confirms the profile is not a 16 ms key-handler bottleneck on
origin/dev; its content readiness and full traversal still fail badly. This is one run only. I am continuing the required interleaved comparison before changing app code.Working on the #641 Settings slice in the #642 Round 3 branch
job/blaze-settings, based onorigin/devat687ff703136e71e89f8dfba139e93cd0788b25c1(current head357e2a12c422d8fb948d5c890b338611951856fa). I am checking whether queued route waits let repeated ArrowDown/ArrowUp inputs outrun the sidebar highlight; I will post the 15 ms frame table with the fix results.Photos A/B round 1 (local, Chromium 1440×900, 33 ms, 520 steps each direction, production SPA, same fixture). Warm results:
origin/devA1 → this branch B1: incomplete frames 1682 → 39; unpainted steps 1029 → 115; p95 paint 93,958.8 ms → 485.8 ms; longest task 801 ms → 15,076 ms. The local 1/5/15-minute load averages were 29.13/22.86/17.95 for A1 and 26.64/28.11/24.05 for B1. Cold B1 also recorded 275,091.7 ms p95 paint and a 7,122 ms task, versus A1's 47,617.4 ms and 4,136 ms. These are single-run shared-host numbers: the complete-frame rate improved on B1, while its long task and cold tail are a possible regression that needs the remaining alternating runs and the requested trace before any app change. JSONs:photos-A1.json,photos-B1.jsonunder ignoredartifacts/blaze/ab/.Photos A2 is complete on the same local Chromium 1440x900 / 33 ms / 520-item fixture. Load average was 21.53–23.86 cold and 24.01–26.70 warm.
There are no identity mismatches. The branch warm paint tail is far lower than both dev samples, but B1 has a 15.076 s warm task versus 0.801–0.835 s on dev. Cold p95 varies greatly between dev repeats, so it is not stable enough yet to classify as a branch regression. These are single-host A/B1/A2 observations; continuing alternating runs and tracing the warm main-thread work before changing app code.
Photos B2 (branch), same local Chromium 1440x900 / 33 ms / 520-item fixture: load average was 24.08 cold and 19.36 warm. Cold: 9 incomplete frames, 174 unpainted steps, p95 paint 232,534.8 ms, longest task 6,808 ms. Warm: 2 incomplete frames, 148 unpainted steps, p95 paint 130,977.1 ms, longest task 6,808 ms. No identity mismatches; max key handler slice was 7.4 ms cold / 2.1 ms warm.
This is still a large warm completeness improvement over dev A1/A2 (1,682/1,904 incomplete frames), but it misses the zero-incomplete/zero-unpainted and <=50 ms target. Warm p95 differs sharply from B1's 485.8 ms, so the tail is not yet repeatable. B1 and B2 both show multi-second long tasks (15,076 ms and 6,808 ms) versus 801–835 ms on A1/A2. Continuing the third pair and then tracing before touching app code.
Photos A/B/A/B/A/B is complete. All six runs use Chromium 1440x900, 33 ms cadence, 520 fixture photos, 520 steps each direction per cold/warm pass, production web bundles and the same local server binary. Measurements are local; the perf VM is unreachable. There were no selected/content identity mismatches.
Across three runs, dev has about 1,766 cold and 1,842 warm incomplete frames on average; the branch has 13 cold and 14 warm. The branch also reduces unpainted steps (warm mean 93 versus 1,021 on dev). Its median warm p95 paint is 485.8 ms versus 93,958.8 ms on dev. The measured regression is the branch's cold longest task in all three runs (6.8–12.9 s; dev 0.6–4.1 s), and two of three branch warm passes also exceed dev's 0.8–2.2 s range. Paint tails vary widely under host load. I will capture the requested warm Photos and Money traces and post attribution before changing application code.
Chrome warm traces captured before application changes, using the production build with external source maps, Chromium 1440x900, 33 ms cadence, and local API-backed fixtures. Trace files:
artifacts/blaze/traces-mapped/photos-warm.{profile,timeline}.jsonandartifacts/blaze/traces-mapped/money-warm.{profile,timeline}.json. Trace timing is attribution-only because profiling adds overhead.Photos: 520 items; 1 ms V8 sampling; 182,537 samples / 296.6 s sampled.
systemTimeZone()—packages/ui/src/time.ts:302formatLongDate()—packages/ui/src/time.ts:232downloadUrl()—apps/web/src/lib/files/api.ts:308timeOptions()—packages/ui/src/time.ts:339captureLabel()—apps/web/src/lib/photos/format.ts:35PhotoTimelinecallscaptureLabelfor tile accessibility labels. The sampled hot path repeatedly createsIntl.DateTimeFormat()to resolve the same system time zone. The timeline also records 110.7 s inclusive ImageDecodeTask time (largest 2.02 s); style 0.52 s; layout 1.09 s; main-thread Paint 1.07 s; RasterTask 17.6 s; and GC 18.5 s. The longest traced RunTask was 2.72 s. This points to timezone lookup as the main attributable JS cost, with image decode work also substantial; style/layout/paint are small by comparison.Money: 220 accounts; 1 ms V8 sampling; 28,806 samples / 28.2 s sampled.
getBoundingClientRectfocusfetchmoveAccount()—apps/web/src/lib/components/SidebarLinks.svelte:91rows()—apps/web/src/lib/components/money/MoneySidebar.svelte:40Money timeline totals: style 297 ms; layout 532 ms; paint/raster 8.79 s; GC 655 ms; longest traced RunTask 314 ms. The blaze Long Task observer recorded 617 ms in this traced pass. The profile does not attribute that task to one large application function; native focus and rectangle work are the largest identified per-event costs, and the route page/layout functions are each under 90 ms sampled self time. The current
moveAccountstill scans the entire sidebar list for each key, anddrainAccountMovesstill processes intermediate routes serially, so I will remove that unbounded per-step work as required. The trace does not establish the queue as the single source of the longest task.Money A1 (origin/dev), local Chromium 1440x900 / 33 ms, 220-account fixture: cold had 368 mismatch and incomplete frames, 440 unpainted steps, no paint latency, and a 174 ms longest task (load average 7.49 / 13.39 / 16.85). Warm had 456 mismatch and incomplete frames, 440 unpainted steps, no paint latency, and a 174 ms longest task (load average 6.20 / 12.81 / 16.60).
The dev build does not move Money account selection with held ArrowDown/ArrowUp, so it never paints the expected account route. The branch comparison will include the new navigation behavior as well as its performance cost; these A1 values are not a same-behavior latency baseline. Continuing the alternating runs.
Money A/B/A/B/A/B is complete. All six runs use local Chromium 1440x900, 33 ms cadence, the real API-backed 220-account/220-transaction fixture, production bundles and the same server binary. Load averages are recorded in each JSON; the perf VM is unreachable.
Dev does not switch Money accounts with held arrows, so all 440 steps are unpainted and its p95 is unavailable. The branch implements navigation with zero identity mismatches and reduces warm incomplete frames from 229–456 to 33–40, but it still misses 130–154 steps and leaves 36 incomplete frames on average. Branch warm p95 paint is 20.8–54.6 s. Its longest tasks were 697 ms, 3,547 ms and 989 ms (median 989 ms), versus 174 ms, 339 ms and 784 ms on dev (median 339 ms). The branch queue/navigation path remains over the <=50 ms target and must be fixed; comparison timing has the expected behavior difference.
The first pinned Chromium repeat run failed before measurement with
TypeError: Cannot read properties of undefined (reading 'indexOf')insummarizePassatbench/blaze.mjs:355.waitForPaintedSteps()returned samples and steps but omitted the sampledidsarray that the summary indexes. I addedidsto both the polling and final snapshots. The run was pinned to CPUs 0-1; host load was 30.99, 26.37, 22.97. I am rerunning once after this harness fix.Files A1/B1 first pair, local Chromium 1440x900 / 33 ms, full 1,200-entry fixture, production bundles. Neither run had selected/content identity mismatches.
The branch improves completeness in this pair, but its cold and warm paint tails and longest task regress. This is a single pair under high local load; continuing A2/B2/A3/B3 before classifying the result or changing app code.
The corrected pinned Chromium probe completed data collection but failed the requested per-frame assertion. At 15 ms cadence on CPUs 0-1 (host load at launch: 32.30, 27.71, 23.71), the warm pass had 2 highlight-lag and 2 content-intent-lag frames out of 218 sampled warm frames. At 4119.3 ms, after key intent 203 expected
admin/maintenance(index 17), both selected and content had fallen back toadmin/backups(index 16); at 4352.6 ms, intent 208 expectedadmin/users(index 12), both had fallen back toplugins(index 11). The pane and highlight stayed in sync (mismatchFrames=0). This is consistent with overlapping SvelteKitgotocalls landing out of order. I am changing the route writer to allow one in-flightgotoand queue only the latest URL target; local highlight and pane selection still update in the key task.The follow-up run after serializing route writes exposed a frame-probe clock flaw. At high load,
installSampler()stored therequestAnimationFramescheduled timestamp, but it read the DOM when the callback ran. A queued key task can run between those points: the frame sample then contains the new selected/content IDs whilekeysPressedexcludes the key because itsperformance.now()time is newer than the old rAF timestamp. Example: in the warm pass the sample at 270.5 ms showedmaintenancewhile only key 1 (apps) was counted; key 2 was recorded at 282.3 ms. The probe reported 11 warm mismatches from that combination. I am changing frame time toperformance.now()inside the callback so the expected intent and DOM snapshot share one clock. This run is not valid proof of a product lag.After the callback-clock correction, the 15 ms Chromium run (CPUs 0-1) reports zero warm-frame highlight/content lag across 447 frames, zero incomplete warm frames, p95 frame time 37.5 ms, and 44.1% Chromium CPU for the warm burst. The full 200 Down + 200 Up warm intent table is in
artifacts/blaze/settings-e2e-641.json. The cold pass still failed: 3,157 of 3,158 sampled frames lagged, with a 1,504 ms longest task; the rail remained at Apps while its document-level input sampler recorded keys. I am adding focus state to the local frame evidence to distinguish a focus handoff from cold pane mounting. The cold result does not alter the warm-pass frame proof.Files A/B/A/B/A/B is complete. All runs use local Chromium 1440x900, 33 ms, full 1,200-entry mixed fixture, production bundles and the same server binary. No run had selected/content identity mismatches. Load average during measured phases ranged from 17.61 to 31.84 across the one- and five-minute readings; all numbers are local because the perf VM is unreachable.
Across the warm runs, branch incomplete frames average 235 versus 424 on dev, and unpainted steps average 916 versus 994. Branch median warm p95 paint is 55.2 ms versus 21.1 ms on dev; median longest task is 1,966 ms versus 1,160 ms. The branch therefore improves completeness while regressing the warm paint tail and task length across these three samples. The p95 and longest-task results vary with host load, so I will use traces and post-fix measurements to isolate the remaining work.
The latest raw frame data explains the cold-only mismatch. On the first cold key, the event target and active element were the Account rail row; subsequent events had no
data-sidebar-idon the target or active element, and sampled frames had no focused rail ID. The warm pass kept focus and still had zero lag. OverlaySurface deliberately sets initial focus in a later frame (focusTrapwithdeferFocus), so the cold probe was sending keys before that focus handoff had settled. I added a two-rAF wait after the surface reports complete, then the probe focuses the first rail row. This aligns the cold input start with the real post-open focus state.Tabs cross-revision A/B/A/B/A/B comparison is complete with the fixed runner. Fixture and profile are unchanged: Chromium 1440x900, 33 ms cadence, 200 key steps, local production build, same server binary and fixtures. Medians across three runs per revision:
The branch paints more held-key steps eventually, but warm incomplete frames are slightly higher, warm p95 paint is about 2.5x the dev median, and both branch task medians exceed 50 ms. Neither revision meets the zero-incomplete, no-task-over-50-ms target. The A/B runner records 200 keydown handler samples per pass with max handler time at or below 9.2 ms; the long tasks occur outside the handler itself. Run artifacts are in the local ignored
artifacts/blaze/ab/tabs-{A1,B1,A2,B2,A3,B3}-fixed.jsonfiles.Money retest after the first Round 2 fix (single local Chromium 1440x900, 33 ms pass; full 220-account fixture):
Compared with the earlier three-run branch median (warm p95 20.8–54.6 s; longest task median 989 ms; incomplete 33–40; unpainted 130–154), the task duration and paint tail improved, but complete-paint counts regressed. Source review found that the first fix cancels stale prefetch transaction reads, while selected route reads still have no AbortSignal. The page increments a request token to suppress stale UI publication, but that does not stop the underlying getTransactions request. I am testing cancellation of superseded active reads while keeping a promoted neighbor request alive.
Money retest after aborting superseded active register requests (single local Chromium 1440x900, 33 ms cadence; fixture creates all 220 accounts and transactions through the API):
This still misses the zero-incomplete / zero-unpainted / ≤50 ms target. Compared with the immediately prior one-run retest, warm p95 and longest task increased (16,915.4 → 18,361.8 ms; 186 → 1,397 ms), while incomplete frames fell slightly (314 → 284). The active-read cancellation did not restore complete paint; I will use the captured warm trace and route data to identify the task source before another change. Results are local because the perf VM is unreachable.
Money follow-up trace (Chromium 1440 px, 33 ms cadence; local fixture). This traced warm pass had 100 incomplete frames, 430 unpainted steps, p95 paint 7,950 ms, and a 222 ms longest task. Key input had 0.1 ms p95 / 6.8 ms max. Of 26,337 CPU samples, 12,708 ms were
(program)and 9,688 ms idle; the largest named browser self-time entries were querySelector (360 ms), focus (132 ms), resolve (111 ms), URL (100 ms), fetch (74 ms), and getBoundingClientRect (61 ms). Timeline totals: style/layout 232 ms, paint 6,028 ms (30 ms max), raster 259 ms, function calls 2,432 ms (46.9 ms max), and max RunTask 205 ms. This capture does not show a long account-navigation handler as the cause of the paint tail. Results still vary substantially across fixture runs; the paint-completion gap needs the next bounded-prefetch measurement.Money lookahead experiment (local Chromium 1440x900, 33 ms, full 220-account fixture): increasing the prefetch window from 3 to 11 produced 266 cold / 281 warm incomplete frames, 423 unpainted steps in both phases, warm p95 paint 24,942.3 ms, and a 3,973 ms longest task. The preceding full 3-neighbor run had 284 warm incomplete frames, 421 unpainted steps, p95 18,361.8 ms, and a 1,397 ms longest task. The wider window starts more real API work but does not improve the number of steps that paint; it increases the measured warm tail. I am restoring the three-neighbor cap and adding a test for that bound.
Photos retest after caching the system time zone (local Chromium 1440x900, 33 ms, 520-image fixture): warm recorded 61 incomplete frames and 350 steps never painted complete; p95 paint was 97,037 ms and the longest task was 3,582 ms. Key handling stayed at 0.1 ms p95 / 7.5 ms max. The local server used about 54% CPU warm and peaked near 473 MiB RSS. This does not meet the warm target. The original trace's
systemTimeZone()hotspot is removed by the cache, so I am capturing another warm trace to identify the remaining decode or rendering work before changing the viewer.Photos warm source-mapped trace after the time-zone cache (Chromium 1440 px, 220 steps; trace overhead applies): 45.7 s of sampled self time was non-idle browser JS. The largest mapped app functions were
formatLongDateinpackages/ui/src/time.ts(7.74 s),timeOptionsthere (5.25 s),downloadUrlinapps/web/src/lib/files/api.ts(5.36 s),formatTimeinpackages/ui/src/time.ts(5.25 s in its own aggregate), andcaptureLabelinapps/web/src/lib/photos/format.ts(0.86 s). The Photos viewer maps all tiles toViewerItemobjects when its selected index changes; each pass formats capture labels and rebuilds download and thumbnail URLs across the full collection. This is O(collection size) per key and accounts for the repeated format/URL work. ImageDecodeTask totaled 19.35 s with a 755.5 ms maximum; Decode Image totaled 15.02 s (185.9 ms max); Decode LazyPixelRef totaled 16.39 s (436.1 ms max); RasterTask totaled 9.21 s (682.6 ms max); Paint 0.95 s (59.8 ms max); Layout 0.40 s (22.1 ms max); UpdateLayoutTree 0.29 s (18.9 ms max); GC sampled self was 1.20 s. I am removing the full-list rebuild per selection and will measure again.Correction to the mapped Photos profile table above:
formatTime()self time was 1.75 s (atpackages/ui/src/time.ts:363);timeOptions()self time was 5.25 s (atpackages/ui/src/time.ts:345).Photos retest after stabilizing the viewer-item collection (local Chromium 1440x900, 33 ms, full 520-photo fixture): warm recorded 260 incomplete frames, 890 unpainted steps, p95 paint 59,822.3 ms, 2,764 ms longest task, and key-handler max 5.7 ms. The preceding full fixture run had 61 incomplete frames / 350 unpainted steps, p95 97,037 ms and 3,582 ms longest task. The current warm server CPU was 67.7% versus 53.7% in the preceding pass, so a single local pair is too noisy to claim the incomplete count improved or regressed. Both runs miss the target. I will confirm the source-mapped JS profile after the collection change.
Photos source-mapped follow-up trace after the collection cache (Chromium 1440 px, 220 steps; local, trace overhead applies):
downloadUrl()self time fell from 5.36 s to 18.6 ms;formatLongDate()from 7.74 s to 14.2 ms;timeOptions()from 5.25 s to 16.3 ms; sampled GC from 1.20 s to 229 ms. The prior O(collection) URL and date work is gone from each selected-item update. The updated warm trace measured 80 incomplete frames, 314 unpainted steps, p95 paint 24,087 ms, and a 301 ms longest task; key-handler max was 11.4 ms.The remaining long task aligns with one full layout of 654 render objects (288.8 ms,
dirtyObjects: 1) immediately before the first recorded keydown. The timeline totals show image decoding on renderer worker threads: ImageDecodeTask 14.07 s total / 725 ms max, Decode Image 11.10 s / 133.5 ms max, Decode LazyPixelRef 11.56 s / 139.6 ms max, RasterTask 4.13 s / 516.7 ms max. Main-thread Paint totaled 400 ms (21.1 ms max), Layout 618 ms (288.8 ms max), and UpdateLayoutTree 202 ms (17.3 ms max). The remaining profile is not per-key JavaScript formatting or URL construction. I am retaining these as local-host limitations to recheck in the requested browser/viewport matrix; the warm target remains unmet.Tabs A/B validity finding: the branch adds registered mode shortcuts 6–9 in
+layout.svelteandTabBar.svelte; the compared dev revision registers only shortcuts 1–5. The runner sent digits 1–9 in both revisions, so dev ignored four of every nine mode requests. The earlier Tabs p95/task comparison therefore does not hold a same-workload baseline. I am adding a runner count option and will repeat the interleaved A/B runs over the five shortcuts supported by both revisions; the branch’s full nine-mode target will remain a separate current-build check.Corrected Tabs baseline (same workload)
The earlier Tabs A/B comparison pressed nine keys on both revisions, but
origin/devonly registers five shortcuts. That comparison was not equivalent. I reran an interleaved A/B/A/B/A/B profile at Chromium 1440×900, 33 ms, 200 steps, withBLAZE_TAB_MODE_COUNT=5on both revisions and the same local server, build mode, and fixture.The branch median does not show a regression in incomplete frames or p95 for this common five-key workload. Unpainted steps and longest-task median are worse on the branch, with substantial run-to-run spread. Both revisions miss the target of zero incomplete frames and no task over 50 ms. These local results do not support attributing the original apparent regression to the branch. The branch’s separate nine-shortcut trace remains useful for current-build attribution; I will report it separately from this baseline comparison.
#641 closeout for
job/blaze-settings, headbf3ad5f29d1108c34e87c0e9d20b1dbe67ffc5c3.The benchmark keeps rail selection synchronous with repeated keys, renders the content for the latest selection per frame, and serializes only route writes. The corrected sampler reads both key intent and DOM state on the same callback clock.
At 15 ms key repeat in Chromium pinned to CPUs 0–1, the warm traversal sampled 398 frames: highlight lag 0, content lag 0, mismatch 0 and incomplete frames 0. The cold traversal still had 21 incomplete frames. The detailed run table:
At this cadence, keys can arrive faster than display frames; the frame assertion stayed aligned to the latest intent on every warm frame. The cold first traversal does not meet the no-incomplete-frame target.
Shared gate output and the Notes suite exception are recorded in the final #642 comment. The production captures for Settings are attached there at phone, tablet and desktop widths in light and dark.
Photos post-fix cross-browser profile
Local production build, real 520-photo fixture, 33 ms cadence, 1,040 key events per cold/warm pass (520 forward and 520 backward). Screenshots were captured from the same build and fixture at 390, 820 and 1440 px in Light and Dark. The full JSON is in
artifacts/blaze/photos-final.jsonin the worktree.Selected and content IDs matched in all warm frames. The failure is image completeness/paint latency, not selection identity. WebKit's zero incomplete frames at phone width does not mean every step completed: 562 of 1,040 steps had no sampled complete frame for their target. Chromium also exceeded the 50 ms long-task goal by a wide margin.
The existing source-mapped Chromium trace after the collection cache showed
downloadUrl()at 18.6 ms,formatLongDate()at 14.2 ms, andtimeOptions()at 16.3 ms total, down from 5.36 s, 7.74 s, and 5.25 s. It also showed 360 file-download requests, repeated per-photo tag lookups, 14.07 s of renderer-thread image decoding, and 4.13 s raster work. I am investigating the repeated selection side work and bounded image-cache churn before changing this path.Photos matrix after Info-request and frame-coalescing changes
Local production build; 520 real photos; Chromium and WebKit; 1440×900 and 390×844; 33 ms and 15 ms; 1,040 key events per cold/warm pass. Selected/content IDs matched in every warm row. The test still misses the selected-image completeness target. Full data:
artifacts/blaze/photos-final-v2.json; screenshots:artifacts/blaze/screenshots/photos/.The frame-coalescing test confirms only the latest queued target is selected once per frame. The current step counter still asks whether each individual key event, including one superseded before the next frame, received a complete paint. I will update the sampler to report those superseded inputs separately and limit paint latency to the same or next frame. The measured warm incomplete frames and long tasks remain real failures; I am continuing the requested Money, Files and Tabs runs before changing the Photos image prefetch window.
The previous matrix identified a measurement defect before interpreting its results: Money compared the displayed register with the stale
aria-currentroute marker instead of the focused account, and the runner counted every intermediate key event as a required paint even when a surface coalesces events within one animation frame. The sampler now records the focused Money account, marks earlier same-frame destinations as superseded, and requires the final destination to become complete within the next sampled frame.bunx vitest run src/lib/navigation/blazeMetrics.test.tspasses (3 tests). I am rerunning the affected profiles with this corrected sampler; the earlier step-level paint counts are superseded.The corrected full Photos matrix reproduces a warm-path failure. Warm Chromium results (1440/390, 33/15 ms) report 202–370 incomplete frames, 239–627 latest destinations missing the 33 ms paint deadline, and 76–1,132 ms longest tasks. Warm WebKit reports 1–22 incomplete frames and 196–445 late destinations; WebKit does not expose Long Tasks API values in this runner. Selection/content mismatch frames are 0. The source-mapped warm trace from the attribution pass identifies image decode/raster as the dominant blocking work (Decode Image max 133.5 ms, Raster max 516.7 ms); I am fixing the hidden image work/prefetch path before another matrix.
The current production build now records 0 incomplete warm frames in all eight Photos browser/viewport/cadence combinations. Warm Chromium key-handler maxima are 0.1–6.8 ms and the runner recorded no warm Long Tasks; warm WebKit Long Tasks are unavailable in its engine. The next-target paint deadline still reports 168–743 late targets, and local headless frame-sample p95 is 98–240 ms while host load averaged 12.8–14.6. This run meets the explicit warm incomplete-frame goal, but the late-target and frame-cadence results need attribution before I report the Photos path as complete.
Fresh warm Photos trace: Chromium 1440 px, 520 items, 33 ms cadence. The profile shows little named app JavaScript per step. Largest named self-time entries were History.replaceState 390.4 ms, V8 garbage collector 151.9 ms, querySelector 79.1 ms, Svelte render.js 33.7 ms, Svelte batch.js 26.5 ms, and Svelte DOM event dispatch 22.1 ms. The app bundle frames without matching source maps were each below 22 ms; the benchmark's own
number()sampler was 13.9 ms total.Timeline totals (max event in parentheses): ImageDecodeTask 5.1 ms (0.13 ms); UpdateLayoutTree 266.4 ms (9.36 ms); Layout 307.9 ms (5.41 ms); Paint 411.6 ms (9.62 ms); RasterTask 1,003.2 ms (6.16 ms). Sampled GC self time was 151.9 ms. The longest traced RunTask was 241 ms on VizCompositorThread, not the page main thread; its thread CPU time was 95 ms. The untraced warm matrix recorded no Long Tasks entries in Chromium and 0 incomplete frames, but p95 requestAnimationFrame sample intervals were 98–240 ms and 168–743 latest targets missed the 33 ms deadline. I am recording this frame-pacing gap as a local browser/compositor limitation because the profile points away from synchronous decode, app JavaScript, style, layout, paint, or raster as the cause.
The corrected Money matrix seeded all 220 accounts and completed its Chromium cases, but a later WebKit case timed out in the runner's 120-second focus/selection/register settle wait. The run failed before writing the summary JSON. I am adding a final-state snapshot of the focused account, route-selected account and displayed register so I can isolate the exact browser/viewport case before interpreting the timing data.
Money held-key follow-up: a targeted WebKit 390×844, 33 ms run completed the 220-account seed and route settle, then recorded 718 warm mismatch frames and 719 incomplete frames across 400 arrow events. The first sampled frame had focus on
blaze-account-001while botharia-currentand the register still showedblaze-account-000; warm key-handler work stayed at 0–1 ms, and WebKit did not expose Long Tasks. This points to route/register paint lag rather than a slow key handler. The current code rebuilds account-link records from the route on each account change, so I am removing that 220-row dependency and keeping current-page state to two attribute updates. Result:artifacts/blaze/money-webkit-phone-diag.json.Money serialization prevented the previous 120 s settle timeout, but did not meet the paint target. WebKit 390×844 at 33 ms finished with a complete final route; the warm pass still had 424 incomplete frames and 417 focus/content mismatches across 400 ArrowDown/ArrowUp events, with p95 frame interval 116 ms and max key-handler work 1 ms. The trace samples show focus one account ahead of the register during most of the pass. I am moving the existing three-register prefetch window to the latest focused target so its data can start loading before route navigation. Result:
artifacts/blaze/money-serialized-webkit-phone.json; host load average was 11.78 / 15.39 / 18.67.Focused-prefetch Money Chromium 1440×900, 33 ms (local; load average 27.50 / 25.02 / 23.63): warm recorded 303 incomplete frames, 302 focus/content mismatches, 301 unpainted destinations, p95 frame interval 133.4 ms, max key-handler work 6.3 ms, and longest Long Task 101 ms. Cold was 267 incomplete / 266 mismatches / 82 ms longest task. The prefetch window improved WebKit phone warm incomplete frames from 424 to 308, but neither profile meets the zero-incomplete or 50 ms task target. Result:
artifacts/blaze/money-focused-prefetch-chromium-desktop.json. I am capturing a post-change warm trace to attribute the 101 ms task before selecting the next fix.Post-change Money profiling update for #641 (local host load was high: 22.8–27.5).
Warm 200-step runs after latest-route coalescing and focused three-register prefetch:
The traced Chromium 1440×900 pass reported 362 incomplete frames (trace overhead), 56 ms longest task. Timeline totals: main-thread RunTask 11.16 s; FunctionCall 3.32 s (max 23.8 ms); UpdateLayoutTree 309.7 ms (max 8 ms); Layout 747.6 ms (max 11.3 ms); Paint 4.38 s (max 21.9 ms); RasterTask 320 ms (max 6.2 ms). Two inspected long tasks were paint/layerization-heavy; one included a keydown dispatch of 15.8 ms and a minified app call of 11.6 ms. CPU sampling showed
focusself-time 593 ms,fetch293 ms,querySelector197 ms, GC 31.6 ms; app frames were minified in the captured trace. The result still misses the zero-incomplete and 50 ms targets. Results:artifacts/blaze/money-focused-prefetch-chromium-desktop.json,artifacts/blaze/money-focused-prefetch-webkit-phone.json, andartifacts/blaze/traces-money-post-prefetch/.Full post-change Money matrix (local host, 33 ms cadence, 200 key steps per direction) finished on both browsers and viewports. All eight cold/warm passes failed the complete-paint assertion. Warm results:
Frame samples show the focused account updates at keydown, but the register content remains on the prior account until the async transaction data arrives. The handler stays under 1 ms in every warm case; the remaining gap is register paint readiness. Full JSON:
artifacts/blaze/money-full-final.json. Host load was shared and high; I am treating these as local diagnostic results, not a clean-host performance claim.Finished the current #641 pass.
Branch:
job/blaze-surfacesHead:
f94fc31442e85cbfd9d605ba2f4c45ab501ba08f(includes the required merge oforigin/dev).Built: coalesced held-key selection work to the latest target per frame; kept Files selection indexes and Money sidebar row state stable; bounded Quick Look image, PDF, and text preview work; deferred full image decode off the navigation path; bounded Money register prefetch and stale-read cancellation; and extended Blaze metrics for superseded destinations, Money timeout state, and trace summaries.
Files:
apps/web/src/lib/files/FilesBrowser.svelte,apps/web/src/lib/files/selection.ts,apps/web/src/lib/photos/PhotoViewer.svelte,apps/web/src/lib/money/{api.ts,store.svelte.ts},apps/web/src/lib/components/{SidebarLinks.svelte,money/MoneySidebar.svelte},apps/web/src/routes/money/[budget]/accounts/[[account]]/+page.svelte,packages/ui/src/{imageCache.ts,navigation/latestFrame.ts},packages/ui/src/components/viewer/{QuickLook.svelte,ImageView.svelte,PdfView.svelte,TextView.svelte,pdfPreviewCache.ts,textPreviewCache.ts},packages/ui/src/components/TabBar.svelte,bench/blaze.{mjs,md}, and related unit tests and harness updates.Performance: the A/B/A/B
origin/devcomparison and the required pre-change Photos and Money trace attribution were posted earlier in this issue. The latest Photos profile had zero warm incomplete frames in all 8 browser/viewport/cadence cases; Chromium reported no warm Long Task entries and WebKit does not expose that API. The final Money matrix did not meet the target. Warm results were Chromium 1440×900: 258 incomplete frames, 256 never-painted destinations, 78 ms longest task; Chromium 390×844: 571, 399, 71 ms; WebKit 1440×900: 126, 126, Long Tasks API unavailable; WebKit 390×844: 340, 331, Long Tasks API unavailable. Warm key handlers were at or below 1 ms. Frames show focused account identity updates immediately, while register content trails until its async data arrives. Raw result:artifacts/blaze/money-full-final.json. The full Files and Tabs matrices were not rerun after the merge; their older local runs remain inartifacts/blaze/and show failures.Production screenshots from the merged build cover all 4 surfaces × 3 widths × 2 themes under
artifacts/blaze/screenshots/{files,money,photos,tabs}/. They remain in the worktree and were not committed.fj v0.6.0exposes no issue-asset upload command, so the screenshots are not attached to this comment.Gates:
The check diagnostics are in
apps/web/e2e/csp.mjs,apps/web/e2e/harness.mjs, andbench/blaze.mjs; the same typing debt was present before the final merge.bun run testpassed.Known gaps: Money still exceeds both the incomplete-frame and 50 ms warm-task targets in Chromium; WebKit Long Task measurements are unavailable. Files and Tabs need a current post-merge matrix. Screenshot attachments remain outstanding.
Decisions not specified by DESIGN: the Money directional prefetch window remains three registers. An earlier wider window increased server work without improving complete paints, but the final local matrix still misses the paint target. The local captures also ran under shared-host load, so clean-host performance remains unverified.
Results
c4a61e8job/blaze-settings,bf3ad5f)job/maillayouts,f9f360e)job/maillayouts,f9f360e)job/maillayouts,f9f360e)No latency, CPU or RSS samples exist, and no regression is inferred. The full browser and cadence matrices with three interleaved A/B runs did not fit in the perf-VM window.
Commands
For Settings:
BLAZE_BROWSERS=chromium,webkit BLAZE_WIDTHS=1440x900,390x844 BLAZE_CADENCES=33,15 BLAZE_STEPS=200 bun bench/blaze.mjs --surface settings --json <output>.For Mail: the same environment and command with
--surface mail-columns,--surface mail-splitand--surface mail-morph, usingbench/blaze.mjsfromjob/maillayouts. Each run would use the saved dev or feature production bundle, an optimized release server,/root/hdd-emu.sh run-limited,TMPDIR=/srv/hdd-emu/tmpandflock -w 14400 /root/perf.lock.Starting round 3 on
job/blaze-surfaces. Branch HEAD isf94fc31442e85cbfd9d605ba2f4c45ab501ba08f;origin/devbase isc4a61e8cf090170f35b1bed3350d9de20c83ecd5.I will compare the branch check output with
origin/dev, run the Files and Tabs production blaze matrix on the locked perf VM, capture the requested macOS-rendered UI evidence, and record Money read-path findings on #687. No push, deploy, or merge.Check-scope finding: the branch’s
svelte-checkreachese2e/csp.mjs,e2e/harness.mjsandbench/blaze.mjsthroughapps/web/src/lib/navigation/blazeMetrics.test.tsimportingbench/blaze.mjs. That import graph adds browser-only JavaScript to the Svelte check.I ran
bun run checkatorigin/dev(c4a61e8cf090170f35b1bed3350d9de20c83ecd5) in a detached worktree with the same installed workspace dependencies. Its output endssvelte-check found 4 errors and 0 warnings in 1 file; all four arenav.mode6–nav.mode9insrc/lib/shortcuts/registry.ts. It reports no diagnostics in the three browser/benchmark files. The current branch reportssvelte-check found 404 errors and 0 warnings in 3 files. I will keep the existing metric assertions and move the pure helpers into typed app source, so this test no longer widens the check graph.Round 3 web test finding:
bun run testcompleted in 800.33 s with 13 failed files, 22 failed tests and 1,059 passed tests (1,081 total). All listed failures were test timeouts (mostly the 5 s default; one 15 s test), and Vitest also reported a worker termination insrc/lib/components/analytics/BklitTooltipMaterial.test.ts. Transform time was 2,380.20 s tracked across workers (59%); the build host load average was 168.47 at completion. The focused changed-metrics test passes: 1 file, 3 tests. No existing expectations were changed. This run does not establish whether the unrelated component timeouts reproduce on a quieter host.Perf finding (branch A1, before the
origin/devcomparison): Files used its 1,200-item fixture; the comparison traversal was 200 steps across Chromium/WebKit, phone/desktop and 33/15 ms. The lock-held load average was2.70 1.31 0.60. The runner wrotefiles-A-A1.jsonbut failed its completeness gate in all 16 phase/cases. Selected warm results: Chromium desktop/33 ms had 80 incomplete frames, 137 latest targets without a complete paint and a 339 ms longest task; Chromium phone/33 ms had 156 incomplete, 326 unpainted and a 653 ms longest task; Chromium phone/15 ms had 159 incomplete and 240 unpainted; WebKit phone/33 ms had 33 incomplete and 160 unpainted (WebKit does not expose this runner's long-task value). ID mismatches were zero. The B1 run onorigin/devis in progress, so these results are not yet labelled regressions.Files A/B table (round 3, run pair 1). Both production bundles used the same current runner, 1,200-item mixed fixture on the #549 HDD emulator, and the same full browser/viewport/cadence matrix; this pair used 200 steps per pass. A = branch
edb8861, B =origin/devc4a61e8. Both runs held/root/perf.lock; load inside A/B locks was2.70 1.31 0.60/4.22 6.73 3.87.Warm values are
incomplete frames / latest destinations without complete paint / p95 paint ms / longest task ms:ID mismatches were zero in every pass. These data show branch regressions in Chromium phone (both cadences), Chromium desktop at 15 ms, and smaller WebKit unpainted counts in several cases; I am tracing the Files code before deciding the smallest fix. Both revisions miss the zero-incomplete target. Full JSON is retained on the worktree/perf VM; screenshots remain separate.
Round 3 report — head
f4ebbac5c731b5ed6f15a934fcb433056c54c6ca(branchjob/blaze-surfaces). No push or deploy.Built:
apps/web/src/lib/navigation/blazeMetrics.ts, sobun run checkno longer imports browser-onlye2e/harness.mjs/e2e/csp.mjs/bench/blaze.mjsthrough the test. Theorigin/devcheck atc4a61e8had 4nav.mode6–nav.mode9errors inpackages/ui/src/components/TabBar.svelte; it did not type-check those three.mjsfiles. Branch check passed with 0 errors and 0 warnings before the final Files change.navigator.platform=MacIntelanduserAgentData.platform=macOS; the runner asserts both values. Files and Tabs captures cover 390, 820 and 1440 px in Light and Dark. They are in the ignored worktree atartifacts/blaze/screenshots/{files,tabs}/; they are not attached to this comment.Files perf evidence: A1/B1 each ran the full browser, width and cadence matrix with the 1,200-item fixture and 200 steps per pass. There was one full-matrix pair, not three repeated full matrices. A1/B1 warm values below are
incomplete / unpainted / p95 paint ms / longest task ms; zero ID mismatches in all cases:A2/B2 repeated Chromium phone/33 ms after the Files change. A2/B2 warm was
129 / 338 / 32.2 / 102versus119 / 301 / 31.2 / 120. The change lowered the longest task but did not close the completeness regression; unpainted targets were higher. No third interleaved pair was completed. Both versions still miss the zero-incomplete target.Tabs: A1 ran the matrix using five common modes. B1 skipped all 16 cases because
origin/devhas no visible mode tray (surface list is not present at this width). The benchmark docs define that older revision as not applicable, so this is not a valid A/B baseline. A1 warm Chromium had 68/135 incomplete/unpainted at desktop 33 ms, 39/79 at desktop 15 ms, 175/102 at phone 33 ms and 170/139 at phone 15 ms. No repeated Tabs rounds were completed.Gates and evidence:
bun run checkbefore the final Files reduction:svelte-check found 0 errors and 0 warnings. The post-merge final check was started but did not finish before the 2.5 h round limit.bun run test:Test Files 13 failed | 149 passed (162);Tests 22 failed | 1059 passed (1081); duration800.33s. Failures were timeouts across unrelated files. Vitest reported 2,380.20 s of tracked transform time and a terminated worker. Host load average at completion was 168.47. Focused changed-metrics test passed: 1 file, 3 tests.bun run buildpassed after the Files change:✓ built in 8m 33s;Wrote site to "build".node --check bench/blaze.mjspassed before the screenshot run. The macOS screenshot assertions passed.Known gaps: fewer than three interleaved measurements; Files still misses the complete-paint target and the A2/B2 comparison is mixed; Tabs has no
origin/devbaseline; screenshot PNGs remain local and are not attached; the post-merge check,cargo clean, and removal of web build output did not complete within this round. No existing test expectation was changed.Decisions where DESIGN was silent: use a 200-step traversal for the repeated A/B workload while retaining the full 1,200-item Files fixture, to fit the round limit; treat Tabs on
origin/devas not applicable when its mode tray is absent, matchingbench/blaze.md.Starting the requested perf VM rerun for #641. Branch: job/blaze-surfaces. Head/base checkout:
f4ebbac5c. Earlier build-host timings are invalid and will not be used. Compare production origin/dev and branch bundles with one fixed harness/server, three alternating A/B pairs for Settings, Mail, Notes and Files, cold and warm, under /root/perf.lock with HDD emulation. No deployment or push.Fresh verification after merging origin/dev
c4faf184dinto this branch:Coverage finding: bench/blaze.mjs on this branch defines Settings, Files, Photos, Money and Tabs. It has no Mail or Notes adapter. MailView.svelte has no held-arrow message selection handler; NotesExplorer.svelte ArrowDown/Up moves focus without opening a Note. The available Settings and Files A/B matrices are being run on root@10.69.69.63, using three alternating origin/dev (A) / branch (B) pairs with a fixed release server and sampler, under the perf lock and HDD scope. The earlier build-host timings remain invalid.
Measurement validity finding: Settings A1 and B1 each sent 400 key events per phase. Every non-skipped phase sampled only one selected identity, Account. FloatingSidebar.svelte explicitly has no arrow-key handling. Thus these runs prove a missing interaction; their latency cannot be called Settings navigation performance. Mail has no held-arrow message selection and NotesExplorer arrows only move tree focus. Those surfaces cannot supply a valid held-arrow comparison from these two production revisions.
Files probe finding: the old sampler rejected an already decoded visible preview while a hidden full-image decoder existed. Its PDF check also accepted an allocated canvas before rendering (including an explicit false readiness flag). I replaced those checks with one shared visible-element probe: decoded visible image, actual text with no loading status, or non-white raster pixels in the fixed PDF fixture text region. Focused regression verification: 2 test files, 7 tests passed. Both Files revisions will use this same corrected sampler. Canvas readback is benchmark instrumentation only.
Measurement validity finding: holdKey awaited each Input.dispatchKeyEvent/page.keyboard.down acknowledgement, then slept 33 or 15 ms. A main-thread stall therefore reduced the delivered input rate and weakened the Blaze workload. The pre-fix Files comparisons are invalid for the requested fixed cadence; no branch performance verdict is drawn from them.
I extracted the repeat dispatcher into the typed metrics module. A regression test with 300 ms browser acknowledgements failed against the old implementation: only the initial key was sent by 100 ms, where the independently specified deadlines require keys at 0, 33, 66 and 99 ms. The fixed dispatcher sends on absolute deadlines, observes all promises immediately, drains them before key-up, and stops on transport failure. The sampler uses native event timestamps for queue delay and measures handler work separately. Focused verification passed: 3 files, 9 tests. A single corrected round has started on the locked perf VM, with fresh result names and three alternating A/B pairs for the available Settings and Files profiles. No app cache changes have been made from the invalid timing comparison.
Corrected perf-VM round continues at head
8075f518e(samplercadb776e2). Settings A1/B1/A2/B2/A3/B3 completed: all 48 desktop cold/warm phases remain on Account after 400 keys. This does not measure navigation. Files A1/B1/A2 are complete; remaining B2/A3/B3 use the same production bundles and fixed-deadline sampler under /root/perf.lock.A focused branch Chromium desktop/33 ms trace captured a 427.6 ms main-thread task around layer work and a 319.2 ms task containing a 287.7 ms compositor commit. It does not attribute the regression to PDF prefetch. Trace timings are excluded from the A/B table. An isolated production comparison bundle removes only commit 4e58f2779's Quick Look frame queue; a locked VM run will test whether that delay explains the lower complete-paint count. No application change has been made from this hypothesis.
Full web verification already passed after the measurement fixes: svelte-check found 0 errors and 0 warnings; Test Files 164 passed (164), Tests 1087 passed (1087). The final report will quote the actual gate summaries and include all completed pairs.
Head
63529a7edfixes a second measurement bias. The Chromium trace has sampler callback 211 at 60491936136 microseconds, followed by Quick Look update callback 212 at 60491936785 in the same animation frame. The old sampler records the previous item before queued navigation updates, even though the update runs before paint. It adds a false frame of latency to the queued revision.A focused regression test reproduced the old order: observed [1], expected [2]. The fixed sampler moves its pending frame callback behind input-handler frame work on both revisions. Focused verification: Test Files 3 passed (3), Tests 10 passed (10). bun run check: svelte-check found 0 errors and 0 warnings. The requested full web test suite is running.
All earlier paint counters, including the queue and image-prewarming attribution probes, are excluded from the verdict. No application revert is justified by them. The final production A1/B1/A2/B2/A3/B3 round is running under /root/perf.lock in /root/blaze-641-20261002/results-ordered, using sampler
63529a7edand the unchanged A/B bundles and optimized release server. Source files are frozen for this round.The final review reproduced native listener ordering: Chromium drains microtasks between capture and target listeners. The capture-based fix in
63529a7edstill sampled before queued UI work. Its Files timing counts, including results-ordered, are excluded. Settings identity coverage remains valid (19,200 desktop keys, Account unchanged).Fixed native sampling at window bubble, stopped-pass listener/frame cleanup, and rejection of pre-dispatch samples. Native browser regressions pass in Chromium and WebKit. The pure stopped-work regression passed (6 readiness tests); frame-index and cadence regressions passed (6 tests). A focused two-worker run timed out starting one worker on the build host, so readiness was rerun with one worker. The requested full test and check commands are running.
A1/B1/A2/B2/A3/B3 Files round now runs under the perf VM lock in results-final with frozen corrected source and the same production bundles and server. Starting inside-lock load: 0.02 0.29 2.64. No application revert can be justified from the discarded counts.
Head
63e745a55. The native-order/lifecycle sampler fix isff104ac0a. Later changes document invariants and add BLAZE_FIRST_PAIR=2/3 so a completed pair can be retained on resume.Final
bun run check: exit 0,svelte-check found 0 errors and 0 warnings.Requested
bun run test --maxWorkers=2: exit 1. Verbatim summary:All three failed source-scan tests report
Error: Test timed out in 5000ms.Ten workers reportTimeout waiting for worker to respond. No failed assertion is reported. The unchanged shortcut-registry source test passes alone. No expectations or timeout limits were changed. All 12 focused measurement tests and the native Chromium/WebKit ordering/lifecycle regressions passed. Repeat the full suite in the merge round; this is not a full-suite pass.The first corrected matched Files pair is mixed: A completes 41/1204 eligible targets, B 118/1093. Chromium 15 ms cases regress in frame intervals. A focused queue-removal bundle is worse (phone/15 ms p95 intervals 749.9 ms cold, 900 ms warm); it does not support reverting
4e58f2779. An image-prefetch-disabled probe is queued. B2 incurred an HDD startup delay with idle CPU and one active measurement scope. Keep startup separate from measured input phases. The final table and remaining work follow at the job time limit.Final report (partial). Stopped at the four-hour job limit. The requested three-pair comparison and regression fix are not complete.
Head:
c97afaec36. Branch: job/blaze-surfaces. No push, deployment or owner merge. The authorized origin/dev merge wasffaad902f, with A pinned toc4faf184df. B's production bundle isffaad902f; later commits change the measurement code and documentation only.Built: fixed-deadline repeats and visible-content readiness, a serialized perf-VM comparison driver, native input ordering/lifecycle regressions, stopped-pass cleanup, a pre-dispatch sample guard, and a pair-resume option. The frozen sampler producer is
ff104ac0a. An independent read-only code review found no remaining definite sampler defect. No product interaction was added or changed this round.Files: bench/blaze.mjs, bench/blaze-ab.sh, bench/blaze-native.test.mjs, bench/blaze.md; apps/web/src/lib/navigation/blazeMetrics.ts, blazeMetrics.test.ts, blazeReadiness.test.ts, blazeCadence.test.ts; docs/perf/2026-10-02-blaze-surfaces-641.md. docs/DESIGN.md changed only through the authorized origin/dev merge.
Coverage: Settings has six identity runs (19,200 desktop keys), but Account remains selected in every phase; arrow navigation is absent in both revisions, so no navigation latency is available. Phone Settings is a drill-in list. Mail lacks held-arrow message selection and a profile. Notes arrows move tree focus without opening the focused Note and have no valid profile. Those interactions were not fabricated.
Two complete Files A/B pairs were measured on root@10.69.69.63 with /root/perf.lock held for every run. Same pinned optimized server, production bundles, sampler and HDD settings: direct I/O, 8 ms read/write delay, 200 IOPS; full 1,200-file fixture, 200 keys each direction. Cold uses a restarted server/context and dropped Linux page caches; warm reuses them. Server SHA-256: 5eb0ba4775542f517948c2b396ba436df44cd9e0a0cb2ad7fd41c3b7e10e9a9d. All earlier Files counters (results, results-fixed, results-ordered) are excluded due to driver or sampler defects. No build-host timing enters this table. Only this job's measurement scope was active during the spot check. Per-run load readings are retained in the raw logs.
Provisional table (two pairs, not three):
Matched production runs: files-A1, files-A2, files-B1, files-B2
Complete means selected content ready within 33.33 ms of native event creation. Superseded same-frame targets are excluded from eligible. Frame intervals measure DOM sampling, not GPU presentation. WebKit does not expose Long Tasks.
A: complete/eligible=99/2529, keys=12800
serverCpuPercent: median=26.85, max=83.5
serverRssAverageKiB: median=354368.0, max=455000
serverRssPeakKiB: median=392106.0, max=523292
jsHeapPeakBytes: median=17150000.0, max=23100000
B: complete/eligible=224/2193, keys=12800
serverCpuPercent: median=25.200000000000003, max=44.3
serverRssAverageKiB: median=232431.0, max=458020
serverRssPeakKiB: median=346010.0, max=458020
jsHeapPeakBytes: median=15200000.0, max=21700000
Verdict: mixed and incomplete. B completes 224/2193 eligible targets (10.2%), A 99/2529 (3.9%). The 33 ms cases generally improve. Chromium phone/15 ms regresses in both pairs: cold median p95 frame interval 99.9 → 200.0 ms; warm 158.3 → 216.7 ms. Cold complete targets fall 12 → 3, warm 22 → 6. Neither revision meets the zero-incomplete-target target.
Attribution probes used the same frozen final sampler and lock. C removes only Quick Look's frame queue (
4e58f2779): phone/15 ms cold 2/33 complete, p95 749.9 ms; warm 5/21, 900 ms. D disables image prefetch while retaining that queue: cold 0/63, 183.3 ms; warm 3/67, 166.7 ms. C worsens frame intervals. D improves some intervals but does not restore the reference completion rate. These isolated probes do not establish one offending commit, so no unsupported application revert was made. Attribution and repair of the fast-repeat regression remain unfinished.Final gates, verbatim excerpts:
bun run test --maxWorkers=2exited 1:All three source-scan failures report
Error: Test timed out in 5000ms.All ten worker errors report[vitest-pool-runner]: Timeout waiting for worker to respond. No assertion failure is reported. The unchanged shortcut-registry source test passes alone. Existing expectations and timeout limits were not changed. Full log: artifacts/blaze/perf-vm-20261002/test-final.log.Focused metrics and cadence: two files, six tests passed. The initial focused attempt lost a readiness worker at startup; readiness then passed alone with one worker (one file, six tests). Native regression, exit 0:
cargo fmt --check: exit 0, no output. No Rust crate changed, so no Rust Clippy/test run.cargo clean: exit 0,Removed 1 file, 356B total. Local web build output, baseline tree and copied archives were deleted; ignored artifacts remain. The unfinished A3 run was stopped and excluded. The perf lock was released and the resume wrapper is staged on the VM.Known gaps: pair 3; valid Settings/Mail/Notes timing surfaces; fast-repeat regression attribution/fix; full suite completion without host timeouts. No new screenshots: no screen changed this round. Long Tasks are unavailable in WebKit; these are DOM-readiness/frame samples, not GPU presentation measurements. Browser RSS was not measured; server RSS and Chromium JS heap are reported.
Decisions: pin one existing optimized server for both web bundles; use one shared visible-content probe; use the issue's minimum 200 keys per direction while retaining the full fixture. Keep missing navigation as a coverage gap. Do not revert application behavior from an ambiguous isolated probe. No new product design decision.
UX gaps closed: none in product code; measurement false-frame, stopped-pass and pre-dispatch defects fixed. UX gaps left: Settings arrows, Mail held-arrow selection, Notes opening the focused Note, Files fast-repeat behavior.
For the merge round / remaining work: on the perf VM, use the recorded environment in /root/blaze-641-20261002 and run
BLAZE_FIRST_PAIR=3 bash bench/blaze-ab.sh bundles results-final fileswith the staged resume wrapper. It holds the perf lock per run and keeps pairs 1/2. The sampler and bundles remain frozen. Complete the third pair, then attribute/fix the Chromium regression and obtain a three-pair verdict. Runcd apps/web && bun run test --maxWorkers=2once on the combined branch to obtain a complete suite result; runcd apps/web && CALTERNAL_E2E_ASSET_OVERRIDE=1 bun run test:e2e:filesto verify real preview identities and controls. Full Rust, adversarial, release, deployment and Mac checks remain with the merge round.Report and raw evidence: docs/perf/2026-10-02-blaze-surfaces-641.md; artifacts/blaze/perf-vm-20261002/final/; provenance.json and stopped-round.log; VM /root/blaze-641-20261002/results-final/ and diagnostics-final/. Partial A3 has no JSON and does not enter the matched table. Issue remains open.