fix(kanban): stall veto measures CPU burned now, not lifetime pcpu - #1063
Conversation
_worker_cpu_active read `ps -o pcpu`, which on Linux procps is lifetime cputime/elapsed. A worker that burned CPU once and then stalled read busy for minutes to hours and vetoed its own reclaim; a fresh idle test child read busy ~1 s per 1 ms of startup CPU (the t_46a2f8a1 flake). The probe is now two psutil cpu_times() samples 0.5 s apart (delta > 0 == active) through a _process_cpu_seconds sampler seam that replaces #1040's ps-table seam; tests inject the sampler. NoSuchProcess -> idle; psutil missing / AccessDenied / any other error -> active (never authorizes a kill). Children are never sampled. Real-probe tests rotate the fault: fresh idle child, once-busy-now-blocked child (~1 s CPU then blocked), genuinely busy child, exited pid. Supersedes #1028 and #1038. Verified: test_kanban_progress_stall.py 15 passed (Mac Studio); mutant `return after > 0` (lifetime semantics) fails 7/15.
|
🤖 merged-by: apollo · lane: discord · gate: BYPASS: FR paused 09-22; gate=CI green + Apollo review · why: t_46a2f8a1: stall-veto probe = psutil cpu_times delta over 0.5s on #1040's injection seam (replaces lifetime ps pcpu: once-busy stalled workers vetoed reclaim forever); fail-safe kept (unknown=>veto, NoSuchProcess=>idle); real-probe tests rotate the fault; supersedes #1028/#1038 (closed); CI 39/39 green on 592aff3; reviewed by Apollo 05:0x PT |
FleetReviewPost-merge review ( Reviewed with 2 of 3 model families — openai unavailable. Confidence: 4/5 No actionable findings. FleetReview provenance · models: C=claude-code-opus-5, D=grok-4.6 · cost: $1.84 · duration: 1h 00m 21s · rounds: 3 · files examined: 2 |
Card: t_46a2f8a1. Supersedes #1028 and #1038 (both conflict with main after #1040).
Bug
_worker_cpu_activereadps -o pcpu. On Linux, procps reports that as lifetime cputime divided by elapsed time. Two effects:_wait_idleflake on loaded runners.Fix
The probe now takes two psutil
cpu_times()samples 0.5 s apart and treats a delta greater than 0 as active. It goes through a new_process_cpu_seconds(pid)sampler seam, which replaces #1040's ps-table seam. Tests inject the sampler.Tests
_FakeCpusampler. The production delta logic still makes the decision.Verification
return after > 0(lifetime semantics): 7 of 15 fail on both hosts.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.