# Handoff Where the work in flight stands. The settled layout design, the vocabulary and the measurement method are in `docs/LAYOUT.md`; what the review of #19 found is in `docs/LAYOUT_LOG.md`. ## The Iris layout repair is submitted **Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `7e2b4cd`, and past the reviewed `cadfba0` it is five rounds, each described in `docs/LAYOUT_LOG.md`: - **The repair**, `add6774` and `84dad21` -- collapsed-share placement, retained mask ownership, a redraw-on-reparent defect, and repeated work in the test harness. - **The vocabulary and the container API**, `5642f20` through `58ce74d`. - **Naming**, `55df32a` through `40b89c1`. - **A sweep over the logic those names exposed**, `8d2b7a5` and `6c84b6f`. - **A clarity sweep**, `3da1c71` and `7e2b4cd` -- naming the pairs layout returns, `Span::slot`, and a diagnostic that printed the rel base while calling it the box. The settled design of the last three is in `docs/LAYOUT.md` under "Three names, and the one argument that says them". Bryan settled the API over 2026-09-17 to 19; it is current, not frozen. The core design remains sound. Round-to-nearest is still unchanged. Two checkouts share one Git storage: `/home/bob/repos/iris` is the active `layout/one-ask` worktree, and `ai-app-2/iris` stays on `main` at the app's `32f6ad8` pin until the integration below is ready. ### How to check a round **Always**, because they cost nothing: format, workspace clippy under `-D warnings` with and without `layout-diagnostics`, the workspace tests, and the **cold dump**. `layout_dump` over 400 depth-5 trees is 34,492 boxes, and it is the only thing that catches two same-typed values being swapped, which is the failure mode of a rename or a move. The repair moved 650 of those boxes, all from the collapsed-share correction; every commit since has been byte-identical to `84dad21`, the clarity sweep included. **Only when the change can alter what layout computes**: the three seed scans -- 400 at depth 5, 1,000 at depth 6, 2,000 at depth 4. They cost about a quarter of an hour and they exist to find logic that is wrong on some tree shape, so a rename has nothing for them to find (Bryan, 2026-09-19). Never start one and then edit the tree: cargo rebuilds mid-flight and exits 1 from a compile error, which reads exactly like a fuzzer failure. ## What is next, in order 1. **Bryan's review of #19.** Fixes are themselves unreviewed code: repeat `pre-submit-review` over each round's changes, and apply the gate above to whatever each one touched. The ordinary oracle does not replace absolute geometry and retained-primitive expectations. 2. **Integrate the app's Iris capabilities before changing its pin.** `32f6ad8` has 45 commits not reachable from the review branch; shared UI ownership, richer masks, Android support, and app-side performance work must survive the integration. The app then absorbs the branch's vocabulary and container API, all of it already upstream: `rest` -> `leftover`, `SizeRule` beside widgets, alignment properties, the removal of `OrthoSize`, region/placement/rel_base, and `PlaceDesc`. 3. **Round-to-nearest**, CPU and shader together as one verified change. Bryan approved it on 2026-09-17 and neither half has landed; the derivation, the form to use and what to re-check are in `docs/LAYOUT.md` under "Rendering the grid (pending)". Wanted but not started, recorded in `iris/TODO`: transforms on a move entry, so a whole subtree scales or rotates with one buffer write and no redraw. Compose-style stretch at the end of a scroll area is the use that prompted it. A move entry only translates today, and composing through one scales the `rel` part while `px` passes through untouched, so fixed-size content and glyphs do not follow a shortened entry. ## Smaller layout items, none urgent - Nested spans pass `leftover` weight up, so three leftover children in one inner span beside one in another get three quarters to one quarter. No other layout system does that; confirm it is wanted. - A span can overflow itself without bound, so boxes of negative length reach children and nothing states what a widget may assume about one. - `Fixed::div` by zero answers `MIN`/`MAX` while `ratio` answers `ZERO`; both are caller bugs under `debug_assert`, but the fallbacks differ. - `docs/LAYOUT.md` §4, §5 and the density section name `Painter::place`, `Painter::region()`, `SetSize`, `desired_width`, `apply_rest`, `Len::dp`, `Aligned` and `MaxSize`, none of which exist. Do not restore `OnResize::Translate` or `OrthoSize`. - `LazySpan`, then `SizeRule::{Min, Max, Clamp}`. A cap may not contain `leftover`; whether `Max` narrows the child's drawing box is a product decision. - `Scroll` taking a direction rather than one axis. Other product work is in `docs/PLAN.md` and the focused documents it links. Do not mix it into the Iris layout branch.