Hazel Work Dashboard

A copy of the Hazel Work Dashboard that Matthew runs on his laptop, published within a minute or two of each change to its notes, and every 15 minutes for the status from GitHub. Its localhost links work only there.

Updated 2026-10-16 00:15 MDT, by ~/localhost-index/update.py (PR titles and status from GitHub).

History: every change to this page, a folder for each year, month and day, also pushed to matthewhammer/hazel-work-notes (public). Published within a minute or two of each change to our notes, and every 15 minutes for the status from GitHub: matthewhammer.org/hazel/work-dashboard/. How we work with this page: agent-instructions.md. This is version 0.0.3: VERSIONS.md lists what each version has. Closed tickets: their own page. This page reloads itself when it changes (checked every 90 s while it is open).

Current ticket: ^ticket(127)

performance · from Matthew, 2026-10-15 🌙 long run 🪷 blocked on Matthew

Started Thu Oct 15, 11:44 PM MDT · elapsed

A report on the performance PRs to dev: an executive summary and a merge plan. Matthew, 2026-10-15 21:37: a report about the dashboard's set of performance PRs (https://matthewhammer.org/hazel-work-notes/#perf-prs: #2681, #2679, #2678, #2675, #2673, #2661, #2651, #2652, #2614, #2610, #2671, #2672, #2606, #2603, and the #2490 spike), giving an executive summary for Cyrus, or Alexander, or Andrew, or Matt K: for each PR, (1) why it is important (the savings in responsiveness, or memory, etc., with the measured numbers and where they come from), and (2) reasons not to merge it to dev ASAP, hopefully not too many, but honest and open, doing the work for them (conflicts with dev's head, tests and CI state, risks, what a reviewer should look at, what overlaps #2469). And a merge plan (Matthew, 21:38): an order, which can go together, what depends on what, and what each needs first. A draft in the performance series for his review; nothing posted to GitHub or published until he says. Tonight, after hours (🌙). 21:38, Matthew: include a dependency graph of the PRs as a picture (which PR builds on, or conflicts with, which), and repeat the relevant plots from earlier reports where they show a PR's savings (with their sources).

Now: Overnight summary (Matthew back about 06:30). LIVE: Dress Up 0.0.57 (42 flowing stream and brook, the swing swings its sitter; 128 shorts and swimsuits on posed legs; 129 the Pose tab first: standing, cross-legged meditating with closed eyes and hands in the lap, five dances; turning feet; 130 the hug: far arm behind; 131 the profile puddle). WAITING ON YOU (🪷, all local, nothing posted): ^report(16) draft, two drag fixes side by side (http://localhost:8131/series/016/; coalescing cuts a long drag's freeze 4.0 -> 2.2 s, 10 of 10 rounds; views in the worker do not help) [91]; ^report(17) draft, the performance PRs' executive summary and merge plan, fifteen with #2608, and all fifteen merged pass the full suite, 4,756 tests (http://localhost:8131/series/017/) [127]; the outline deep link ?outline=ux&ux=... (local 438812718b) [25]; the cell memo (page time -2/3, nothing visible moved: recommend not pushing) [24]; CI budgets as local branches off dev in ~/hazel-ab-coal: statics passes [13], a recursive-library step budget [14], byte budgets [15], and 19's finding (no call memo on dev; jsoo GC counters are zeros) [19]. Nothing is running now. Servers: 8000 dashboard, 8131 series, 8133 Dress Up, 8353 the outline link + cell memo build (#2635-based); 8311 #2597 (hazel-splicerefs-full) restarted at 23:45.

Work Queue (Active Tickets)

What we mean to do next, in order: a few tickets, not the backlog. We push a ticket onto the front or the back, and reorder as we go; a ticket leaves the queue when it closes. Each links to its full row in the backlog.

NextTicketAreaTicket
🪷 Blocked on Matthew: waiting for his response
1^ticket(18) 🪷 blocked on MatthewperformanceOption B from ^report(5): evaluate each livelit's view in the worker, keep the last Html sent per livelit, and post patches to it, so view…
2^ticket(102) 🪷 blocked on MatthewhazelReply to Alexander on the deep links PR (#2583; Matthew writes the reply by hand). Alexander (7h3kk1d) replied today at 11:00 to our…
🌙 Long runs: for when Matthew is away from the keyboard
3^ticket(91) 🌙 long run 🪷 blocked on MatthewperformanceDrag stalls: how many changes does a drag process, and does coalescing slider input help? From ^ticket(90): on #2635's head a 1.5 s drag of…
4^ticket(25) 🌙 long run 🪷 blocked on Matthewtesting, UXCode-driven tests of the outline modes: a URL parameter (or test hook) that opens a slide in UX mode with chosen GUI rows, so a script…
5^ticket(24) 🌙 long run 🪷 blocked on MatthewperformanceOpen cells draw their livelit views without the view memo (live_html, 449 ms per change profiled in ^report(8)'s B with ^ticket(6)'s fix),…
6^ticket(127) current 🌙 long run 🪷 blocked on MatthewperformanceA report on the performance PRs to dev: an executive summary and a merge plan. Matthew, 2026-10-15 21:37: a report about the dashboard's…
7^ticket(13) 🌙 long run 🪷 blocked on Matthewperformance, CIStatics counts on dev: the analyses-per-expression counter and Test_StaticsPasses from #2635 (bd90642654, da3251d3e5), with a small corpus…
8^ticket(14) 🌙 long run 🪷 blocked on Matthewperformance, CIA budget on a slide: the evaluator's work after a figure move in the woods, where reuse failed before #2675. 2026-10-15T21:29: Matthew:…
9^ticket(15) 🌙 long run 🪷 blocked on Matthewperformance, CIByte budgets: elaboration sizes on dev, and the worker's message sizes for a fixed interaction. 2026-10-15T21:29: Matthew: after hours…
10^ticket(19) 🌙 long run 🪷 blocked on Matthewperformance, CIBudgets harder to fool (^report(6)'s update, a count is not a time): count the call memo's own work (the nodes its keys put in form) and,…

Localhost ports

PR # and titleRepo and branchLocalhost
#2635 Livelits × modular editors: merge #2469 into the livelits branchhazelgrove/hazel
integration/livelits-modular-editors
localhost:8341
Scenes slide
#2597 User-Defined Livelits, as in PLDI '21, and beyond.hazelgrove/hazel
integration/livelits-splicerefs-full
localhost:8311
#2635 Livelits × modular editors: merge #2469 into the livelits branchhazelgrove/hazel
perf/2635-names (into integration/livelits-modular-editors)
not served
#2675 Incremental evaluation reuses expressions around a recursive lethazelgrove/hazel
recursive-let-reuse (into dev)
not served
#2676 The cursor inspector can show a long type whole, on several lineshazelgrove/hazel
cursor-inspector-full-types (into dev)
not served
— Hazel performance analysis (the report's sources)matthewhammer/hazel-performance-analysis, checked out at ~/hazel-perf-report
main (public: a push publishes, so drafts wait)
localhost:8131/series/
— Messed Up Dress Up (the game)matthewhammer/kids-choice-games, folder dress-up/, public with its history from 2026-10-09
Its own Pages site deploys every push to main. Edit ~/kids-choice-games: ~/hazel/experiments/polygons-plain/dress-up.html is a symlink to it.
main
not served

Other PRs we are tracking

Not about performance: features, fixes, docs, CI.

PR # and titleBranch → baseStateCIReviewMergeUpdatedNote
#2676 The cursor inspector can show a long type whole, on several linescursor-inspector-full-types → devopen✓ 5 passedno review yetmergeable2026-10-12The type-expansion panel (issue #2674). Its fix for module signatures' parentheses is only on #2635: dev prints a signature as a labeled tuple.
#2583 Deep links: the URL can say which slide, which panel, and where the cursor isdeep-links → devopen✓ 5 passed⚠️ changes requestedconflicts2026-10-15
#2613 Colors: every var() a stylesheet reads is one the theme definesconfiguration-undefined-colors → devopen✓ 5 passedno review yetmergeable2026-09-29
#2605 Substitution: a let's definition sees the outer binding, not its ownsubstitution-let-def-scope → devopen✓ 5 passedno review yetmergeable2026-09-27
#2608 Leave the source's whitespace and comments out of elaborationselab-no-secondary → devopen✓ 5 passedno review yetmergeable2026-09-30
#2592 Report each error once, not once per wrappererror-dedup-wrappers → devdraft✓ 5 passedno review yetmergeable2026-09-23
#2491 docs: research-paper implementation status reportdocs/research-status-report → devdraft✓ 7 passedno review yetmergeable2026-09-22Docs.
#2577 Serve the release web build from an Internet Computer canisteric-canister → devdraft✓ 7 passedno review yetconflicts2026-09-22
#2616 non-`dev` (`integration/livelits-splicerefs-full`): Remote refs: splices a Fumola instance reads and writesremote-splices → integration/livelits-splicerefs-fullopen✗ 2 failing: checks / Fast checks (failure), checks / Full tests (failure); ✓ 1 passedno review yetconflicts2026-10-04Remote splices, the base of #2650. On the back burner since 2026-10-05.
#2650 non-`dev` (`remote-splices`): Hazel's state and Fumola instances on an Internet Computer canisteric-canister-fumola → remote-splicesopen✗ 2 failing: checks / Fast checks (failure), checks / Full tests (failure); ✓ 1 passedno review yetmergeable2026-10-05The IC canister demo. On the back burner since 2026-10-05.
#2536 non-`dev` (`integration/modules-livelits`): experimental language integrationsexperimental-lang-integration → integration/modules-livelitsdraft✓ 5 passedno review yetmergeable2026-09-22Fumola-in-Hazel, shelved since 2026-09-16 (its issues go to Adapton/fumola).

Repositories we deploy

Pushed to directly, without PRs. The version is the newest in each project's VERSIONS.md. Deployed means Pages has built the branch's latest commit; a repository without a Pages site runs where its links point.

Repository and branchLatest commitVersionDeployedOpen PRsNote
matthewhammer/kids-choice-games
main
c058d1d Messed Up Dress Up 0.0.57: poses, flowing water, and a hug (2026-10-16)Messed Up Dress Up 0.0.57 (2026-10-15)✓ deployed c058d1d
the game, live
localhost:8133/dress-up.html
🎵 the tunes (MP3s)
noneThe kids' toys, prototyped in plain JS with real players before the Hazel slides formulate them as user-defined livelits (#2635, #2597; ^report(1) on). Each version is tagged dress-up-X.Y.Z.
matthewhammer/dress-up-pictures
main
048e549 2026/10/15: Messed Up Dress Up 0.0.55 (2026-10-16)—✓ deployed 048e549
every picture, by day
localhost:8133/screenshots/
noneThe Dress Up picture archive, apart from the game (^ticket(106)): each day, every background and chip menu at its defaults, as PNG + SVG + settings. Unchanged files are symlinks to the day they last changed. ~/du-shots/tools/archive-today.sh makes a day.
matthewhammer/dress-up-music
main
bce8822 days.json, for the music player (ticket 119) (2026-10-16)—✓ deployed bce8822
every tune, by day
localhost:8133/music/
noneThe Dress Up music archive, apart from the game (^ticket(106)): each day, every tune at its defaults, one loop each, as MP3. Unchanged tunes (by fingerprint) are symlinks to the day they last changed.
matthewhammer/hazel-work-notes
main
5e00bb5 Publish 2026-10-16 00:00 MDT: index.html, closed.html (2026-10-16)Hazel Work Dashboard 0.0.3 (2026-10-13)✓ deployed 5e00bb5
the dashboard, published
the dashboard, localhost:8000
its history, localhost:8000/notes/
noneThis page's code (dashboard/, run in place: ~/localhost-index links to it), its history and agent-instructions.md. PUBLIC since 2026-10-13: its Pages site serves a copy of this page (noindex), redirected to from matthewhammer.org/hazel/work-dashboard/. Cron commits and pushes a snapshot, data.json and the public copy when the page changes; the code is committed by hand.
matthewhammer/hazel-performance-analysis
main
3262f63 ^report(15): a dated update, published 2026-10-15: not like for like (shape counts) (2026-10-16)—no Pages site
the series, published
drafts, localhost:8131/series/
noneThe performance analysis series, for outside readers (^report(1) on), with its history since 2026-10-09 and its own agent-instructions.md. Public since 2026-10-12. Published by copying a report to the homepage repo; a push here is public too, so drafts wait for review.

Performance Analysis and Improvement

Tracked in hazelgrove/hazel#2609 (performance challenges). Write-ups: the performance analysis series (local sources).

Performance PRs

Against #2609; the last three (#2606, #2603, #2490) are from before it.

PR # and titleBranch → baseStateCIReviewMergeUpdated
#2681 A value known to have a type is not walked again for itascriptions-has-type → devopen✓ 5 passedno review yetmergeable2026-10-13
#2679 An ascription pushed through a value gives the value back when it already has the typeascriptions-copy-on-change → devopen✓ 5 passedno review yetmergeable2026-10-12
#2678 CI fails when an evaluation does more work than its budgetci-perf-budgets → devopen✓ 5 passedno review yetmergeable2026-10-12
#2675 Incremental evaluation reuses expressions around a recursive letrecursive-let-reuse → devopen✓ 5 passedno review yetmergeable2026-10-12
#2673 Incremental evaluation recognizes an unchanged expression by its Merkle hashreuse-check-merkle-hash → devopen✓ 5 passedno review yetmergeable2026-10-13
#2661 Types get a Merkle hash; the evaluator asks is_consistent once per pairtyp-hash-consistent → devopen✓ 5 passedno review yetmergeable2026-10-10
#2651 Statics: a module binding analyzes its definition once, not twicestatics-module-def-once → devopen✓ 5 passedno review yetmergeable2026-10-05
#2652 Eval worker in Firefox: start it at load, and do not time out a reply that is queuedeval-worker-start-at-load → devopen✓ 5 passedno review yetmergeable2026-10-06
#2614 Load text about 2.5× faster: whole tokens, one re-groutparser-perf → devopen✓ 5 passedno review yetmergeable2026-09-29
#2610 Parse the load fallback with the segmented parser, projectors keptparse-fallback-segmented → devopen✓ 5 passedno review yetmergeable2026-09-30
#2671 MapPiece keeps unchanged pieces as the same objectsmappiece-keep-identity → devopen✓ 5 passedno review yetmergeable2026-10-10
#2672 Measuring the font no longer scrolls the editor to the caretfont-metrics-keep-scroll → devopen✓ 5 passedno review yetmergeable2026-10-10
#2608 Leave the source's whitespace and comments out of elaborationselab-no-secondary → devopen✓ 5 passedno review yetmergeable2026-09-30
#2606 Keep the incremental cache in the eval workereval-worker-held-cache → devopen✓ 5 passedno review yetmergeable2026-09-30
#2603 Statics: a let is analyzed once unless it refers to itself, plus three smaller speedupsdev-statics-perf → devopen✓ 5 passedno review yetmergeable2026-09-26
#2490 SPIKE: compile the Hazel evaluator with wasm_of_ocaml and benchmark itwasm-eval-bench-spike → devdraft✓ 7 passedno review yetconflicts2026-09-22

The integration branches also carry these fixes:

PR # and titleBranch → baseStateCIReviewMergeUpdated
#2635 Livelits × modular editors: merge #2469 into the livelits branchintegration/livelits-modular-editors → integration/livelits-splicerefs-fulldraft✗ 2 failing: checks / Fast checks (failure), checks / Full tests (failure); ✓ 1 passedno review yetconflicts2026-10-15
#2597 User-Defined Livelits, as in PLDI '21, and beyond.integration/livelits-splicerefs-full → integration/livelits-splicerefsopen✓ 5 passedno review yetmergeable2026-10-15

Full Backlog (All Tickets)

All our open tickets: important and not done; the few we mean to do next are in the work queue. Numbered in our own sequence from #1; a number is never reused. A closed ticket moves to the closed tickets, with how it ended.

TicketAreaTextFrom
^ticket(13)performance, CI
queued
🌙 long run
🪷 blocked on Matthew
Statics counts on dev: the analyses-per-expression counter and Test_StaticsPasses from #2635 (bd90642654, da3251d3e5), with a small corpus subset in the quick suite. 2026-10-15T21:29: Matthew: after hours tonight if time is left (🌙), as local branches against dev for his review.^report(6)
^ticket(14)performance, CI
queued
🌙 long run
🪷 blocked on Matthew
A budget on a slide: the evaluator's work after a figure move in the woods, where reuse failed before #2675. 2026-10-15T21:29: Matthew: after hours tonight if time is left (🌙), as local branches against dev for his review.^report(6)
^ticket(15)performance, CI
queued
🌙 long run
🪷 blocked on Matthew
Byte budgets: elaboration sizes on dev, and the worker's message sizes for a fixed interaction. 2026-10-15T21:29: Matthew: after hours tonight if time is left (🌙), as local branches against dev for his review.^report(6)
^ticket(16)CIAsk the maintainers to require the test jobs for merging into dev: today no check is required, so a red budget is a signal, not a gate.^report(6)
^ticket(17)performance, CIA timing report that informs and doesn't fail: base and head on one runner, repeated, phase by phase, perhaps from #2161's harness (David's call).^report(6)
^ticket(18)performance
queued
🪷 blocked on Matthew
Option B from ^report(5): evaluate each livelit's view in the worker, keep the last Html sent per livelit, and post patches to it, so view evaluation leaves the main thread. Needs the view runner (ViewCmdRunner) in the worker, a patch format, an element on the page that owns each livelit's DOM and applies patches, and handlers dispatched by id. Keep the page's own path for an interaction's immediate redraw, or every drag waits a round trip. Its condition is now met (2026-10-12, see ^ticket(10)): evaluating the view is about 69% of the main thread in a woods figure move, and C would save about 2%. Weigh it against making the view itself cheaper first (^ticket(1), ^ticket(2)). PROTOTYPED 2026-10-14 (local branches, nothing pushed; work notes http://matthewhammer.org/hazel-work-notes/work-notes/2026/10/14/2026-10-14T2120-0600.html): MvuShape and ViewCmdRunner moved to the language library (61d031fd93, no change in behavior); the worker runs view commands to Html, reusing an unchanged view per projector (fast_equal), and whole programs fold their views in too (experiments on experiment/2635-views-in-worker-all, ede920b07e). Full Body: the main thread about 540 ms (UX mode) / 220 ms (whole program) less per change, the redraw no later; Kids' Choice: release about 45 ms later (144 → 187–196 ms). Waits for Matthew's design calls: which livelits' views move (all, or the costly ones), and the on-screen ids in the request. 2026-10-15T18:52: tagged 🪷 blocked on Matthew: its next step is his call (see above).^report(5)
^ticket(19)performance, CI
queued
🌙 long run
🪷 blocked on Matthew
Budgets harder to fool (^report(6)'s update, a count is not a time): count the call memo's own work (the nodes its keys put in form) and, if js_of_ocaml can report it, memory allocated, beside the evaluator's steps. 2026-10-15T21:29: Matthew: after hours tonight if time is left (🌙), as local branches against dev for his review.^report(6)
^ticket(24)performance
queued
🌙 long run
🪷 blocked on Matthew
Open cells draw their livelit views without the view memo (live_html, 449 ms per change profiled in ^report(8)'s B with ^ticket(6)'s fix), where the whole-program editor uses memo_view (163 ms in C). Give cells the memo. (Corrected 2026-10-12: B's 0.48 s of of_segment was the autosave printing text, not the cells' code views.) 2026-10-15T21:29: Matthew: tonight after hours (🌙), local only.^report(8)
^ticket(25)testing, UX
queued
🌙 long run
🪷 blocked on Matthew
Code-driven tests of the outline modes: a URL parameter (or test hook) that opens a slide in UX mode with chosen GUI rows, so a script reaches ^report(8)'s B without clicking through the outline. Matthew: "let's consider that too with our UX feature". 2026-10-15T21:29: Matthew: tonight after hours (🌙), local only.^report(8)
^ticket(43)dress upMessed Up Dress Up: postcards. Save the friend and their scene as one picture, with a caption to write on it, ready to send.Matthew, 2026-10-13, in chat (ideas from ^ticket(40)'s doorways)
^ticket(54)performance, #2469Offer ^ticket(7)'s three ports to #2469, from the local branch, with ^report(13)'s numbers. ^report(13)'s What next, step 1: "Offer the three ports to #2469, from the local branch, with this report's numbers." The branch: port-2469-t7 in ~/hazel-port-2469, three commits on #2469's head c1e4aeee4a, which is still its head (2026-10-14), so they apply as they are: 128f3f303d (the worker's statics projection updated, not rebuilt), cdb799a376 (EvalInfo updated at the keys DefStatics changed), 474b1e050e (DefStatics keeps an item's patched root when nothing it is made from changed). Its quick tests passed whole. To do: push the branch under a name of Matthew's, and post on #2469 the branch, the three commits and ^report(13)'s numbers for them; #2469 is Andrew's PR, so a progress note, no @-mention, no action asked; Matthew approves the post before it goes.Matthew, 2026-10-14 (^report(13), What next, step 1)
^ticket(91)performance
queued
🌙 long run
🪷 blocked on Matthew
Drag stalls: how many changes does a drag process, and does coalescing slider input help? From ^ticket(90): on #2635's head a 1.5 s drag of Full Body's arm length stalls the page about 4 s (whole program), and each processed change costs about 0.9 s of main thread, so the stall is mostly how many changes a drag triggers. Steps: (1) count, per drag: the slider's input events, the eval requests the page posts to the worker and the replies, and the heavy frames (gaps over 50 ms); (2) find where a slider's input becomes an edit, and whether changes already coalesce (the newest value only) while one is in flight; (3) if not, try coalescing on a local branch: while a change is in flight, keep only the newest value and process it when the change lands; (4) measure with drag_stall.py (C and B), release to redraw, and Kids' Choice, against the head; (5) then decide ^ticket(18) with both in hand. Local only until Matthew says. FINDINGS 2026-10-15: a transient input (a drag's preview) sends a quiet repaint action, and the page recalculates for each one, walking the whole program in EvalResult.calculate's reuse check (Calc.set -> fast_equal_with_lexemes, ~40% of a drag's main thread, profiled). Coalescing built (local perf/2635-coalesce-drag-repaint, 3eb4489124; counters in a MEASURE commit): only 1.5-3 of a drag's ~13 inputs coalesce. Measured in alternating sessions, whole program, drag stall: head 4.1 s, prototype (^ticket(90)) 2.6, coalescing 2.8, head 3.2, coalescing 4.2: the drift between sessions is larger than any build's effect, so neither fix is shown. Next (Matthew to say): an interleaved A/B, both builds served at once, alternating drag by drag, 10+ each; and try skipping the whole-program walk for a preview. Report: a new report on drags, once the A/B is in (the next free number: ^report(15) is now ^ticket(120)'s draft). 2026-10-15T18:52: tagged 🪷 blocked on Matthew: its next step is his call (see above). 2026-10-15T21:29: Matthew: yes, the interleaved A/B, tonight after hours (🌙): head against each prototype (coalescing, views in the worker), both served at once, alternating drag by drag, 10+ each.Matthew, 2026-10-15
^ticket(102)hazel
queued
🪷 blocked on Matthew
Reply to Alexander on the deep links PR (#2583; Matthew writes the reply by hand). Alexander (7h3kk1d) replied today at 11:00 to our comment of 10-14 linking the plan page; he couldn't comment on that page, so he left his notes on the PR. His two points on the plan's sketch: (1) name `target`'s constructors `Documentation` and `Scratchpad`, not `Slide` and `Share`, and use records instead of tuples where there are several fields (`Scratchpad({name, share})`); (2) the `request` record allows a `position` without a `target`: he'd like a type that rules it out. Fact for the reply: on the branch as pushed (09-22), `?caret=` without `?slide=` puts the caret in whatever opens (the reader's last slide or scratchpad), so such a link depends on the reader's saved state. That supports nesting the position inside the place, e.g. `{place: option({target, position: option(position)}), panel: option(panel_request)}`. A panel-only link stays meaningful. Then revise the plan, and later the branch, to match whatever is agreed. He liked the rest. Also worth an answer: where he should comment on plans next time (the PR itself, or the PR description). 2026-10-15T15:59: tagged 🪷 blocked on Matthew (his reply, written by hand), at the end of the queue.Matthew, 2026-10-15
^ticket(127)performance
current
🌙 long run
🪷 blocked on Matthew
A report on the performance PRs to dev: an executive summary and a merge plan. Matthew, 2026-10-15 21:37: a report about the dashboard's set of performance PRs (https://matthewhammer.org/hazel-work-notes/#perf-prs: #2681, #2679, #2678, #2675, #2673, #2661, #2651, #2652, #2614, #2610, #2671, #2672, #2606, #2603, and the #2490 spike), giving an executive summary for Cyrus, or Alexander, or Andrew, or Matt K: for each PR, (1) why it is important (the savings in responsiveness, or memory, etc., with the measured numbers and where they come from), and (2) reasons not to merge it to dev ASAP, hopefully not too many, but honest and open, doing the work for them (conflicts with dev's head, tests and CI state, risks, what a reviewer should look at, what overlaps #2469). And a merge plan (Matthew, 21:38): an order, which can go together, what depends on what, and what each needs first. A draft in the performance series for his review; nothing posted to GitHub or published until he says. Tonight, after hours (🌙). 21:38, Matthew: include a dependency graph of the PRs as a picture (which PR builds on, or conflicts with, which), and repeat the relevant plots from earlier reports where they show a PR's savings (with their sources).Matthew, 2026-10-15