Record the fifth sweep and point the handoff at 7502176

The renderer, the text store, the input default and the harness, which the
four earlier rounds did not read, plus a second look at `redraw`.
This commit is contained in:
iris-ai committed 2026-09-20 01:03:05 -04:00
1 parent 03c8933612
commit 718923c217
2 files changed
+79 -3

No files matched your search

+7 -3
View File
@@ -6,8 +6,8 @@ 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 `69ba915`,
and past the reviewed `cadfba0` it is six rounds, each described in
**Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `7502176`,
and past the reviewed `cadfba0` it is seven rounds, each described in
`docs/LAYOUT_LOG.md`:
- **The repair**, `add6774` and `84dad21` -- collapsed-share placement,
@@ -23,6 +23,10 @@ and past the reviewed `cadfba0` it is six rounds, each described in
against the placed box rather than the box asked about, two things nothing
read, three reuse rejections the diagnostics could not see, and a fuzz case
that ran only in the long scan.
- **A sweep over the renderer, the text store and the retained path**,
`d8d5122` through `7502176` -- a contract kept where the new window left
it out, a surface configured under its own texture, a counter naming the
wrong contract, and three things nothing reads.
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
@@ -42,7 +46,7 @@ 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.
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
+72
View File
@@ -6,6 +6,78 @@ nothing here is rediscovered. Each entry says who found it and when.
it (settled design, the measurement method) belongs in `docs/LAYOUT.md`, and
the current plan is in `docs/HANDOFF.md`.
## Fifth sweep: the retained path, the renderer and the diagnostics (2026-09-20)
Over the parts the four earlier rounds did not read -- the renderer, the
text store, the input default, the harness -- and once more over `redraw`.
Four findings, `d8d5122` through `7502176`. The cold dump is byte-identical
to `781199a` and all three seed scans pass (400 at depth 5 in 69.45s, 1,000
at depth 6 in 214.69s, 2,000 at depth 4 in 419.50s).
**A contract was kept where it no longer held** (`d8d5122`). The sibling of
`713e3e7`, in the same function. `redraw` keeps the narrower of the old and
the fresh contract so widening and narrowing back do not churn the parent.
The drawing's half asks `was_holds.contains(window, rel_base, region)` first;
the answer's half did not. A widget whose answer contract widened in a frame
that also resized the window therefore kept a range the new window is
outside, and the parent's next ask refused it and redrew the whole subtree --
throwing away the drawing that widget had just made. Cost, not geometry: the
size kept is the size just reported. It needs both a resize the root does not
absorb and a mark on a deeper widget in the same frame, which is what
`a_contract_this_window_is_outside_is_not_kept` builds; it draws the leaf
twice at `781199a` and once with the guard in.
**Configuring a surface under its own texture** (`02048ea`). wgpu 30 says at
both `Surface::configure` and `Surface::get_current_texture` that configuring
while a texture the surface handed out is still alive panics. The
`Suboptimal` arm of `UiRenderer::draw` configured with the texture it was
about to draw with in hand, so the first suboptimal frame -- a resize or a
display change on some drivers -- takes the app down rather than rebuilding
the swapchain. The texture is good for that frame, so it is drawn with and
presented and the rebuild happens after `present` consumes it. Not
reproducible on demand here; the claim rests on wgpu's own documented panic.
**A counter named the wrong contract** (`9b4cc32`). `AxisHolds` is four
contracts and `diag::outside` counted three: a refusal because this window
is outside the range the drawing was made for bumped "reuse outside: a rel
base". A window range is pixels and a rel base pin is a window-unit length an
unchanged window can still change, so the rig answered "why did that
redraw?" with the wrong one for every resize. Same class as `8088a1f`.
**Three things nothing reads** (`7502176`). `Axis::pair` and
`RegionAlign::NEAR` arrived on this branch with no caller and never got one;
`Holds::contains` took `&self` where its five siblings on the same `Copy`
pair take `self`. The comment beside a span's cross-axis accumulator said a
scalable child "makes Children scalable too" -- `Children` names nothing in
this repository, and what it makes scalable is the span.
### Tripped a rule and left as it stands
- `Painter::text_data` has no caller either, and is the only way a widget in
`draw` can reach `TextData` at all (`painter.rsc` is private). It replaces
`main`'s `text_resources`, which the app does not call today but which the
pending integration may want. Deleting a framework's one escape hatch to
the text store while the app is still on the old pin is not a sweep's call.
- `TextData`'s spare store clones the whole string into `Placed` on every
re-break. Bounded at 128 entries, but the clone is per re-break and
proportional to the text; a transcript-sized text would pay it on every
width change. Left because a cheaper key changes what "two texts of the
same words share an answer" means, which is a design question.
- `TextEdit`'s undo history pushes a whole copy of the text per changed
keystroke and is never bounded, and `apply_event` clones the text on every
event including the arrow keys. Both are on `main` verbatim and unchanged
by this branch, so they belong to a change of their own.
- `ActivationState::update` writes four arms where the `Start`/`On` and
`End`/`Off` pairs are identical, and `is_off` is `!is_on`. Also verbatim
from `main`.
- `TextView::draw`'s empty-with-hint branch matches on `self.hint` again
after `is_some()` guarded it, so its `None` arm is unreachable. The guard
cannot become an `if let` because `self.render(painter)` needs `&mut self`
between the two. Left rather than cloning the handle to satisfy the shape.
- `CurrentSurfaceTexture::Lost` is answered by reconfiguring, where wgpu says
to recreate the surface. It will not panic, and recreating needs the
window; worth doing with the next renderer change rather than this one.
## Quality sweep of the whole branch (2026-09-20)
A fourth sweep, over the layout core, the arithmetic, the atlas, the sensor