fix(kvb-org-queue): an idle queue no longer waits on a head the host load alone keeps out

evaluate() counted a non-hotfix entry that passed every queue check but was held back by the live host load as granted for every entry after it: its slot, the exclusive-kind drain and its CPU/RAM share. With RAM held outside the queue the head never started and nothing behind it did either (2026-11-12 03:50 UTC: 27 entries, no job active, host idle). While no queue job is active, such an entry now reserves nothing and holds nothing back; with jobs active it keeps its reservation, and a load-held hotfix still holds back every entry after it. Replayed on the live queue, the fix grants test-nostack-1035 at once.

🎯 Fix: 93 %
💥 Break: 4 %
💸 Cost: 100 %
⏱️ Time: 100 %
🛡️ Security: 100 %
🏆 Score: 89
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-12 08:08:40 +00:00
1 parent 4ab13b6e65
commit 256fe2c327
2 files changed
+36 -9

No files matched your search

+15 -8
View File
@@ -406,7 +406,10 @@ def evaluate(entries: list[dict], free_gb: float, floor: float, stage: str, memo
holds it, so a lower entry never takes a higher entry's slot; one
blocked by disk or budget reserves its need against the entries after it.
A hotfix entry that passes every check but the host load holds back
every entry after it, so lighter jobs cannot keep the load up. An
every entry after it, so lighter jobs cannot keep the load up. While no
queue job is active, any other entry the host load alone keeps out
reserves nothing and holds nothing back: that load lies outside the
queue, so holding the queue frees none of it. An
exclusive entry that only running jobs of other kinds keep out holds
back every entry after it but light ones, so none overtakes it. A waiting
entry whose holder has not polled for CLAIM_SECONDS reserves nothing and
@@ -435,13 +438,17 @@ def evaluate(entries: list[dict], free_gb: float, floor: float, stage: str, memo
if reason is not None and kind in exclusive:
drain = entry["id"]
if reason is None:
reason, used, available = resources(need, share, used, available, floor, budget, taken)
if reason is None and entry["hotfix"] and entry["id"] in loaded:
reason, held = loaded[entry["id"]], entry["id"]
elif reason is None:
taken += 1
counts[kind] += 1
busy.add(workdir)
reason, after, left = resources(need, share, used, available, floor, budget, taken)
if reason is None and entry["id"] in loaded and (entry["hotfix"] or not active):
reason = loaded[entry["id"]]
if entry["hotfix"]:
held = entry["id"]
else:
used, available = after, left
if reason is None:
taken += 1
counts[kind] += 1
busy.add(workdir)
verdicts[entry["id"]] = reason
for entry in waiting:
if silent(entry, now):
+21 -1
View File
@@ -296,9 +296,29 @@ class TestEvaluate(unittest.TestCase):
self.decide([hotfix, light], loaded={"j1": load}),
{"j1": load, "j2": "waits behind hotfix j1, which the host load holds back"},
)
self.assertEqual(self.decide([job(1), light], loaded={"j1": load}), {"j1": None, "j2": None})
self.assertEqual(self.decide([job(1), light], loaded={"j1": load}), {"j1": load, "j2": None})
self.assertEqual(self.decide([hotfix, light]), {"j1": None, "j2": None})
def test_with_no_job_active_a_head_the_host_load_alone_keeps_out_reserves_nothing_and_with_one_active_it_does(self):
load = "RAM 55 % used + 41 % still to come reach the limit 90 %"
head, twin = job(1, kind="quality-high"), job(2, kind="quality-high", task="work/b")
gate, light = job(3, task="work/b"), job(4, kind="test-nostack", task="work/c")
shares = {"j1": {"ram": 41, "cpu": 62}, "j2": {"ram": 41, "cpu": 62}, "j3": {"ram": 20, "cpu": 40}, "j4": {"ram": 6, "cpu": 40}}
rules = {"slot_limits": {"quality-high": 1, "test": 5, "test-nostack": 6}, "exclusive": {"quality-high", "test"}, "light": {"test-nostack"}}
loaded = {"j1": load, "j2": load}
self.assertEqual(
self.decide([head, twin, gate, light], loaded=loaded, footprints=shares, **rules),
{"j1": load, "j2": load, "j3": None, "j4": None},
)
running = job(5, kind="test-nostack", task="work/c", status="active")
self.assertEqual(
self.decide([running, head, twin, gate, light], loaded=loaded, footprints=shares | {"j5": {"ram": 6, "cpu": 11}}, **rules),
{
"j1": None, "j2": "all 1 quality-high slots taken", "j3": "test runs only beside test-nostack, but quality-high runs",
"j4": "CPU 73 % in use or reserved + 40 % > budget 100 %; reserved",
},
)
class TestHistory(unittest.TestCase):
@classmethod