/** * Health drift check. * * Wraps the existing health-runner. Health-check failures are * informational (DRIFT, not BLOCKED) — the user might want to update * even if some module is currently unhealthy (an update could fix it). * * Unmeasured is reported, never folded into green: a module with no * health_check hook, and a module whose checks all reported skip, have * contributed no measurement at all, and both render the fleet UNKNOWN * rather than READY (celilo#1326). The same rule reaches one level down — * a module that measured something but skipped a check gets an * `unmeasured` finding beside its verdict, so a VERIFIED module whose * meaningful probe was skipped is still visible. * * The health-runner result is passed in directly so this file stays * pure for testing. The aggregator wires `runAllHealthChecks` to it. */ import type { HealthWaiver } from '../../manifest/schema'; import type { HealthCheckResult } from '../health-runner'; import type { DriftFinding } from './types'; /** Render a waiver as the annotation carried on the `unmeasured` finding. */ export function waiverAnnotation(waiver: HealthWaiver): string { return `WAIVED by ${waiver.by} (${waiver.at}): ${waiver.reason}`; } export interface HealthAuditDeps { results: HealthCheckResult[]; } function skippedChecksFinding(r: HealthCheckResult, code: string, message: string): DriftFinding { const details = r.checks .filter((c) => c.status === 'skip') .map((c) => ` • ${c.name}: ${c.message}`) .join('\n'); return { category: 'health', severity: 'unmeasured', code, message, details: details || undefined, remediation: `celilo module health ${r.moduleId} --debug`, actionable: true, subject: r.moduleId, }; } export async function auditHealth(deps: HealthAuditDeps): Promise { const findings: DriftFinding[] = []; for (const r of deps.results) { const skipped = r.checks.filter((c) => c.status === 'skip'); const measured = r.checks.filter((c) => c.status !== 'skip'); // A waiver annotates an `unmeasured` finding; it never replaces it. // The severity stays `unmeasured` so the fleet verdict stays UNKNOWN // (D3) — zero unmeasured findings after a waiver would mean the // waiver re-greened the board, which is the failure it guards. const waiverNote = r.waiver ? ` — ${waiverAnnotation(r.waiver)}` : ''; if (r.status === 'no-checks') { // Either the module declares no health_check hook, or the hook ran // and every check reported skip. Neither measured anything. findings.push( skipped.length > 0 ? skippedChecksFinding( r, 'health_unmeasured', `${r.moduleId}: all ${skipped.length} health checks skipped — nothing measured${waiverNote}`, ) : { category: 'health', severity: 'unmeasured', code: 'health_unmeasured', message: `${r.moduleId}: no health_check hook — never measured${waiverNote}`, remediation: `Add a health_check hook to the ${r.moduleId} module manifest`, actionable: false, subject: r.moduleId, }, ); continue; } if (skipped.length > 0) { findings.push( skippedChecksFinding( r, 'health_checks_skipped', `${r.moduleId}: ${skipped.length} of ${r.checks.length} health checks skipped${waiverNote}`, ), ); } if (r.status === 'healthy') continue; const failingChecks = measured .filter((c) => c.status === 'fail' || c.status === 'warn') .map((c) => ` • ${c.name}: ${c.message}`) .join('\n'); findings.push({ category: 'health', severity: 'drift', code: r.status === 'unhealthy' ? 'health_unhealthy' : `health_${r.status}`, message: `${r.moduleId}: ${r.status}${r.error ? ` — ${r.error}` : ''}`, details: failingChecks || undefined, remediation: `celilo module health ${r.moduleId} --debug`, actionable: true, subject: r.moduleId, }); } return findings; }