ChromeBar declutter — show the commit once
The srv·client·kaval identity rail printed the same commit three times in the happy path. Keep the three familiar columns, but show the shared commit once (in srv), collapse client to a muted ≡ when it matches, and move kaval's duplicate commit + closure-hash into its panel — so the rail stays recognizable while the redundancy is gone, and divergence still spells itself out inline.
The rail is too crowded — and most of it is the same fact, repeated. In a
clean deploy the server, this browser’s bundle, and the kaval daemon are all
built from one HEAD, so the rail prints d07ea54 three times behind three
labels. packages/client/src/ui/IdentityRail.tsx Shipped in
#1359 .
The crowding — three SHAs for one bit
The three columns exist to flag disagreement — client ≠ srv (a stale cached
bundle), kaval ⬆ update (the daemon a build behind). When everything agrees —
the ~95% case — that machinery just repeats one identity. Only 98eeac0 (kaval’s
nix closure hash) is genuinely distinct, and it’s a content hash, not a
GitHub-navigable commit.
Show the commit once
Keep the three familiar columns and the labeled kaval panel button — just
stop repeating the commit. It shows once, in srv (the canonical identity).
client collapses to a muted ≡ (“same build as the server”), and kaval
drops its duplicate commit + closure-hash down into its panel, keeping only its
live dot · uptime on the strip.
98eeac0 · restart · kaval-tui). One dot per axis: srv’s carries data-ws-status, kaval’s data-daemon-state.No new affordance, no hover-to-reveal, no disclosure triangle — the rail reads the same as before, just without the echo. Every dropped fact stays reachable: the client commit in the About dialog, kaval’s commit + closure-hash in its panel.
Divergence spells itself out
The dedup only collapses what’s redundant. The moment a column actually disagrees it expands back to its own commit + an actionable chip — automatically, nothing to click. These are the signals the three columns existed for.
client behind server
clientStale()kaval a build behind
kavalUpdatePending()daemon stopped
DAEMON_STATE_PRESENTATION[state].labelserver unreachable
data-ws-status hook), distinct from a red kaval dot. wsDot(props.status)What moves where — nothing is lost
| Current element | Where it lives now |
|---|---|
| server commit | the one shown (srv column), a GitHub link |
| client commit (when it matches) | a muted ≡ — its real SHA is in the About dialog |
| client commit (when stale) | inline, beside the ≠ srv chip |
| kaval commit | KavalInfoDialog (off the strip) |
kaval closure hash 98eeac0 | KavalInfoDialog (it’s a content hash, not navigable) |
kaval dot · uptime · ⬆ update | inline on the kaval button (unchanged) |
| srv WS-tone map (was duplicated in mobile chrome) | one shared wsDot in useDaemonStatus.ts |
What we tried first — and backed off
The first cut went further: collapse to a single worst-of health dot + one
commit, with the per-source split behind a hover tooltip and a ▸ disclosure
that opened the kaval panel. Driving it live killed it on two counts:
- The hover/dropdown breakdown was machinery for a non-problem. At rest it
reveals
d07ea54 / d07ea54 / d07ea54— the exact redundancy the collapse removed. The one case where the split matters (divergence) already fans out inline on its own, so nothing needs un-hiding. - A
▸reads as “expand,” not “open a modal.” Clicking the disclosure triangle opened the kaval dialog — and that modal’s full-screen backdrop then sat on top of an unrelated “App updated → Reload” card and ate the click. A disclosure that doesn’t disclose is a broken affordance.
So the shipped design keeps the familiar columns and the labeled kaval button, and just deletes the echo. Two further-out options, for the record:
- Most minimal —
srv ● v1.1.0 d07ea54only, kaval reached via the command palette. Cleanest, but dropskaval-tuidiscoverability at rest. - Full collapse + dropdown — the first cut above. Rejected: the dropdown un-hides the redundancy, and the triangle misreads as a disclosure.