Record the exact composition, and the seed it stops one step short of

`45a7176` composes a box down its move chain on a grid fine enough to round
once instead of once a level. `Holds::through`'s two-route allowance is two
half steps where it was three, and it cost nothing: 1,880M instructions and
755M cycles against 1,908M and 760M, with all twenty-five work counters
identical. What paid for the widening is that a length composes on its own in
half the multiplies both ends of a box need, and that only the fraction needs
the extra room.

The i64 item in "Next" keeps the measurement that redirected it, since
aiming the work at the screen invariant would have been wasted.

One half step further is arithmetically available and not taken: shrinker
seed 220 on `reorder` then diverges warm against cold, by re-breaking a
wrapping text whose reported width moves a `Branch` onto its other subtree.
That is written up under the `Holds::through` invariant with its reduction
command and its ten-widget tree, and it is the next thing to chase.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-16 21:31:37 -04:00
1 parent b0c13b85a9
commit da2f93254e
1 file changed
+45 -23
+45 -23
View File
@@ -8,7 +8,7 @@ log.
Canonical Iris `main` is **`ca2b4b2`** (#17, the headless rig). **#18 Canonical Iris `main` is **`ca2b4b2`** (#17, the headless rig). **#18
`split/18-position-chain`** is open in `/home/bob/repos/iris-pr18`; its local `split/18-position-chain`** is open in `/home/bob/repos/iris-pr18`; its local
head is **`d21a215`**, eighty commits, pushed. Built-in alignment is head is **`45a7176`**, eighty-one commits, pushed. Built-in alignment is
complete there; see "Built-in alignment" below for the retained-layout complete there; see "Built-in alignment" below for the retained-layout
details. No PR reviews were present when checked on 2026-09-15. details. No PR reviews were present when checked on 2026-09-15.
@@ -167,15 +167,16 @@ in, and it is compiled out of the release runs above.
## Verification ## Verification
**At `e166e00`**, the current head: **At `45a7176`**, the current head:
- `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- - `cargo fmt --all --check`, `cargo clippy --workspace --all-targets --
-D warnings`, `cargo test --workspace`: sixteen targets green, 83 suite -D warnings`, `cargo test --workspace`: sixteen targets green, 83 suite
tests, 17 core unit tests, 11 generated cases. What stays ignored is the tests, 17 core unit tests, 11 generated cases. What stays ignored is the
long runs and the profiling rigs; no known defect is ignored any more. long runs and the profiling rigs; no known defect is ignored any more.
- The release oracle at 100 seeds in 14.3 s, **all fifteen shrinker cases at - The release oracle at 100 seeds in 14.3 s, **all fifteen shrinker cases at
400 seeds of depth 5** in 57 s, and **1000 seeds of depth 6** in 145 s. The 400 seeds of depth 5** in 57 s, and **1000 seeds of depth 6** in 143 s. The
last two pass for the first time. last two pass for the first time, and have kept passing across every
commit since.
- `view`, `minimal` and `random` render byte-identical at 1920x1200 against - `view`, `minimal` and `random` render byte-identical at 1920x1200 against
`98d4e98`. `tabs` and `text` changed twice on purpose: `08c9d5a` moved an `98d4e98`. `tabs` and `text` changed twice on purpose: `08c9d5a` moved an
antialiased edge by less than a pixel (see "Performance") and `2bc6bdf` antialiased edge by less than a pixel (see "Performance") and `2bc6bdf`
@@ -758,10 +759,29 @@ pixels and `Holds`. Decided with Bryan on 2026-09-15.
point that need not contain the box the part was drawn in. What it allows point that need not contain the box the part was drawn in. What it allows
for has two parts and they are not the same shape. for has two parts and they are not the same shape.
- **The two routes to a length** -- composed down the chain against - **The two routes to a length** -- composed down the chain against
measured against the window -- get three half steps either side. That is measured against the window -- get two half steps either side, since
the floor: two fires the `Holds` assertion on eleven generated cases. `45a7176` made the walk round once instead of once a level. It was three
Four was tried and was overshoot, and tightening it moved none of the while composing rounded per level, and four before that, which was
rig's twenty-five work counters, so slack here buys no reuse (`38eba54`). overshoot. Tightening it has never moved one of the rig's twenty-five
work counters, so slack here buys no reuse.
**One half step further is arithmetically available and deliberately not
taken.** The `Holds` assertion is quiet at one, and the whole-of-a-box
case becomes an exact identity. What stops it is shrinker seed 220 on
`reorder`, which then lays out differently warm than cold: too narrow a
range is supposed to cost a redraw and nothing else, and there it
re-breaks a wrapping text, whose reported width moves a `Branch` onto
its other subtree. **That is the next thing to chase** -- it is the
unsettled-text family rather than a rounding question, it reduces to ten
widgets, and closing it is what lets this go lower:
```sh
SHRINK_SEED=220 SHRINK_DEPTH=5 SHRINK_CASE=reorder \
cargo test --release --test shrink -- --ignored --nocapture
```
The tree is `Scroll(X) { Pad as a region node { Span(X) { Branch,
Span(X){ wrapped text, one-line text } } } }`.
- **The multiply on the way in** gets one more step at the top of the range - **The multiply on the way in** gets one more step at the top of the range
and nothing at the bottom, since truncation only ever drops. The whole of and nothing at the bottom, since truncation only ever drops. The whole of
a box has no multiply in it, however many pixels are added to it, and a box has no multiply in it, however many pixels are added to it, and
@@ -954,9 +974,10 @@ Queued from this work, in order:
since `a8898aa`. Still awaiting Bryan: whether a `Max` narrows the box the since `a8898aa`. Still awaiting Bryan: whether a `Max` narrows the box the
child draws in, or only what the parent reports for it. child draws in, or only what the parent reports for it.
- **Compose in `i64` and narrow only when storing** (Bryan, 2026-09-16). - ~~**Compose in `i64` and narrow only when storing**~~ -- **done in
Chosen for the share spread; **what it buys is not that**, found on `45a7176`**, and what it bought is below. The rest of this item is kept
2026-09-16 and worth reading before starting. because the measurement in it is what stopped the work being aimed at the
wrong thing.
The range inside a single operation is already protected -- `Fixed::mul` The range inside a single operation is already protected -- `Fixed::mul`
widens to `i64` for the product, `Holds::through` does all of its widens to `i64` for the product, `Holds::through` does all of its
@@ -986,19 +1007,20 @@ Queued from this work, in order:
pushes a value across the `floor` -- which is what moved `tabs`'s corner pushes a value across the `floor` -- which is what moved `tabs`'s corner
arcs by a pixel at `08c9d5a`. arcs by a pixel at `08c9d5a`.
What is left to buy is **layout's own decisions**, which is not nothing: What it bought is **layout's own decisions**: `Holds::through`'s two-route
the `Span` leftover boundary and the clamp crossover are structural allowance went from three half steps to two, and the whole of a box now
decisions taken on a pixel comparison, `Holds` validity is a pixel maps back to one step rather than one step per level of nesting.
interval, and warm-against-cold agreement is the thing every rig here
measures. The success test is `Holds::through`'s two-route allowance
shrinking from three half steps toward zero, in debug where the assertion
is live.
Two things to decide before starting: how many fractional bits the **And it was free.** 1,880M instructions and 755M cycles against 1,908M
intermediate keeps, since chained multiplies accumulate them and an `i64` and 760M, medians of 25 with all twenty-five work counters identical.
runs out too; and whether it keeps `UiSpan::within` inside the inliner, Two things paid for the widening and are the reason to keep them: a
which is what actually moves cycles there -- a `Wide` that makes the body *length* composes on its own in two multiplies a level rather than the
bigger loses on the axis the truncating multiply won on. four both ends cost, since where the parent sits falls out of the
difference; and the pixel term takes its fraction on the ordinary grid, so
only the fraction itself -- the part that compounds multiplicatively --
needs the room. A third, skipping a parent that spans its own box, cost
18M instructions and is not there, the same verdict `UiSpan::within`'s
short-circuits got.
Other queued work, in dependency order: Other queued work, in dependency order: