A spine on the edge, and one screen or two or four (0.26.0) - #1284
Merged
Conversation
A bar in the header was not it. The control belongs to the frame: the leftmost thing on the screen and the first thing in the document, the full height of the window, with the word running bottom to top the way a word runs on a spine. Closed it is the word; open it is the word next to the list; and it is the only way in or out, because a second control that opens the same column is a second thing to keep in step with the first. The accent runs the whole height and stays whether the column is open or shut. A line that appears and disappears is a state indicator competing with the background; a line that is always there is the edge of the room, and the open state has the background and the ink to say it. ⛔ The text turns, not the button. `transform` on the button rotates the whole box with it, so the border and the accent would be drawn on the edge away from the column instead of the one beside it - correct in the element's own coordinates and backwards on the screen. And the column's own header lost its title: with the spine beside it, the two sat twenty pixels apart saying the same word. The row keeps its height from its padding, so it still lines up with the app header. Three known-bads on the new gate: the control moved after the conversation pane, where it reads as one of that pane's buttons; a second control carrying `aria-controls="rail"`; and the vertical writing dropped, which leaves the word running across a column 34px wide.
At 34px with nothing but letters the spine read as a label somebody had printed on the frame, which is the one thing it must not read as. Wider, and with the same chevron the step rows use, drawn from borders rather than an icon: it points into the room when the column is shut and back out when it is open, so the thing you press also says which way it goes. The chevron and the word are two rows of one grid, centred together - pinned to the top the arrow sat 450px from the word and they read as separate things on the same strip. And a list is set apart on BOTH sides. Only stepping the left is why it still read as prose with dots in it: measured on a real answer, the items began 26px in from the paragraph above and ended at 548, the same pixel the paragraph ended on, so the block was indented on one edge and flush on the other. The eye reads that as the same column, slightly ragged, rather than as something set inside it. 2.6em in and 1.4em back gives it two edges of its own: 36px and 20px on the running page.
⛔ THE CONSTRAINT THIS PANE WAS BUILT AROUND IS FOUR TIMES SMALLER THAN THE FILE SAID. It assumed a frame costs 22 ms of pipe, and everything followed from that: one live pane, seven previews taking turns at one every 400 ms, and a comment explaining that eight panes would want 2.3 seconds of pipe per second. Measured again on 2026-09-09 with four real browsers over the same Link the interface uses, a frame costs 5 to 6 ms - the capture already runs inside the engine, and the server hands over the latest picture rather than taking one. Four panes polled flat out delivered 80 frames a second in total, about 20 each, and an action still landed in 49 ms against 40 with a single pane. The pane was rationing something that had stopped being scarce. So the stage is a grid of 1, 2 or 4 live screens, chosen from the chrome and remembered per browser. The vocabulary is a control room's because the job is a control room's: one screen when you are watching the work, four when you are keeping an eye on it. The budget is still spent deliberately rather than to the limit - 25 frames a second at one-up, 20 each at two, 10 each at four, so 40 requests a second at most against the 80 measured as affordable. Clicking a screen brings that browser to the front, which at one-up means it fills the stage: that is what "click it and go to another screen" means. The strip below carries whatever the stage does not, so at four-up with four browsers it is empty and at one-up with eight it holds seven. ⛔ And every screen says how old its picture is. On a healthy stage each one is refreshed every 40 to 100 ms, so anything past two seconds means that browser has stopped answering while its last frame sits there looking alive. Stale has to look stale: it is the first rule in a control room and the fifth state a real-time dashboard needs after empty, loading, error and partial. ⛔ And the pump can no longer be killed by a bad pass, because it was, the first time this ran. `ageAll` reached for the age label on the placeholder cell, which has no caption, threw, and the throw was outside the fetch's try - so the timer at the bottom was never reached and the loop stopped for good, in silence. A dead pump reads as a server that has stopped answering rather than as a page with a bug in it. The body is a separate function now and the scheduler only schedules. The picture is anchored rather than sized in percent: `height:100%` on a grid item whose parent takes its height from a flex row does not resolve, so it fell back on its own aspect ratio and came out 23px taller than its box - measured - sitting over the caption underneath. Six known-bads on the new gates, all killed, plus the pace gate rewritten: it asserted a literal pause that no longer exists, and now reads the table of frames a second and checks both edges - never below what the engine is told to produce, never above what the pipe was measured to carry.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The constraint this pane was built around is four times smaller than the file said
It assumed a frame costs 22 ms of pipe, and everything followed from that: one live pane, seven previews taking turns at one every 400 ms, and a comment explaining that eight panes would want 2.3 seconds of pipe per second.
Measured again with four real browsers over the same Link the interface uses:
A frame costs 5 to 6 ms, not 22: the capture already runs inside the engine, and the server hands over the latest picture rather than taking one. Four live screens cost about half the pipe and an action still lands in 49 ms. The pane was rationing something that had stopped being scarce.
So the stage is a grid of 1, 2 or 4 live screens, chosen from the chrome and remembered per browser - a control room's vocabulary because the job is a control room's: one screen when you are watching the work, four when you are keeping an eye on it. The budget is still spent deliberately rather than to the limit: 25 frames a second at one-up, 20 each at two, 10 each at four, so 40 requests a second at most against the 80 measured as affordable.
Clicking a screen brings that browser to the front, which at one-up means it fills the stage. The strip below carries whatever the stage does not.
Every screen says how old its picture is. On a healthy stage each is refreshed every 40 to 100 ms, so anything past two seconds means that browser has stopped answering while its last frame sits there looking alive. Stale has to look stale: the first rule in a control room, and the fifth state a real-time dashboard needs after empty, loading, error and partial.
The sessions column opens from a spine
A hamburger says "there is a menu here" only to somebody who has already learned that it does. The control is part of the frame now: the leftmost thing on the screen and the first thing in the document, the full height of the window, the word running bottom to top the way a word runs on a spine, with the accent beside it whether the column is open or shut. It is the only way in or out, because a second control that opens the same column is a second thing to keep in step with the first.
The
aria-labelhad to go with the icon: with a word written on the button, an aria-label REPLACES that name, so a screen reader would announce something that is not there and voice control would not find it (WCAG 2.5.3).Two defects found by looking rather than reading
The pump died and said nothing.
ageAllreached for the age label on the placeholder cell, which has no caption, threw, and the throw was outside the fetch's try - so the timer at the bottom was never reached and the loop stopped for good. A dead pump reads as a server that has stopped answering rather than as a page with a bug in it. The body is a separate function now and the scheduler only schedules.The picture was 23px taller than its box and sat over the caption:
height:100%on a grid item whose parent takes its height from a flex row does not resolve, so it fell back on its own aspect ratio. Anchored instead.Gates
The part that decides WHICH browsers are on the stage is executed under node, because it is arithmetic over the fleet and a string scan cannot see it. Six known-bads, all killed: server order instead of watched-first, no running filter, no slice by layout, a strip that stops excluding the stage, no age stamp, and the pass back inside the scheduler.
The pace gate was rewritten: it asserted a literal pause that no longer exists, and now reads the table of frames a second and checks both edges - never below what the engine is told to produce, never above what the pipe was measured to carry.
488 tests green.