BETTER SETTINGS: organise Settings so it feels non-overwhelming and close to the User (grill pending); includes Connected Accounts #407
Open
opened 2026-09-29 06:47:26 +00:00 by kayg
·
124 comments
No Branch/Tag specified
dev
wip/rev2-money-ident
wip/restyle-notes
wip/previewcard-1098
wip/palette2-1123
wip/palette-1093
wip/onboard2-1141
wip/onboard-1141.aborted-early
wip/onboard-1141
wip/nlpchip-1127
wip/morph-1104
wip/merge-round-7c5
wip/merge-round-7c4
job/notifloop-1194
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
job/onboard-1141
wip/sidebar3-1094
wip/rev2-webperf
job/collabloss-1197
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/tagperf-1186
wip/segmented-1200
job/restyle-files
job/tagdnd-1187
job/merge30
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
job/adv-1202
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#407
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?
Request (owner, 2026-09-29)
"instead of having two sign in forms in Mail and Calendar, this stuff should live in Settings → Integrations and we should have checkboxes after the fact for mail/calendar/contacts"
Grill (open; do not build until answered and recorded in DESIGN.md)
Decided (owner, 2026-09-29), recorded in DESIGN §49: I1 yes (Apple's Internet Accounts model); I2 yes; I3 yes; I4 Google OAuth if possible without a licence — research in #408; I5 hide Contacts until it exists; I6 no migration, users add accounts again.
Starting #407 on branch
job/integrations, based onc46515046871936ad681c4d00e8b76de69dde3b7(devat worktree start). I am reading the recorded decisions and tracing the existing mail and CalDAV account stores before changing account/settings code.Finding: Mail M1 currently stores its app-password envelope in
mail_accounts; Calendar stores a separate credential envelope incalendar_accounts. Mail sync reads credentials frommail_accounts, and Calendar refresh reads them fromcalendar_accounts. This means a single Integrations sign-in needs one shared credential record plus service rows that reference it; duplicating the secret would preserve the current split model rather than satisfy §49.Progress: the shared Index account and credential layer is committed as
892cab35(feat(db): store one shared integration credential). It stores one encrypted envelope per provider account, binds it to the User and stable account ID, and records Mail/Calendar support and enablement separately.Focused gate output:
Finding: the existing Mail and Calendar account PATCH/DELETE routes can change one service projection without changing the shared Integration row. I am making those routes reject changes for linked accounts and routing service toggles through the central Integration API. I am also persisting CardDAV discovery for future Contacts support while keeping the Contacts control hidden per I5.
Decision not specified in DESIGN: an account deep link uses
/settings/integrations/accounts?account=<stable-account-id>. Copy link returns to that exact account row. I will keep this route in the final report for owner confirmation.Finding: Mail IMAP already pinned its socket to a public DNS answer, but the new CalDAV and autoconfiguration HTTP requests only validated DNS before reqwest resolved the host again. That left a DNS-rebinding path to private addresses. The setup probes now share the public-endpoint resolver and pin reqwest to its validated addresses; integrated Calendar clients repeat that resolution and pinning on each operation. These pinned requests also bypass environment proxies so the proxy cannot perform a second, unchecked resolution.
Finding: the first implementation rejected the state where both service checkboxes were off. The issue says each checkbox controls that service's sync independently, so I removed the last-service restriction. The shared account and credential stay saved, while both sync projections can be disabled and re-enabled later.
Follow-up decision: the account schema already has a CHECK constraint that requires Mail or Calendar to remain enabled, and the existing database test asserts that invariant. I restored the UI/API guard and kept that existing behavior. Each service can be switched off while the other remains on; Disconnect removes the account. The issue does not state whether both may be off, so I retained the schema invariant for owner confirmation.
Finding: the existing Mail table rejects a duplicate owner/email/IMAP endpoint, and Calendar rejects a duplicate owner/endpoint. Because #407 does not migrate legacy accounts, trying to add one of those accounts through Integrations could hit a service projection unique index after the central row was inserted and return HTTP 500. The transaction rolls back; Mail and Calendar projection unique violations now return HTTP 409 with a fixed message.
Finding: Mail's existing row menu still showed Turn off for Integration-backed Mail accounts. That action called the legacy Mail endpoint, which correctly returns 409 because the shared account must be changed in Integrations. Linked rows now show Manage in Integrations and hide the legacy service toggle and Disconnect actions. A UI test covers this menu.
Implementation report
Built and pushed
job/integrationsat head90071e870a179203ec97326ee3f2e9a9ae00a626.Delivered
.well-knownCalDAV/CardDAV endpoints. Mail and Calendar settings now link to the shared account.Focused gate output
Decisions and known gaps
/settings/integrations/accounts?account=<stable account id>.imap.<domain>/smtp.<domain>fallback and.well-knownDAV discovery.git merge dev,cargo fmt --check,cargo clippy --all-targets -- -D warnings, fullcargo test,bun run --cwd apps/web check, and fullbun run --cwd apps/web testremain outstanding. The focused tests above and one endpoint-specific adversarial round passed.Screenshot attachments
Integrations
Mail
Calendar
Starting #407 on branch job/integrations. Current head:
90071e870a. Current merge-base with dev:c465150468(dev is70fce97594). Continuing after visual review rejection with the Apple-style provider chooser, provider-specific sheet, service switches, and connected account status requested in the job.Finding:
IntegrationsSection.sveltestill renders a segmented provider control and shows username/server fields in the default flow. Its empty state contains#297, “source of truth,” and “encrypted app password,” which are internal terms the requested screen must not show.IntegrationAccountViewexposes enablement but no sync state; the existing Mail sync endpoint exposeslast_errorandbackfill_complete, and Calendar account rows exposelast_error. I will compose status from those real account APIs and use their existing retry operations.Decision for #407: add Yahoo as a supported provider preset because it is explicitly requested and Yahoo documents an app password plus IMAP/SMTP and CalDAV access (https://help.yahoo.com/kb/SLN4075.html, https://help.yahoo.com/kb/SLN4707.html). The current API contract has no Outlook preset, so I will omit Outlook. Provider marks will use neutral calternal glyphs with provider names; I will not copy brand artwork without a verified usage guideline.
Finding: the existing
integration_accounts.providerCHECK rejects Yahoo with SQLite code 275 (CHECK constraint failed: provider IN (\x27icloud\x27, \x27fastmail\x27, \x27gmail\x27, \x27other\x27)). I added a migration regression test that inserts an existing Fastmail account before the provider migration, then checks that the account remains after Yahoo is enabled.Progress: committed the Yahoo provider storage migration as
2b24ed67. The migration widens the provider CHECK while preserving existing credentials and service selections. Evidence:cargo test -p calternal-dbpassed (15 unit tests; 16 passed, 1 ignored in integration tests), andcargo clippy -p calternal-db --all-targets -- -D warningspassed. The server API and Settings flow are in progress.Progress: the Settings flow now has provider rows, provider-specific setup sheets, initial Mail/Calendars switches, stable provider/account links, and connected-account status with retry. The focused UI suite passes: 5 tests passed. Connected status comes from the existing Mail and Calendar APIs; the error-row test uses test fixtures only. Rust API gates and production screenshot proof remain in progress.
Progress update: the Yahoo provider migration commit is
036a8bbf(the earlier progress note named its pre-amend hash). The chooser, provider-specific setup sheets, service switches, connected-account status rows, and focused UI tests are now implemented. Current focused UI result: 1 file passed, 5 tests passed. The local review harness covers the requested 48 screenshots. Remaining: finish server clippy/tests, mergedevonce, run final gates and the production screenshot matrix, then attach the evidence here.Finding: the first
cargo clippy -p calternal-server --all-targets -- -D warningsrun stopped incrates/calternal-plugin/src/outbound.rs:57and:63withclippy::needless_return.git blameshows both lines were added in this integrations branch's outbound DNS helper (87fc9aec). Removing the two unnecessaryreturnkeywords preserves the validated-address behavior and lets the server gate reach this route.Resolved finding: the two unnecessary returns in the outbound DNS helper were removed without changing its address validation. Per-crate gates passed for the helper crate:
The fix is committed as
c28e6f44. I will repeat the required gates on the single mergeddevtree before the final report.Finding: the first server all-targets check reached the API source and caught an incomplete Yahoo mapping in
mail_settingsatcrates/calternal-server/src/integrations.rs:399:Provider::Yahoowas missing from theMailProvidermatch (E0004). The fix maps the Yahoo preset to the existingMailProvider::Customprojection and adds an assertion to the Yahoo preset unit test. The same attempt also showed the server binary embedsapps/web/build; I will build the production SPA before repeating this gate.Finding after the required
devmerge: the production SPA build failed withCould not resolve '../parts/AccountRow.svelte'inIntegrationsSection.svelte:13. The merge brings the sharedSettingsRowfrom #402 and removesAccountRow; I am moving the connected account row toSettingsRow, which supports the stable anchor, selection, status, actions, and full-width service controls used here.The post-merge
cargo clippy -p calternal-server --all-targets -- -D warningsgate found twocollapsible_iferrors: the Mail re-enable sync queue condition inintegrations.rs:986and the nested integration-key guard insystem_plugin.rs:70. Both were folded into let-chain conditions without changing behavior. I am rerunning the server gates now.The production screenshot run captured the chooser at 390 px in light mode, then stopped at iCloud because the provider-heading locator used a non-exact name and matched both the sheet title and the page heading. I am tightening that locator to the exact provider label before recapturing the full 48-image matrix.
The exact-label locator passed iCloud, Google, Fastmail, and Yahoo, then found two identical “Other account” headings. The sheet title and form heading share that label, so the exact match is still ambiguous for Other. I am scoping the wait to the provider form heading id and will rerun the matrix.
The review harness captured all eight 390 px light states. On the first dark state it detected that the app correctly maps the paper family to its midnight palette, while the harness expected the light palette name. I am updating the fixture to expect
midnightin dark mode, then will capture the full matrix again.The first connected-list screenshots showed the shared row icon centered on its title-and-meta stack, several pixels below the email cap line. I added a
SettingsRowtitle-alignment option using CSSlhandcapunits and enabled it on the connected Mail, Calendar, and Integration account rows. I am rebuilding and recapturing before attaching evidence.Integrations #407 complete
Branch:
job/integrationsHead:
16d6b06c7b9372945becc00c40370c336f2c10e3Working tree: clean. The single required
devmerge is included. No push, deployment, or merge was performed.Built
/settings/integrations/accounts?account=<id>.Files
Gates
Output excerpts are verbatim.
cargo fmt --all --checkexited 0 with empty stdout.The API-client check exited 0 with no generated diff. Screenshots are untracked and not committed; all 48 PNGs are attached to this issue. Web build output was deleted after capture. Cargo search confirmed the manifest/lock versions used for
chacha20poly13050.11.0,getrandom0.4.3,quick-xml0.42.0,url2.5.8, andtokio1.53.1.Decisions
Customprovider value because the Mail provider enum has no Yahoo variant; the shared account retains Yahoo identity.Known gaps
"use client"directives; the build exited 0.Starting round 3 of #407.
job/integrations9bf3d549b41f5fe97c29148220a1a9c484faf63d(current merge-base withorigin/dev)16d6b06c7b9372945becc00c40370c336f2c10e3I am applying the resolved §49 provider-capability defaults and finishing the chooser, provider sheet, and connected-account row fixes. I will fetch and merge
origin/devonce before final gates, then report the gate output and capture set here.Round 3 finding: the attached chooser capture shows the same globe on iCloud, Google, Fastmail, Yahoo, and Other, with a separate Copy link control on every provider row. The iCloud capture shows Calendars off, and its Services legend sits 18 px farther right than the email field. The connected error capture shows Copy link and Disconnect as separate actions beside Retry.
I checked the providers’ official mark terms before choosing glyphs: Apple requires express authorization for its graphic marks, Google’s published G asset rules cover approved Google sign-in buttons (this flow uses app passwords), Fastmail grants limited approved use and bars logo distribution, and Yahoo requires express permission unless a use is expressly allowed. The component records the source URLs and uses distinct neutral glyphs instead.
Progress: committed the chooser and connected-row fixes as
816319f5, then merged the once-fetchedorigin/dev(918b4764a) cleanly. Current head is791cd7a7dcb95d0b65989e6423197bd2a4f0e2b0.Focused UI tests passed (7 tests). Post-merge
cargo fmt --checkpassed with empty output, andbun run checkreportedsvelte-check found 0 errors and 0 warnings. The migration audit found no collision:origin/devhas DB migrations0001–0006; this branch keeps0007–0009.The full
bun run testsuite is running. Next are the requested per-crate gates, production screenshot matrix, API-client check and integrations adversarial probe.Finding: the post-merge full web suite exited 1 with
2 failed | 127 passed (129)files and2 failed | 826 passed (828)tests. Both failures hit the configured 5 s timeout: the first Integrations test and the unchanged ThemePicker variant test. The focused Integrations suite passed all 7 tests before the full run. At the end of the run,psshowed Vitest active in both this worktree andagenda-413for about 3 minutes. This is timing evidence under concurrent CPU load; no existing assertion was changed. I am recording the failed full-suite gate rather than increasing its timeout.Starting round 3 on branch job/integrations. Current HEAD:
791cd7a7d(includes the prior merge of origin/dev). I am fixing provider marks, chooser actions and provider sheet layout, then I will run the requested web and Rust gates and refresh artifacts/integrations screenshots.Finding from the supplied artifacts: the three flagged 1440px PNGs still show the earlier chooser and account row (shared globe icons, visible Copy link/Disconnect pills, and the old right-overlapping setup card). The current source at
816319f5balready uses distinct glyphs, overflow menus, a centered glass OverlaySurface and provider capability defaults. I am rebuilding the production binary and refreshing the evidence matrix so the screenshots match the reviewed source; I will fix any remaining layout issue visible in the new captures.Resuming round 3 on branch job/integrations. HEAD:
8ffc68b980; origin/dev:55a2f90feb; merge base:918b4764ad. Worktree was clean. Continuing the requested chooser, provider sheet, service defaults, and connected-row menu fixes, then gates and visual captures.Merge finding: origin/dev added a second Mail sign-in form, which conflicts with DESIGN §49 I2. I am keeping the Integrations-only setup already on this branch and preserving origin/dev's independent Mail read-marking preference and reader/cache features.
Round 3 resumed on job/integrations at
8ffc68b98, after origin/dev merge791cd7a7d. This worktree has unrelated staged changes outside integrations; I am preserving those and continuing only the remaining #407 fixes.Owner decision (2026-09-30): the section is named Connected Accounts, not "Integrations".
Apply it to the sidebar label, the page title, the deep-link slug (
settings/connected-accounts; keep a redirect fromsettings/integrationsif it ever shipped), the i18n strings, tests, DESIGN §49 and CONTEXT.md. Code identifiers may stayintegrationsinternally if renaming them is noisy, but user-facing text must say Connected Accounts.SETTINGS → Integrations: one sign-in per provider account, then Mail/Calendar/Contacts checkboxes (grill)to BETTER SETTINGS: organise Settings so it feels non-overwhelming and close to the User (grill pending); includes Connected AccountsScope widened (owner, 2026-09-30): this issue is now Better Settings: "organise it in a better way that it feels non-overwhelming, and closely clustered to the user so everything makes sense." It needs a grill before any reorganisation is built (the owner will run it later).
Review finding: the fresh 390 px run stopped because the runner waited for #integration-provider-title to be visible. The phone layout intentionally hides that body heading and uses OverlaySurface's sticky sheet title. I am updating the runner to assert the visible provider sheet and its chrome title; the product view was not reached by this assertion.
Review finding: desktop geometry checks ran during OverlaySurface's entrance motion. A new provider can still be 24 px into its horizontal fly transform after two frames; the settled card is centered at x=440..1000 in the 1440 px capture. I am making the runner wait for finite surface animations before checking placement.
Finding during final checks: the merged web token guard flagged local radius/leading values in the integration sheet plus a numeric fallback in shared SettingsRow. Replaced them with shared role tokens; the focused token check now passes. The initial full web check had failed at this guard.
Finding during merged-tree web validation: also exposed that workspace dependencies were not installed ( is declared and locked; bun install v1.4.2 (744846f84)
Checked 631 installs across 749 packages (no changes) [7.00s] installed it) and an incoming Mail settings test imported from Vitest instead of Testing Library. Corrected the import without changing assertions; rerunning the web check now.
Owner confirmed the Better Settings plan (2026-09-30): DESIGN §50 at
0dc772c36. Build launches after the Connected Accounts job (integrations) merges; it folds in #474 (Title Case) and uses #482's header.Merged-tree validation findings for #407:
#407 final report
Branch:
job/integrationsHEAD:
6276f89e438f21bdce247d0fb8338e08f4ac98e0Merged
origin/devonce inbfd4a811c.Built
The 48 production-build review captures are in
artifacts/integrations/and attached to this issue. They cover phone (390 px), tablet (820 px), and desktop (1440 px), in light and dark. The issue currently has 66 attachments including this set.Files (48)
apps/web/e2e/integrations-review.mjs,apps/web/package.json,apps/web/src/routes/settings/[...path]/+page.svelte,apps/web/src/routes/settings/calendars/CalendarsSection.svelte,apps/web/src/routes/settings/integrations/IntegrationsSection.svelte,apps/web/src/routes/settings/integrations/IntegrationsSection.svelte.test.ts,apps/web/src/routes/settings/mail/MailSection.svelte,apps/web/src/routes/settings/mail/MailSection.svelte.test.ts,apps/web/src/routes/settings/parts/SettingsRow.svelte,apps/web/src/routes/settings/parts/icons.ts,apps/web/src/routes/settings/sections.test.ts,apps/web/src/routes/settings/sections.ts.contracts/openapi.json,packages/api-client/src/generated.ts.crates/calternal-db/Cargo.toml,crates/calternal-db/src/integrations.rs,crates/calternal-db/src/lib.rs,crates/calternal-db/src/migrations.rs,crates/calternal-db/src/migrations/0007_integrations.sql,crates/calternal-db/src/migrations/0008_integration_carddav.sql,crates/calternal-db/src/migrations/0009_yahoo_provider.sql.crates/calternal-plugin/Cargo.toml,crates/calternal-plugin/src/lib.rs,crates/calternal-plugin/src/outbound.rs,crates/calternal-server/Cargo.toml,crates/calternal-server/src/integrations.rs,crates/calternal-server/src/main.rs,crates/calternal-server/src/system_plugin.rs,crates/calternal-server/src/wire.rs.crates/plugins/calendar/src/cache/crypto.rs,crates/plugins/calendar/src/cache/mod.rs,crates/plugins/calendar/src/cache/store.rs,crates/plugins/calendar/src/client/mod.rs,crates/plugins/calendar/src/items.rs,crates/plugins/calendar/src/routes.rs,crates/plugins/calendar/src/search.rs,crates/plugins/calendar/src/view.rs,crates/plugins/calendar/tests/cache.rs.crates/plugins/mail/src/cache.rs,crates/plugins/mail/src/cache/store.rs,crates/plugins/mail/src/crypto.rs,crates/plugins/mail/src/imap.rs,crates/plugins/mail/src/lib.rs,crates/plugins/mail/src/routes.rs,crates/plugins/mail/src/sync.rs.Cargo.lock,tests/adversarial/integrations_api.mjs,tests/adversarial/run.sh.Gates
cargo fmt --check: exit 0; stdout and stderr empty.bun run check:Full
bun run test:The timeout was in the unrelated
ThemePicker.svelte.test.tskeyboard submenu test. Focused rerun:bun run build:Clippy:
Rust tests:
bash packages/api-client/check-generated.sh:Generated diff check passed with no changes.
Integrations adversarial probe:
Cleanup:
Web build output was removed.
Known gaps
Decisions not specified in DESIGN
Starting the Connected Accounts rename on
job/integrations, based on6276f89e438f21bdce247d0fb8338e08f4ac98e0. I am fetching and mergingorigin/devfirst, then I will update the user-facing names, canonical settings deep link and legacy redirect, DESIGN §49, and the glossary. I will leave the separate §50 reorganisation untouched.Finding: Mail and Calendar still expose the old section name in their linked-account conflict messages, so those API errors remain visible to Users after the Settings rename. I changed those messages and nearby account documentation to say Connected Accounts. The API route names and Rust identifiers remain unchanged.
Finding:
cargo test -p calternal-servercompleted with 89 tests passed, 1 failed and 2 ignored. The sole failure was the existing serializedwire::tests::live_apps_run_in_separate_processeswrapper: itsfull_app_setup_session_config_and_backupchild timed out atwire.rs:7104after 16.60 seconds. Several other server builds were active during this run. I did not change the test or its expectation; I am treating this as a load-only timeout per the job rules.Completed
The Settings label, page title, and account group title now say Connected Accounts. The canonical deep link is
/settings/connected-accounts; old/settings/integrationslinks resolve to it. Mail and Calendars use the canonical links and updated copy. I updated DESIGN §49 and the CONTEXT glossary. Code identifiers remainintegrations; I did not start the §50 reorganisation.Branch:
job/integrationsHead:
493a9510be56e84e4bc552bf76884a581b51e105Files
apps/web/src/routes/settings/apps/web/e2e/integrations-review.mjsapps/web/e2e/route-perf.mjscrates/plugins/mail/,crates/plugins/calendar/crates/calternal-db/src/integrations.rs,crates/calternal-server/src/integrations.rsdocs/DESIGN.md,CONTEXT.mdGates
bun run checkoutput:bun run testoutput:cargo fmt --check: exit 0, no output.cargo clippy -p calternal-db --all-targets -- -D warnings: exit 0;Finished dev profile in 3m 02s.cargo test -p calternal-dboutput:cargo clippy -p calternal-server --all-targets -- -D warnings: exit 0;Finished dev profile in 1m 25s.cargo test -p calternal-server: 89 passed, 1 failed, 2 ignored. The existingwire::tests::live_apps_run_in_separate_processeswrapper timed out infull_app_setup_session_config_and_backupatcrates/calternal-server/src/wire.rs:7104after 16.60s while the shared host had concurrent Rust jobs. No test expectation changed. This was reported as a load-only timeout.cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings: exit 0;Finished dev profile in 2m 42s.cargo test -p calternal-plugin-calendar: 51 library tests, 1 cache integration test and 3 protocol tests passed; 1 manual benchmark ignored.cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings: exit 0;Finished dev profile in 28.99s.cargo test -p calternal-plugin-mail: 34 tests passed.bun run buildpassed:✓ built in 3m 1s;Wrote site to "build". The existing Rolldown"use client"module directive warnings remained. I rancargo cleanand removedapps/web/buildafter evidence capture.Screenshots
The production SPA review passed:
PASS Connected Accounts review: 60 screenshots. It covers the chooser, five provider forms, service checklist, connected account state, Mail and Calendar views at 390, 820 and 1440 px in light and dark themes. The API account rows are Playwright fixtures in the review harness only.Performance
Measured on
perf-testunder/root/perf.lock, three runs at 390 and 1440 px. Load average inside the lock: before0.01, 0.09, 0.13; after3.44, 1.14, 0.49.1072/1080 ms; 1440 px1633/3195 ms.422869JS gzip bytes and68636CSS gzip bytes.0.2%/164930355bytes. Peak CPU/RSS during the burst:248.13%/182079488bytes.80273requests, p502 ms, p9510 ms; all80273returned HTTP 200.docs/perf/baseline.jsonis commit37788888. Its Appearance route p50/p95 was 390 px3246/5190 ms, 1440 px2953/4055 ms; settings bundle321592JS gzip and53020CSS gzip. That baseline predates this build. In the measured build, Appearance p50/p95 was1104/1218 msat 390 px and1606/1787 msat 1440 px.Opening Photos…; this is outside #407 and is filed as #521. The route samples and burst completed.Decisions and gaps
Product decisions follow the 2026-09-30 owner instruction and DESIGN §49: retain the internal ID, use the new canonical slug, redirect the old slug, and leave §50 for its separate job. The only gate gap is the shared-host timeout in the server test above. The separate Photos Tab navigation issue is recorded in #521.
Starting #407 on branch job/integrations at base
493a9510be. I am auditing the Connected Accounts UI, routes, shared surfaces and existing e2e coverage before making the requested polish changes.Finding:
IntegrationsSection.sveltestill renders a separate provider ⋯ control beside the full-row open action, styles fields locally withvar(--surface)/var(--line), uses text pills for Copy link, and shows the Contacts promise below Services. The shared Settings input recipe uses--input-surface;packages/uihas no reusable text input component. I will use one shared component for this form and move provider extras into the row context menu.#407 implementation slice committed on
job/integrationsatf45c72a16.The first
bun run checkfound a direct140ms easeprovider-row transition in the touched component. I replaced it with the shared--dur-pressand--ease-standard-outtokens required by #477. The next check found an over-narrow test comparison against the removed section ID; the assertion now checks the section ID and label arrays. Focused tests passed (3 files, 21 tests); the correctedbun run checkpassed with 0 errors and 0 warnings.The first desktop screenshot matrix run captured all 390 px and 820 px states. It stopped on the Gmail dialog at 1440 px when its center was 1.016 px from the viewport center, just outside the existing 1 px assertion. A separate stabilized geometry probe measured the same shared dialog at 0 px offset. The review helper now waits for the entrance transform to finish before measuring; the 1 px expectation remains unchanged. I am rerunning the matrix to regenerate the full screenshot set.
cargo fmt --checkfound one ordering mismatch in the server module declarations from theorigin/devmerge resolution (integrationsandlocation). I am applying rustfmt's order before the per-crate gates; no server behavior changes.Completed: Connected Accounts polish (#407)
Branch:
job/integrationsHead:
920bfd3d51676217c66d13db144f35e119e66a15Built
/settings/integrationspath and#integrationshash resolve to the canonical section.TextInputandOverlaySurface, improved field and service spacing, made Copy link an icon button with its warm tooltip, and removed the Contacts placeholder.The existing
/api/v1/system/integrations/*API paths stay intact. The e2e review used deterministic UI fixtures with the production app and a real local server. No fixture data ships in the UI.Screenshots and e2e
The e2e captured 60 review screenshots across phone (390), tablet (820), and desktop (1440), in both themes. I attached 18 representative chooser/list, Gmail form, and connected-state screenshots to this issue, covering each viewport and theme.
The authenticated two-User route matrix passed:
Gates
cargo fmt --checkexited 0 with no output.Vitest also printed jsdom
Window.scrollTo()and CSS parsing notices; the suite exited 0. The production build used by e2e passed earlier in this run. Cargo output was cleaned after the gates (Removed 17369 files, 9.8GiB total);apps/web/buildand.svelte-kitoutput were removed.Performance profile
The existing route profile now includes the Connected Accounts list, Gmail form, and legacy route. I ran it locally with 3 samples per viewport, a 2,000-file Home, and a 24-request concurrency burst. The local host load average was
[26.28, 25.81, 24.18]before and[17.32, 25.83, 26.53]after the run.Connected Accounts list p50/p95 (ms): 390px
4143/6260; 820px4409/4513; 1440px1575/2764. Gmail form p50/p95 (ms): 390px2411/5268; 820px5108/5463; 1440px2292/3876. The connected-accounts API read measured4.8/20ms with 50 successful 200 responses. The request burst served 16,938 requests in 12,015ms; p50/p95 was8.5/56.3ms, all responses were 200, and peak RSS was342,913,024bytes.docs/perf/baseline.jsonhas no Connected Accounts route or API sample. Its closest Settings route, Appearance, recorded p50/p95 of1037/1190,1144/1157, and1584/2069ms at 390, 820, and 1440px. Its baseline server burst recorded2.1/11.9ms and 71,751 successful requests; the baseline host load was[0.15, 0.39, 1.03]before. These figures are not directly comparable to this run because the local host was heavily loaded.Files
apps/web/e2e/integrations-review.mjs,apps/web/e2e/route-perf.mjs,apps/web/src/lib/search/providers.test.ts,apps/web/src/routes/settings/[...path]/+page.svelte,apps/web/src/routes/settings/calendars/CalendarsSection.svelte,apps/web/src/routes/settings/connected-accounts/ConnectedAccountsSection.svelte,apps/web/src/routes/settings/connected-accounts/ConnectedAccountsSection.svelte.test.ts,apps/web/src/routes/settings/mail/MailSection.svelte,apps/web/src/routes/settings/parts/settings-forms.css,apps/web/src/routes/settings/sections.test.ts,apps/web/src/routes/settings/sections.ts,crates/calternal-server/src/main.rs,packages/ui/src/components/TextInput.svelte, andpackages/ui/src/index.ts.Known gaps and decisions
Live third-party provider connections were not part of the e2e; it uses local API fixtures for repeatable UI states. I kept the existing API paths and made the former Settings path and hash aliases to preserve saved links. Those are the only compatibility decisions beyond the name and layout already set by DESIGN §49 and this issue.
Starting round 3 on branch job/integrations. Base SHA:
cc25c441b7. I am checking the Connected Accounts UI, shared Settings add-flow surfaces, and legacy Mail/Calendar schemas before changes.Upgrade finding: the old Mail credential AAD is
calternal-mail-app-password-v1\0owner\0account, while Calendar binds its credential kind intocalternal-calendar-credential-v1\0owner\0account\0kind. Mail also stores SMTP username/password separately from the IMAP login. A byte-for-byte copy into the shared Integration row would therefore fail decryption and lose SMTP identity. The upgrade now re-wraps each credential in memory into the shared encrypted payload, including SMTP fields, then clears the source credential only in the same transaction that stores the central row. I am adding regression coverage for the cached Mail projection and rollback behavior.Migration test finding: Mail and Calendar can use the same visible address but keep different app passwords. The first merge rule treated that as a conflict, which safely rolled back but did not carry both service sign-ins into Connected Accounts. I am updating the shared encrypted credential envelope to preserve a separate Calendar login/password when needed, just as it now preserves Mail's separate SMTP login/password. The linked Calendar cache keeps its existing projection ID.
UI verification finding: the production E2E measured 0 px between the Services legend and the first Mail row. The 12 px CSS grid gap does not apply between a fieldset legend and its first child in the rendered browser. I am replacing that gap with explicit legend spacing and will rerun the real-browser geometry check.
Desktop E2E evidence: the shared dialog received the correct 120 px Settings-pane offset, but a Connected Accounts style still set
left: 50%, overriding the shared placement rule. The rendered center therefore stayed at the viewport center and missed the content center by 120 px. I am removing that local position override and keeping only the provider form's width and height limits.Finding: Calendar's stored credential type includes an encrypted OAuth2 variant (
crates/plugins/calendar/src/cache/crypto.rs,Credential::OAuth2). The first migration draft treated that payload as unsupported, which would have left all legacy Mail and Calendar rows unmigrated if one OAuth row existed. The shared encrypted envelope now retains its access and refresh tokens, and the upgrade regression checks both tokens and the linked Calendar projection. Existing CalDAV OAuth behavior remains unchanged because the client has not implemented OAuth authentication.Finding from the final DB gate: migration 0010 must allow both service switches off so it can preserve a legacy row exactly, while the normal create and update API still requires a service. The existing
account_cannot_have_no_enabled_servicesDB test asserted the old schema constraint. I replaced that expectation with a regression that stores and reads the both-off legacy state, as required by #407 I6; the API validation remains unchanged.Merged origin/dev code failed server clippy: state.client(&account)? used an async future without awaiting it at crates/plugins/calendar/src/routes.rs:1201. Updated it to await the client result; this is on the Calendar event duplication path. Re-running the affected gates.
Server clippy found the upgrade-test helper seed_legacy_mail_account exceeded the argument limit (10/7) at integrations.rs:1795. Grouped its fixture fields in LegacyMailAccountSeed; Gmail/custom fixtures and assertions are unchanged. Re-running the server gate.
Decision where DESIGN §49 I6 is silent: run the one-time move during server startup and record completion in the database; expose only a safe state/error code through the authenticated migration-status route so old accounts are available before Settings loads and failures stay visible there. Reuse each Mail account ID as the shared account ID to preserve Mail foreign keys and links. Keep each Calendar projection/cache ID unchanged and add its shared-account link. This leaves provider cache identities stable while the shared row owns credentials and service switches.
The first post-merge E2E exited before captures at harness.mjs:94: saveThemePreference accessed window.__userStorageTest.getItem, which was undefined in the fresh viewport context created by captureWidth. The signed-in setup context had installed the test seam, but new capture contexts had not. I am installing the existing test seam in each capture context and will rerun the production matrix.
#407 round 3 report
Branch:
job/integrationsHead:
ffb73a099ad521cca3d854507a2ad02f198c27e8Built
OverlaySurface: centered in the Settings detail pane on desktop and displayed as the floating sheet on phones. This follows Settings → Apps → Calendar Feeds → Create calendar feed.Upgrade safety
The one-time startup migration moves pre-branch Mail and Calendar accounts into
integration_accountsin one transaction. It re-wraps each legacy secret into the shared AEAD envelope in memory, preserves separate SMTP and Calendar sign-ins and encrypted OAuth tokens, infers providers from saved values or server hosts, and carries service switches forward. Mail IDs stay stable. Calendar cache IDs and cached Events stay stable and link to the shared account ID. Old service rows remain read-only projections; legacy ciphertext is cleared only inside the successful transaction. A failed migration rolls back and leaves source rows in place, with a safe status available in Settings.legacy_accounts_upgrade_losslessly_and_only_oncebuilds theorigin/devschema, seeds a Gmail-style account, a custom IMAP account, cached Mail messages and UID state, plus Calendar Basic and OAuth rows. It verifies the same Mail page, IDs, flags and cursor after migration, preserved account names and credentials, stable Calendar cache IDs, and idempotency.legacy_account_failure_keeps_source_rows_and_reports_safe_statusverifies rollback and the failure status.Screenshots
Fresh screenshots from the production SPA and real server. The connected-row state uses test-only API fixtures; no provider credentials were used.
Verification
Gate output excerpts are verbatim.
cargo fmt --all --checkexited 0 with no output. The final commit only changes documentation; formatting was rerun after it.Performance
bench/integrations-407.mjsran locally with 250 non-secret rows on a busy host (load average 9.53, 10.92, 14.38). Account list p50/p95 was 22.8/89.8 ms; migration status was 8.0/52.9 ms. The 24-request burst completed in 641.3 ms for account lists and 223.79 ms for migration status. Mean/peak server RSS was 135,841,515/137,207,808 bytes; mean/peak CPU was 30.12/73.9%.docs/perf/baseline.jsonhas no directly comparable Connected Accounts profile, so these numbers do not establish a regression.Known gap
Legacy Calendar OAuth token pairs remain encrypted and preserved, but the current CalDAV client still does not support OAuth sync. The migration does not add an OAuth flow or change that existing behavior. E2E connected-state screenshots use test-only account API fixtures.
Decisions where DESIGN §49 was silent
Otherrows also require the displayed email. Keep both-services-disabled legacy rows as-is during migration; new create/update requests still require one service enabled.OverlaySurfacecreate-flow pattern named above for provider setup.Main files
Settings UI and tests:
apps/web/src/routes/settings/connected-accounts/ConnectedAccountsSection.svelte,apps/web/src/routes/settings/[...path]/+page.svelte,apps/web/src/routes/settings/parts/SettingsRow.svelte, Settings Mail/Calendar sections, styles and E2E review.API and storage:
crates/calternal-server/src/integrations.rs,crates/calternal-db/src/integrations.rs, core migrations0007–0010, andcrates/plugins/calendar/migrations/0005_integration_account_link.sql. Mail/Calendar credential, cache, route and client adapters are undercrates/plugins/mail/src/andcrates/plugins/calendar/src/.Contracts and evidence:
contracts/openapi.json,packages/api-client/src/generated.ts,tests/adversarial/integrations_api.mjs, andbench/integrations-407.mjs.Independent data-integrity review started on job/integrations-review, based on
ffb73a099a. No production code changes, push or deploy. Tests will be supplied as patches. Fetched origin/dev is687ff70313. At this SHA, Mail migration 0009 from #626 is not yet present; the duplicate-message hotfix keeps the first UID. I will check the #626 branch separately and label that fixture clearly.Independent #407 review: two blocking findings at
ffb73a099.crates/plugins/mail/src/routes.rs:1532–1535and1635–1638still decryptaccount.encrypted_credential. The account migration explicitly clears that ciphertext (crates/calternal-server/src/integrations.rs:416–417). Sync correctly usesdecrypt_integration, but these routes return 500 before contacting the provider.calternal-db/src/migrations.rs:167–185checks only known versions; it does not reject unknown newer versions. Thus the old binary can pass schema startup and health while Mail/Calendar sync cannot authenticate.deploy/deploy-cloud.sh:41–50has no restore or downgrade guard. Startup does create a pre-migration Index snapshot (wire.rs:1135–1142); rollback must restore the correct snapshot or refuse the old binary before it opens the upgraded Index.Tests are building: exact cache snapshots for 4,000 messages and 18 repeated message IDs, idempotent rerun, credential preservation after re-wrap, and a fault injected after Mail ciphertext is cleared inside the transaction. No fixes to production code are made by this review.
Additional #407 finding: legacy create APIs remain active after the one-time migration.
POST /api/v1/mail/accounts(mail/src/routes.rs:814–836) andPOST /api/v1/calendar/accounts(calendar/src/routes.rs:805–838) still store standalone service accounts.integrations.rs:180–186returns immediately whenever the global marker is complete. Later service rows will not appear in Connected Accounts, including after a restart. A diagnostic test seeds a second legacy account after completion and checks that another migration call skips it. Fix by retiring or delegating legacy create writers, or by safely reconciling new rows. This is a control-state consistency gap, not a claim that existing cached messages are deleted.#626 compatibility finding: after Mail migration 0009 removes UNIQUE(folder_id,generation,message_id), the reviewed binary still uses that conflict target in
mail/src/cache/store.rs:988–991. SQLite rejects the membership INSERT with “ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint”. Ship #626's store adapter change together with its SQL; the Connected Accounts migration preserving cache rows does not itself provide runtime compatibility with Mail 0009. This is covered by the production-shaped fixture diagnostic. Fetched origin/dev still has Mail 1–8; this finding concerns the pending #626 production shape.Independent #407 diagnostic test patch against
ffb73a099. Test-only commit:8274c17e8. No production fixes. Four diagnostics passed at the review target; observed 500s are evidence of defects, not acceptance expectations for the eventual fixes. The SQL fixture is the exact pending #626 migration from98b627f45. All credential strings are inert test fixtures. The server test build requires a production web build for RustEmbed.Final review head:
ad7e25c6392e75cd8360c82b9e716c8011b7fca1. Full final gate output follows verbatim; dependency build lines are retained.Final gate transcript
Gated code head:
af6616f4dc. All commands exited 0.cargo fmt --check(exit 0):stdout and stderr were empty.
cargo clippy -p calternal-server --all-targets -- -D warnings(exit 0):cargo test -p calternal-server --quiet -- --test-threads=1(exit 0):cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings(exit 0):cargo test -p calternal-plugin-mail --quiet -- --test-threads=1(exit 0):Independent #407 review finished. Verdict: NO-GO.
Final review head:
ad7e25c6392e75cd8360c82b9e716c8011b7fca1onjob/integrations-review. Assessed implementation:ffb73a099ad521cca3d854507a2ad02f198c27e8. Gated code head after the required origin/dev merge:af6616f4dc1fff6ed3c13a6bdf17dd018dfee0a0. Test-only patch commit:8274c17e8, posted above. No production fixes, push, deploy or issue close. Worktree is clean.Connected Accounts migration review — #407
Review target:
ffb73a099a.Verdict: NO-GO.
Review branch: job/integrations-review. No production fixes are authored. Final gates run after the required merge of origin/dev.
Fetched origin/dev:
687ff70313.Findings in progress
integrations.rs:163–465). Each schema migration has a separate transaction (migrations.rs:189–208). This is not one transaction across the full schema upgrade.download_attachmentandchange_read_statestill call legacyInstanceKey::decrypt(mail/src/routes.rs:1532–1535,1635–1638), unlike sync'sdecrypt_integrationbranch. Migrated accounts therefore return 500 for provider attachment fetch and changed read state.98b627f45e, not on origin/dev. Test fixture uses that exact SQL and labels it as a pending branch dependency.Claim-by-claim evidence
late_statement_failure_rolls_back_then_retries. Pending: abrupt process termination was not injected at every statement.mail/src/sync.rs:283–313) and uses the saved folders/generations. Literal ciphertext/nonce preservation is refuted: the old Mail AAD (mail/src/crypto.rs:190–192) differs from shared AAD (calternal-db/src/integrations.rs,associated_data). Re-wrap retains IMAP and separate SMTP passwords. Server supplies the same key to both adapters and the migration (wire.rs:1094–1098,1223). No password entry is required for the new sync path. Read-state and attachment routes remain broken.calendar/src/cache/store.rs:159–190). Existing preservation test also covers a merged account with distinct Mail and Calendar passwords and a legacy OAuth envelope (integrations.rs:2059–2290). A real CalDAV client was not run; database href, UID, etag and iCalendar equality is the evidence for stable identities.integrations.rs:194–198,262–266). Matching requiresaccount.owner_id == owner_id(310–312), inserted rows retain owner_id, and updates bind both owner and account ID. Request account reads are scoped. Mail joins require bothi.id = a.idand equal owners (mail/src/cache/store.rs:420–456). Calendar joins require both link/ID and equal owners (calendar/src/cache/store.rs:159–190). The new legacy-status query is instance-wide and returns only state/error code, not account counts or identities.New route classification
All five operations are under
/api/v1/system/integrations. They are User/data-scope routes, not admin-only routes.principalrejects no context/no User with 401, rejects no data scope/invalid User ID with 403, and permits a valid User with data scope (integrations.rs:744–756). No role check restricts these operations to admins. Data-scoped App Passwords or agents with a User identity meet this local guard; account-only scope does not./accountslist_integration_accountsfilters owner_id; API omits credentials/accounts/accounts/{id}/accounts/{id}/legacy-migrationExisting route test:
account_list_and_mutations_are_scoped_to_the_authenticated_userchecks anonymous, wrong scope and foreign-owner list/PATCH/DELETE. Code references above cover POST's principal binding and the status route.Migration ordering and dev drift
Core 7–10 and Calendar 5 have no collision against fetched origin/dev (core 1–6, Calendar 1–4). Mail 9 belongs to another namespace, so it does not collide with core 9. The pending #626 SQL rebuilds only mail_memberships and does not touch account credentials. It can run before or after the account move. The fixture uses #626 first. Without #626, the reviewed branch still has UNIQUE(folder_id,generation,message_id), so the production shape cannot be represented in its unmodified schema.
origin/dev includes #613 first-sync code. Compared with origin/dev, the reviewed branch has the old short-window assertion. It includes the duplicate-skip hotfix, but lacks 687ff7031’s change that keeps a short window instead of rolling it back. Those independent fixes must survive integration; they are not evidence of migration data loss. Tests never change existing assertions to make failures pass.
Decisions and scope
Additional finding: legacy create routes remain active
POST /api/v1/mail/accounts(mail/src/routes.rs:814–836) andPOST /api/v1/calendar/accounts(calendar/src/routes.rs:805–838) still write standalone legacy account rows. After the global completion marker, the migration returns before scanning those rows (integrations.rs:180–186). Thus current legacy API clients can create accounts that never appear in Connected Accounts, even across a restart. The Settings screen loses the central account controls for those rows. Retire or delegate those create routes to the central writer, or safely handle new legacy rows. Test:completed_marker_skips_later_legacy_accountsuses the same legacy storage shape and proves the skip without provider access. This also explains why an old-image-only downgrade followed by a re-upgrade is unsafe.#626 compatibility finding
Once Mail migration 9 has been applied, this reviewed binary's
store_windowstatement is invalid. It still hasON CONFLICT(folder_id,generation,message_id) DO NOTHING(mail/src/cache/store.rs:988–991). Migration 9 removes that UNIQUE constraint, and SQLite rejects that conflict target before it inserts any membership. #626's store adapter change must ship with its migration; copying only the SQL does not make this binary compatible. The production-shaped test reproduces the precise conflict-target error with the reviewed INSERT shape. No cache rows are changed by that rejected statement. This is also another reason that an old binary must not open a database migrated by #626.Required fixes before GO
Measured preservation evidence
These are complete ordered row comparisons, not selected fields. Each before/after FNV-1a checksum is equal. Password values are checked in memory and are not logged. Re-wrap changes nonce and ciphertext as required by the new AEAD domain.
Local account-move duration in the pinned-target run: 3,173 microseconds. No matching account-migration profile exists in docs/perf/baseline.json. This single local timing is not p50/p95, CPU or RSS evidence and does not support a performance claim. This review adds no production hot path or user-facing feature.
Pinned-target diagnostic output, verbatim:
Files and patch
98b627f45.ffb73a099. Diagnostic tests intentionally assert the observed defects; do not treat their 500 assertions as acceptance requirements for a fix.Test commit:
8274c17e8. The merge of origin/dev was automatic and preserved dev's short-window fix. No manual merge resolution changed any existing assertion. The patch omits inherited production changes and review prose.Known gaps
Final gates
Gated code head:
af6616f4dc. Final report commits change documentation only.All commands use CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4 and the worktree target/tmp as TMPDIR. CARGO_TARGET_DIR is the preset job directory.
cargo fmt --check(exit 0):stdout and stderr were empty.
cargo clippy -p calternal-server --all-targets -- -D warnings(exit 0), terminal summary verbatim:cargo test -p calternal-server --quiet -- --test-threads=1(exit 0):cargo clippy -p calternal-plugin-mail --all-targets -- -D warnings(exit 0), terminal summary verbatim:cargo test -p calternal-plugin-mail --quiet -- --test-threads=1(exit 0):Full output is saved in artifacts/gate-transcript.md and posted verbatim on #407. The three ignored Server tests run through live_apps_run_in_separate_processes. The two ignored Mail tests require the isolated TLS provider and the large-history performance profile. No existing expectation was edited by this review.
The production web build succeeded to provide the RustEmbed input. No web source changed. Module and function comments in all touched test files were re-read before this report.
Cleanup
Cargo build output and web build output were removed. Cargo cleanup output, verbatim:
Round 4 started on job/integrations, base/head
ffb73a099a. Read CLAUDE.md, CONTEXT.md, DESIGN §33/34/49/50 and the independent NO-GO review. First slice fixes shared credential consumers; next preserves legacy encrypted sign-ins and reconciles unlinked rows on every boot. No push, deploy or integration into dev. Diagnostic defect assertions will change only where #407 explicitly requires the new behavior. #626 SQL will not ship independently of its adapter.Round 4 evidence: imported review tests fail on the reviewed code for exactly the three required changes (3 failed, rollback test passed). Mail read-state/attachment return 500 instead of endpoint validation; migrated legacy decrypt fails; later rows are skipped. Production code now uses one shared Mail decrypt resolver, keeps legacy kind/nonce/ciphertext for rollback, and scans unlinked rows on every boot. A later Calendar row can match the existing shared Mail sign-in inside the writer transaction. Minimal public addition: calternal-db exports its existing account-row decoder so startup does not duplicate provider decoding or read a different transaction snapshot.
UI slice committed as
e696e4113. Targeted component tests: 10 passed; svelte-check: 0 errors and 0 warnings. The fill on connected rows came from LocationGroup's global.settings-row.deep-linkedstyle; it now targets only#opt-location. OverlaySurface gets an optional shared header snippet; provider setup uses ModeHeader (PillGroup actions and ProgressiveBlur) once in both presentations. Other uses one server glyph; Google keeps its initial inside the same neutral circle. Updated old icon/title test expectations only because the Round 4 brief explicitly changes them.Decisions: retain legacy sign-ins now and remove them only with a future explicit downgrade boundary; this does not claim rollback safety across #626's incompatible membership schema. The 4,000-message/4,018-membership fixture uses a test-only schema shape, without registering or shipping the pending #626 migration. No dependency changes are required. Browser plugin is unavailable; use the repo Playwright harness.
Round 4 integrity progress on
job/integrations(Mail resolver commit99eab5ae3; visual surface commite696e4113).The imported independent-review regressions now pass: exact full-column comparisons of the 4,000-message / 4,018-membership fixture; legacy Mail IMAP/SMTP and Calendar credential recovery with their original AAD; rollback after a late statement failure; separate migrated attachment and read-state routes; late Mail account reconciliation; late Calendar linking to existing shared Mail; and the real-listener two-User owner matrix. The exact migrated fixture also passed a scripted Mail resume: 4,000 messages, 4,018 memberships, zero repeated UID FETCH commands.
Evidence:
The new public DB decoder is small: startup uses the existing account decoder inside its writer transaction. This avoids a separate reader snapshot and duplicate provider parsing. The independent read-only code review found no blocking integrity defect. Full Server checks are running before the migration commit.
The perf VM connection returned
No route to host. The new migration profile will use the local host and report this limit. The fixture schema is test-only; this branch does not register pending Mail 0009 SQL. The final origin/dev merge remains to be done once before final gates.A shared UI follow-up is needed for the 2026-10-01 keyboard-motion override. This is existing code, not a new provider-specific branch:
packages/ui/src/motion.ts:72–77still returns immediate motion when rootdata-inputiskeyboard, andpackages/ui/src/tokens.css:1475–1502sets duration tokens to zero and cancels CSS motion in that modality. Provider setup uses the shared helper and does not setinstantOpen.Removing that policy changes every route and the shared motion tests. I have kept Round 4 on its requested account-integrity and visual fixes; this existing global policy needs the shared motion job. Reduced-motion support remains in place. This is a UI behaviour gap, not an account-integrity gate failure.
Round 4 post-merge gates are green.
origin/devwas fetched and merged once at6dfa0706d; fetched dev is687ff703136e71e89f8dfba139e93cd0788b25c1. It includes the Mail short-window fix and has no #626 migration. Mail ends at 0008; Calendar ends at 0004; core ends at 0006. This branch's core 0007–0010 and Calendar 0005 do not clash. No Mail 0009 SQL was included.Verbatim Server result:
DB, Mail, Calendar and Plugin Clippy/tests passed as well. Web:
svelte-check found 0 errors and 0 warnings, 149 files / 1,023 tests passed. Full raw gate logs will accompany the final report. Comments for changed Mail consumers and legacy-AAD helpers were reviewed and completed in8f0f3c679.The exact post-merge migrated fixture again passed the Mail handoff:
All six full-column cache snapshots remain equal. The migration profile ran once locally (perf VM unreachable): sequential p50/p95 7.218/13.744 ms, three-worker burst 8.300/43.933 ms. Mean/peak sequential worker RSS 61.04/76.94 MiB; mean worker CPU 35.81%. CPU/RSS includes fixture seeding and comparison, unlike migration latency. No matching profile exists in docs/perf/baseline.json, so no threshold regression can be established from this comparison.
The review matrix will now cover 66 screenshots: all prior 60 plus Location in all widths/themes, because the row-fill fix scopes a Location-owned rule. A small public test-harness addition lets the existing passkey helper register an invited User, without duplicating registration/login logic. The bounded local contract check will use both real Owner/member sessions as well as the already-passing trusted-context route tests. Provider sign-in is not attempted by these fixtures.
The final connected-row alignment check found a width-dependent cause: the status chip wraps below the email on phone, but shares its first flex line on wider screens. The old icon offset added a cap height; removing that term alone did not meet the ±1 px rule at every width (phone 1.5 px, tablet 0.5 px, desktop -2.0 px).
Commit
fd259dc17gives the email a trimmed cap box and puts its status below it at every width. The icon centers on that box with CSS only. Minimal public addition: SettingsRow exposes its existing first-row/normal-row top inset as a CSS hook, with the same defaults. Connected Accounts uses the hook to reserve icon ascent without copying spacing constants. Nested service rows keep their original layout. All 1,023 Web tests, svelte-check and the production build passed.The initial fresh capture closed its browser late in the desktop dark theme. No app exception was captured, and those stale files were not accepted as evidence. The capture now starts a fresh browser for each width, sequentially, and preserves primary failures during cleanup. Phone and tablet are complete; desktop is running. The final report will include only the completed final matrix and its measurements. No test assertion was relaxed.
Round 4 report:
job/integrations, headc81cf1dfccbf6600d1250fdf8e0c8a0e6335eab6. The one finalorigin/devmerge used687ff703136e71e89f8dfba139e93cd0788b25c1. No push or deploy. The issue remains open.Built:
Files (includes the required origin/dev Mail store fix):
apps/web/e2e/harness.mjsapps/web/e2e/integrations-review.mjsapps/web/src/routes/settings/account/LocationGroup.svelteapps/web/src/routes/settings/connected-accounts/ConnectedAccountsSection.svelteapps/web/src/routes/settings/connected-accounts/ConnectedAccountsSection.svelte.test.tsapps/web/src/routes/settings/parts/SettingsRow.sveltebench/integrations-migration-407.pybench/mail-sync.pycrates/calternal-db/src/integrations.rscrates/calternal-db/src/lib.rscrates/calternal-server/src/integrations.rscrates/calternal-server/src/integrations_review.rscrates/calternal-server/tests/review/production_shape.sqlcrates/plugins/mail/src/cache/store.rscrates/plugins/mail/src/crypto.rscrates/plugins/mail/src/routes.rscrates/plugins/mail/src/sync.rsdocs/DESIGN.mdpackages/ui/src/components/OverlaySurface.sveltetests/adversarial/integrations_api.mjsIntegrity evidence:
The Server suite includes separate migrated attachment/read-state cases, late Mail reconciliation, late Calendar linking, transaction rollback and the real-listener two-User matrix. Foreign list/mutation calls preserve the owner boundary. The exact migrated Index is handed to the Mail resume test. Full-column equality is checked for all six cache tables; checksums are diagnostic summaries.
#626 and migration numbering:
The fetched origin/dev has Mail migrations 0001–0008 and does not contain #626. This branch registers no Mail 0009 SQL. The duplicate-membership fixture is a test-only schema, with no production migration version. Core 0007–0010 and Calendar 0005 do not clash with the fetched origin/dev. #626 SQL must ship with its store adapter. Legacy credential retention does not make rollback across that unrelated incompatible schema safe; use its matching Index snapshot.
Verbatim gate result lines (the full unchanged logs are in the evidence archive):
cargo fmt --checkand the explicit included review-module format check: exit 0, no output.cargo clippy -p calternal-db --all-targets -- -D warningsandcargo test -p calternal-db -- --test-threads=1:cargo clippy -p calternal-plugin-mail --all-targets -- -D warningsandcargo test -p calternal-plugin-mail -- --test-threads=1:cargo clippy -p calternal-plugin-calendar --all-targets -- -D warningsandcargo test -p calternal-plugin-calendar -- --test-threads=1:cargo clippy -p calternal-plugin --all-targets -- -D warningsandcargo test -p calternal-plugin -- --test-threads=1:cargo clippy -p calternal-server --all-targets -- -D warningsandcargo test -p calternal-server -- --test-threads=1:bun run checkandbun run test:Production evidence:
bun run buildandcargo build -p calternal-serverpassed. The app is served by the built Server. The Server capture build embedsfd259dc174; the final head adds only the capture-runner resource fix. Account rows in the screenshot harness are deterministic test fixtures; no fixture rows ship in the UI. The Browser plugin was unavailable, so the repo Playwright harness was used.The capture covers all five provider setups, chooser, connected account, service checklist and Mail/Calendar account links at 390/820/1440 px in light and dark (66 screenshots including Location). The screenshots are attached for the orchestrator visual review.
Performance (local shared host; perf VM returned
No route to host):Existing metadata profile, 250 synthetic account rows and a 24-read burst (local):
Decisions:
Known gaps:
Attachments:
Cleanup: Cargo and Web build output and test temporary data were removed. The worktree is clean. Review artifacts remain in artifacts/.
Independent #407 round-4 re-check started on job/integrations-recheck at
c81cf1dfcc. Scope: four required integrity fixes, imported assertion audit, exact #626 migration ordering and diff risk scan. Tests/documentation only; no push or deploy.Independent round-4 re-check: new blocking reproduction for #407 / DESIGN §49 I6.
Calendar-first then later legacy Mail for the same Fastmail username returns AccountConflict. The Calendar account is already linked, so the unlinked-Calendar query is empty and no existing shared Calendar row is loaded for matching. The later Mail row attempts a new shared INSERT with the same (owner_id, provider, email), which hits the unique constraint. The writer transaction also rolls back an unrelated later Mail account. Both Mail rows remain unlinked on two consecutive boot calls; legacy ciphertext and the prior shared row stay intact. Diagnostic: integrations::tests::independent_review::diagnostic_later_mail_conflicts_with_existing_shared_calendar. Its rejection assertion records the defect; it is not acceptance behavior.
Focused result, verbatim:
No product edits. The imported tests retain full-column cache equality, exact retained Mail credential bytes, successful legacy decrypt, and successful later-row checks. The exact #626 SQL is copied from
3286cad72into a test-only fixture; both fresh/upgraded orders and the dependency's corrected membership conflict target pass. That dependency still must ship SQL and store adapter together. A read-only merge-tree check identifies conflicts in Mail routes/sync; keep the shared credential resolver and #626 UID behavior when resolving them. Full crate gates are running.Independent #407 round-4 re-check finished. Verdict: NO-GO.
Final head:
47f98145758e51fa36c75774ffd55efb45ce0c21. Branch:job/integrations-recheck.Connected Accounts round-4 re-check — #407
Verdict: NO-GO. Required fix 3 is incomplete.
Review target:
c81cf1dfccbf6600d1250fdf8e0c8a0e6335eab6.Branch:
job/integrations-recheck. Gated test head:17572313299b864c8316bfc228fa0e8482b03fc2.Fetched
origin/dev:687ff703136e71e89f8dfba139e93cd0788b25c1.The required fetch and merge returned
Already up to date.No product code changed. No push or deploy.Required fixes
decrypt_account, as do sync and legacy PATCH. Calendar uses its shared resolver. The migrated cache resume test passes.3286cad72applies before or after #407 on fresh and upgraded Index schemas. Both version-9 namespaces remain registered. Foreign keys and repeat application pass. The dependency's corrected membership INSERT accepts duplicate UIDs.Blocking reproduction
Both calls return
AccountConflict. Both Mail accounts remain unlinked. The old shared row and all legacy Mail account columns stay unchanged. This is not data loss, but it fails the required late-account migration contract.The Mail scan only loads rows with no shared ID match (
integrations.rs:187). The Calendar scan skips linked rows (:256). It loads existing shared accounts only to accept later Calendar rows, through a Mail join (:261–268). It never matches a later Mail row to the shared Calendar account. The shared INSERT (:434) then violates the unique User/provider/email constraint. The transaction rolls back the unrelated late row too.Required correction: reconcile later Mail rows against existing shared Calendar sign-ins. Keep each service's cache identity and both sign-ins. Add an acceptance test for this reverse order. The new diagnostic asserts the observed rejection as defect evidence; it is not an acceptance requirement.
Verbatim diagnostic evidence:
Imported test audit and diff risks
No imported integrity assertion was removed or relaxed. Full-column equality still covers all six production-shaped cache tables, with 4,000 messages and 4,018 memberships. The old defect assertions became the behavior explicitly required by #407: successful legacy decrypt, later rows included, and endpoint validation after shared decrypt. The route tests deliberately invalidate the legacy copy, so they cannot pass by using it.
The duplicate-membership fixture changed only its comments and migration registration; its SQL shape is unchanged. Another fixture edit sets the production-shaped folder to completed generation 1 rather than active pending generation 2. Thus the no-refetch test covers a completed live cache. The re-check ordering test retains the original pending generation 2 and compares its full cache rows before and after migration. Pending-generation provider resume is not covered.
#626 remains a dependency. The reviewed
c81cf1dfcwriter still has the removed message-ID conflict target; the imported diagnostic correctly proves that it fails against the new schema. At3286cad72, Mail 0009 and the corrected store adapter are both present. They must ship together. An old image needs its matching Index snapshot after #626, as DESIGN §49 I6 states.A read-only
git merge-treefound conflicts between the two heads in Mail routes, sync, IMAP, cache exports, Plugin code, Mail Settings tests/UI and the benchmark sampler. It did not change the worktree. Keep the shared credential resolver and #626 UID behavior when resolving them. This review did not build a resolved combined tree.The remaining round-4 source diff did not expose another account-integrity blocker. Visual quality remains with the orchestrator. The shared keyboard-motion gap was already reported by the author and is outside this integrity re-check.
Built and files
Only tests and this report were added.
crates/calternal-server/src/integrations_review.rs: four fresh/upgraded migration-order cases and the reverse late-service diagnostic. Existing helpers and imported assertions are reused.crates/calternal-server/tests/review/mail_626_at_3286cad72.sql: byte-for-byte test fixture from the dependency head. It is not registered in production.review-findings.md: verdict, evidence and gates.Atomic test commits:
35cce7c46(ordering) and175723132(late Mail diagnostic). Module and function comments in all touched test files were re-read.Gates
All Cargo commands used
CARGO_PROFILE_DEV_DEBUG=line-tables-only,CARGO_INCREMENTAL=0,CARGO_BUILD_JOBS=4and worktreetarget/tmpasTMPDIR. The presetCARGO_TARGET_DIRwas unchanged.These commands exited 0 with empty stdout and stderr:
cargo fmt --checkrustfmt --edition 2024 --check crates/calternal-server/src/integrations_review.rscargo clippy -p calternal-server --all-targets --quiet -- -D warningscargo clippy -p calternal-plugin-mail --all-targets --quiet -- -D warningscargo test -p calternal-server --quiet -- --test-threads=1, exit 0, complete output verbatim:cargo test -p calternal-plugin-mail --quiet -- --test-threads=1, exit 0, complete output verbatim:cargo test -p calternal-plugin-mail --quiet migrated_production_shape_resumes_without_refetch -- --ignored --test-threads=1 --nocapture, exit 0, complete output verbatim:The focused review round passed nine tests. Verbatim result:
The production Web build passed to supply the Server's embedded assets. No Web source was edited, so Web type/test gates were not repeated. Raw logs remain in
artifacts/recheck/.Known gaps and decisions
Cleanup
Cargo and Web build output and test temporary data were removed. Review artifacts remain in
artifacts/recheck/. Cargo cleanup output, verbatim:Round 5 started on job/integrations at
c81cf1dfcc, base origin/dev687ff70313. The required fetch and merge returned Already up to date. I will import the re-check tests, preserve both service cache identities for Calendar-first migration, isolate each legacy account transaction, and correct the two reported layout defects. No push or deploy.Committed the visual fix as
86dedc347and core migration support as the latest branch commit. Core migration 0011 adds an owner-bound Mail projection map and fixed per-account failure codes without changing any legacy Mail/cache column. cargo fmt --check and calternal-db clippy passed with empty output; calternal-db tests passed (17 unit tests; 16 integration tests, 1 ignored). The reverse-order regression now tests case/whitespace normalization, another User with the same sign-in, retained Calendar and SMTP secrets, shared-AAD Mail decrypt, switches, removal, and reboot idempotence. The old late-statement test expectation is updated only for the explicitly required per-account rollback contract: Mail commits while Calendar rolls back. The perf VM is unreachable (No route to host); measurements will be local.Round 5 integrity fix committed at
e4f13d733. A later Mail sign-in now joins the owner-scoped Connected Account with the same normalized provider sign-in. The original Calendar secret and separate SMTP secret stay in the shared envelope. Mail cache IDs and every legacy account column stay unchanged. Each account commits separately; conflicts retain their rows, report a fixed code with the requesting User's cache ID, and retry on the next boot.The acceptance test also covers trim/case matching, another User with the same sign-in, unrelated account migration, shared-AAD Mail decrypt with an unusable downgrade copy, service switches, removal, and a byte-identical reboot. Imported tests include the exact #626 SQL in both fresh/upgraded orders. No imported cache-integrity assertion was removed. The rejection diagnostic and whole-pass rollback expectation changed only where Round 5 explicitly requires the opposite behavior.
The two initial failures were new fixture errors: a duplicate address inserted before its owner changed, and a non-UUID User ID. Both fixtures are corrected.
Final Server gate output so far, verbatim:
Mail tests, verbatim:
Server and Mail clippy passed with empty output. Calendar gates and the production review build are running. No push or deploy.
Round 5 validation progress at
3c7f9ce1b.Full web gates passed before the final parent-header correction: 149 files, 1,025 tests; svelte-check 0 errors and 0 warnings. The final CSS correction hides the parent Settings sheet title as well as the chooser while nested provider setup is open. The first production capture exposed this second source of ghost text; final matrix is being rebuilt and recaptured.
One time-boxed local adversarial round passed:
Migrated cache resume proof:
Performance VM access failed with No route to host. Local shared-host results (load average [25.58154296875, 24.8310546875, 23.39794921875]): Calendar-first average p50/p95 28.004/30.228 ms, three-worker burst 12.505/16.269 ms. No matching migration baseline exists. CPU and RSS plus production-shape workload results are saved for the final evidence attachment.
Generated action metadata was stale and omitted all five Connected Account APIs. Regenerated contracts/actions.json and docs/parity-matrix.md, as required by DESIGN §41: 338 operations, 320 tools, 0 adapter gaps. No new route or authorization policy. calternal-api gates passed (9 tests); Server gates are rerunning because it embeds this metadata.
Decisions: retain distinct legacy Mail cache IDs through a core owner-bound link; report safe failed account IDs per User; hide parent sheet text during nested setup; restore generated adapter parity. No push, deploy or further merge.
Round 5 completed on job/integrations at
6ad967087b.Base:
c81cf1dfcc. One fetch and merge of origin/dev (687ff70313) completed before final gates: Already up to date. No push or deploy.Built:
47f9814575. Tests cover both installation orders on fresh/upgraded Index schemas, exact cache bytes, mixed-case/space sign-ins, different service secrets, unrelated late accounts, two Users, real Mail consumers, conflict retry and no-op reboot.Files:
Gates:
Cargo environment: CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4, TMPDIR=/target/tmp. Preset CARGO_TARGET_DIR retained. Tests ran one crate at a time.
cargo fmt --checkand per-cratecargo clippy -p <crate> --all-targets --quiet -- -D warningsfor db, server, mail, calendar and api exited 0 with no output. The direct rustfmt check of the included review module also exited 0 with no output. Test output below is verbatim.cargo test -p calternal-db --quiet -- --test-threads=1cargo test -p calternal-server --quiet -- --test-threads=1cargo test -p calternal-plugin-mail --quiet -- --test-threads=1cargo test -p calternal-plugin-calendar --quiet -- --test-threads=1cargo test -p calternal-api --quiet -- --test-threads=1bun run check(web), verbatim:bun run test --maxWorkers=1(web), verbatim summary:API client test output, verbatim summary:
Registry and parity checks, verbatim:
Production web and Server builds exited 0. Final device/theme evidence, verbatim:
One time-boxed local adversarial round (180-second limit), verbatim:
Migrated cache resume proof, verbatim:
Performance:
Decisions:
integration_mail_linkstable retains Mail cache IDs when the Connected Account already has a Calendar ID. Same-ID projections remain compatible. A composite owner-bound foreign key and unique shared service slot prevent cross-User or duplicate links. Migration 11 was free on fetched origin/dev.Known gaps:
Comments were re-read in every changed source file; a stale whole-pass rollback comment was corrected. The imported #626 SQL fixture is byte-for-byte identical to the review branch. No review artifacts are committed.
Cleanup output, verbatim:
Evidence attachments:
Second independent re-check started for #407. Branch: job/integrations-review-round5. Base/reviewed author head:
6ad967087b. One fetch and merge of origin/dev completed: Already up to date. Tests only; verify imported assertions, Calendar-first merge, per-account rollback/retry, reboot, shared credential consumers, downgrade bytes and exact #626 ordering. No push or deploy.Independent Round 5 finding: the original Fastmail Calendar-first merge is fixed, but the new matcher rejects unrelated Other Mail accounts that share a local login name.
Reproduction in
diagnostic_distinct_other_servers_with_same_login_conflict: seed two valid legacy Mail rows for one User, emailreader@alpha.exampleatimap.alpha.exampleand emailreader@beta.exampleatimap.beta.example, both with local loginreader, distinct IDs and creation times. Reconcile twice. Both calls return AccountConflict. Only one Connected Account exists; the second Mail row remains unlinked and has a fixed account_conflict failure entry. All legacy Mail columns remain unchanged.Evidence:
cargo test -p calternal-server --quiet -- --test-threads=1exited 0:test result: ok. 127 passed; 0 failed; 3 ignored; 0 measured; 0 filtered out; finished in 40.05s. The diagnostic asserts the observed defect, not desired acceptance behavior. No existing test expectation changed in this review.Cause: integrations.rs:320-340 loads all shared rows for the User/provider and treats normalized username equality as a match without comparing custom server identity. The Mail service-slot occupancy check then rejects the second unrelated account. Round 4 inserted separate Mail rows and did not apply that matcher to incoming Mail. This violates the required unrelated-account migration contract. Tests-only review: product behavior is unchanged. Final gates and loopback round are still in progress.
Independent second re-check finished. Verdict: NO-GO.
Final head:
cd79e2a660f88ea98c90b52222e9323f5cb92268. Working tree clean. Test changes:48167e0ec3e912535540244e2160aa7c50e52d39; report commit:cd79e2a660f88ea98c90b52222e9323f5cb92268. No push or deploy.#407 second re-check: NO-GO
The original Calendar-first Fastmail defect is fixed. A new matching defect blocks an unrelated Other account. Product code was not changed.
Reviewed author head:
6ad967087b73b523218caa1edc2b7524ba6aca85.Gated test head:
48167e0ec3e912535540244e2160aa7c50e52d39.Branch:
job/integrations-review-round5.The single required fetch and merge used
origin/devat687ff703136e71e89f8dfba139e93cd0788b25c1. Output:Already up to date.No push or deploy.Results
decrypt_account; its AAD uses the shared ID.Required fix
crates/calternal-server/src/integrations.rs:320–340matches every shared account for the User/provider by normalized login. It does not use the custom server to distinguish Other sign-ins. The service-slot check then rejects the second Mail account.The new diagnostic creates valid legacy accounts:
reader@alpha.example, serverimap.alpha.example, loginreader.reader@beta.example, serverimap.beta.example, loginreader.Reconciliation twice returns
AccountConflict. Only one Connected Account exists. The second account remains unlinked and has anaccount_conflictentry. Every legacy Mail column remains unchanged. Round 4 did not apply this shared-account matcher to incoming Mail, so this is new in Round 5.Keep distinct Other server sign-ins separate. Retain the named-provider merge, each service's cache identity and every credential. After the fix, change this diagnostic to require both accounts to migrate and an unchanged reboot. Its current assertions record the defect; they do not define accepted behavior.
Verbatim evidence:
Imported test audit
Compared independent head
47f98145758e51fa36c75774ffd55efb45ce0c21, import1d8d1d6dc, and the reviewed author head. The exact #626 SQL and production-shape SQL fixtures are byte-identical. Full-column equality still covers six cache tables with 4,000 messages and 4,018 memberships. The shared/legacy secret assertions remain.The old reverse-order rejection diagnostic was replaced with
later_mail_merges_with_existing_shared_calendar. Its acceptance checks are stronger. The old whole-pass rollback assertion changed to one committed Mail account because Round 5 explicitly requires per-account isolation. No imported cache-integrity assertion was weakened. This review changed no existing expectation.The source scan checked owner-bound Mail links, shared AAD resolution, toggles, disconnect, sync queue IDs, status failure IDs and UI references to the shared ID. No other new integrity blocker was found. This job adds no migration; fetched
origin/devhas no conflicting core 0011.Built and files
crates/calternal-server/src/integrations_review.rs: two independent tests for repaired credential retry, reopened-Index idempotence, and the distinct-server diagnostic. Reuses existing fixture and snapshot helpers.review-findings.md: this report.Module and function doc comments were re-read. No dependencies or versions changed.
Gates
All Cargo commands used
CARGO_PROFILE_DEV_DEBUG=line-tables-only,CARGO_INCREMENTAL=0,CARGO_BUILD_JOBS=4and worktreetarget/tmpforTMPDIR. The presetCARGO_TARGET_DIRwas retained. Final tests ran one crate at a time. The final snapshot/build runs usedRUSTC_WRAPPER=because the shared sccache server referenced another job's deleted temp directory.These commands exited 0 with empty stdout and stderr:
cargo fmt --checkrustfmt --edition 2024 --check crates/calternal-server/src/integrations_review.rscargo clippy -p calternal-server --all-targets --quiet -- -D warningscargo clippy -p calternal-plugin-mail --all-targets --quiet -- -D warningscargo test -p calternal-server --quiet -- --test-threads=1, exit 0, complete output verbatim:cargo test -p calternal-plugin-mail --quiet -- --test-threads=1, exit 0, complete output verbatim:cargo test -p calternal-server --quiet independent_review -- --test-threads=1 --nocapture (with snapshot directory), exit 0, complete output verbatim:cargo test -p calternal-plugin-mail --quiet migrated_production_shape_resumes_without_refetch -- --ignored --test-threads=1 --nocapture (with snapshot path), exit 0, complete output verbatim:The first ignored resume invocation omitted the snapshot setting. The first snapshot export used a directory that did not exist. Both failed in test setup and passed after the settings and directory were supplied. The first Server build failed in shared sccache with a deleted temp path. Raw attempt logs remain in
artifacts/integrations-recheck/.The production Web build (
bun run --cwd apps/web build) and production Server build (cargo build -p calternal-server --quiet) exited 0. The Server build had empty stdout and stderr.One time-boxed local API round used the production Server and SPA (
timeout 180s bun tests/adversarial/integrations_api.mjs), exit 0. Output verbatim:No additional non-SLOW API finding appeared in this round. It uses inert credentials and no provider sign-in.
Known gaps
Decisions
Reuse the existing fixture helpers. Check no-op boot through an actual close/reopen of the Index. Record the wrong rejection as a diagnostic without changing product behavior. No new product design decision was made.
Cleanup
Cargo output, Web build output, snapshots and test runtime directories were removed. Review logs remain in
artifacts/integrations-recheck/. Cargo cleanup output, verbatim:Starting Round 6 on job/integrations at base/head
6ad967087b. Read the latest NO-GO and review-findings.md atcd79e2a66. I will import the retry/reopened-Index tests and turn the distinct Other server diagnostic into acceptance coverage, then use one endpoint-aware sign-in identity for creation and boot reconciliation. No push or deploy.Finding: the shared account UNIQUE(owner_id, provider, email) also rejects distinct Other endpoints with one email label. Round 6 adds a core schema upgrade that preserves account/credential bytes and saves/restores the owner-bound Mail links while rebuilding the table with foreign keys enabled. Named-provider labels retain their partial unique index. One sign_in_identity function now defines endpoint/login matching for creation and reconciliation. Decision: Other usernames retain case; IMAP and SMTP host/port/login are identity fields; CalDAV host/port/login identifies Calendar. Do not infer identity across distinct Other protocols from a login alone. This explicitly changes legacy_accounts_upgrade_losslessly_and_only_once: its imap.custom.example and dav.custom.example rows now remain separate, with unchanged caches and secrets. The imported diagnostic alone changes from defect-recording rejection to required acceptance; retry/reopened-Index and named-provider Calendar-first tests remain intact.
Progress: committed the endpoint-label schema slice as
9923ccb22. Populated migration preserves encrypted bytes and Mail links, and foreign-key ownership/delete checks pass. cargo fmt --check and cargo clippy -p calternal-db --all-targets --quiet -- -D warnings exited 0 with empty output. Database test output (verbatim result lines): test result: ok. 18 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.22s / test result: ok. 16 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 1.78s. Server clippy also exited 0 with empty output. Web check: svelte-check found 0 errors and 0 warnings. Web test: Test Files 149 passed (149); Tests 1025 passed (1025). The full Server test run is in progress. Perf VM SSH failed with No route to host; measurements will be labelled local.Finding: local performance profile completed with load average 21.12 before and 19.67 after; perf VM was unreachable. Two Other servers p50/p95 migration = 10.124/15.051 ms, worker mean CPU 39.57%, mean RSS 48,846,953 bytes, peak RSS 59,392,000 bytes. Three parallel workers with 250 Other servers each = p50/p95 19,563.384/19,782.577 ms, mean worker CPU 70.73%, mean RSS 58,500,712 bytes, peak RSS 63,467,520 bytes. This reveals quadratic candidate endpoint reads for a large custom-account list; it is a performance limitation, not an integrity failure. There is no corresponding migration metric in docs/perf/baseline.json, so no threshold comparison or regression claim is possible. Raw data: artifacts/integrations-round6/performance.json. Cache migration with 4,000 messages remains p50/p95 7.847/10.814 ms. The documentation audit corrected stale comments about the both-off legacy state, link cascades, and the test-only review module in
bba06d4d1. Final Web gates passed again: 0 diagnostics, 149 files / 1,025 tests. Final Rust gates and the production Server build are in progress.Round 6 implementation complete at
bba06d4d17072f63dc25768a36424c37af898b6aonjob/integrations. No push or deploy. The single fetch/merge usedorigin/devat687ff703136e71e89f8dfba139e93cd0788b25c1:Already up to date.Fetched core migrations end at 0006, so new core 0012 does not collide.Built:
sign_in_identityrule for account creation and boot reconciliation. Named providers use the normalized sign-in address; Other uses protocol hosts, ports and usernames. Distinct Other servers with the same local login both migrate.cd79e2a66; replaced its owner-requested defect diagnostic with acceptance. Added shared-label, endpoint/port/login and creation-matcher isolation coverage. Calendar-first Fastmail, unrelated-account isolation, retained credentials, cache bytes and reboot no-op pass.Files:
Atomic commits:
9923ccb22schema;f3d206997identity and regressions;5bc1c1ce4profile;bba06d4d1comment audit. No dependencies or versions changed. No UI source changed.Gates:
All Cargo commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0, CARGO_BUILD_JOBS=4, worktree target/tmp for TMPDIR, and the preset CARGO_TARGET_DIR. RUSTC_WRAPPER was empty because the previous review found a stale shared sccache temp path.
These commands exited 0 with empty stdout and stderr: cargo fmt --check; rustfmt --edition 2024 --check crates/calternal-server/src/integrations_review.rs; cargo clippy -p calternal-db --all-targets --quiet -- -D warnings; cargo clippy -p calternal-server --all-targets --quiet -- -D warnings. The comment-only audit also passed direct rustfmt checks of the changed Rust files.
cargo test -p calternal-db --quiet -- --test-threads=1, exit 0, complete output verbatim:cargo test -p calternal-server --quiet -- --test-threads=1, exit 0, complete output verbatim:bun run --cwd apps/web check, exit 0, complete output verbatim:bun run --cwd apps/web test --silent --reporter=dot, exit 0, complete output verbatim:Performance (local shared build host, debug test binary): perf VM SSH failed with
No route to host. These are timed migrations; worker CPU/RSS includes fixture setup and verification. No equivalent migration metric exists in docs/perf/baseline.json, so no threshold comparison is possible.Load averages before: [21.1171875, 24.44921875, 24.07861328125]; after: [19.671875, 23.36767578125, 23.7314453125]. Raw data: artifacts/integrations-round6/performance.json.
Decisions:
Known gaps:
Module and changed-function comments were re-read. The audit corrected stale service-switch and projection-deletion descriptions.
Build and one time-boxed local API round:
bun run --cwd apps/web build, exit 0. Build output is in web-build.log.cargo build -p calternal-server --quiet, exit 0, empty stdout and stderr.timeout 180s bun tests/adversarial/integrations_api.mjs, exit 0, complete output verbatim:No additional non-SLOW API finding appeared. The round used the real Server and production Web build, inert credentials, and real owner/member sessions. It performed no provider sign-in.
Cleanup completed: Cargo output and generated Web build directories were removed. Only review logs and performance data remain in artifacts/integrations-round6/; no artifact was committed. Working tree is clean. Cargo cleanup output verbatim:
The issue remains open for independent re-check. No push or deploy.
Third re-check started on review/integrations-407-round6, base
bba06d4d17. Tests-only review of endpoint identity, unchanged prior regressions, core 0012 upgrade and Mail 0009 ordering. No push or deploy.Third re-check evidence: Mail 0009 at
c4a61e8cfis byte-identical to the exact-SQL ordering fixture (cmp exit 0). Compared imported regression function bodies withcd79e2a66: all retained regressions are unchanged. Added test-only host canonicalisation (Unicode/punycode, host case, final dot, ports and case-sensitive Other logins), plus populated core 0011 to 0012 upgrades in both Mail 0009 orders with exact account/link/cache snapshots. cargo fmt --check and Server all-targets Clippy have passed; Server tests are running. Required origin/dev merge returned Already up to date.Tests committed as
8623562e3on review/integrations-407-round6. Final Server gates passed: formatting (empty output), all-targets Clippy with -D warnings, and 131 tests passed / 0 failed / 3 ignored. Core Index tests passed (18 unit tests; 16 integration tests passed, 1 ignored). The ignored Mail resume test and the bounded real-session local contract check remain in progress before the final verdict.GO for #407 Round 6: the third re-check found no new blocker in the reviewed migration and sign-in identity behavior.
Branch:
review/integrations-407-round6. Head:8623562e35dad96413ce79ec5f737abc02dee236.Review base:
bba06d4d17072f63dc25768a36424c37af898b6a.The required fetch and merge of
origin/dev(687ff703136e71e89f8dfba139e93cd0788b25c1) returnedAlready up to date.No push or deploy.Built and files:
crates/calternal-server/src/integrations_review.rs. No production code changed.Confirmed:
cd79e2a66unchanged. Only the already-authorized Round 6 distinct-server acceptance replaced its earlier defect diagnostic.c4a61e8cf090170f35b1bed3350d9de20c83ecd5is byte-identical to the existing fixture (cmp, exit 0).All gates below exited 0. These are verbatim result excerpts; complete logs remain in
artifacts/round6-review/.cargo fmt --check: empty output. The final comment audit also passed formatting with empty output.cargo clippy -p calternal-server --all-targets -- -D warningscargo test -p calternal-servercargo test -p calternal-dbcargo test -p calternal-plugin-mail migrated_production_shape_resumes_without_refetch -- --ignored --nocaptureThe production Web build and
cargo build -p calternal-server --quietexited 0. The Server build produced empty output.One bounded local contract round,
timeout 180s bun tests/adversarial/integrations_api.mjs --contract-only, exited 0. Complete output, verbatim:Known gaps:
c4a61e8cfproduction binary was not tested. This worktree's Mail crate still ships migrations through 0008.Decisions: no new product design decision. Reused the existing fixtures and snapshot helper. Kept the historical #626 fixture name because its SQL matches
c4a61e8cfexactly. No existing test expectation was changed by this re-check.Re-read all module/function doc comments in the touched file. Cleanup removed Cargo output, Web output, the fixture snapshot and test runtime directories. Working tree is clean. Cargo cleanup output, verbatim:
The issue stays open for the orchestrator.
Owner (2026-10-02): no row dividers inside Settings section cards; separate rows by spacing only (shared SettingRow/card component). Folded into the Settings redesign brief.
Starting #407 work on branch job/settings-50, based on job/merge-round-7a at
2f4482ded0.Finding during the Cmd+K access checks: the member Settings index correctly includes
Sync & Backupat/settings/sync-backup, so the old broadbackupsubstring assertion incorrectly treated a User page as Admin content. I changed the guard to assert the actual Admin route is absent and added an assertion for the User page. The access suite also awaited a live/api/v1/searchrequest even though its assertions discard server results; after giving that provider a valid empty test response, the client access suite completed without the timeout/provider leak. Evidence:bunx vitest run --project=unit --reporter=dot src/lib/search/access.test.ts—Test Files 1 passed (1),Tests 5 passed (5).Integration finding: after merging the required
origin/dev(440e19dce) and movedjob/merge-round-7a(efe8323f) branches, neithercontracts/openapi.jsonnorpackages/api-client/src/generated.tscontains/api/v1/shortcuts/preferencesor its initialize route, and the mergedcalternal-serverhas no shortcut preference handler. The retained #542 preset chooser calls those routes.bun run checktherefore ends with 7 errors, all inapps/web/src/lib/shortcuts/preferences.ts, for missing paths and response fields. The separatejob/shortcuts-542branch carries this behavior in the server, CLI and MCP crates; integrating it would change other crates' behavior outside #407's Settings scope. I am continuing the Settings work without adding a local-only fallback and will report the unresolved #542 integration dependency.Copy audit evidence for the Connected Accounts scope in this issue. The current Settings UI still shows provider sign-in forms in Mail and Calendars. The labels also name third-party products and use protocol terms.
apps/web/src/routes/settings/sections.ts:81,87-89: “Calendars”, “Calendar accounts” and “Connect a calendar account”. Provider sign-in belongs under “Connected Accounts”; Calendar settings should keep only calendar preferences and a link to the account.apps/web/src/routes/settings/sections.ts:95,98-99: “Mail”, “Mail accounts” and “Connect a mail account”. Mail settings should keep only mail preferences and a link to the account.apps/web/src/routes/settings/calendars/calendarAccounts.ts:19,26,33: provider choices “iCloud”, “Fastmail” and “Nextcloud”. Replace these visible product names with a generic account choice. Show the User’s account name or email after sign-in.apps/web/src/routes/settings/calendars/calendarAccounts.ts:28-29: “Your Fastmail email address.” and “Make an app password in Fastmail … with calendar (CalDAV) access.” → “Your email address.” and “Create an app password in your account settings, with Calendar access.”apps/web/src/routes/settings/calendars/calendarAccounts.ts:35-36: “Your Nextcloud username.” and “Make an app password in Nextcloud … The server URL ends in /remote.php/dav.” → “Your username.” and “Create an app password in your account settings. Enter your calendar server address.”apps/web/src/routes/settings/calendars/calendarAccounts.ts:66: “point to a CalDAV server” → “use a calendar server address”.apps/web/src/routes/settings/mail/MailSection.svelte:52,60,68: provider labels “Gmail”, “iCloud” and “Fastmail”; line 54 “Your full Gmail address.”; line 62 “Your Apple Account email address.”; lines 70-72 “Your Fastmail email address.” / “Create a Fastmail app password”. Replace with generic account names and help such as “Your full email address” and “Create an app password in your account settings.”apps/web/src/routes/settings/mail/MailSection.svelte:614: “Connect an IMAP account”, “source of truth”, “encrypted app password” and “rebuildable copy” expose protocol and implementation details. Use plain copy about connecting a mail account and what happens to saved mail when it is removed.apps/web/src/routes/settings/mail/MailSection.svelte:633,665,669-676,678,680-681: “IMAP”, “SMTP”, “TLS” and “STARTTLS” appear in help, field labels and choices. Use “Incoming mail server”, “Outgoing mail server”, “Port” and plain secure-connection choices. Keep technical values in the fields only where a custom server needs them.Owner rule: use “Connected Accounts” for provider sign-ins and do not name third-party products in UI copy. DESIGN §49 I1-I2 says a provider account is added once under Connected Accounts; Mail and Calendars keep service preferences and link to that account.
Expected behaviour: one Connected Accounts page owns provider sign-in. The Mail and Calendar pages do not ask for a second sign-in. Visible setup copy uses plain words and no provider product names or protocol acronyms.
Test idea: like a User, add one account, enable its Mail and Calendar services, then open both Settings pages. Check that each page links to the same Connected Account and that visible and screen-reader labels contain no provider name or protocol acronym.
Static audit evidence for DESIGN §§49-50:
Settings still has separate account setup flows. apps/web/src/routes/settings/sections.ts:80-100 registers Calendar accounts / Connect a calendar account and Mail accounts / Connect a mail account as separate pages. The Calendar form asks for provider URL, username and password in apps/web/src/routes/settings/calendars/CalendarsSection.svelte:408-436; Mail loads its own accounts at apps/web/src/routes/settings/mail/MailSection.svelte:86,544.
Expected: one Connected Accounts page signs in once per provider account and enables Mail, Calendar and Contacts there; service pages keep preferences and link back to the account. Regression idea: connect one provider account once, toggle two services, and verify both service views use that account.
More copy evidence for Settings → Apps and Settings → Calendars
Settings → Apps
apps/web/src/routes/settings/apps/AppsSection.svelte:19: row namesAPI,CLI,MCP,WebMCP. Use plain choices such asOther apps,Apps on this device,AI helpers, andThis browser.:21-25:App passwords and external API clients,Installation tokens, including command line clients,Remote AI client tools,Tools available to this browser, andApple Notes sync over IMAP. Use one short description for each task. Remove the protocol and product names.:57-60:Instance app access,App access, and descriptions withclient surfaceandclients. UseAppsand describe which apps can use this User's data or every User's data.Settings → Apps → Calendar feeds
apps/web/src/routes/settings/apps/CalendarFeedsGroup.svelte:60-65: the status can showApple Calendar,Outlook,Google Calendar,Thunderbird, or a raw user-agent string. Use a neutral label such asCalendar app; do not show the raw user-agent string.:160-162:Calendar feeds,Publish a read-only Calendar feed, andPublished calendar feeds. UseShare a calendarand explain that a link lets other people see the selected events.:187-220:No published feeds yet,New feed,Create calendar feed,New Calendar Feed,Source,Area tag,Detail,Full,Busy only,Feed colour, andInclude dated Tasks as Events. Use short task labels, such asNo shared calendars yet,Share a calendar,What to share,Details,Full details, andBusy times only.:213,217,220-221:Anyone with the link can read this feed,webcal links,HTTPS, andWebcal. Use plain text such asAnyone with this link can see these events,Scan with a calendar app to add them,Web link, andCalendar app link.Settings → Calendars → External calendars
apps/web/src/routes/settings/calendars/ExternalCalendarsGroup.svelte:103:Subscribe to an HTTPS or webcal link. The remote Calendar is stored as a read-only layer and is refreshed on its own schedule.SayPaste a calendar link. It appears here, and calternal checks for updates automatically.:105,126,130-131:External calendar subscriptions,No external calendars yet. Add a public Calendar URL below.,Calendar URLwith anhttps://… or webcal://…placeholder, andLayer colour. UseShared calendars,No calendars yet. Add a calendar link below.,Calendar link, andCalendar colour.These are copy defects in the Settings structure covered by #407 and DESIGN §§49–50. The owner rule from 2026-10-02 also says not to name third-party products in the UI.
Test idea: open each group and check its heading, empty state, form, status text, and screen-reader labels. Add and refresh one real calendar link. Confirm that no protocol name, raw user-agent string, or product name appears.
More Mail copy evidence for Settings and the reader
apps/web/src/routes/settings/mail/MailSection.svelte:78-79:The username your mail provider gives you. It defaults to your email address./Use an app password if your mail provider offers one.→Use the sign-in name from your mail account./Use an app password if your mail account offers one.:190:Enter the SMTP username or use the same sign-in for both servers.→Enter the sending account name or use the same sign-in for both mail servers.:222-223:The provider refused the username or app password./The provider could not be reached securely. Check the server settings and try again.→Your mail account did not accept that sign-in. Check the account name and app password./Could not connect to your mail account securely. Check the account settings and try again.:620,632:Choose when opening a message marks it as read at your mail provider.and the screen-reader labelMail provider→Choose when to mark opened messages as read.andMail account.apps/web/src/lib/mail/MailView.svelte:249:The read state could not be saved to the provider.→Could not update this message in your mail account.:544:This message exceeds the cached body limit. The remaining content is unavailable here.→This message is too long to show in full. The rest is not available here.:636:Connect an IMAP account to read Mail.→Connect a mail account to read Mail.Test idea: check each error and empty state. Confirm Mail uses the account in Connected Accounts and does not ask for a second sign-in.
settings-50 report
Status: The implementation is committed on
job/settings-50, but the job is incomplete. The required real-server review and final gates did not finish before the four-hour job cap. Do not treat this report as a merge-ready verification.Head:
1dc1cba58804b03051135eb1f7f4285a2fec41b1Built
Files
apps/web/src/routes/settings/sections.ts,sections.test.ts,[...path]/+page.svelte,api.svelte.ts, and the Settings account/admin/apps/calendars/files/jobs/mail/photos/plugins/shortcuts section files.apps/web/src/lib/search/providers.ts,providers.test.ts,access.svelte.ts,access.test.ts,apps/web/src/lib/shortcuts/*, andapps/web/src/lib/components/KeyboardShortcutsCard.svelte.packages/ui/src/components/SettingRow.svelte,FloatingSidebar.svelte,apps/web/src/lib/components/app-sidebar.svelte, andapps/web/src/routes/settings/parts/AccountList.svelte.apps/web/e2e/settings-review-50.mjs,apps/web/e2e/maintenance-links.mjs,apps/web/package.json, andbench/settings-shortcut.mjs.Gate output
The production web build completed after the Copy link CSS fix:
The earlier
bun run checkintegration pass reported the missing #542 API types. These lines are verbatim from that run; it reported seven errors inapps/web/src/lib/shortcuts/preferences.ts:The targeted Settings registry tests passed:
The local server build was interrupted while still linking under shared-host contention:
Cleanup completed:
The final full
bun run check,bun run test, generated contract check, parity check, production E2E, benchmark run, and adversarial round were not completed. No Rust source or route changed in this job. The full Settings E2E was not run, so the legacy redirects in that script have not been confirmed against a local server.Known gaps and UX gaps left
/api/v1/shortcuts/preferencesor its response fields from #542. The preset chooser remains server-backed and does not have a local-only fallback; it cannot complete until that API change is merged. The earlier type check found seven related errors.1440 /settings/appearance: data-ready p50 1,584 ms, p95 2,069 ms; it is not the same route or workload.UX gaps closed
The implementation adds Copy link controls for Settings destinations and rows, exact shortcut deep links from Cmd+K, real plugin-catalog retry/offline handling, keyboard ordering for Tabs, phone back navigation, and shared row spacing without separators.
Decisions
Mac checks pending
The macOS VM is offline, so it was not contacted. Run
test:e2e:settings-50with the local server and Mac platform emulation, capture the files underartifacts/settings-50/review, inspect every requested viewport/theme and zoom in on icon/label rows, then attach them for visual review.settings-50 verification and finish (branch
job/settings-50, head656d22421)Picks up the verification that was cut at the time limit. Web-only; no Rust changed. Server: prebuilt
merge-round-7adebug binary, run in a private mount namespace so its runtimerust-embedfolder serves this worktree'sapps/web/build.Bugs found and fixed
afterNavigatereadfrom.url.pathname;from.urlis null on the first callback. The throw aborted SvelteKit's callbacks, so Back (button or browser) from a pushed page changed the URL to/settingsbut kept the detail page. Nowfrom?.url?.pathname, andtofalls back topage.url.Kbdhides hint caps on touch devices. A newreferenceprop keeps them visible on this list. Caps now line up with the first line of a wrapped label.segmentvariant needs a PillGroup), and its hover reveal rule came before the hide rule, so hover never showed it. Nowvariant="pill", with the rules in the right order. Calendar feeds, MCP event subscriptions and External Calendars links also use the pill variant now./api/v1/shortcuts/preferences), which is only onjob/shortcuts-542. I removed the preset row, its search labels and the sign-in sync from this branch; #542 adds them back. Also fixed'to' is possibly 'null'.apps-devices,admin/app-access,/settings/tabs/calendar/add) and Title Case (Your Accounts). The review e2e had wrong selectors (phone detail heading, cardaria-busy, dotted IDapp.settings) and pressed Cmd+K before its handler was attached.Maintenance naming: the tree no longer uses "Maintenance". DESIGN §50 names both pages Background Work and S3 says the same name twice is fine at two scopes, so I left both labels as they are.
Gates (verbatim)
Settings open timing
bench/settings-shortcut.mjs(1440,/settings/plugins, 30 runs, shared host with load average about 26): open p50 291 ms, p95 664 ms, mean 348 ms; browser CPU per open p50 495 ms; JS heap 19.3 MB. Burst of 50 Cmd+, presses: 644 ms, Settings stayed open.#sec-activeexists (7 warm opens): 299, 223, 257, 300, 207, 244, 177 ms.Open for review (not changed)
Screenshots: 208 captures (every section at 390/820/1440, light and dark, Mac platform signals) plus 40 review-flow captures, kept locally for the visual review.
Owner decision (2026-10-03): hide per-plugin Settings pages that have no settings for the User; a page appears automatically once a plugin offers at least one setting. Also: cache the plugin list so Tabs/Admin rows don't jump in, and on touch use the swipe Copy link action instead of an icon on every row.
Starting Settings production round on
job/round-settings, basecfee85c6b11537968aaa0685d1ed1c3ac68a8c3e. Integratejob/oneacct-1014(includes Settings §50), resolve against origin/dev, verify Settings and Connected Accounts, and prepare staging evidence. Production is out of scope. Known plugin-list cache and touch Copy link follow-ups remain out of this round.Integration finding:
job/oneacct-1014fast-forwarded fromcfee85c6bto12893025e. The one required origin/dev refresh then merged #724 atc64119671, without conflicts. The Settings slice changes web/UI only. The dev refresh changes calternal-fs, calternal-notes-core, calternal-plugin-notes and calternal-plugin-calendar; these get sequential Rust gates. No changed routes or OpenAPI contract. The staging Users have zero Connected Accounts. Staging smoke will use temporary real API rows, with no API interception; provider login/successful external sync is not claimed.Gate finding: the merged Calendar account heading used
font-weight: 600at CalendarsSection.svelte:381. Full Vitest: 155 files/1091 tests passed, one shared font-weight guard failed. Replaced the numeric value withvar(--weight-semibold)(the same 600 weight). The original assertion is unchanged. Focused guard + Calendar, Mail and Connected Accounts tests: 4 files, 23 tests passed. Production assets rebuilt after this fix.Evidence finding: Settings review initially rendered the prebuilt server’s old embedded UI because the scripts did not call
routeCurrentBuild. Added the existing production-asset helper to the Settings and Connected Accounts review contexts. No test expectations changed. The corrected run captures this branch’s production build at macOS platform signals and all required widths/themes.Staging limitation: both available staging sessions have zero Connected Accounts, and creation requires a successful provider login. A private input-file path was requested; credentials are never requested in chat. Without it, staging can prove real empty states only, and the populated-account smoke remains incomplete.
Final web gates after the Calendar heading-token fix:
Settings #407 review passed at 390/820/1440 in light/dark, including 26 legacy Settings redirects and the Calendar overflow Settings action. Production assets were served with the existing override helper against the prebuilt API server. Notes-plugin tests: 186 passed, 1 ignored (real-server upgrade E2E fixture), plus the integration test passed. Calendar gates and Connected Accounts review are running.
Connected Accounts production UI review passed: 66 macOS-rendered captures across 390/820/1440 light/dark; provider setup, switches, Copy link menus, Mail options, Calendar options and Manage links exercised. The populated UI rows in this local review are test fixtures. Label alignment offsets were 0.0078125–0.015625 px.
Focused real-server contract and two-User isolation check passed:
Calendar Clippy completed successfully. The long-running sequential gate shell was interrupted with exit 143 before it started Calendar tests; the missing
cargo test -p calternal-plugin-calendar -- --test-threads=4is now running separately. The passed commands are not repeated.Local review artifacts are attached to #407 (macOS, all widths/themes). Connected Accounts population uses explicit test fixtures; staging will use only real API rows.
All requested per-crate Rust gates passed.
cargo fmt --checkreturned 0 with no output.cargo clippy -p calternal-fs --all-targets -- -D warningsandcargo test -p calternal-fs -- --test-threads=4:cargo clippy -p calternal-notes-core --all-targets -- -D warningsandcargo test -p calternal-notes-core -- --test-threads=4:cargo clippy -p calternal-plugin-notes --all-targets -- -D warningsandcargo test -p calternal-plugin-notes -- --test-threads=4:cargo clippy -p calternal-plugin-calendar --all-targets -- -D warningsandcargo test -p calternal-plugin-calendar -- --test-threads=4:Staging image build started from
92634987e, with the assigned target, four Cargo jobs, OPENSSL_NO_VENDOR=1 and this worktree’s production web build. It uses the shared existing recipe inscripts/staging-724-build.sh, withCALTERNAL_BUILD_BRANCH=job/round-settings.UX finding in the inherited account contract: ConnectedAccountsSection.svelte disables Mail when it is the account’s last active service;
integrations.rs:update_accountreturns 400 with “Keep at least one service enabled” if both become off. The existing #407 reconciliation notes explicitly retain that rule for new create/update requests. Thus the Mail-off smoke uses an account that also has Calendar enabled, as the inherited #1014 review does. A Mail-only account cannot be paused through its switch. I have not changed this Server behavior in the Settings integration round; it remains a UX gap for owner review.Candidate image built successfully from
92634987e97d428741829706e50f39a6c934afe4:The live XUser runner stopped during setup because it requires
debug/calternal, while the staging recipe builds the CLI inrelease/. The release CLI exists and is the same candidate. Added a target-directory symlink (not repository source) at the expected test location and resumed within the existing 15-minute round budget. No expectations were changed. The completed preparation already confirmed revoked-share and missing-item HTTP 404 profiles match (median delta 0.9 ms, 12 alternating pairs).Settings production round — #407
Head:
dae797a33635374c3ca94f66ea70b3bff362e1fc.Integrated
job/oneacct-1014(includes Settings §50), then merged origin/dev once. The origin/dev refresh also includes #724. No conflicts or contract regeneration were required.Files and changes
apps/web/src/routes/settings/calendars/CalendarsSection.svelte: use the shared semibold token; the numeric-weight guard found this.apps/web/e2e/settings-review-50.mjsandintegrations-review.mjs: use current production assets with a prebuilt API server.apps/web/e2e/staging-settings-407.mjs: real staging data, required widths/themes, service-off consistency, cleanup and preference restoration.scripts/staging-724-build.sh: one image recipe with an explicit job-branch override; the default remains unchanged.tests/adversarial/test_settings_private_inputs.py: test the actual staging entry point with malformed private JSON. The failure output must not include its contents.Gates (verbatim)
cargo fmt --checkexited 0 and emitted no output. Other gate output follows.cargo clippy -p calternal-fs --all-targets -- -D warningsandcargo test -p calternal-fs -- --test-threads=4:cargo clippy -p calternal-notes-core --all-targets -- -D warningsandcargo test -p calternal-notes-core -- --test-threads=4:cargo clippy -p calternal-plugin-notes --all-targets -- -D warningsandcargo test -p calternal-plugin-notes -- --test-threads=4:cargo clippy -p calternal-plugin-calendar --all-targets -- -D warningsandcargo test -p calternal-plugin-calendar -- --test-threads=4:web-check-final.log:web-test-final.log:settings-e2e.log:accounts-e2e.log:accounts-isolation-candidate.log(exact release candidate):xuser-classification.log:Local screenshots
Mac platform signals, 390/820/1440 px, light and dark. Settings review: 40 captures; Connected Accounts review: 66. Connected Account populations in the local UI review are test fixtures; the API isolation test uses real sessions and an inert test-owned row.
UX gaps closed
UX gaps left
Decisions
Release and isolation gates (verbatim)
Production web build:
Staging release build:
The live matrix ran against that release candidate. The first setup attempt found no debug CLI; a symlink in the assigned target directory pointed to the built release CLI. No source or test expectation changed. The matrix completed within its single time-boxed round.
The 25 routes without generic fixture factories are a coverage limit. The focused Connected Accounts test above covers foreign account PATCH/DELETE with a seeded row and real sessions. Provider sync itself was not verified.
python3 -m unittest discover -s tests/adversarial -p test_settings_private_inputs.py:Rust tests ran sequentially with four test threads. The initial gate wrapper stopped after Calendar clippy; only the missing Calendar tests were resumed. The full web suite initially found the numeric font-weight guard; after the token fix, the focused tests and full suite passed. No existing expectations were changed.
Staging
Deployed
localhost/calternal-cloud:staging-92634987eto staging only. Production was not touched. Image build source:92634987e97d428741829706e50f39a6c934afe4. Later commits change only staging test safety and its Python regression test; compiled app/server inputs are identical to the final head.The supplied deployment script was read and used. The staging environment file was verified unchanged. Deployed image identity matches the local image.
Staging smoke produced 24 real-API captures: Settings home, Connected Accounts, Mail and Calendars, each at 390/820/1440 px in light/dark with macOS platform signals. Appearance was restored. Browser error assertions passed. These captures show real empty states; populated local review captures use explicit test fixtures.
This smoke exited 2 to report incomplete coverage. No private provider-input file was supplied. Thus account uniqueness with two real Mail accounts and one CalDAV account, and Mail-off stopping sync on staging, remain unverified.
For the merge round
Complete the populated staging smoke with approved private provider inputs. Use an empty test User and at least one account with both Mail and Calendar enabled. The optional setup removes only accounts it creates and restores preferences:
It must prove each account appears once, service pages contain their options and Manage links, and turning Mail off stops sync. If staging already has the required accounts, omit the input-file variable. Full global e2e and Mac interop remain merge-round scope. Performance measurements were not run because this issue is not about performance, per the final verification policy.
Cleanup and status
Doc comments in changed files were reviewed.
git diff --checkpassed; the worktree is clean. Cargo and web build output were removed; review artifacts remain ignored.Local commits only. No push, no dev/main merge, no production deployment. The job branch contains the requested integration and the single origin/dev refresh.
SETTINGS ROUND READY FOR PRODUCTION: no — the required populated staging smoke remains incomplete.