feat(tui-go): health-checks pane

Surface the health subsystem (llama/event-store/disk probes) in the TUI,
mirroring the session-stats pane: ClientMessage.GetHealthChecks ->
ServerMessage.HealthChecks (health.checks, reuses HealthReport) ->
StreamQueries.healthChecks via HealthInspectionService; Go OverlayHealth on
key H + palette 'health checks', pull-based fetch, per-subject status with
degraded loud. Empty/disabled -> visible fallback (no blank/lie). Go+Kotlin
golden tests pin the wire contract field-for-field. Observability spec §4/§3.
This commit is contained in:
2026-06-14 18:57:51 +04:00
parent 09f05549a0
commit fd67a6c68d
13 changed files with 285 additions and 3 deletions
@@ -164,6 +164,39 @@ func TestDecodeGoldenServerFrames(t *testing.T) {
}
},
},
{
name: "health.checks carries nested health report",
json: `{"type":"health.checks","health":{"overall":"DEGRADED","subjects":[` +
`{"subject":"DISK","status":"DEGRADED","metric":"free_bytes","observedValue":512000000,` +
`"detail":"disk free below 1 GB threshold","since":"2026-06-14T10:00:00Z"},` +
`{"subject":"EVENT_STORE","status":"HEALTHY","metric":"write_latency_ms","observedValue":4,` +
`"detail":"ok","since":"2026-06-14T09:00:00Z"}],` +
`"checkedAt":"2026-06-14T10:05:00Z"}}`,
wantType: TypeHealthChecks,
eventBear: false,
check: func(t *testing.T, m ServerMessage) {
if m.Health == nil {
t.Fatalf("health.checks: Health is nil")
}
if m.Health.Overall != "DEGRADED" {
t.Fatalf("health.checks overall = %q, want DEGRADED", m.Health.Overall)
}
if len(m.Health.Subjects) != 2 {
t.Fatalf("health.checks subjects len = %d, want 2", len(m.Health.Subjects))
}
disk := m.Health.Subjects[0]
if disk.Subject != "DISK" || disk.Status != "DEGRADED" || disk.ObservedValue != 512000000 {
t.Fatalf("health.checks DISK subject: %+v", disk)
}
es := m.Health.Subjects[1]
if es.Subject != "EVENT_STORE" || es.Status != "HEALTHY" {
t.Fatalf("health.checks EVENT_STORE subject: %+v", es)
}
if m.Health.CheckedAt != "2026-06-14T10:05:00Z" {
t.Fatalf("health.checks checkedAt = %q", m.Health.CheckedAt)
}
},
},
{
name: "workflow.proposed carries candidate workflows",
json: `{"type":"workflow.proposed","sessionId":"s1","proposalId":"prop-1","prompt":"Run one?",` +
@@ -248,6 +281,11 @@ func TestEncodeGoldenClientFrames(t *testing.T) {
}
},
},
{
name: "GetHealthChecks encodes correctly",
frame: GetHealthChecks(),
wantType: clientPrefix + "GetHealthChecks",
},
{
name: "DiscardIdea carries the ideaId",
frame: DiscardIdea("i1"),