From f8628e6ee0d2c33d287ec9086ff5328d982e88c3 Mon Sep 17 00:00:00 2001 From: jenkins Date: Tue, 25 Aug 2026 16:54:04 -0300 Subject: [PATCH] Revert "hermes(agent): make titan-22 the strong primary home (no worker label)" This reverts commit 2de52ec3e2e42696ae411482cb16f27ff1f5d273. --- services/hermes/agent-deployment.yaml | 40 +---------------------- testing/tests/test_hermes_agent_layout.py | 29 ++-------------- 2 files changed, 3 insertions(+), 66 deletions(-) diff --git a/services/hermes/agent-deployment.yaml b/services/hermes/agent-deployment.yaml index 822cf8b9..9fce2b2c 100644 --- a/services/hermes/agent-deployment.yaml +++ b/services/hermes/agent-deployment.yaml @@ -24,7 +24,7 @@ spec: ai.bstein.dev/router-wire-contract: ollama-numeric-keepalive ai.bstein.dev/execution: Hermes Kanban with durable direct Codex and Claude Code CLI workers ai.bstein.dev/model-policy: Jetson-assisted AUTO routing, low through xhigh, cross-provider fallback - ai.bstein.dev/placement: primary amd64 accelerator titan-22; arm64 rpi5 fleet fallback; storage-backbone nodes excluded + ai.bstein.dev/placement: titan-08 rpi5; storage-backbone nodes excluded ai.bstein.dev/config-rev: "20260824-claude-fable-quota" prometheus.io/scrape: "true" prometheus.io/path: /metrics @@ -97,19 +97,10 @@ spec: securityContext: seccompProfile: type: RuntimeDefault - # APPLY ONLY AFTER the multi-arch hermes-agent image is built + validated - # (both arch leaves + promoted index). titan-22 is the STRONG/primary home - # for hermes-agent; the arm64 pi fleet is an OR'd fallback so the worker is - # never stranded. titan-22 is a hard-tainted accelerator, so this pod does - # NOT require node-role.kubernetes.io/worker for titan-22 and instead - # tolerates the accelerator taint + targets the accelerator label. affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - # Fallback set: the arm64 pi fleet (unchanged). nodeSelectorTerms - # are OR'd, so hermes-agent still runs here if titan-22 is - # unavailable. - matchExpressions: - key: kubernetes.io/arch operator: In @@ -120,42 +111,13 @@ spec: - key: kubernetes.io/hostname operator: NotIn values: [titan-04, titan-06, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] - # Primary amd64 home: accelerator titan-22. No worker=true here. - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: [amd64] - - key: node-role.kubernetes.io/accelerator - operator: In - values: ["true"] - - key: kubernetes.io/hostname - operator: In - values: [titan-22] preferredDuringSchedulingIgnoredDuringExecution: - # STRONG primary preference: titan-22 (weight 100, the scheduler - # maximum) outranks the pi-fleet nudge below, so hermes-agent - # actually lives on titan-22 whenever it is schedulable. - weight: 100 - preference: - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: [titan-22] - # Weaker fallback nudge within the pi fleet. - - weight: 50 preference: matchExpressions: - key: hardware operator: In values: [rpi5] - tolerations: - # Permit (do not force) scheduling onto the hard-tainted accelerator - # titan-22. This only lets hermes-agent consider titan-22; it does not - # change jellyfin's media-core priority or preemption. - - key: node-role.kubernetes.io/accelerator - operator: Equal - value: "true" - effect: NoSchedule initContainers: - name: init-config image: busybox:1.37 diff --git a/testing/tests/test_hermes_agent_layout.py b/testing/tests/test_hermes_agent_layout.py index 1d9de7cb..3c343e67 100644 --- a/testing/tests/test_hermes_agent_layout.py +++ b/testing/tests/test_hermes_agent_layout.py @@ -154,37 +154,12 @@ def test_agent_avoids_unhealthy_nodes_and_stays_on_storage_workers(): assert hostnames["operator"] == "NotIn" assert set(hostnames["values"]) >= {"titan-04", "titan-19"} - # Two OR'd terms: the arm64 pi fleet (fallback) and the amd64 accelerator - # titan-22 (primary home once the multi-arch image exists). - assert len(terms) == 2 - pi_fleet = {item["key"]: item for item in terms[0]["matchExpressions"]} - assert pi_fleet["kubernetes.io/arch"]["values"] == ["arm64"] - assert pi_fleet["node-role.kubernetes.io/worker"]["values"] == ["true"] - - titan22 = {item["key"]: item for item in terms[1]["matchExpressions"]} - assert titan22["kubernetes.io/arch"]["values"] == ["amd64"] - assert titan22["kubernetes.io/hostname"]["values"] == ["titan-22"] - assert titan22["node-role.kubernetes.io/accelerator"]["values"] == ["true"] - # titan-22 access must NOT depend on the generic worker label. - assert "node-role.kubernetes.io/worker" not in titan22 + assert len(terms) == 1 preferences = pod["affinity"]["nodeAffinity"][ "preferredDuringSchedulingIgnoredDuringExecution" ] - # titan-22 is the STRONG primary (max weight 100) and outranks the pi-fleet - # nudge (50), so hermes-agent actually lives on titan-22 when schedulable. - assert [item["weight"] for item in preferences] == [100, 50] - primary = preferences[0]["preference"]["matchExpressions"][0] - assert primary["key"] == "kubernetes.io/hostname" - assert primary["values"] == ["titan-22"] - - # The pod tolerates the accelerator hard taint so it can consider titan-22. - assert { - "key": "node-role.kubernetes.io/accelerator", - "operator": "Equal", - "value": "true", - "effect": "NoSchedule", - } in pod["tolerations"] + assert [item["weight"] for item in preferences] == [100] hermes = next(item for item in pod["containers"] if item["name"] == "hermes") assert hermes["resources"]["requests"] == {