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 ## The Iris layout repair is submitted
**Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `69ba915`, **Iris PR #19** (`layout/one-ask`) replaces closed #18. The tip is `7502176`,
and past the reviewed `cadfba0` it is six rounds, each described in and past the reviewed `cadfba0` it is seven rounds, each described in
`docs/LAYOUT_LOG.md`: `docs/LAYOUT_LOG.md`:
- **The repair**, `add6774` and `84dad21` -- collapsed-share placement, - **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 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 read, three reuse rejections the diagnostics could not see, and a fuzz case
that ran only in the long scan. 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 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 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 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 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 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 **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 -- 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 it (settled design, the measurement method) belongs in `docs/LAYOUT.md`, and
the current plan is in `docs/HANDOFF.md`. 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) ## Quality sweep of the whole branch (2026-09-20)
A fourth sweep, over the layout core, the arithmetic, the atlas, the sensor A fourth sweep, over the layout core, the arithmetic, the atlas, the sensor