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:
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user