port: pickers (approved mockup) #853

Closed
kayg wants to merge 18 commits from port/port-pickers into dev
Owner

Ports the approved mockup rounds 8a–8c (block registry behind / and Insert, PR #491) and the [[ / @ / # pickers (T1–T3) into the product. One picker, one key model, one registry.

Size: ~2,100 lines added / 730 removed (about half is tests and spec updates). It is one PR because replacing NotePicker/TagPicker and the CodeMirror list is one interlocked change; core interaction is packages/editor/src/transforms/picker.ts + insert/ + InlinePicker/PickList.

What changed

  • / menu: typing / at the start of a line or after a space opens the glass list under the caret, grouped (Basic, Lists, Links). Narrows as you type (label, other words, letters in order: bllt finds Bullet list). "and/or", "/usr/bin" and http:// stay text. It never opens in code, links, the properties, the title or a table row.
  • One registry feeds / and the Insert sheet. InsertSheet's hardcoded list is gone; it reads the registry and redraws when a block registers late.
  • One picker for /, [[, @, #, replacing CodeMirror autocompletion (which also drops @codemirror/autocomplete from the editor). Rows are PickRows that know what choosing them does. NotePicker.svelte and TagPicker.svelte are deleted: FieldPicker.svelte (a search field over the same PickList) serves Move to…, Link to… and the "+" tag popover.
  • One keyboard model (pickKey): ↑ ↓ (round the ends), Enter, Tab (a tag with tags inside opens it), Esc. The same function drives the list under the caret and the search fields.
  • Touch and phone: mouse lights on movement and chooses on press; a finger taps to choose and drags to scroll (8 px). The list keeps inside the visual viewport, above the keyboard and above the bottom bar, below the caret line or above it when fewer than three rows fit.
  • Links in files stay standard markdown ([Name](<Name.md>)); [[ ]] is never written (e2e asserts it). Missing/unmade/Create/Mentioned-in rows and the # tag rows with counts are as ADR 0040.
  • Day link action: @ limited to days (link-targets.days).

Adding a block (for port-tables)

packages/editor/src/insert/registry.ts, exported from @calternal/editor:

import { registerBlock } from '@calternal/editor'
registerBlock({
  id: 'table', label: 'Table', group: 'Basic', icon: 'table',
  keywords: ['grid', 'rows', 'columns'],
  markdown: '| Column | Column |\n| --- | --- |\n|  |  |',
  caret: 2,            // optional: offset in `markdown` where the caret lands (default: the end)
})

Call it once, from the table module's own load (it does not need this PR's code to be loaded first; registerDefaultBlocks() only adds the built-ins and ids replace). It shows up in / and in the Insert sheet at once. markdown may be a function (the time-log line). The block goes into the empty caret line, or on a new line after it. Optional shortcut (hint chip), badge, pick: { kind, trigger } for picker-starting actions. onBlockActions(fn) is for UIs that list them.

Gates (exact commands, ~/bin/slot, CI=1, --retries=0)

  • packages/editor: bunx tsc --noEmit clean; bunx vitest run 531 passed (new test/picker.test.ts: registry, insert, triggers, keys, links never [[ ]]).
  • apps/web: bunx svelte-check --threshold error 0 errors; vitest 78 passed.
  • Playwright e2e/slash-menu.spec.ts (new), tag-picker, link-suggest, lazy-ui, preload, glass-roots, text-size, phone-targets, sheet-geometry, missing-links with CALTERNAL_BIN=… bunx playwright test <specs> --workers=1 --retries=0: dev-01 Chromium chromium-1440 78 passed / 27 skipped; chromium-390 101 passed + 1 failure (link-suggest, hover lit a row under a resting pointer) fixed in the last commit and rerun at both widths (link-suggest + slash-menu ×2, 48 passed); dev-02 WebKit webkit-1440 78 passed, webkit-390 102 passed. (Server binary: the BM5-era debug build; no backend change.)
  • Phone layout covered at 390 and at 320/360/375/390 (Insert grid).

Typing latency (keypress → paint, Chromium, dev-01)

apps/web/e2e/typing-latency.spec.ts (report only, LATENCY=1, no asserts): 215 keys of prose, 135 keys of look-alikes ("and/or", "issue #12", "a @ b"), and real triggers ([[Ab, #ta, @to, /he). Three interleaved runs, base (origin/dev) vs this branch. dev-01 was at load 21–27 from other jobs, so wall time is noise-bound (p50 140–200 ms both sides, no pattern); the steadier number is main-thread CPU per key (CDP ThreadTime):

prose look-alikes real triggers
base 11.5 / 10.5 / 10.5 ms 11.6 / 10.6 / 11.4 28.1 / 20.4 / 24.8
branch 10.3 / 9.9 / 10.0 19.9* / 11.3 / 10.3 23.5 / 29.0 / 24.2

* one outlier under load; the other two runs match base. No regression on plain prose (slightly lower: no autocompletion extension). Wall p50/p95 are in the run log. Real-trigger cost is dominated by the list render, not by the controller. Open: a quiet-machine run on the perf VMs is worth doing before a train.

Bundle (gzip, vite build, base → branch)

  • first screen (html-referenced js+css): 314,236 → 305,336 B (−8.9 KB: no @codemirror/autocomplete)
  • all js+css: 460,562 → 453,797 B (−6.8 KB); idle chunk +1.6 KB (picker list + registry UI), loaded when the editor has been idle or on the first /.

Screenshots

Product vs mockup pairs at 1440×900 and 390×844 on the control host: ~/Developer/Worktrees/shots/port-pickers/ ({product,mockup}-{slash,slash-li,note-picker,at-picker,tag-picker,insert-sheet}-{1440,390}.png).

Decisions

  • No [[ ]] in files; Tab takes a row like Enter (a tag with tags inside opens it); ↑ ↓ wrap.
  • The picker stays open through changes that are not typing (the note is tidied by the app right after a keystroke) when the words it completes are unchanged, following them if text above moves; paste, undo and other devices never open it.
  • Move to… / Link to… keep their sheet with a search field (there is no text to type into), but it is the same list and keys as the one under the caret.
  • Registry stores plain markdown + caret offset (not block types), so any area can add a block without touching the editor.

Not ported (and why)

  • Embeds / Media / ![[, Link | Embed switch, › parts: the product has no embed block yet (they come with attachments/embeds). The registry's Embeds and Media groups exist; nothing registers in them.
  • Note box (callout): no callout block in the product. Table: port-tables registers it.
  • Chip caret (chip-caret.ts): the drawn caret inside a link chip; the product's links are not chips yet (ADR 0040 look is already in cm-links). Not part of the pickers.
  • Block search inside [[ (blocks of notes, from the palette provider): the product's link ranking has no block provider.
  • Day link offers existing day notes only (no create-on-pick for a day that has no note).
  • The list's "settle" glide on touch is ported; the Link|Embed pill spring is not (no switch).

Risks

  • Typing-path numbers above are from a loaded machine; confirm on perf VMs.
  • WebKit on a real iPhone keyboard (visual viewport shifts) is only covered by the mockup's math ported as-is; needs a device pass.

Update (head 2b3f5001): quiet-machine latency, final sweeps, phone #

Latency on perf-01 (4 vCPU, ~/bin/perf-lock per run, release server f087aa1f… for both sides, vite build of origin/dev vs this branch relayed from dev-01 with sha256 check; Chromium, Home of 1,000 notes; per key: main-thread CPU (CDP ThreadTime) and keydown→next frame p50/p95; every scenario at full speed (x1) and CPU slowed 4x (x4); 6 interleaved rounds, order alternating, medians [min–max]; harness apps/web/perf/pickers-typing.perf.ts, summary files in shots/port-pickers/perf-ab-perf01.txt):

scenario (CPU ms/key, median) base x1 → branch x1 base x4 → branch x4
prose, ordinary note 5.44 → 5.54 (+2%) 62.7 → 62.6 (−0.3%)
prose, middle of a 2,000-line note 25.9 → 26.8 (+3%) 142.7 → 146.8 (+3%)
look-alikes ("and/or", "#12", "a @ b", "http://x") 5.84 → 5.84 (0%) 63.8 → 64.0 (+0.2%)

Latency p50/p95 on those three: equal within noise (p50 48–57 ms both sides; p95 90–142 ms both; ±5%, ranges overlap). No regression on plain typing, in a long note, or on look-alikes. (The 2,000-line note at x4 has 11–14 s outliers in a few runs on BOTH builds (base 3/6 in the first session, 1–2/6 in the second); a pre-existing stall of the long note under 4x, not from this branch.)

While a list is open (the trigger typed through three times, Esc each time; CPU ms/key, x1 / x4):
[[: 12.3 → 12.8 (+4%) / 89.2 → 93.0 (+4%) · #: 11.5 → 15.3 (+33%) / 95.6 → 95.1 (−0.5%) · @: 13.8 → 15.9 (+15%) / 97.0 → 104.7 (+8%) · /: 12.9 → 15.6 (+21%) / 95.2 → 100.2 (+5%; the base has no / menu to open, so this one is a new feature's cost, not a regression).
p50 with a list open: [[ x4 58 vs 74 ms (better), # x4 74 vs 73, @ x4 75 vs 65, p95 mixed (−39% … +22%) with wide ranges. Open item, honest: with a list open the branch spends about 2–4 ms more CPU per key at full speed than CodeMirror's own tooltip did (about +5% under 4x slowdown), while latency percentiles are within noise. I cut the per-key layout work in InlinePicker (no re-measuring while the trigger stays; first session before that cut showed +12–25% on the combined trigger scenario) and the second session above is after it. A sampled CPU profile (25 open/close cycles of @to) was too noisy on the loaded dev VM to name one function. If this is not acceptable for the train, the next step is keeping the list's shell mounted between opens.

Sweeps on 2b3f5001 (specs: slash-menu, tag-picker, link-suggest, lazy-ui, preload, glass-roots, glass, text-size, phone-targets, sheet-geometry, missing-links, editor, vim, links-parity, touch-select, block-no-text-sel; CI=1 --retries=0 --workers=1, through ~/bin/slot): dev-01 chromium-1440 116 passed / 1 failed (missing-links:380, a 0.67 px layout tolerance on the card buttons; 5/5 on rerun), chromium-390 139 passed / 1 failed (touch-select:163, timing; passed on rerun); dev-02 webkit-1440 113 passed, webkit-390 137 passed. The first sweep on the previous commit had two other flakes (a trace-directory race caused by my own parallel job, and one WebKit glass-roots timeout); both passed 18/18 and 60/60 on rerun. Unit: editor 531, web 78, tsc/svelte-check clean.

Phone # at 390 (shots/port-pickers/): product-tag-picker-390.png (counts at the right, same rows as the mockup's) and product-tag-picker-low-390.png (a 390×520 window, caret on the last line: the list opens above the line and stays clear of the bar). In that synthetic window there is no real keyboard to scroll the last line above the bar, so that line sits under the bar; the list itself is placed correctly.

Budget (kayg approved, 2026-11-08 08:20 IST): kayg approved raising the lazy budget total, up to 543.9 KiB. perf/budgets.json in this PR sets each named lazy line to the largest size measured over the 17 approved ports after trimming (rounded up to 0.01 KiB) and the total to the sum of the lines (543.25 KiB). The same file is in the first PR of every stack, so whichever merges first carries it. First paint is judged separately and has not been raised.

Ports the approved mockup rounds 8a–8c (block registry behind `/` and Insert, PR #491) and the `[[` / `@` / `#` pickers (T1–T3) into the product. One picker, one key model, one registry. **Size:** ~2,100 lines added / 730 removed (about half is tests and spec updates). It is one PR because replacing `NotePicker`/`TagPicker` and the CodeMirror list is one interlocked change; core interaction is `packages/editor/src/transforms/picker.ts` + `insert/` + `InlinePicker`/`PickList`. ## What changed - **`/` menu**: typing `/` at the start of a line or after a space opens the glass list under the caret, grouped (Basic, Lists, Links). Narrows as you type (label, other words, letters in order: `bllt` finds Bullet list). "and/or", "/usr/bin" and `http://` stay text. It never opens in code, links, the properties, the title or a table row. - **One registry feeds `/` and the Insert sheet.** `InsertSheet`'s hardcoded list is gone; it reads the registry and redraws when a block registers late. - **One picker for `/`, `[[`, `@`, `#`**, replacing CodeMirror `autocompletion` (which also drops `@codemirror/autocomplete` from the editor). Rows are `PickRow`s that know what choosing them does. `NotePicker.svelte` and `TagPicker.svelte` are deleted: `FieldPicker.svelte` (a search field over the same `PickList`) serves Move to…, Link to… and the "+" tag popover. - **One keyboard model** (`pickKey`): ↑ ↓ (round the ends), Enter, Tab (a tag with tags inside opens it), Esc. The same function drives the list under the caret and the search fields. - **Touch and phone**: mouse lights on movement and chooses on press; a finger taps to choose and drags to scroll (8 px). The list keeps inside the visual viewport, above the keyboard and above the bottom bar, below the caret line or above it when fewer than three rows fit. - Links in files stay standard markdown (`[Name](<Name.md>)`); `[[ ]]` is never written (e2e asserts it). Missing/unmade/Create/Mentioned-in rows and the `#` tag rows with counts are as ADR 0040. - `Day link` action: `@` limited to days (`link-targets.days`). ## Adding a block (for port-tables) `packages/editor/src/insert/registry.ts`, exported from `@calternal/editor`: ```ts import { registerBlock } from '@calternal/editor' registerBlock({ id: 'table', label: 'Table', group: 'Basic', icon: 'table', keywords: ['grid', 'rows', 'columns'], markdown: '| Column | Column |\n| --- | --- |\n| | |', caret: 2, // optional: offset in `markdown` where the caret lands (default: the end) }) ``` Call it once, from the table module's own load (it does not need this PR's code to be loaded first; `registerDefaultBlocks()` only adds the built-ins and ids replace). It shows up in `/` and in the Insert sheet at once. `markdown` may be a function (the time-log line). The block goes into the empty caret line, or on a new line after it. Optional `shortcut` (hint chip), `badge`, `pick: { kind, trigger }` for picker-starting actions. `onBlockActions(fn)` is for UIs that list them. ## Gates (exact commands, `~/bin/slot`, CI=1, --retries=0) - `packages/editor`: `bunx tsc --noEmit` clean; `bunx vitest run` 531 passed (new `test/picker.test.ts`: registry, insert, triggers, keys, links never `[[ ]]`). - `apps/web`: `bunx svelte-check --threshold error` 0 errors; vitest 78 passed. - Playwright `e2e/slash-menu.spec.ts` (new), `tag-picker`, `link-suggest`, `lazy-ui`, `preload`, `glass-roots`, `text-size`, `phone-targets`, `sheet-geometry`, `missing-links` with `CALTERNAL_BIN=… bunx playwright test <specs> --workers=1 --retries=0`: dev-01 Chromium `chromium-1440` 78 passed / 27 skipped; `chromium-390` 101 passed + 1 failure (link-suggest, hover lit a row under a resting pointer) fixed in the last commit and rerun at both widths (link-suggest + slash-menu ×2, 48 passed); dev-02 WebKit `webkit-1440` 78 passed, `webkit-390` 102 passed. (Server binary: the BM5-era debug build; no backend change.) - Phone layout covered at 390 and at 320/360/375/390 (Insert grid). ## Typing latency (keypress → paint, Chromium, dev-01) `apps/web/e2e/typing-latency.spec.ts` (report only, `LATENCY=1`, no asserts): 215 keys of prose, 135 keys of look-alikes ("and/or", "issue #12", "a @ b"), and real triggers (`[[Ab`, `#ta`, `@to`, `/he`). Three interleaved runs, base (`origin/dev`) vs this branch. dev-01 was at load 21–27 from other jobs, so wall time is noise-bound (p50 140–200 ms both sides, no pattern); the steadier number is main-thread CPU per key (CDP `ThreadTime`): | | prose | look-alikes | real triggers | |---|---|---|---| | base | 11.5 / 10.5 / 10.5 ms | 11.6 / 10.6 / 11.4 | 28.1 / 20.4 / 24.8 | | branch | 10.3 / 9.9 / 10.0 | 19.9* / 11.3 / 10.3 | 23.5 / 29.0 / 24.2 | \* one outlier under load; the other two runs match base. No regression on plain prose (slightly lower: no autocompletion extension). Wall p50/p95 are in the run log. Real-trigger cost is dominated by the list render, not by the controller. **Open:** a quiet-machine run on the perf VMs is worth doing before a train. ## Bundle (gzip, `vite build`, base → branch) - first screen (html-referenced js+css): 314,236 → 305,336 B (−8.9 KB: no `@codemirror/autocomplete`) - all js+css: 460,562 → 453,797 B (−6.8 KB); idle chunk +1.6 KB (picker list + registry UI), loaded when the editor has been idle or on the first `/`. ## Screenshots Product vs mockup pairs at 1440×900 and 390×844 on the control host: `~/Developer/Worktrees/shots/port-pickers/` (`{product,mockup}-{slash,slash-li,note-picker,at-picker,tag-picker,insert-sheet}-{1440,390}.png`). ## Decisions - No `[[ ]]` in files; Tab takes a row like Enter (a tag with tags inside opens it); ↑ ↓ wrap. - The picker stays open through changes that are not typing (the note is tidied by the app right after a keystroke) when the words it completes are unchanged, following them if text above moves; paste, undo and other devices never open it. - Move to… / Link to… keep their sheet with a search field (there is no text to type into), but it is the same list and keys as the one under the caret. - Registry stores plain markdown + caret offset (not block types), so any area can add a block without touching the editor. ## Not ported (and why) - **Embeds / Media / `![[`, Link | Embed switch, `›` parts**: the product has no embed block yet (they come with attachments/embeds). The registry's `Embeds` and `Media` groups exist; nothing registers in them. - **Note box (callout)**: no callout block in the product. **Table**: port-tables registers it. - **Chip caret** (`chip-caret.ts`): the drawn caret inside a link chip; the product's links are not chips yet (ADR 0040 look is already in `cm-links`). Not part of the pickers. - **Block search inside `[[`** (blocks of notes, from the palette provider): the product's link ranking has no block provider. - Day link offers existing day notes only (no create-on-pick for a day that has no note). - The list's "settle" glide on touch is ported; the Link|Embed pill spring is not (no switch). ## Risks - Typing-path numbers above are from a loaded machine; confirm on perf VMs. - WebKit on a real iPhone keyboard (visual viewport shifts) is only covered by the mockup's math ported as-is; needs a device pass. --- ## Update (head `2b3f5001`): quiet-machine latency, final sweeps, phone `#` **Latency on perf-01** (4 vCPU, `~/bin/perf-lock` per run, release server `f087aa1f…` for both sides, `vite build` of `origin/dev` vs this branch relayed from dev-01 with sha256 check; Chromium, Home of 1,000 notes; per key: main-thread CPU (CDP `ThreadTime`) and keydown→next frame p50/p95; every scenario at full speed (x1) and CPU slowed 4x (x4); 6 interleaved rounds, order alternating, medians [min–max]; harness `apps/web/perf/pickers-typing.perf.ts`, summary files in `shots/port-pickers/perf-ab-perf01.txt`): | scenario (CPU ms/key, median) | base x1 → branch x1 | base x4 → branch x4 | |---|---|---| | prose, ordinary note | 5.44 → 5.54 (+2%) | 62.7 → 62.6 (−0.3%) | | prose, middle of a 2,000-line note | 25.9 → 26.8 (+3%) | 142.7 → 146.8 (+3%) | | look-alikes ("and/or", "#12", "a @ b", "http://x") | 5.84 → 5.84 (0%) | 63.8 → 64.0 (+0.2%) | Latency p50/p95 on those three: equal within noise (p50 48–57 ms both sides; p95 90–142 ms both; ±5%, ranges overlap). **No regression on plain typing, in a long note, or on look-alikes.** (The 2,000-line note at x4 has 11–14 s outliers in a few runs on BOTH builds (base 3/6 in the first session, 1–2/6 in the second); a pre-existing stall of the long note under 4x, not from this branch.) While a list is open (the trigger typed through three times, Esc each time; CPU ms/key, x1 / x4): `[[`: 12.3 → 12.8 (+4%) / 89.2 → 93.0 (+4%) · `#`: 11.5 → 15.3 (+33%) / 95.6 → 95.1 (−0.5%) · `@`: 13.8 → 15.9 (+15%) / 97.0 → 104.7 (+8%) · `/`: 12.9 → 15.6 (+21%) / 95.2 → 100.2 (+5%; the base has no `/` menu to open, so this one is a new feature's cost, not a regression). p50 with a list open: `[[` x4 58 vs 74 ms (better), `#` x4 74 vs 73, `@` x4 75 vs 65, p95 mixed (−39% … +22%) with wide ranges. **Open item, honest:** with a list open the branch spends about 2–4 ms more CPU per key at full speed than CodeMirror's own tooltip did (about +5% under 4x slowdown), while latency percentiles are within noise. I cut the per-key layout work in `InlinePicker` (no re-measuring while the trigger stays; first session before that cut showed +12–25% on the combined trigger scenario) and the second session above is after it. A sampled CPU profile (25 open/close cycles of `@to`) was too noisy on the loaded dev VM to name one function. If this is not acceptable for the train, the next step is keeping the list's shell mounted between opens. **Sweeps on `2b3f5001`** (specs: slash-menu, tag-picker, link-suggest, lazy-ui, preload, glass-roots, glass, text-size, phone-targets, sheet-geometry, missing-links, editor, vim, links-parity, touch-select, block-no-text-sel; `CI=1 --retries=0 --workers=1`, through `~/bin/slot`): dev-01 `chromium-1440` 116 passed / 1 failed (`missing-links:380`, a 0.67 px layout tolerance on the card buttons; 5/5 on rerun), `chromium-390` 139 passed / 1 failed (`touch-select:163`, timing; passed on rerun); dev-02 `webkit-1440` 113 passed, `webkit-390` 137 passed. The first sweep on the previous commit had two other flakes (a trace-directory race caused by my own parallel job, and one WebKit `glass-roots` timeout); both passed 18/18 and 60/60 on rerun. Unit: editor 531, web 78, `tsc`/`svelte-check` clean. **Phone `#` at 390** (`shots/port-pickers/`): `product-tag-picker-390.png` (counts at the right, same rows as the mockup's) and `product-tag-picker-low-390.png` (a 390×520 window, caret on the last line: the list opens above the line and stays clear of the bar). In that synthetic window there is no real keyboard to scroll the last line above the bar, so that line sits under the bar; the list itself is placed correctly. **Budget (kayg approved, 2026-11-08 08:20 IST):** kayg approved raising the lazy budget total, up to 543.9 KiB. `perf/budgets.json` in this PR sets each named lazy line to the largest size measured over the 17 approved ports after trimming (rounded up to 0.01 KiB) and the total to the sum of the lines (543.25 KiB). The same file is in the first PR of every stack, so whichever merges first carries it. First paint is judged separately and has not been raised.
kayg added 18 commits 2026-11-02 10:33:43 +00:00
One framework-free registry feeds the / menu and the Insert sheet. The CodeMirror
autocompletion list is replaced by one picker controller (/, [[, @, #) with one key
model, drawn by InlinePicker + PickList.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
PickList: same rule for pointerover
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
29c435fd6b
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Owner

housekeeping #1009: rebased+failing, left open for review.

rebased shared field picker, retaining dev lazy code, CSS, toolbar, and picker chunk behavior. phone Attach now uses the shared editor blockById/insertBlockAction API.

head: d4554835fa2ef0e26b5615e285eea35e7f44d753; based on dev cd7f84432febfc63b788fbb9b9f9950452982d74, pushed with the original exact force-with-lease.

frontend frozen install, check, lint, build and unit tests passed. bundle gate failed. first-paint brotli vs dev: JS 231679 B (+902 B), CSS 18386 B (+0 B).

targeted Chromium and WebKit specs at 1440 and 390 never started. the audit waited more than three hours behind the live daily-train-1107 locks (first queue at 23:45 IST, 7 November; final queue cleanup after 02:46 IST, 8 November). browser validation and UI captures are unrun. only this audit’s exact queued units were stopped; the train locks and owners were left intact. hot-path perf qualification is unrun.

all executed gates used the VM Nix environment, shared Mac lock and slot. exact commands, source heads, logs and dev baseline. frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head.

original-head cherry/patch inventory, pr-853.md; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above.

final queue, cleanup and source-verification evidence.

housekeeping #1009: rebased+failing, left open for review. rebased shared field picker, retaining dev lazy code, CSS, toolbar, and picker chunk behavior. phone Attach now uses the shared editor blockById/insertBlockAction API. head: `d4554835fa2ef0e26b5615e285eea35e7f44d753`; based on dev `cd7f84432febfc63b788fbb9b9f9950452982d74`, pushed with the original exact force-with-lease. frontend frozen install, check, lint, build and unit tests passed. bundle gate failed. first-paint brotli vs dev: JS 231679 B (+902 B), CSS 18386 B (+0 B). targeted Chromium and WebKit specs at 1440 and 390 never started. the audit waited more than three hours behind the live daily-train-1107 locks (first queue at 23:45 IST, 7 November; final queue cleanup after 02:46 IST, 8 November). browser validation and UI captures are unrun. only this audit’s exact queued units were stopped; the train locks and owners were left intact. hot-path perf qualification is unrun. all executed gates used the VM Nix environment, shared Mac lock and slot. [exact commands, source heads, logs and dev baseline](https://git.kayg.org/attachments/870a0fef-2e31-425c-aea6-eb87a66d365a). frontend inputs are identical to the tested frontend tree when a Rust-only repair changed the head. [original-head cherry/patch inventory](https://git.kayg.org/attachments/e05a38dc-c028-4d77-8655-efa9d5c8ea50), `pr-853.md`; unmatched entries are missing-patch candidates, with semantic overlap/replacements noted above. [final queue, cleanup and source-verification evidence](https://git.kayg.org/attachments/7ab315a5-4b6c-4af1-971b-cdae2637adae).
Author
Owner

Final-port test pass (issue #1009), READY: no: specs pass; bundle gate fails; first paint is bigger than dev.

head d4554835fa2ef0e26b5615e285eea35e7f44d753

Targeted specs, CI=1 --retries=0 --workers=1, dev-01 Chromium and dev-02 WebKit (through ~/bin/slot), against a dev-head backend (cd7f84432).

spec Chromium 1440 Chromium 390 WebKit 1440 WebKit 390
glass-roots, glass, lazy-ui, link-suggest, preload, slash-menu, tag-picker, typing-latency 57/57 60/60 57/57 60/60

Bundle gate: perf/web.sh --bundle-only --gate (the 17 failures from the housekeeping audit). Per the gate's own rule (total_js_brotli budget must equal the sum of the named chunk budgets) a cap can only move between named chunks; there is no donor chunk inside this PR, so a fix is a code cut or a decision by kayg. I raised nothing and moved nothing.

  • idle-screens 52.71 vs 51.8. First paint JS +902 B vs dev (rule: <= dev). It touches typing (pickers): the perf ABAB x5 for typing is required and not done.

Not done: Not run yet: Mac VM Safari blur/frame check and perf ABAB x5 on the perf VMs (they need a ready PR first); light/dark 2x screenshots against the mockup are only done for #888 (see its comment).

Not marked READY FOR MERGE.

**Final-port test pass (issue #1009), READY: no: specs pass; bundle gate fails; first paint is bigger than dev.** head `d4554835fa2ef0e26b5615e285eea35e7f44d753` Targeted specs, `CI=1 --retries=0 --workers=1`, dev-01 Chromium and dev-02 WebKit (through `~/bin/slot`), against a dev-head backend (`cd7f84432`). | spec | Chromium 1440 | Chromium 390 | WebKit 1440 | WebKit 390 | |---|---|---|---|---| | glass-roots, glass, lazy-ui, link-suggest, preload, slash-menu, tag-picker, typing-latency | 57/57 | 60/60 | 57/57 | 60/60 | **Bundle gate:** `perf/web.sh --bundle-only --gate` (the 17 failures from the housekeeping audit). Per the gate's own rule (`total_js_brotli` budget must equal the sum of the named chunk budgets) a cap can only move between named chunks; there is no donor chunk inside this PR, so a fix is a code cut or a decision by kayg. I raised nothing and moved nothing. - `idle-screens` 52.71 vs 51.8. First paint JS +902 B vs dev (rule: <= dev). It touches typing (pickers): the perf ABAB x5 for typing is required and not done. **Not done:** Not run yet: Mac VM Safari blur/frame check and perf ABAB x5 on the perf VMs (they need a ready PR first); light/dark 2x screenshots against the mockup are only done for #888 (see its comment). Not marked READY FOR MERGE.
Author
Owner

Screenshots and state (issue #1009), b5f66d2844

READY FOR MERGE (issue #1009), b5f66d2844

gate result
first paint JS 229512 B: -1643 B (plain) / 229440 B: -1182 B (normalised)
first paint CSS 18371 B: +0
specs, Chromium + WebKit, 1440 + 390 124 passed, 13 skipped (the dev failures aside)
perf/web.sh --bundle-only --gate passes (budget: this stack's lines at measured sizes, kayg's approval; total in merge order stays under 543.9 KiB)
perf ABAB x5 + control below
screenshots 2x, light + dark, 1440 + 390; real Safari below / in this thread

First paint. Plain build vs dev (231155 B JS / 18371 B CSS): 229512 B: -1643 B. Hash-normalised vs dev (230622 B): 229440 B: -1182 B. CSS: 18371 B: +0. Dev itself fails five phone specs after #1014 on Chromium and WebKit at 390 (glass:76, lazy-ui:70, preload:89 x3); they fail the same way on this PR's head and are not caused by it.

Perf (perf-02, Chromium 4x CPU slowdown, 10k Home, release dev server for every arm, rotated rounds, 5 rounds; devA/devB are the same dev build, the control). Median of the 5 per-run medians [min-max], ms; taken on the previous dev (this PR's picker code changed only by the install fix since):

metric devA devB (control) #853
typing, long note p50 22.3 [22.1-22.6] 22.4 [21.8-23.4] 22.5 [21.3-34.4]
typing, long note CPU/key 26.9 27.4 26.8
typing, nested list p50 42.2 42.4 41.7
typing, nested list CPU/key 49.1 49.8 49.1
open note, shown p50 35.0 35.3 34.0
list flick, CPU 70.8 75.4 74.7

Everything sits inside the dev-vs-dev control.
Found by the Safari shots and fixed: on a cold page load in real Safari the /, [[, @, # list never opened in the first editor (the picker's install was remembered per editor, but a note's text replacing the preview rebuilds the editor's plugins, so a load finished after the rebuild marked the editor installed and the live picker never installed). It is keyed per compartment now, with a unit test that fails without the fix. Cold-load check in real Safari on fresh origins, no retry: / 4 of 4, [[ 4 of 4, # 4 of 4, @ 3 of 4 (then 8 of 8 on fresh origins; the one miss is not explained).

Differences from the mockup: the product's Insert sheet has no Table, Note box or Media tiles (Table comes with #845; the others are later ports) and no title bar; the product's [[/@ list has no Link | Embed switch and no Blocks section; the product's tag list has its own (smaller) counts and sits under the caret where the mockup's sits right of it; the slash list has no Table or Note box rows.

Screenshots (2x; light and dark; 1440x900 and 390x844). Left: the approved mockup (review/calendar-2). Right: this PR.

slash

mockup this PR
1440 light
1440 dark
390 light
390 dark

insert-sheet

mockup this PR
1440 light
1440 dark
390 light
390 dark

note-picker

mockup this PR
1440 light
1440 dark
390 light
390 dark

at-picker

mockup this PR
1440 light
1440 dark
390 light
390 dark

tag-picker

mockup this PR
1440 light
1440 dark
390 light
390 dark

Real Safari (Mac VM, safaridriver, 1x: the VM reports devicePixelRatio 1)

slash

light dark
1440
390

insert-sheet

light dark
1440
390

note-picker

light dark
1440
390

at-picker

light dark
1440
390

tag-picker

light dark
1440
390

Real Safari on the fixed head b5f66d284 (Mac VM, 1x). This supersedes the set above, which was taken before the fix: in it the pickers had to be retried because of a bug found by taking these shots (the picker lost its install when the editor was rebuilt while its code was loading; fixed, with a unit test that fails without the fix). Cold-load check on fresh origins, no retry: / 4 of 4, [[ 4 of 4, # 4 of 4, @ 3 of 4 (then 8 of 8 on fresh origins; the one miss is not explained).

slash

light dark
1440
390

insert-sheet

light dark
1440
390

note-picker

light dark
1440
390

at-picker

light dark
1440
390

tag-picker

light dark
1440
390
**Screenshots and state (issue #1009), b5f66d2844dd89cb517e6ad1f41fc074b4c84600** **READY FOR MERGE (issue #1009), b5f66d2844dd89cb517e6ad1f41fc074b4c84600** | gate | result | |---|---| | first paint JS | 229512 B: -1643 B (plain) / 229440 B: -1182 B (normalised) | | first paint CSS | 18371 B: +0 | | specs, Chromium + WebKit, 1440 + 390 | 124 passed, 13 skipped (the dev failures aside) | | `perf/web.sh --bundle-only --gate` | passes (budget: this stack's lines at measured sizes, kayg's approval; total in merge order stays under 543.9 KiB) | | perf ABAB x5 + control | below | | screenshots 2x, light + dark, 1440 + 390; real Safari | below / in this thread | **First paint.** Plain build vs dev (231155 B JS / 18371 B CSS): 229512 B: -1643 B. Hash-normalised vs dev (230622 B): 229440 B: -1182 B. CSS: 18371 B: +0. Dev itself fails five phone specs after #1014 on Chromium and WebKit at 390 (`glass:76`, `lazy-ui:70`, `preload:89` x3); they fail the same way on this PR's head and are not caused by it. **Perf (perf-02, Chromium 4x CPU slowdown, 10k Home, release dev server for every arm, rotated rounds, 5 rounds; `devA`/`devB` are the same dev build, the control).** Median of the 5 per-run medians [min-max], ms; taken on the previous dev (this PR's picker code changed only by the install fix since): | metric | devA | devB (control) | #853 | |---|---|---|---| | typing, long note p50 | 22.3 [22.1-22.6] | 22.4 [21.8-23.4] | 22.5 [21.3-34.4] | | typing, long note CPU/key | 26.9 | 27.4 | 26.8 | | typing, nested list p50 | 42.2 | 42.4 | 41.7 | | typing, nested list CPU/key | 49.1 | 49.8 | 49.1 | | open note, shown p50 | 35.0 | 35.3 | 34.0 | | list flick, CPU | 70.8 | 75.4 | 74.7 | Everything sits inside the dev-vs-dev control. **Found by the Safari shots and fixed:** on a cold page load in real Safari the `/`, `[[`, `@`, `#` list never opened in the first editor (the picker's install was remembered per editor, but a note's text replacing the preview rebuilds the editor's plugins, so a load finished after the rebuild marked the editor installed and the live picker never installed). It is keyed per compartment now, with a unit test that fails without the fix. Cold-load check in real Safari on fresh origins, no retry: `/` 4 of 4, `[[` 4 of 4, `#` 4 of 4, `@` 3 of 4 (then 8 of 8 on fresh origins; the one miss is not explained). Differences from the mockup: the product's Insert sheet has no Table, Note box or Media tiles (Table comes with #845; the others are later ports) and no title bar; the product's `[[`/`@` list has no Link | Embed switch and no Blocks section; the product's tag list has its own (smaller) counts and sits under the caret where the mockup's sits right of it; the slash list has no Table or Note box rows. ### Screenshots (2x; light and dark; 1440x900 and 390x844). Left: the approved mockup (review/calendar-2). Right: this PR. **slash** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/aeacf2d2-1cbf-4123-80b0-a414a57bf9b6) | ![](https://git.kayg.org/attachments/0955e881-11a2-4bc6-bfdb-7f9116536d46) | | 1440 dark | ![](https://git.kayg.org/attachments/d2620083-898a-4444-8754-ddf6903c1891) | ![](https://git.kayg.org/attachments/667435c5-b983-4eac-afe2-1672f65d06aa) | | 390 light | ![](https://git.kayg.org/attachments/727dcf45-e6d5-4b3c-ac45-e28ac5408b6d) | ![](https://git.kayg.org/attachments/98557d5e-e309-4272-bd52-cf1275afaa0a) | | 390 dark | ![](https://git.kayg.org/attachments/e534875b-64f4-4bf0-8929-8b85cc556fd5) | ![](https://git.kayg.org/attachments/18d08334-0c8a-43e1-b313-8c53a9b61da7) | **insert-sheet** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/b67a2954-54dc-4721-b9e2-89c21e1e6803) | ![](https://git.kayg.org/attachments/34d36476-f1f8-446a-8284-cc8ad4be0a69) | | 1440 dark | ![](https://git.kayg.org/attachments/18a61f5e-cec2-4e1c-92f2-311431621fdf) | ![](https://git.kayg.org/attachments/efa2da00-76cd-4f0b-be4a-8cfbf84a7548) | | 390 light | ![](https://git.kayg.org/attachments/c0a30f1d-5b2e-4503-9078-ad3f481b35a5) | ![](https://git.kayg.org/attachments/44cab01b-8eba-4a73-b370-d3a1f69d7426) | | 390 dark | ![](https://git.kayg.org/attachments/1beaca42-c5dc-447e-80a7-2bd0da2289dc) | ![](https://git.kayg.org/attachments/b397e772-2048-47f5-a1a6-757f13e13ac4) | **note-picker** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/65142823-08be-46bc-9ee8-65633a59e6ab) | ![](https://git.kayg.org/attachments/72ffb188-e3ea-4376-b7f6-4c165f306f6b) | | 1440 dark | ![](https://git.kayg.org/attachments/7c40eeca-51f4-40fa-960e-8a6423a01b31) | ![](https://git.kayg.org/attachments/be1b4786-bcfa-471d-bed6-126acd1144f3) | | 390 light | ![](https://git.kayg.org/attachments/9042dfc1-b49d-4b9c-843e-5202fa09ac9d) | ![](https://git.kayg.org/attachments/1d8a341c-f48d-411a-b01e-cd08d58ac3f9) | | 390 dark | ![](https://git.kayg.org/attachments/7d96f7e8-d09a-4211-81bc-651e98352eec) | ![](https://git.kayg.org/attachments/5f66fa98-40f8-4d63-b2e5-20863a8cc9f1) | **at-picker** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/ab5138b8-d991-4f9d-9f2c-e9336a7302b2) | ![](https://git.kayg.org/attachments/a7f0285e-fc72-4c6c-8db8-3e9327aceaf3) | | 1440 dark | ![](https://git.kayg.org/attachments/51c0a91f-039f-4efe-bdfd-a8687ed03f5e) | ![](https://git.kayg.org/attachments/11f71941-32e3-4e7b-94e5-439243d2aafe) | | 390 light | ![](https://git.kayg.org/attachments/060dfd6a-d61e-430a-be6c-ee9fdf92dec1) | ![](https://git.kayg.org/attachments/caf121ec-9cc3-4d43-9340-60acb9b3465b) | | 390 dark | ![](https://git.kayg.org/attachments/b19b0152-75eb-49c4-8a00-c2962a9057d2) | ![](https://git.kayg.org/attachments/153064d1-f5fb-4f74-ac71-488b25f81a7f) | **tag-picker** | | mockup | this PR | |---|---|---| | 1440 light | ![](https://git.kayg.org/attachments/bc7f078c-ae08-4b31-ab57-dbbf8c884e10) | ![](https://git.kayg.org/attachments/c12a725b-7a94-45b6-83c0-86cb99b2408f) | | 1440 dark | ![](https://git.kayg.org/attachments/e21e5247-7439-4bb1-bfe2-824b217cd247) | ![](https://git.kayg.org/attachments/f4a0fb0d-92f1-475a-ac3b-bae2c7b397b8) | | 390 light | ![](https://git.kayg.org/attachments/79102c7e-a47c-4912-b21d-d8d854f3fc20) | ![](https://git.kayg.org/attachments/6d6a140f-b8f6-42f2-8041-6a4742e86876) | | 390 dark | ![](https://git.kayg.org/attachments/fa468d60-0848-4125-b478-f4bfd6cb141e) | ![](https://git.kayg.org/attachments/f5ad2111-8ba9-40eb-b770-e16102c22ca0) | ### Real Safari (Mac VM, safaridriver, 1x: the VM reports devicePixelRatio 1) **slash** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/e4806a5e-4146-472d-89bc-0779b2d59042) | ![](https://git.kayg.org/attachments/0d6aa7e6-865f-43de-8330-b93d7e2b4a17) | | 390 | ![](https://git.kayg.org/attachments/098b93e2-7028-40af-b0ec-98f625bed00b) | ![](https://git.kayg.org/attachments/375de146-da79-4cda-92ac-86755a8a397b) | **insert-sheet** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/5439efaa-77f0-45e1-bf52-37760c35311d) | ![](https://git.kayg.org/attachments/18655d29-d07e-48a6-adcd-7b2235ca8b74) | | 390 | ![](https://git.kayg.org/attachments/410996b3-b86d-4c7e-a053-1d92252a83f4) | ![](https://git.kayg.org/attachments/d88015eb-c79f-4921-b8ee-c95f6213cb49) | **note-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/e9a32e97-7f21-41df-a92c-b3074bc087c6) | ![](https://git.kayg.org/attachments/8360dfdd-5cf8-442c-8b09-ebac3296383b) | | 390 | ![](https://git.kayg.org/attachments/7c863934-3081-4cca-89fd-9d41c16f2ee5) | ![](https://git.kayg.org/attachments/5a64bab5-ac82-4e1e-a283-6b1feec07fe1) | **at-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/818eb56b-cbdd-413d-961a-a2e0729b30dd) | ![](https://git.kayg.org/attachments/2f26603b-62f3-48be-8949-46476e1d4fb0) | | 390 | ![](https://git.kayg.org/attachments/364bac0d-ae9a-40eb-954b-e411e92ec3b0) | ![](https://git.kayg.org/attachments/45d88002-e4f7-4b45-bcc8-a9a61351c371) | **tag-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/1c5e8022-eb6f-4e1a-9668-2603c4697cbb) | ![](https://git.kayg.org/attachments/b3e55b92-4509-4768-954e-a30557590930) | | 390 | ![](https://git.kayg.org/attachments/8977d251-dccb-4fb6-a4d4-c7090c36ac98) | ![](https://git.kayg.org/attachments/0c4fb0a1-5679-4023-a9fa-ef73249a8b06) | ### Real Safari on the fixed head b5f66d284 (Mac VM, 1x). This supersedes the set above, which was taken before the fix: in it the pickers had to be retried because of a bug found by taking these shots (the picker lost its install when the editor was rebuilt while its code was loading; fixed, with a unit test that fails without the fix). Cold-load check on fresh origins, no retry: / 4 of 4, [[ 4 of 4, # 4 of 4, @ 3 of 4 (then 8 of 8 on fresh origins; the one miss is not explained). **slash** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/422d2e79-610e-4652-838e-55c1c2fb0d69) | ![](https://git.kayg.org/attachments/a1cb2769-16fa-408a-8331-b022d6379c49) | | 390 | ![](https://git.kayg.org/attachments/82df58c3-b3a5-4ab9-a6c3-8f664e17706c) | ![](https://git.kayg.org/attachments/e1cc3a7a-eca7-434c-b8f0-8dd4fdb2ad1f) | **insert-sheet** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/dc82025f-5655-4f80-a82b-001101f247a3) | ![](https://git.kayg.org/attachments/fca9d82e-0f44-4f02-a934-4f5dea8a1f89) | | 390 | ![](https://git.kayg.org/attachments/f267cbdb-b83c-441b-92d4-e2b1e93efb3b) | ![](https://git.kayg.org/attachments/fec6d2ae-dad1-4b7d-8f56-d7b02b3d5507) | **note-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/953793d9-e3e7-4ffa-9029-ef840a492753) | ![](https://git.kayg.org/attachments/ec3fb3c4-58ef-4157-b7c0-30285a2ea95e) | | 390 | ![](https://git.kayg.org/attachments/6eb804b0-88dd-41aa-9405-01bf554c9957) | ![](https://git.kayg.org/attachments/db32e27c-4a64-4b19-bf9a-b2daf64b8715) | **at-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/25d032f9-752e-4434-b405-5ebb359f196f) | ![](https://git.kayg.org/attachments/1a4856f7-bb14-4041-9aba-8f3ce3e0ff63) | | 390 | ![](https://git.kayg.org/attachments/29b895b6-cc85-4b28-ba12-401f94cca5ce) | ![](https://git.kayg.org/attachments/18e53923-ebc6-4e7f-b702-5b5c8e7199c9) | **tag-picker** | | light | dark | |---|---|---| | 1440 | ![](https://git.kayg.org/attachments/eadda5e2-4933-4753-9662-73afe30714cc) | ![](https://git.kayg.org/attachments/d41e2e76-3f65-42db-af71-9d90e43b7782) | | 390 | ![](https://git.kayg.org/attachments/c143b552-beba-4653-b2a5-0ce5f39eb85a) | ![](https://git.kayg.org/attachments/abf71564-9e92-4aa0-aee3-1e5c00912622) |
Author
Owner

Restacked on dev d4b32af94, head a24d87101: READY FOR MERGE.

gate result
first paint JS vs dev (plain 228525 B / normalised 228128 B) 227125 B: -1400 B / 226798 B: -1330 B
first paint CSS vs dev 18126 B 18126 B: +0
specs, Chromium + WebKit, 1440 + 390 picker, slash, tag, link, glass, preload, typing-latency, divider specs: 120 passed (Chromium) / 120 (WebKit); the failures are dev's own (below)
Tasks card on this head tasks-card: 11 passed, both engines
perf/web.sh --bundle-only --gate passes; budget file regenerated on dev's current one: picker-list line 9.7 -> 3.7 KiB, total 506.7 KiB

Dev d4b32af94 itself fails 9 specs (palette preload:118 at 1440 and 390, glass:76, lazy-ui:70, preload:89 x3 at 390), on Chromium and WebKit; the same ones fail on this head and none is new.

The merge with the Tasks stack needed one change: #889's card handed the old tagPicker loader to the Tasks card, and this PR replaces TagPicker with FieldPicker, so the Tasks card's tag picker is the shared FieldPicker now (fix(tasks): the Tasks card's tag picker is the shared FieldPicker). The perf and Safari results in the earlier comment still apply (the picker code is unchanged).

**Restacked on dev `d4b32af94`, head `a24d87101`: READY FOR MERGE.** | gate | result | |---|---| | first paint JS vs dev (plain 228525 B / normalised 228128 B) | **227125 B: -1400 B** / 226798 B: -1330 B | | first paint CSS vs dev 18126 B | 18126 B: +0 | | specs, Chromium + WebKit, 1440 + 390 | picker, slash, tag, link, glass, preload, typing-latency, divider specs: 120 passed (Chromium) / 120 (WebKit); the failures are dev's own (below) | | Tasks card on this head | tasks-card: 11 passed, both engines | | `perf/web.sh --bundle-only --gate` | passes; budget file regenerated on dev's current one: picker-list line 9.7 -> 3.7 KiB, total 506.7 KiB | Dev `d4b32af94` itself fails 9 specs (palette `preload:118` at 1440 and 390, `glass:76`, `lazy-ui:70`, `preload:89` x3 at 390), on Chromium and WebKit; the same ones fail on this head and none is new. The merge with the Tasks stack needed one change: #889's card handed the old `tagPicker` loader to the Tasks card, and this PR replaces TagPicker with FieldPicker, so the Tasks card's tag picker is the shared FieldPicker now (`fix(tasks): the Tasks card's tag picker is the shared FieldPicker`). The perf and Safari results in the earlier comment still apply (the picker code is unchanged).
Author
Owner

Merged to dev (head a24d87101). First paint −1400 B, specs and gate green, screenshots checked by the orchestrator. Ships with the next daily train.

Merged to dev (head a24d87101). First paint −1400 B, specs and gate green, screenshots checked by the orchestrator. Ships with the next daily train.
kayg closed this pull request 2026-11-09 05:52:45 +00:00
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
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!853
No description provided.