Thank you, @aureas. Looking through that section, the implications are pretty clear:
(For Z5, and presumably true for Z6 when not contradicted)
The upper window has variable height (of n lines) and the same width as the screen. (It is usual for interpreters to print the upper window on the top n lines of the screen, overlaying any text which is already there, having been printed in the lower window some time ago.) Initially the upper window has height 0. When the lower window is selected, the game can split off an upper window of any chosen size by using the split_window opcode.
When text reaches the bottom right of the lower window, it should be scrolled upwards. (When the text style is Reverse Video the new blank line should not have reversed colours.) The upper window should never be scrolled: it is legal for a character to be printed on the bottom right position of the upper window (but the position of the cursor after this operation is undefined: the author suggests that it stay put).
There are eight “windows”, numbered 0 to 7. The code -3 is used as a window number to mean “the currently selected window”. This selection can be changed with the set_window opcode. Windows are invisible and usually lie on top of each other. All text and graphics plotting is always clipped to the current window, and anything showing through is plotted onto the screen. Subsequent movements of the window do not move what was printed and there is no sense in which characters or graphics ‘belong’ to any particular window once printed. Each window has a position (in units), a size (in units), a cursor position within it (in units, relative to its own origin), a number of flags called “attributes” and a number of variables called “properties”.
Parts of 8.8.3 are also included in DM4 on p. 312 (or at https://inform-fiction.org/manual/html/s42.html):
Windows have no visible borders and usually lie on top of each other. Subsequent movements of the window do not move what was printed and there is no sense in which characters or graphics “belong” to any particular window once printed.
Here “movements of the window” must mean “use of the @move_window opcode”.
By combination of the above, it looks like anything printed outside of the upper window’s boundaries effectively becomes part of the lower screen, and is subject to scrolling, while things printed within the boundary of the upper window are not.