Record the root unification, and where bounds stand

`0d03267` in iris unifies the root's layout path with every other widget's:
`Placing::WINDOW` is the box nobody drew and `Placing::ask` the one place a
box is decided. The leftover-as-a-minimum gap the log recorded for
`root_layout` is closed by it rather than left.

`SizeRule::{Min, Max, Clamp}` is on `layout/bounds` and not in #19. Every
hand-written test passes and the 400-seed scan does not, for a reason that is
a design question: a bound is the first rule whose effect depends on the box
its parent gives it, and the retained machinery hands a widget a box by paths
that never ask it again. The log records the four readings measured and what
each one's seeds were, so none of them is tried twice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-20 14:35:28 -04:00
1 parent 6a92857079
commit 149a6838af
2 files changed
+91 -15

No files matched your search

+27 -15
View File
@@ -55,6 +55,12 @@ and past the reviewed `cadfba0` it is twelve rounds, each described in
overflow its pixels asked for, said as the place the parent gives and
sharing one comparison with the span; and `Image` grown in the generated
trees, which is the only widget here whose hint is a length in pixels.
- **One ask, the root's included**, `0d03267` -- the root had a layout path
of its own, so a rule that reads the box it is offered reached every widget
but that one. `Placing::WINDOW` is the box nobody drew and `Placing::ask`
the one place a box is decided; the root's own path is now the bookkeeping
a widget with no parent keeps. Bryan asked for this rather than a widget
above the root, which would pin the tree to pixels.
The settled design of the vocabulary rounds is in `docs/LAYOUT.md` under
"Three names, and the one argument that says them". Bryan settled the API
@@ -110,14 +116,15 @@ the name it is reachable by.
**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,488** boxes
-- **34,571 since `2dba90b` grew images in the trees**; counted again on
2026-09-20, the fourth through eighth sweeps having all repeated 34,492, which
is a `wc -l` of the whole run rather than of its box lines -- 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. Count the lines
that are a box (`grep -cE '^[0-9]+ [0-9]+ '`), not the output. The repair moved 650 of those
boxes, all from the collapsed-share correction; every commit since has been
byte-identical to `84dad21`.
the **cold dump**. `layout_dump` over 400 depth-5 trees is **34,571** boxes
since `2dba90b` grew images in the trees, and `0d03267` left every one of them
byte-identical. It was 34,488 before the images; the fourth through eighth
sweeps all repeated 34,492, which is a `wc -l` of the whole run rather than of
its box lines, so count the lines that are a box
(`grep -cE '^[0-9]+ [0-9]+ '`). 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`.
**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
@@ -185,19 +192,24 @@ glyphs do not follow a shortened entry.
- A `leftover` under a parent that does not divide is a minimum size --
`max(box, px + rel*box)` (Bryan, 2026-09-20), which is a `SizeRule::Min` of
`rel(1.0)` and shares `Painter::longer_than` with the span. Done in
`b295c8b` for a widget its parent asks; `root_layout` still reads the old
way, for which see `docs/LAYOUT_LOG.md`.
`b295c8b`, and in `0d03267` for the root as well, which used to read it the
old way.
- `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. `Min` is `Painter::longer_than` again -- a `leftover` where
nothing divides it is already a `Min` of `rel(1.0)` -- so it belongs on
that path rather than beside it.
- `SizeRule::{Min, Max, Clamp}` is written and pushed as `layout/bounds`
(`76aaf06`), and **is not ready to land**: every hand-written test passes,
including a capped scroll taking its viewport from the cap, but the
400-seed scan does not, and the reason is a design question Bryan has to
settle -- see `docs/LAYOUT_LOG.md` under "Bounds are a rule that reads its
box". Bryan settled two things already: `Max` narrows the child's drawing
box (2026-09-20), and a rule gives a length or bounds one but never both,
since a capped share is said with two widgets. A cap may not contain
`leftover`.
- `LazySpan`.
- `Scroll` taking a direction rather than one axis.
Other product work is in `docs/PLAN.md` and the focused documents it links.