Move the round detail out of the handoff, and say when a scan is owed

The handoff said "three rounds" over four bullets and carried the detail of
each, which belongs in the findings log. It now names the four and their
commit ranges and points at `LAYOUT_LOG.md`, which gains the naming and
sweep round in full.

The check section split in two: the cheap gate runs on every change
including a rename, because the cold dump is the only thing that catches two
same-typed values being swapped; the seed scans run only when the change can
alter what layout computes, and never with the tree still moving under them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-19 22:27:34 -04:00
1 parent d12cbcd499
commit 1442443e78
2 files changed
+81 -39

No files matched your search

+52
View File
@@ -6,6 +6,58 @@ 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`.
## Naming and logic sweep (2026-09-19)
Settled with Bryan across one session, on the branch past `58ce74d`. Nothing
here changed what layout computes: the cold dump is byte-identical to
`58ce74d` at every commit.
**How a description is said.** A `PlaceDescAxis` is built by chaining off the
value that says it -- `UiSpan::within_desc`/`shifted_desc`, `Len::as_desc` --
never by a constructor naming the type, because a constructor sends the
reader back to the start of the line. The `_desc` suffix is what says which
type comes out. `PlaceDescAxis::on_axis(axis)` lifts one axis into a pair
with the whole box across it; `on` alone was rejected as contentless and
reserved for events. `from_axes` is the constructor taking a function, beside
the `from_axis` taking one axis and two values.
**Arithmetic that needed a comment became a name.** `UiSpan::place` was the
aligned-placement rule written out three times; `LayoutLen::without_leftover`
was the sibling `apply_leftover` never had, at six sites; `is_px`,
`is_only_leftover` and `declared` name field comparisons the surrounding
comments had to translate; `Holds::covers` was interval containment by hand.
Seven module-level functions became methods on the value each took first.
**Every pair is a struct of two per-axis values, read with `[axis]`.**
`LayoutHolds` was four two-element arrays, so none of its own operations
could be written once; it is `AxisHolds` on `x` and `y`, and `and`, `covers`
and `contains` lost their loops. `impl_axis_index!` gives every pair
`Index<Axis>`/`IndexMut<Axis>`, replacing eighteen `axis`/`axis_mut`
methods -- `const_index` keeps them usable in const context. The bare
`[Option<LayoutLen>; 2]` became `Declared` of `Option<Len>`, which makes
"a share is never a declaration" structural rather than two filters and a
comment.
**Two findings in the logic, both one mistake.** A value computed from other
state was being stored as if it were state, and in both cases the visible
symptom was something that looked like an off-by-one:
- A `Span` carried `start` as a third accumulator beside `fixed` and `taken`,
assigned at three points, when every assignment was `reached(fixed,
taken)`. Both ends of a slot are now read where they are used; the variable
and two of the three calls per child go, and the gap added after the last
child derives nothing rather than needing to be subtracted.
- The measuring loop's `cursor` added `px` and `rel` by hand where the
placing loop below said `fixed += len.without_leftover()` -- the same sum,
one of them named.
**One property that held but nothing guarded.** A `Scroll`'s draw writes
`amt` and `snap_end`, so a second draw at another viewport reads what the
first wrote. Warm matches cold only because re-clamping is idempotent and
monotone. The seed scans build `Scroll`s and never scroll one, so this was
untested; `a_scrolled_view_resized_lands_where_a_cold_layout_puts_it` scrolls
four distances, one past the end, then widens. It passes.
## Follow-up implementation review (2026-09-19)
The ask/place split, window-unit frames, exact validity preimages, and