Record decided-box oracle blocker
This commit is contained in:
1 parent
3eda6f00c8
commit
39978ff8ea
2 files changed
+110
-29
No files matched your search
+41
-29
@@ -16,19 +16,20 @@ baseline this work must preserve or improve. `/home/bob/repos/iris-pr18` has
|
||||
since moved to a different WIP branch; do not use that checkout as #18.
|
||||
|
||||
The continuation is `/home/bob/repos/iris-layout-experiment`, branch
|
||||
`wip/transparent-frames`, head **`4328eac`**, five commits over **`34cafb6`**.
|
||||
It implements transparent frames, pins the two open failures, and corrects
|
||||
`Scroll`'s content length, but it is not ready to replace #18:
|
||||
`wip/transparent-frames`, committed head **`4328eac`**, five commits over
|
||||
**`34cafb6`**, plus an uncommitted step 3/4 experiment. It implements
|
||||
transparent frames, pins the two open failures, and corrects `Scroll`'s
|
||||
content length, but it is not ready to replace #18:
|
||||
|
||||
- the shrinker disagrees warm versus cold at seed 2 (`repaint`) and seed 108
|
||||
(`reorder`) at depth 5;
|
||||
- the uncommitted experiment passes both focused regressions and the 114-test
|
||||
suite, but every non-ignored fast-oracle case stops on a cold-layout
|
||||
placement assertion, usually at `Text`;
|
||||
- `many` and `resize` still do more work than #18 on a deep tree;
|
||||
- a resolved `leftover` share does not yet narrow its child's frame;
|
||||
- step 3 exposed a widget-contract question that must be planned before the
|
||||
retained protocol can change; see **Step 3 stop** below.
|
||||
|
||||
The app's Iris pin is unchanged. The step 3 experiment described below was
|
||||
reverted; the experiment checkout was clean at `4328eac` when last inspected.
|
||||
The app's Iris pin is unchanged. Keep the experiment's uncommitted changes as
|
||||
evidence; do not commit them as the protocol until the stop below is resolved.
|
||||
|
||||
## The two rules to protect
|
||||
|
||||
@@ -214,29 +215,40 @@ fresh-answer experiment (seeds 184, 246, 292 and 372).
|
||||
|
||||
### 3. Evaluate children in parent-decided boxes
|
||||
|
||||
**STOP: this step needs planning before implementation continues.** A direct
|
||||
implementation was tried and fully reverted. It always kept the fresh answer,
|
||||
made placement reuse-or-translate (asserting if the retained drawing did not
|
||||
hold), asked `Span` children provisionally in the whole box before decided
|
||||
placement, gave `Stack` overlays the sizing child's reported box, and changed
|
||||
the random `Branch` tail to `Part::Of(40px..FULL)`. Both new focused tests
|
||||
passed, but 17 ordinary suite tests failed.
|
||||
**STOP: this step needs planning before implementation continues.** The first
|
||||
17 suite failures were not sufficient evidence for stopping: most were test
|
||||
fixtures that encoded the old paired-draw cost while their empty drawing used
|
||||
only the answer. The experiment now separates answer-only pixel reads from
|
||||
drawing reads, keeps answer and final-drawing contracts independent, asks
|
||||
`Span` children provisionally with `Fill`, re-asks them in their decided
|
||||
slots, narrows resolved-share frames, and re-asks local redraws at the
|
||||
question their answer came from. It also fixes two real defects found along
|
||||
the way: an overfull span falsely pinned itself to `far`, and a narrowed share
|
||||
frame omitted a nonzero parent-extent start.
|
||||
|
||||
Several failures state a load-bearing contract contrary to this plan rather
|
||||
than exposing another container bug. `ReadsBox` and `ReadsWidth` deliberately
|
||||
read the offered box, report one quarter of it, and their tests require two
|
||||
draws: one to answer and one in the answer-derived box. The tests' own comment
|
||||
says those draws come in pairs. `a_widget_asked_again_on_another_layer_is_drawn_there`
|
||||
likewise requires a second draw when placement changes the layer. Other
|
||||
failures include root resize/one-step validity tests, region-node placement,
|
||||
and `a_one_pixel_line_keeps_its_pixel_through_a_chain`.
|
||||
That version passes the full 114-test suite, both focused regressions, the
|
||||
region-node test, the one-pixel chain, and the wrap-at-remaining-room test.
|
||||
The tests were checked individually before migration; geometry assertions
|
||||
were retained, and drawing-dependency fixtures still use ordinary `px_len`.
|
||||
|
||||
The unresolved decision is therefore public widget semantics, not another
|
||||
definition of measurement: either a widget must now guarantee that a drawing
|
||||
holds for the answer box it reports (and the contrary tests, documentation,
|
||||
and any real widgets must be redesigned), or placement sometimes has to run
|
||||
the body in an answer-derived box, contradicting the decided-box rule. Do not
|
||||
resume step 3 until that choice and its migration are written into the plan.
|
||||
The release fast oracle then stopped in all eleven non-ignored cases during
|
||||
*cold layout*, before any warm/cold comparison. The repeated shape is a leaf,
|
||||
usually `Text`, asked provisionally in a `Within` box, reporting a smaller
|
||||
answer, whose retained drawing contract covers only the provisional pixel
|
||||
width. Placement into the reported box therefore hits the new
|
||||
reuse-or-translate assertion. One representative assertion shows `Text` with
|
||||
an X part of `FULL`, a centered answer span about 89.5 px wide, and a drawing
|
||||
extent contract pinned at 45 px. A generated `Stack` also fails after
|
||||
reporting a 178x21 px answer from `FULL` while retaining an `extent_len` pin
|
||||
to `FULL`.
|
||||
|
||||
This is a real public-contract boundary, not a stale oracle: decide whether
|
||||
every leaf as well as every container must guarantee that its provisional
|
||||
drawing holds in the answer box it reports, and specify how `Text` establishes
|
||||
that guarantee, or allow some answer-derived leaf evaluation while keeping
|
||||
containers out of their own answers. The latter is a semantic distinction the
|
||||
current `Widget` API does not express. Do not weaken the assertion, special
|
||||
case `Text`, or resume the oracle until this choice is written into the plan.
|
||||
|
||||
Change placement so an answer-derived box never runs a container body.
|
||||
Placing becomes reuse-or-translate. Remove the offer/measurement gate and
|
||||
|
||||
@@ -65,6 +65,75 @@ evaluations of a ten-widget subtree in one cold layout, from `Within(cursor..
|
||||
far)` measuring rooms followed by `Fill(slot)` placing, with the span's
|
||||
`extent_len` pin forcing a redraw at every box length.
|
||||
|
||||
## Original step 3 plan, preserved verbatim (planner, 2026-09-18)
|
||||
|
||||
This is the original idea from ai-app-2 `280fad7`, kept here even as the
|
||||
handoff's stop notice changes with new evidence:
|
||||
|
||||
> ### 3. Evaluate children in parent-decided boxes
|
||||
>
|
||||
> Change placement so an answer-derived box never runs a container body.
|
||||
> Placing becomes reuse-or-translate. Remove the offer/measurement gate and
|
||||
> its retained bookkeeping only as each caller stops needing it; do not leave
|
||||
> a parallel old path.
|
||||
>
|
||||
> Three current widgets must stop depending on measuring boxes they will never
|
||||
> own:
|
||||
>
|
||||
> - `Span`: do not read `extent_len` unconditionally. Slots depend on `far`
|
||||
> only when shares exist (the decided slot fills its part) or for negative
|
||||
> direction; compute negative-direction slots from `total`. Pin the extent
|
||||
> length only in those cases.
|
||||
> - `Stack`: draw non-sizing children in `From(0..size)` on an axis where the
|
||||
> sizing child's answer is `px`/`rel`, and `All` where it is `leftover`,
|
||||
> instead of drawing them in `All` of the measuring room.
|
||||
> - `Branch` in the random rig: express "the rest of my box" as
|
||||
> `Of(40px..FULL)` rather than reading `extent_len(Y)`.
|
||||
>
|
||||
> Every drawing must hold for the answer box it supplies. The two focused tests
|
||||
> from step 1 and the existing region-node and decided-box tests must pass here.
|
||||
|
||||
The surrounding seven-step implementation plan remains in `docs/HANDOFF.md`;
|
||||
the quoted text above is the part whose interpretation is now blocked, so it
|
||||
must remain available even if the live handoff is rewritten.
|
||||
|
||||
## Step 3 experiment after verifying the tests (worker, 2026-09-18)
|
||||
|
||||
The initial 17 suite failures mixed obsolete expectations with real defects.
|
||||
`ReadsBox`, `ReadsWidth`, and `Measured` used pixel reads to compute only their
|
||||
answer; failing `Counted` cases installed a box dependency without drawing
|
||||
anything. Those fixtures encoded the old second draw inside the answer box.
|
||||
Giving the painter answer-only pixel reads preserved their invalidation and
|
||||
geometry claims while removing the obsolete paired-draw count. Separate
|
||||
fixtures still exercise actual drawing dependencies with ordinary pixel
|
||||
reads.
|
||||
|
||||
The experiment then reached a green 114-test suite. Its substantive findings:
|
||||
|
||||
- answer validity and final-drawing validity must remain independent all the
|
||||
way through `draw_inner`; returning their old combined contract falsely
|
||||
pinned wrappers such as `Pad` to provisional boxes;
|
||||
- a repeated ask of one child replaces that child's provisional final-drawing
|
||||
contract rather than intersecting both drawings forever;
|
||||
- provisional `Span` asks fill their measuring room; `Within` immediately
|
||||
tries to put the child in its own answer before the span decides anything;
|
||||
- only an actually allocated share pins final span slots to `far`; an
|
||||
overfull row with a requested but unallocated share uses fixed slots;
|
||||
- a narrowed share frame is `Part::From(slot)` of the span's *extent*, not a
|
||||
zero-based span in the forwarded frame;
|
||||
- a local redraw re-asks the question that produced the retained answer and
|
||||
marks the parent to restore any distinct final placement.
|
||||
|
||||
The release fast oracle then failed all eleven ordinary cases during cold
|
||||
layout. Most failures were `Text`: its provisional drawing was pinned to a
|
||||
pixel width that did not include the smaller box its answer selected. A
|
||||
generated `Stack` showed the same class through a symbolic `FULL` pin. This
|
||||
is stronger evidence than the original suite failures: the generated tests
|
||||
are not asserting draw counts or the old two-draw protocol, and no warm state
|
||||
exists yet. The open decision is whether the guarantee quoted above applies
|
||||
to every leaf and how `Text` can establish it, or whether answer-derived leaf
|
||||
evaluation remains legal while container evaluation does not.
|
||||
|
||||
## What the plan of 2026-09-18 got wrong (planner, same day)
|
||||
|
||||
The plan claimed the retained model rests on the frame's length being the
|
||||
|
||||
Reference in new issue
Block a user