Expand description
Status bar widget — always visible, single row at the bottom of the screen (above the prompt).
Layout, left-to-right (full tier, ≥ 80 cols):
[MODE] engine:<health> feed:<age> dd:<pct> ops:<LABEL>
Plus a retry:N addendum when the WS is disconnected and has
already attempted a reconnect.
Design rules:
- Mode label left-aligned and colored; never truncated.
- Engine health is one word: OK / RECONNECTING / DOWN.
- Feed age renders as seconds; caution > 3 s, alert > 10 s.
- Drawdown reads
risk.drawdown_pct. Thresholds:- missing →
dd:--(muted). - halted →
dd:HALTin alert+bold (kill_all or circuit-breaker tripped). Hides the number on purpose — “the engine is refusing new risk” is the headline; the exact dd figure is a detail the/stateoverlay has more room for. - 0 .. 2% → primary.
- 2 .. 5% → caution.
-
5% → alert.
- missing →
- Operator-state segment is always visible, never hidden
(Addendum A §2.3 — the indicator is present even at STEADY so
the operator never has to guess whether the system is
watching). Appearance:
ops:?— classifier has not reported yet (muted).ops:<LABEL>— label colored byColorHint.ops:<LABEL>*— label is stale (muted asterisk).
The label is sourced from the engine’s GET /operator/state
endpoint (ADR-016); the CLI never computes it locally.
§Width-responsive tiers
The status bar picks the widest tier that fits in area.width.
Tiers are defined so that each narrower tier is a strict subset
of the tier above, and the ordering is driven by operator-safety
priority — we drop diagnostic segments (retry count, feed age)
before we drop risk segments (drawdown, halt), and we never drop
ops: at any width.
Tier::Full— all segments, double-space separators.Tier::Compact— drops theretry:Naddendum and uses single-space separators between segments.Tier::Minimal— renders[MODE] ops:<LABEL> dd:<pct>only. The operator’s minimum useful floor: which mode you are in, what state the engine thinks you are in, and whether capital is bleeding.
§rate: (CLI-side) and hl: (Hyperliquid-side)
The two are parallel by design so an operator reads both with the same eye movement. Both use a shared “tri-color” policy:
- headroom ≥ 25 % → primary
- 10 % ≤ headroom < 25 % → caution
- headroom < 10 %, tokens > 0 → alert
- tokens == 0 →
<name>:EXHin alert+bold
rate:N/M reads from the CLI-side token bucket
(zero_engine_client::RateBudget) that the caller hands in
each render. None → rate:? in metadata color (the same
honest-rendering rule ops:? uses before the classifier
reports).
hl:N/M reads from /v2/status.hl_rate which the engine
optionally reports. Unset → hl:?. Once the engine-side cut
surfaces the field (tracked separately from the M2_PLAN row),
this segment starts showing live Hyperliquid pressure without
any CLI code change.
§Rendering
The widget is pure: given a Mode, an EngineState snapshot, a
Theme, and a now: DateTime<Utc>, it builds a Line and
paints it into the buffer. All freshness math flows through the
caller-supplied now so snapshot tests can freeze time.
Structs§
Enums§
- Tier
- Width-responsive tier picked by
StatusBar::render.