Skip to content

Fail-safe hardening: never leave the R730 uncooled#1

Merged
sethpjohnson merged 1 commit into
mainfrom
claude/o03q6gcj-failsafe-hardening
Jul 17, 2026
Merged

Fail-safe hardening: never leave the R730 uncooled#1
sethpjohnson merged 1 commit into
mainfrom
claude/o03q6gcj-failsafe-hardening

Conversation

@sethpjohnson

@sethpjohnson sethpjohnson commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

The controller switches the iDRAC into manual fan mode and is then solely responsible for cooling the server. This PR makes every failure path fail safe — restore BMC auto control or hold/raise speed — instead of leaving fans pinned low:

  • Abnormal exits restore auto mode: API server errors route through an error channel to a single sync.Once restore choke point; the control loop recovers panics; only SIGKILL/power loss can skip the handback.
  • Sensor loss fails up, not down: read errors hold speed (never read as 0°C), empty CPU/GPU parses are errors, 3 consecutive failures enter failsafe — BMC auto mode restored and retried every tick until confirmed (restore_pending in /api/status).
  • Write-failure watchdog: 3 consecutive failed fan writes → sticky failsafe (BMC keeps control until restart; no manual/auto oscillation).
  • Exec timeouts on all ipmitool/nvidia-smi calls: max(3s, min(10s, interval)).
  • Critical temps bypass step-ramping straight to max speed (validated critical_cpu_temp/critical_gpu_temp keys), overriding even manual overrides.
  • Config safety refusal: a config that parses but fails validation refuses to start (BMC keeps auto control) rather than silently discarding iDRAC credentials; a missing config still starts on defaults. ⚠️ Mildly breaking: existing configs with cpu_threshold ≥ 85 must set critical_cpu_temp explicitly.
  • Truthful status: currentSpeed updates only after confirmed writes; failsafe_active, failsafe_reason, restore_pending, last_write_failed exposed.

Review & verification

  • 3-round principal review → APPROVED WITH SUGGESTIONS (follow-ups tracked in dex tl6vr184); reviewer empirically reproduced and re-verified each blocker.
  • go vet, go build, go test -race -count=1 ./... clean (5 new test files).
  • Acceptance-verified against the live demo binary: port-occupied startup restores auto mode exactly once and exits 1; critical temp jumps 45%→100% in one tick; ~28s race-build run under concurrent API load with no races; SIGINT restores exactly once; conflicting config exits 1 naming the conflict.

Task: dex o03q6gcj — Tier 1: Fail-safe hardening

🤖 Generated with Claude Code

The controller puts the iDRAC into manual fan mode and is then solely
responsible for cooling. Previously, several failure paths abandoned that
responsibility with fans potentially pinned low. Now every failure path
fails safe:

- Restore BMC auto mode on every abnormal exit: API server errors route
  through an error channel (no more log.Fatalf skipping cleanup), the
  control loop recovers panics, and a sync.Once restore choke point fires
  exactly once. Only SIGKILL/power loss can skip it.
- Sensor loss fails UP: read errors hold speed instead of reading as 0C,
  empty parses (CPU and GPU) are errors, and 3 consecutive failures enter
  failsafe (BMC auto mode restored, retried every tick until confirmed,
  surfaced as restore_pending in /api/status).
- Write failures get the same watchdog; write-failure failsafe is sticky
  (no manual/auto oscillation) until restart.
- All ipmitool/nvidia-smi execs have timeouts: max(3s, min(10s, interval)).
- Critical temps (critical_cpu_temp/critical_gpu_temp, validated at load)
  bypass step-ramping straight to max speed, overriding manual overrides.
- Config that parses but fails safety validation refuses to start (BMC
  keeps auto control) instead of silently falling back to defaults and
  discarding iDRAC credentials; missing config still starts on defaults.
- Truthful status: currentSpeed only updates after confirmed writes;
  failsafe_active, failsafe_reason, restore_pending, last_write_failed
  exposed; currentZone race fixed.

Tests: table-driven coverage for calculateTarget, parsers, failsafe
thresholds/stickiness/restore-retry, panic recovery, config resolution.
go vet and go test -race clean.

Task: dex o03q6gcj - Tier 1: Fail-safe hardening

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EQmqj1Hj8DL3GGAcBDNm8v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant