Skip to content

Settle the panel before pressing, and read the key line's whole register - #39

Merged
max-sixty merged 4 commits into
mainfrom
fix/ci-32779874922
Aug 24, 2026
Merged

Settle the panel before pressing, and read the key line's whole register#39
max-sixty merged 4 commits into
mainfrom
fix/ci-32779874922

Conversation

@leaf-agent

@leaf-agent leaf-agent commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Two test reads are holding ci red on main, one per commit, and neither can show a green test while the other stands — so they are here together rather than in two PRs that would each stay red. They revert independently; nothing in one depends on the other.

The standing mark's pointer

test_the_page_marks_the_comment_the_reader_is_standing_inPage.wait_for_function: Timeout 30000ms exceeded waiting for lf-mark-hover after the pointer is put on the standing mark. First seen on run 32779874922; the run that opened this session, 32778837094, failed instead on the note-set axis, which 90ba2a7 had already fixed four minutes after that run was queued.

The walk that puts the reader in a comment opens the panel, and the document slides into its new width over the fifth of a second that follows (syncLayout, the slide panel_settled was written for). The point handed to page.mouse.move is taken on that flight, against a column that is still moving, so the pointer goes where the mark was and the slide carries the mark out from under it. The runtime is right to drop the hover — pageShifted recomputes markAt(pointer.x, pointer.y) after the reflow, and by then the pointer is over ordinary prose. Measured at the read, on Linux:

at the move:  body animations ["margin-right"], margin-right 35.3px, point x=358
600ms later:  body animations [],               margin-right 420px,  mark spans x=172.7..236.4

Nothing retries, because a highlight is not an element — so it surfaces 30s later at the hover wait, reading as though the page had stopped lighting what the pointer is on. panel_settled(page) before the point is read; it consumes the transition through getAnimations(), so it returns on the frame the slide ends rather than encoding the stylesheet's duration. It goes at the geometry read rather than up at the walk, because the three readings in between are about the arrival's lift and are green as they stand.

The key line's rows

test_a_pointer_drag_stops_the_line_offering_the_press_it_refusesassert 'undo' in '⏎ / space\ngrab the card\nesc\nlet go\n?\nmore'. New with 141a430 (#22), which was verified against a base that predates ee4d444.

renderLine now paints two chips — the first row and the way out — and hides the rest behind More, whatever the page is offering. So inner_text no longer answers what a row's when decided: on a board page the widget's own ⏎ / space grab the card and esc let go take both seats, and z undo is invisible whether it is live or not. The read after the drop asked for a chip that page can never paint, and the read mid-drag passed on that same permanent absence — proving nothing about the edge it was written for. What when decides is whether the row is in the line at all:

mid-drag:   ⏎/space press it · c comment on the page · d/u half a page · esc let go · g go to · v versions · i design mode · ? more
after drop: ⏎/space grab the card · c comment on the page · d/u half a page · z undo · esc let go · g go to · v versions · i design mode · ? more

_painted_line returns those rows instead of the visible text. A repaint that never came still leaves the rows the previous state put there, so the reading stays once-only and both edges keep their bug-backs.

Testing

Each fix reproduced at its own failure before the change and green after, at -n0 --run-nightly on Linux, then again together on the rebase onto current main (d3151de): 8 passed over the two tests and the key-line tests around them.

Bug-backs, since a wait added to a timing failure and a widened read are both shapes that can green a test by removing what it proves:

edit result
paintHover(id)paintHover(null) in leaf.js standing-mark test fails at the same hover wait, with panel_settled in place
drop paintKeys() from dragging the line offered a press the dispatcher refuses for the length of a drag
onEnd's dragging(this, false) → bare classList.remove the drop that sent nothing left the line refusing a press that is live

uv run pytest tests -n2 — 494 passed, 6 skipped. pre-commit clean on the changed file. The full --run-nightly module is left to this PR's own ci.


Automated fix for failed run

@leaf-agent

Copy link
Copy Markdown
Collaborator Author

Same failure again on main, one commit later: run 32781208623 at c487b5b, test_the_page_marks_the_comment_the_reader_is_standing_in timing out at the same wait_for_function for lf-mark-hover, 1 failed, 1069 passed. c487b5b renames two section headings in examples/ship-review.html, examples/triage-board.html and the generated gallery, and this test serves INLINE_PAGE rather than an example — so the commit cannot reach it, and the failure is the durable one this PR describes rather than anything the run's own change introduced. No second PR opened; this one is the fix.

What is new is an independent check at 141a430, which is main's head and this branch's merge base — so it is the tree the fix would land on, not the one it was cut against:

  • Reproduced before the change: 1 failed in 35.52s at -n0 --run-nightly, deterministic, same Page.wait_for_function: Timeout 30000ms exceeded at line 16345.
  • Green with this branch's two lines applied: 1 passed in 4.74s.
  • Bug-back, arrived at separately from the one in the description and on the same subject: with paintHover(id) replaced by paintHover(null) in leaf.js and the fix in place, it fails again at the same wait — 1 failed in 33.75s. The panel_settled is not standing in for what the wait proves.

On a browser-binary reading of this failure, which came up on #37's thread: this ran on Playwright's pinned headless shell, which is what conftest.py's browser fixture launches (p.chromium.launch(), no channel) and therefore what CI runs too. The failure is not the binary.

main's runs for 61bf2af and 141a430 were still in flight when this was written.

@leaf-agent

Copy link
Copy Markdown
Collaborator Author

Both runs the comment above left in flight have finished, and they disagree — which is worth recording, because the disagreement is the failure's own shape rather than evidence against the fix.

Run 32781525387 at 61bf2af failed exactly as described: test_the_page_marks_the_comment_the_reader_is_standing_in, Page.wait_for_function: Timeout 30000ms exceeded on the lf-mark-hover wait after page.mouse.move(*mark_point(page, "lf-mark-here")), 1 failed, 1069 passed, 6 skipped. 61bf2af is #13's test-only change to two scroll waits, so it cannot reach this test either. This is the run that dispatched this session; no second PR opened.

Run 32781880560 at 141a430main's head, and this branch's merge base — passed this test. Its one failure is test_a_pointer_drag_stops_the_line_offering_the_press_it_refuses, which 141a430 adds in the same commit, so it is #22's own and unrelated to this. The pass is real rather than a deselection: 6 skipped either side, and the passed count moves 1069 → 1070 for the one test 141a430 collects that 61bf2af did not.

So the race is load-dependent on CI while reproducing deterministically at -n0 locally, which is what a mouse move against a column still sliding under syncLayout would do — the 200ms window either has closed by the time the point is read or has not, and two xdist workers on a 4-core runner decide it. The practical consequence for this thread: a green ci on a later commit is not evidence the failure is gone, and it will keep surfacing until the point is read after panel_settled. git merge-tree against 141a430 is clean.

leaf-agent and others added 3 commits August 24, 2026 22:45
The walk that puts the reader in a comment opens the panel, and the document
slides into its new width over the fifth of a second after. The point for the
pointer was taken on that flight, so the slide carried the mark out from under
the pointer and no second mousemove came to correct it: the wait for the hover
ran out thirty seconds later, reading as though the page had stopped lighting
what the pointer is on.

Wait on the slide with panel_settled before reading the point.
The line paints two chips and hides the rest behind More, so `inner_text` no
longer says what a row's `when` decided: on a board page the widget's own two
rows take both seats and `z undo` is invisible whether it is live or not. The
after-drop read asked for a chip that page can never paint, and the mid-drag
read passed on the same absence, proving nothing about the edge it was written
for.

Read every row the line painted instead. A repaint that never came still leaves
the rows the previous state put there, so both bug-backs stand: dropping
paintKeys from `dragging` fails the mid-drag assertion, and returning onEnd to a
bare classList.remove fails the one after the drop.
@leaf-agent leaf-agent changed the title Let the panel finish making room before pressing the standing mark Settle the panel before pressing, and read the key line's whole register Aug 24, 2026
@leaf-agent

Copy link
Copy Markdown
Collaborator Author

Run 32784826135 at d3151de is the first run where both halves land together — 2 failed, 1073 passed, 6 skipped, the standing-mark hover timeout and assert 'undo' in '⏎ / space\ngrab the card\nesc\nlet go\n?\nmore'. d3151de is main's head and this branch's merge base, so ci on main has now been red across four consecutive commits with this PR the only fix in flight. No second PR opened.

What is new beyond the recurrence is that both reproduce deterministically on a CI runner, not only on a workstation. Previous readings had the standing-mark failure as load-dependent under xdist and deterministic at -n0 locally; at -n0 --run-nightly on this Actions runner, on d3151de, both fail on the first attempt, so neither is contention:

d3151de (main):  2 failed, 562 deselected in 37.20s
fc67b85 (this):  2 passed, 562 deselected in  5.86s

The 37s → 5.9s drop is the 30s hover wait that no longer times out. _painted_line is used by exactly one test, so the read's widening reaches nothing else.

How this was run

Same runner as the failing job, Playwright's pinned headless shell (uv run playwright install chromium --only-shell), no channel:

uv run pytest tests/test_render.py -q -n0 --run-nightly \
  -k "test_the_page_marks_the_comment_the_reader_is_standing_in or test_a_pointer_drag_stops_the_line_offering_the_press_it_refuses"

On d3151de the standing-mark test fails at page.wait_for_function("() => (CSS.highlights.get('lf-mark-hover')?.size ?? 0) > 0"), test_render.py:16384, immediately after page.mouse.move(*mark_point(page, "lf-mark-here")) — the point read against the sliding column this PR's panel_settled waits out. d3151de rewrites c's destination and touches no hover paint, and both failures predate it, so it introduced neither.

@max-sixty
max-sixty merged commit 62441dc into main Aug 24, 2026
4 checks passed
@max-sixty
max-sixty deleted the fix/ci-32779874922 branch August 24, 2026 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants