Revert "hermes(agent): make titan-22 the strong primary home (no worker label)"

This reverts commit 2de52ec3e2e42696ae411482cb16f27ff1f5d273.
This commit is contained in:
jenkins 2026-08-25 16:54:04 -03:00
parent 1c495a6e2c
commit f8628e6ee0
2 changed files with 3 additions and 66 deletions

View File

@ -24,7 +24,7 @@ spec:
ai.bstein.dev/router-wire-contract: ollama-numeric-keepalive 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/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/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" ai.bstein.dev/config-rev: "20260824-claude-fable-quota"
prometheus.io/scrape: "true" prometheus.io/scrape: "true"
prometheus.io/path: /metrics prometheus.io/path: /metrics
@ -97,19 +97,10 @@ spec:
securityContext: securityContext:
seccompProfile: seccompProfile:
type: RuntimeDefault 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: affinity:
nodeAffinity: nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms: nodeSelectorTerms:
# Fallback set: the arm64 pi fleet (unchanged). nodeSelectorTerms
# are OR'd, so hermes-agent still runs here if titan-22 is
# unavailable.
- matchExpressions: - matchExpressions:
- key: kubernetes.io/arch - key: kubernetes.io/arch
operator: In operator: In
@ -120,42 +111,13 @@ spec:
- key: kubernetes.io/hostname - key: kubernetes.io/hostname
operator: NotIn operator: NotIn
values: [titan-04, titan-06, titan-08, titan-13, titan-14, titan-17, titan-18, titan-19] 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: 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 - weight: 100
preference:
matchExpressions:
- key: kubernetes.io/hostname
operator: In
values: [titan-22]
# Weaker fallback nudge within the pi fleet.
- weight: 50
preference: preference:
matchExpressions: matchExpressions:
- key: hardware - key: hardware
operator: In operator: In
values: [rpi5] 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: initContainers:
- name: init-config - name: init-config
image: busybox:1.37 image: busybox:1.37

View File

@ -154,37 +154,12 @@ def test_agent_avoids_unhealthy_nodes_and_stays_on_storage_workers():
assert hostnames["operator"] == "NotIn" assert hostnames["operator"] == "NotIn"
assert set(hostnames["values"]) >= {"titan-04", "titan-19"} assert set(hostnames["values"]) >= {"titan-04", "titan-19"}
# Two OR'd terms: the arm64 pi fleet (fallback) and the amd64 accelerator assert len(terms) == 1
# 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
preferences = pod["affinity"]["nodeAffinity"][ preferences = pod["affinity"]["nodeAffinity"][
"preferredDuringSchedulingIgnoredDuringExecution" "preferredDuringSchedulingIgnoredDuringExecution"
] ]
# titan-22 is the STRONG primary (max weight 100) and outranks the pi-fleet assert [item["weight"] for item in preferences] == [100]
# 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"]
hermes = next(item for item in pod["containers"] if item["name"] == "hermes") hermes = next(item for item in pod["containers"] if item["name"] == "hermes")
assert hermes["resources"]["requests"] == { assert hermes["resources"]["requests"] == {