Record the drift a partial repaint causes, and the rigs that reduced it
The oracle and the shrinker had separate generators and separate copies of every scenario, so a failure one found could not be handed to the other: a seed cannot be made smaller. Iris `98d4e98` splits growing a tree into describing one and building it, and puts the cases in one place both rigs run. Any failing seed now reduces with one command, which is written down here. What it found first: marking one widget for redraw moves a span inside a scroll 24px against a cold tree of the same state -- a whole child's height, not a rounding. Five widgets, bisected to `95fb4f9`, where `Masked` began reporting its box rather than its inner's size. Written out and ignored in `tests/cases/unsettled.rs` until it is fixed. Two claims in the verification list were withdrawn against a re-run rather than an argument. The shrinker's "all five cases at 300 seeds of depth 5" does not carry to a rig that runs fifteen cases over different trees and fails at 400. The 1000-seed depth-6 line does not hold at `5ed9e87` either, which fails it on seed 40 after a resize -- so that run was never the clean baseline it was quoted as. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
10e46522b4
commit
bb5b79f2f6
1 file changed
+64
-9
+64
-9
@@ -8,7 +8,7 @@ log.
|
||||
|
||||
Canonical Iris `main` is **`ca2b4b2`** (#17, the headless rig). **#18
|
||||
`split/18-position-chain`** is open in `/home/bob/repos/iris-pr18`; its local
|
||||
head is **`4febabf`**, seventy-one commits. Built-in alignment is complete there;
|
||||
head is **`98d4e98`**, seventy-two commits. Built-in alignment is complete there;
|
||||
see "Built-in alignment" below for the retained-layout details. No PR reviews
|
||||
were present when checked on 2026-09-15.
|
||||
|
||||
@@ -89,6 +89,53 @@ rewrite:
|
||||
`core/src/ui/holds.rs`, the retained tests, and the generated cold-layout oracle
|
||||
pin those rules. Seeds 10 and 86 are now in the ordinary generated set.
|
||||
|
||||
## A warm frame moves a scrolled span, and the rigs that found it
|
||||
|
||||
**The defect.** Marking one widget for redraw moves a span inside a scroll by
|
||||
24px against a cold tree of the same state. Five widgets, in
|
||||
`tests/cases/unsettled.rs` as
|
||||
`redrawing_one_widget_does_not_move_what_scrolls_around_it`, **ignored until
|
||||
it is fixed** so the suite stays honest rather than red:
|
||||
|
||||
Scroll(Y) { Span(DOWN) { Scroll(X){ text } as a region node, rect 87x24 } }
|
||||
|
||||
`git bisect` names **`95fb4f9`**, which made `Masked` report `Size::LEFTOVER`
|
||||
rather than its inner's size. `Scroll` clips through a `Masked`, so what the
|
||||
outer scroll is told its content measures now depends on whether the inner
|
||||
subtree was redrawn this frame. The reasoning in that commit is sound -- a
|
||||
widget that clipped its contents cannot honestly ask for more than its box --
|
||||
so the fix is not to revert it but to stop the outer scroll's content
|
||||
measurement from going through the clipped report. Not attempted yet.
|
||||
|
||||
24px is exactly the sized child's height, so this is a whole child's worth of
|
||||
layout rather than a rounding.
|
||||
|
||||
**The rigs.** `98d4e98` splits `iris::random::grow` into `plan(seed, depth,
|
||||
&edits)` and `build(rsc, &plan)`. A seed cannot be made smaller, which is why
|
||||
a failure the oracle found could never be handed to the shrinker; a `Plan`
|
||||
can, and `tests/scenario/` holds the fifteen cases both rigs now run over the
|
||||
same trees. So any failing seed reduces directly:
|
||||
|
||||
SHRINK_SEED=18 SHRINK_DEPTH=6 SHRINK_CASE=repaint-some \
|
||||
cargo test --release --test shrink -- --ignored --nocapture
|
||||
|
||||
That took seed 18's 277 widgets to 5. The oracle prints the command to reduce
|
||||
whatever it failed on. Seeds still mean the trees they meant: the 1000-seed
|
||||
depth-6 run gives the same three failures with the same boxes before and after
|
||||
the split, which is the check to repeat if the generator is touched again.
|
||||
|
||||
**Unreduced leads**, from the shrinker at 400 seeds of depth 5 -- a level it
|
||||
had never run, since it used to grow its own trees and know five cases:
|
||||
**seeds 2 and 288 on `region-node`**, and **174 and 175 on `repaint-some`**.
|
||||
The `repaint-some` pair is probably the defect above. The `region-node` pair
|
||||
is not obviously the same thing and is the next one to reduce.
|
||||
|
||||
**Depth is what finds these.** Nothing fails at 100 seeds of depth 4, which is
|
||||
all the oracle has ever routinely run. Seeds 18, 190 and 326 fail at depth 6
|
||||
of 1000. Before fixed point, `5ed9e87` fails that same run on seed 40 after a
|
||||
resize and on nothing else, so the partial-repaint family is new since then
|
||||
and the resize one is older than all of it.
|
||||
|
||||
## Verification at `394d514`
|
||||
|
||||
`4febabf` on top of it -- `Fixed` wrapping rather than saturating -- passed
|
||||
@@ -102,11 +149,12 @@ against `394d514`. The measurements are under "Performance".
|
||||
- `cargo test --workspace --all-features`: 105 passed, 10 ignored
|
||||
- The release generated cold-layout oracle passed 100 seeds in 9.4 s, and a
|
||||
shrinker case at 300 seeds in 3.5 s: both run a thread per core but one.
|
||||
- The release shrinker passed **all five** cases -- `resize`, `repaint`,
|
||||
`resize-repaint`, `reorder`, `size-change` -- at 300 seeds of depth 5:
|
||||
26,001 widgets per case, largest tree 331. It passed 1000 seeds of depth 6
|
||||
(159,024 widgets per case, largest tree 587) at `5ed9e87`, before fixed
|
||||
point; re-run that before quoting it again.
|
||||
- The release shrinker passed **all five** cases it had then -- `resize`,
|
||||
`repaint`, `resize-repaint`, `reorder`, `size-change` -- at 300 seeds of
|
||||
depth 5. **That claim does not carry to `98d4e98`**, which runs fifteen
|
||||
cases over the oracle's trees rather than five over its own, and fails at
|
||||
400 seeds of depth 5. Neither does the 1000-seed depth-6 line that used to
|
||||
sit here: re-run, `5ed9e87` fails it too, on seed 40 after a resize.
|
||||
- `tabs`, `view`, `minimal`, `text` and `random` render byte-identical at
|
||||
1920x1200 across the whole fixed-point sequence, and across this session's
|
||||
renames and arithmetic changes on top of it.
|
||||
@@ -621,9 +669,16 @@ cargo test --release --test generated -- --ignored a_long_run_of_seeds_agrees
|
||||
|
||||
`tests/generated.rs` compares a warm incremental tree with a cold tree of the
|
||||
same state. `IRIS_GENERATED_SEED`, `IRIS_GENERATED_SEEDS`, and
|
||||
`IRIS_GENERATED_DEPTH` select failures. `tests/shrink.rs` reduces a failing
|
||||
tree; use it to turn a seed into a readable regression rather than leaving the
|
||||
seed as the only record.
|
||||
`IRIS_GENERATED_DEPTH` select what it covers. `tests/shrink.rs` reduces a
|
||||
failing tree, over the same fifteen cases and the same trees since `98d4e98`,
|
||||
so a seed the oracle fails on goes straight to it -- the failure prints the
|
||||
command. `SHRINK_SEED`, `SHRINK_SEEDS`, `SHRINK_DEPTH`, and `SHRINK_CASE`
|
||||
(a case name, or `all`) select what it tries. Turn what it finds into a test
|
||||
of its own rather than leaving a seed as the record.
|
||||
|
||||
The fifteen cases live in `tests/scenario/mod.rs`, which both targets include
|
||||
by `#[path]`. Adding one there gives it to both rigs at once; a case that only
|
||||
one of them knows is how the two drifted apart in the first place.
|
||||
|
||||
**The float head is checked out at `/home/bob/repos/iris-float-cmp`**, at
|
||||
`5ed9e87` with `394d514`'s `Edits::fixed_branches` cherry-applied to
|
||||
|
||||
Reference in new issue
Block a user