Blog ·
Offline next to a heading saying online
A fail safe default is correct on its own and wrong beside a fact. Rebuilding an agent page as cards made two of those contradictions visible at once.
By Provibr
Whether an agent is connected is not a column. It is a key in Redis with a time to live, refreshed by the gateway, and pushed to the browser over a WebSocket. The database column next to it holds something else entirely: whether the agent is enrolled, pending or revoked, which is administration and not presence.
The component that draws the connected indicator therefore starts pessimistic. With no initial value it renders "offline", and only turns green once the gateway's snapshot has arrived. That is deliberate and it is the right default on its own: saying "connected" before you know is worse than saying it a second late.
On its own is the important part.
Two claims about one fact
Rebuilding the agent detail page as a grid of cards put several things that had been on separate tabs into one view, and that is where a fail safe default stops being safe.
The health band at the top of the page reads the presence key on the server and paints itself green for a connected agent. The chip next to the agent name renders the same fact from the browser side, and with no initial value it said offline. Further down, a panel about the host machine said, in so many words, that nothing was being measured because the agent was offline, underneath a heading that said the agent was online.
None of those three is wrong in isolation. Two of them read the same Redis key, one of them reads it in the browser, and for the first moment after the page loads, one has an answer and the other is still waiting. Put them in three different tabs and nobody notices. Put them in one screen and the page contradicts itself out loud.
The same thing had already happened once on the agent list, where a statistics band counted online agents from those same keys and sat above cards that all said offline until the socket landed. That was the round where the component learned to accept an initial value, and the lesson was written down then: of two claims about the same fact, from the same source, in the same view, one is always wrong.
What the fix looks like is boring. The presence key is read once, on the server, and handed to the header chip, the health band and the host panel as their starting value. The live store still wins the moment anything arrives. The rule underneath is not "pass initial values around"; it is that a fail safe default is a statement about a component in isolation, and the moment a second element in the same viewport knows the answer, the default has become the lie.
What the page shows, in the order somebody needs it
The rest of the round was arrangement, which is a different kind of work but not a lesser one. Six rows, in the order of somebody who has opened this page because something is wrong.
- Is anything the matter, with the four facts that decide it.
- The live numbers: processor, memory, latency, uptime.
- What kind of machine this is, what the agent can do, and where to go next.
- The last hour of usage, as graphs with their tables beside them.
- What happened, what was measured, and where the disk space went.
- Version and licence, the administration underneath.
Judgement, then numbers, then context, then history, then management. The arrangement lives in its own file, and the page file stays the data layer, holding only which read belongs to which tab. That split means the next round that adds one card touches exactly one place, and the round that adds one query touches the other.
The design sketch asked for a disk tile in the second row. There is not one, because the telemetry point the agent sends carries processor, memory, uptime and round trip time and nothing else. The only disk figures on the page are about the artefact cache, and they are on the artefact cache card. Putting a number under a label it does not belong to is how a dashboard starts lying slowly.
Six things left off, with reasons
More decisions went into what is not on this page than into what is, and the reasons are all of the same family: a control that cannot keep its promise is worse than no control.
A range picker on the graphs. The graphs show the last hour, from a live window. Anything longer comes from pre-aggregated rollups, and reading those on an overview page is exactly what our own rules forbid, because the rollup is not the same measurement at a different zoom. There is a route to a page that does it properly instead.
Ping, restart and reboot as buttons. Running a diagnostic needs a target, and the rules about which tool is blocked in which state deliberately live together in one place rather than being restated per button. So the quick actions are links to the page that has both.
Update, licence and token buttons. The licence file carries a secret, and a secret belongs on one screen, not on every screen that mentions it.
A link to the changelog for the installed version. The manifest the agent reports does not carry a URL, and inventing one from the version string would be a link that breaks the first time a release is named differently.
A "view full log" link. The activity page does not filter by agent, so the link would deliver a list the customer then has to search by eye. That is a promise the destination cannot keep.
Friendly names for the agent's capabilities. They are shown as the words the protocol uses, following an earlier decision. A friendly name has to be maintained in nine languages and stops matching the word in the logs on the day someone renames a capability.
There is also a reserved gap. A card with the automatic update schedule was being built in parallel, and it ended up on the settings tab instead, because it is a form, and the same form in two places on one page is precisely the second source of truth the whole layout was supposed to remove. The gap stays, with a note that says if the card ever moves here it moves from settings rather than being added alongside.
The notice that must not exist on a customer's own domain
One card shows a prompt when the company details needed for invoicing are missing. Three things about it were checked rather than assumed.
It uses the dashboard's existing predicate for "are the billing details complete", not a second one written here. Two predicates for one question drift, and the day they disagree the customer sees the prompt on one page and not on the other.
It appears only for someone who can actually act on it, which means the right role and the right surface.
And it must not exist at all on an account domain, the white labelled host where a customer's own customers log in. That was measured with a real session rather than reasoned about: on the account domain the agents page returns 404, because that whole surface is absent there by construction, and on the panel host it returns 200. The 404 is not access control catching something; the page is not there.
The three pixels that turned into another round
The layout was measured at three widths and, at the narrowest, in all nine languages. Nothing overflowed at 390 or at 1440.
At 768 every panel page in the product was three pixels wider than the window. Not this page: every page. That is one reading, in one language and one currency notation; the round that took the header apart swept nine languages in two and found eight to thirty eight pixels. The cause was in the shared header, and the honest thing was to write it down as its own task rather than fix it inside a round about a different screen, because a header that overflows at one width in one language is never a three pixel problem. It turned out to be a category error about which width the header was reading, and it is a bar narrower than its window.
What we would write down
- A fail safe default is a statement about one component alone. Beside a second element that knows the answer, it becomes the false one.
- Two elements rendering one fact must share a starting value. Read it once on the server and hand it down.
- Presence is not status. One is a key with a lifetime, the other is administration; a column that says "enrolled" says nothing about now.
- Keep arrangement out of the data layer. One file for what is read, one for where it goes, and each round touches one of them.
- Do not put a number under a label it does not belong to. If the mockup asks for a tile the telemetry cannot fill, the answer is no tile.
- A control whose destination cannot keep the promise is worse than no control. A log link that cannot filter, a changelog link with no URL.
- Measure absence on a real session. "This page does not exist on that host" is a claim that deserves a request rather than a reading of the code.
For clarity about what this is: the page is built and running, measured with an accessibility pass and a browser sweep in both host arrangements. It was only exercised against a development server, so nothing here says anything about layout shift on a production build, and the live socket was blocked during measurement, so the presence path was proven from the server side rather than end to end.
From the platform work on Provibr. The header defect this page uncovered is in a bar narrower than its window, and how agents keep themselves current without anybody pressing anything is in updated at three in the morning.