The Logs page died permanently every time the host restarted — which the
console's own update flow does. The host's log ring restarts at seq 1 while the
page's cursor stays where it got to, and `GET /logs?after=8000` against a fresh
ring is not an error, it is an empty page forever: no error, no dropped badge,
stale lines on screen, and nothing short of a full reload to get out. A restart
always breaks the poll first, so a failed poll now triggers a re-read from the
start of the ring, and a page whose newest entry is older than what we hold is
recognised as the sequence having restarted.
Follow mode also stopped following at exactly the wrong moment. The autoscroll
effect was keyed on the rendered row count, which pins at the 1000-row DOM cap —
so once the log got busy enough to matter, the effect never re-ran again. It is
keyed on the newest rendered seq now. And pausing now actually pauses: stopping
the interval left React Query's focus/reconnect refetches landing, which evicted
the very lines the operator had paused on.
The rest:
- A plugin could white-screen the whole console by registering `icon:
"constructor"`. The icon map is a plain object, so the inherited key resolved
to `Object`, which is truthy — the fallback never fired and React was handed
`Object` as a component, from inside the app shell.
- Saving a display arrangement deleted the saved position of every device that
was not connected at that moment: the host replaces the whole map, and we only
ever sent the displays we could see.
- Flipping DDC, PnP or dedicated-game-sessions committed whatever unsaved edits
the Custom block was holding, then cleared the "unsaved" badge so there was no
trace of it. Those three apply on top of the SAVED policy now.
- Saving the Custom block put the streamed-screen pin back to whatever it was
when the form was seeded, undoing a change made in the picker below it.
- "End now" on a running game calls the host's only stop, which ends EVERY live
session; on a grace row with no app id it ended every waiting game. Both say so
first now, when there is more than one to lose.
- Edit and Delete were offered on library entries owned by a provider plugin,
which the host refuses with 409 — silently. They are attributed instead.
- An install whose first poll failed never polled again, and one whose host
restarted spun forever with no way to dismiss it.
- Submitting a second pairing PIN showed the previous attempt's "PIN sent"
before a digit was typed, and the paired list it points you at never refreshed.
- The streamed-screen picker claimed an env pin during every slow load, and rows
that cannot be picked now look that way instead of silently eating the click.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>