Record the sixth sweep, and the base every sweep should have used
PR #19's base is upstream/main at ca2b4b2, not the local `main`, which tracks the fork's divergent line and sits four merged pull requests behind it. Diffing against `main` shows #10, #12, #16 and #17 as this branch's work; that is how the parley text migration's undo path kept surfacing in sweeps. Git cannot record a pull request's base and `main` cannot be renamed, so the handoff carries the note and the checkout carries `git iris-base`/`git iris-diff`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
734c521f5d
commit
0ace0e017c
2 files changed
+133
-2
No files matched your search
@@ -39,6 +39,40 @@ Two checkouts share one Git storage: `/home/bob/repos/iris` is the active
|
|||||||
`layout/one-ask` worktree, and `ai-app-2/iris` stays on `main` at the app's
|
`layout/one-ask` worktree, and `ai-app-2/iris` stays on `main` at the app's
|
||||||
`32f6ad8` pin until the integration below is ready.
|
`32f6ad8` pin until the integration below is ready.
|
||||||
|
|
||||||
|
### The base is `upstream/main`, not `main`
|
||||||
|
|
||||||
|
**Diff this branch against `upstream/main`. The local `main` is the wrong
|
||||||
|
base and gives a plausible-looking wrong answer.** PR #19 is
|
||||||
|
`iris-ai/iris:layout/one-ask` into `iris/iris:main`, which is the `upstream`
|
||||||
|
remote, at `ca2b4b2`. Local `main` tracks `origin/main` -- the *fork's* line,
|
||||||
|
which carries the app's own commits, is not an ancestor of upstream's main,
|
||||||
|
and sits four merged pull requests behind it (#10 parley text, #12 pointer
|
||||||
|
routing, #16 draw/size merge, #17 headless rig).
|
||||||
|
|
||||||
|
git diff main...layout/one-ask # WRONG -- base 7b54aaf
|
||||||
|
git diff upstream/main...layout/one-ask # right -- base ca2b4b2
|
||||||
|
|
||||||
|
`git iris-base` and `git iris-diff` are configured in this checkout and use
|
||||||
|
the right one. The authority is gitea, when it matters:
|
||||||
|
|
||||||
|
curl -s -H "Authorization: token $(cat ~/.config/gitea/token)" \
|
||||||
|
https://git.arirex.me/api/v1/repos/iris/iris/pulls/19 \
|
||||||
|
| python3 -c 'import json,sys; print(json.load(sys.stdin)["base"]["sha"])'
|
||||||
|
|
||||||
|
Nothing here can be fixed by renaming: `main` is the app submodule
|
||||||
|
worktree's checked-out branch at its `32f6ad8` pin, and the two worktrees
|
||||||
|
share one ref store. Git has no way to record a pull request's base, so the
|
||||||
|
note is the mechanism.
|
||||||
|
|
||||||
|
This has already cost real work. The sixth sweep reviewed against local
|
||||||
|
`main` for half a session (Bryan caught it, 2026-09-20), and reported the
|
||||||
|
parley migration's undo path as this branch's. The fourth and fifth sweeps
|
||||||
|
deleted `Painter::text_data`, `ActiveData::size_deps` and `SizeRule::apply`
|
||||||
|
partly on the same false reading; the deletions stand on their own merits --
|
||||||
|
`text_data` had no caller at `ca2b4b2` either, and `size_deps` was read there
|
||||||
|
and orphaned by this branch's rewrite -- but "arrived on this branch" was not
|
||||||
|
the reason for all of them.
|
||||||
|
|
||||||
### How to check a round
|
### How to check a round
|
||||||
|
|
||||||
**Always**, because they cost nothing: format, workspace clippy under
|
**Always**, because they cost nothing: format, workspace clippy under
|
||||||
|
|||||||
+99
-2
@@ -6,6 +6,99 @@ 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`.
|
||||||
|
|
||||||
|
## Sixth sweep: the shader boundary and the position widgets (2026-09-20)
|
||||||
|
|
||||||
|
Over what the five earlier rounds did not name -- the WGSL prelude and how
|
||||||
|
it is assembled, the position widgets, `orientation/`, and the sensor walk.
|
||||||
|
**Scoped against `upstream/main` at `ca2b4b2`, which is PR #19's real base**;
|
||||||
|
the first half of this sweep used the local `main` and had to be redone, for
|
||||||
|
which see "The base is `upstream/main`" in `docs/HANDOFF.md`. Two findings.
|
||||||
|
The cold dump is byte-identical to `1096c31` and all three seed scans pass
|
||||||
|
(400 at depth 5 in 69.07s, 1,000 at depth 6 in 169.29s, 2,000 at depth 4 in
|
||||||
|
300.75s).
|
||||||
|
|
||||||
|
**A number both sides count in, written twice.** `module_source` already
|
||||||
|
builds each shader's preamble from `iris_core`'s own constants, with a
|
||||||
|
comment saying why: "a grid the two disagree about puts every coordinate
|
||||||
|
somewhere else". The move-chain work then added, to the very file it
|
||||||
|
prepends, a second copy of two of its own numbers -- `const MOVE_NONE` and
|
||||||
|
`const CHAIN_LIMIT`, under "Keep in step with `iris_core::CHAIN_LIMIT`" --
|
||||||
|
asking a reader by hand for what the mechanism beside it exists to do, and
|
||||||
|
duplicating the reasoning `CHAIN_LIMIT`'s Rust declaration already carries.
|
||||||
|
Both are injected now and the shader declares neither.
|
||||||
|
`every_shader_validates` composes the real preamble so it covers the change;
|
||||||
|
what it could never have caught is the two numbers drifting apart, which is
|
||||||
|
now unrepresentable.
|
||||||
|
|
||||||
|
`MASK_NONE` went in beside them, replacing a bare `4294967295u` in `masked`
|
||||||
|
-- where the CPU deliberately keeps `MaskIdx` and `MoveIdx` as separate
|
||||||
|
types so the two cannot be swapped. **That literal pre-dates this PR**; it
|
||||||
|
is a one-line drive-by in a block the PR was already rewriting, taken
|
||||||
|
because leaving it means a named sentinel for one index and a magic number
|
||||||
|
for its sibling four lines apart. Drop it if the scope matters more.
|
||||||
|
|
||||||
|
**A scroll positioning content it does not position.** Two halves, one
|
||||||
|
mistake, both new in this PR -- the base's `Scroll` has none of this
|
||||||
|
machinery. The author believed `Scroll` places its own content.
|
||||||
|
|
||||||
|
`content_len` is `answer_px.max(container_len)`, so it is never less than
|
||||||
|
the box. Two lines on, `slack` was `(container_len - content_len).max(ZERO)`
|
||||||
|
and `anchor` was `slack * align.rel()` -- provably always zero, whatever the
|
||||||
|
alignment, with `moved` then testing `anchor != ZERO` for nothing.
|
||||||
|
Instrumented at `1096c31`, a centred scroll over 50 px of content in a
|
||||||
|
200 px box prints `slack=0 align=AxisAlign(0.5) anchor=0` and centres the
|
||||||
|
content anyway: the framework does it, by placing the inner's answer in the
|
||||||
|
whole box, which comes out as `rel 0.5 - px 25` and resolves at any length.
|
||||||
|
The comment credited the arithmetic for behaviour it could not produce.
|
||||||
|
|
||||||
|
The same belief cost a redraw. The contract for content that fits was
|
||||||
|
guarded by `align == AxisAlign::NEG`, on the reasoning that at any other
|
||||||
|
alignment "it moves with every length the box takes and the drawing holds
|
||||||
|
for that length alone". It does not move -- the framework's placement is a
|
||||||
|
fraction of the box -- and the default alignment is the middle, so the
|
||||||
|
common case was the guarded one. `Painter::px_len` holds a drawing to the
|
||||||
|
length it read unless the widget says otherwise, so with no `holds` stated
|
||||||
|
the scroll redrew on every box change. Measured with `distinct_widgets`: 1
|
||||||
|
at `CENTER`, 0 at `TOP_LEFT`. Dropping the alignment test gives 0 at all
|
||||||
|
three, which is what `a_fitting_scroll_holds_for_every_box_its_content_fits_in`
|
||||||
|
asserts; it fails at `1096c31` on the `CENTER` case. `align` had no other
|
||||||
|
reader, so the widget no longer asks its own alignment at all -- which is
|
||||||
|
the tell that both halves were one mistake.
|
||||||
|
|
||||||
|
**`UiSpan::translated` and `UiRegion::translated`** arrived on this branch
|
||||||
|
and are reachable only from each other, which is why a plain "is this name
|
||||||
|
used anywhere else" scan does not see them: neither looks unused on its own.
|
||||||
|
The region one carried a performance argument for a function nobody calls.
|
||||||
|
Both deleted.
|
||||||
|
|
||||||
|
### Kept although they pre-date this PR
|
||||||
|
|
||||||
|
`GlyphAtlas::glyph_count`, `TextBuffer::new_empty` and the let-chain in
|
||||||
|
`TextEdit::apply_event` that #10 had expanded into a nested `if`. All three
|
||||||
|
were found under the wrong base and are outside #19's diff; Bryan said to
|
||||||
|
keep them anyway (2026-09-20), since the two are dead either way and the
|
||||||
|
third is a straight restoration.
|
||||||
|
|
||||||
|
### Tripped a rule and left as it stands
|
||||||
|
|
||||||
|
- `diag::untrace_widget` is new here with no caller, which is the test the
|
||||||
|
`translated` pair was deleted by. Left: it is the "removed" half of what
|
||||||
|
`trace_widget`'s own doc promises ("until explicitly removed or cleared"),
|
||||||
|
and `clear_traced_widgets` is the "cleared" half and does have one. A rig
|
||||||
|
drives this API from outside.
|
||||||
|
- `UiSpan::flip` swaps `start.rel` with `end.rel` and `start.px` with
|
||||||
|
`end.px`, where `Len` has exactly those two fields and one swap of the
|
||||||
|
structs would do. Pre-dates this PR.
|
||||||
|
- `UiVec2` translates under three names -- `shift`, `offset`, and
|
||||||
|
`UiRegion::offset` -- beside `Len::offset`, which adds pixels to one end
|
||||||
|
and is a different operation. Pre-existing, and one vocabulary is Bryan's
|
||||||
|
call rather than a sweep's.
|
||||||
|
- The nine `#[allow(unused_variables)]` are all on trait methods with empty
|
||||||
|
default bodies, where the parameter names are the signature's
|
||||||
|
documentation and underscoring them would hide it from implementors.
|
||||||
|
- `GpuPages::update` grows before it drains and both go through the one
|
||||||
|
queue, so the copy is ordered before the writes. Correct as it stands.
|
||||||
|
|
||||||
## Fifth sweep: the retained path, the renderer and the diagnostics (2026-09-20)
|
## 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
|
Over the parts the four earlier rounds did not read -- the renderer, the
|
||||||
@@ -79,8 +172,12 @@ throughout, `LayoutLen::{is_px, is_only_leftover, declared, fills}` and
|
|||||||
same words share an answer" means, which is a design question.
|
same words share an answer" means, which is a design question.
|
||||||
- `TextEdit`'s undo history pushes a whole copy of the text per changed
|
- `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
|
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
|
event including the arrow keys. **`apply_event` is not in this PR's diff at
|
||||||
by this branch, so they belong to a change of their own.
|
all**: it was last touched by #10 and #16, both already on `upstream/main`.
|
||||||
|
It keeps resurfacing in sweeps because they diffed against the local `main`
|
||||||
|
-- see "The base is `upstream/main`" in `docs/HANDOFF.md`. Bryan wants the
|
||||||
|
unbounded push and the clone dealt with as a change of their own
|
||||||
|
(2026-09-20).
|
||||||
- `ActivationState::update` writes four arms where the `Start`/`On` and
|
- `ActivationState::update` writes four arms where the `Start`/`On` and
|
||||||
`End`/`Off` pairs are identical, and `is_off` is `!is_on`. Also verbatim
|
`End`/`Off` pairs are identical, and `is_off` is `!is_on`. Also verbatim
|
||||||
from `main`.
|
from `main`.
|
||||||
|
|||||||
Reference in new issue
Block a user