Now that both the agent image (a68d1c4d, via the kustomize images: override)
and the hux sidecar (build-39) are multi-arch with amd64 leaves, move the worker
onto the amd64 accelerator titan-22:
- Add an OR'd nodeSelectorTerm for amd64 + node-role.kubernetes.io/accelerator +
hostname titan-22, with NO worker=true requirement. Keep the arm64 pi-fleet
term as an OR'd fallback so the worker is never stranded.
- Strong primary preference: hostname=titan-22 at weight 100 (scheduler max),
pi-fleet rpi5 nudge lowered to 50, so hermes actually lives on titan-22.
- Tolerate node-role.kubernetes.io/accelerator=true:NoSchedule (harmless where
absent) and the soft atlas.bstein.dev/media-primary:PreferNoSchedule that
titan-22 currently carries, so the weight-100 preference is not offset and
placement is deterministic.
Completes the titan-22 effort the flip branches missed; the earlier branches
never repointed to multi-arch images, which is why the worker never landed here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
The webui release handoff verified org.opencontainers.image.revision on the
Harbor artifact's own extra_attrs.config.Labels. That works for a single-arch
image, but a multi-arch manifest list has no top-level config, so Harbor reports
the label on each per-arch child. build-38 built + published the index fine, then
failed post-publish with 'Harbor artifact omitted OCI image labels'.
verify_registry_digest now checks the top-level config labels when present
(single-arch, unchanged) and otherwise walks the index references, fetching each
child artifact by digest and asserting its revision label. Mirrors how the agent
image lane already tolerates a multi-arch index, without dropping the supply-chain
label check. Adds multi-arch pass/reject tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
test_gateway_image_honors_ui_model_and_caps_reasoning still pinned the old
arm64-only docker.io base (nousresearch/hermes-agent@sha256:47d4bd4c...). The
agent image moved to the multi-arch mirror base
(harbor-core.harbor.svc.cluster.local/mirror/hermes-agent@sha256:9c841866...)
in 8a710845 for the two-leg build; the test wasn't updated, so it was a latent
red only the webui/quality lane runs. Point the assertion at the current base.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
Repoints both Dockerfile.hermes-webui FROM bases to in-cluster Harbor mirrors
(webui base OCI index + the a68d1c4d multi-arch hermes-agent manifest list),
adds the suspended webui base-mirror Job, and gives the WebUI image build an
amd64 leg on titan-24 plus a manifest-list combine — so the hux sidecar can
schedule onto the amd64 accelerator node titan-22.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
The arch-specific CLI stamp assumed the shared node_modules keeps both arches'
codex native deps, but a sibling-arch npm install removes this arch's binary from
the shared volume. So after running on the other arch, the stamp exists yet the
native codex dep is gone -> configure-agent-clients fails -> churn. Gate the
install on the current arch's native codex package being present, so it self-heals.
Make registry.bstein.dev/bstein/hermes-webui a linux/amd64 + linux/arm64
manifest list so the agent pod's `hux` sidecar (which runs the webui image)
can schedule onto the amd64 node titan-22. Reuses the hermes-agent multi-arch
pattern already on main.
- Dockerfile.hermes-webui: repoint both FROMs to multi-arch, internal sources.
The upstream WebUI base (ghcr sha256:a83a3893..., already a multi-arch OCI
index) is now pulled from the in-cluster Harbor mirror; the agent base moves
from the retired arm64-only leaf (81970563) to the multi-arch agent index
(a68d1c4d). Kaniko selects the matching arch leaf per build node.
- services/harbor/hermes-webui-base-mirror-job.yaml: new suspended, operator-run
skopeo `copy --all` Job mirroring the upstream WebUI base index into Harbor's
`mirror` project (modeled on hermes-agent-base-mirror-job.yaml; reuses the
generic ensure-project helper). Wired into the harbor kustomization.
- Jenkinsfile.hermes-webui-image: arm64 leg (titan-20) + amd64 leg (titan-24,
hostname+arch pin, toleration Exists, resource-capped, own checkout scm) +
Combine multi-arch index stage; per-arch evidence archived alongside the index.
- hermes_multiarch_combine.py: generalize the destination pattern/component to
serve both hermes-agent and hermes-webui (fail-closed to just those two).
- Tests updated to the two-arch topology (two legs, combine, both FROM bases,
the mirror Job, twelve archived evidence files).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf