} */ public function score(Server $server): array { $items = $this->hardening->state($server); // throws if the host can't be read $checks = []; $passed = 0; $applicable = 0; foreach ($items as $it) { // A check counts toward the score only when the OS supports it AND it's a real security // gate (not the neutral auto-updates preference). $counts = $it['supported'] && ! $it['neutral']; if ($counts) { $applicable++; if ($it['secure']) { $passed++; } } $checks[] = [ 'key' => $it['key'], 'label' => $it['label'], 'detail' => $it['detail'], 'secure' => (bool) $it['secure'], 'supported' => (bool) $it['supported'], 'neutral' => (bool) $it['neutral'], 'counts' => $counts, ]; } $score = $applicable > 0 ? (int) round($passed / $applicable * 100) : 100; return [ 'score' => $score, 'rating' => $this->rating($score), 'passed' => $passed, 'applicable' => $applicable, 'checks' => $checks, ]; } /** strong ≥90 · fair ≥60 · weak below — mapped to the status triad in the UI. */ private function rating(int $score): string { return $score >= 90 ? 'strong' : ($score >= 60 ? 'fair' : 'weak'); } }