Files
ai-app/docs/HANDOFF.md
T
2026-09-19 22:25:45 -04:00

5.5 KiB

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 6c84b6f, and past the reviewed cadfba0 it is three rounds:

  • The repair. add6774 fixes collapsed-share placement, retained mask ownership and a redraw-on-reparent defect; 84dad21 removes repeated work in the test harness.
  • The vocabulary and the container API, 5642f20 through 58ce74d. What they settled is described as design in docs/LAYOUT.md under "Three names, and the one argument that says them" -- region, placement and rel_base, and the single impl Into<PlaceDesc> argument that replaced Place, Part, widget_within and the separate rel-base argument. Bryan is still refining this, so treat the API as current rather than frozen.
  • Named operations and Index<Axis>, 55df32a and 2807a92, settled with Bryan on 2026-09-19. A description is built by chaining off the value that says it (UiSpan::shifted_desc, Len::as_desc), never by a constructor naming the type; on is reserved for events, so the lift is PlaceDescAxis::on_axis. Arithmetic that needed a comment became a name: UiSpan::place, LayoutLen::without_leftover/is_px/is_only_leftover/ declared, Holds::covers. LayoutHolds became AxisHolds on x/y, every pair got Index<Axis> through impl_axis_index!, and the bare [Option<LayoutLen>; 2] became Declared of Option<Len>.
  • A sweep over the logic the clearer methods exposed, 8d2b7a5 and 6c84b6f. A Span carried start as a third accumulator when it was always fixed and taken read together, so both ends of a slot are now read where they are used. A Scroll's draw writes amt and snap_end, so warm and cold agree only because re-clamping is idempotent; the seed scans build scrolls and never scroll one, so a test now pins it.

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 each round was checked

Format, workspace clippy under -D warnings with and without layout-diagnostics, the workspace tests both ways, and the three prescribed seed scans -- 400 at depth 5, 1,000 at depth 6, 2,000 at depth 4.

The gate that matters for anything shaped like a rename or a refactor is the cold dump: layout_dump over 400 depth-5 trees is 34,492 boxes, and the compiler cannot catch two same-typed values being swapped. The repair moved 650 of those boxes, all from the collapsed-share correction. Every commit since has been byte-identical to 84dad21, including the whole API rewrite and the naming work above.

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 re-run the three fuzzers and the dump diff for edits to Span, Painter, or render_state. 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.