atlas-iac/testing/tests/test_hermes_worker_hux_delivery.py
jenkins c0a9c92ee4 hermes(worker): stage inert HUX foundation on the worker instance
worker.bstein.dev (the hermes-agent Deployment) gains the same HUX
shape as chat, staged and inert: a foundation-only hux sidecar on the
reviewed WebUI image line (Flux setters bound, 5s probe budgets), an
init that provisions the HMAC identity as slot-100 on the durable home
subtree (create-once context key, O_EXCL subject binding, per-pod
worker key; no relay/router/evidence keys so those trusts fail closed),
and observe-only hook env in the agent container with the runtime
plugin mounted but deliberately NOT enabled - activation is a reviewed
one-line flip per docs/hux/WORKER-PLAN.md, which carries the rollout,
verification gates, canary/rollback ladder and open questions.
Cross-surface continuity remains unclaimed until the live gates pass.
7 new topology-adaptive delivery gates green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BvMSXH8VH2tMWXanb8SJdf
2026-08-24 13:54:27 -03:00

276 lines
11 KiB
Python

"""Flux delivery gates for the Worker (hermes-agent) HUX service boundary.
Topology-adaptive like the chat gates in ``test_hermes_hux_delivery.py``:
while the agent Deployment carries no ``hux`` sidecar the manifests must
contain zero partial Worker HUX wiring; once the sidecar exists, the full
Worker boundary below is enforced strictly. The Worker instance is the
``hermes-agent`` Deployment behind worker.bstein.dev (via the
``oauth2-proxy-hermes-agent`` Service), NOT the dashboard ``hermes``
Deployment. See ``docs/hux/WORKER-PLAN.md``.
"""
import re
from pathlib import Path
import pytest
import yaml
ROOT = Path(__file__).resolve().parents[2]
SERVICE = ROOT / "services/hermes"
AGENT = SERVICE / "agent-deployment.yaml"
AGENT_CONFIG = SERVICE / "agent-configmap.yaml"
CHAT = SERVICE / "chat-statefulset.yaml"
KUSTOMIZATION = SERVICE / "kustomization.yaml"
WEBUI_IMAGE = "registry.bstein.dev/bstein/hermes-webui"
WEBUI_MARKER = '"$imagepolicy": "hermes:hermes-webui-release"'
TAG_MARKER = '"$imagepolicy": "hermes:hermes-webui-release:tag"'
DIGEST_MARKER = '"$imagepolicy": "hermes:hermes-webui-release:digest"'
WORKER_SLOT = "slot-100"
def _deployment() -> dict:
return yaml.safe_load(AGENT.read_text(encoding="utf-8"))
def _pod() -> dict:
return _deployment()["spec"]["template"]["spec"]
def _hux_active() -> bool:
return any(item["name"] == "hux" for item in _pod()["containers"])
def _require_activation() -> None:
if not _hux_active():
pytest.skip("Worker HUX activation topology is not staged in this tree")
def _named(items: list[dict], name: str) -> dict:
return next(item for item in items if item["name"] == name)
def _env(container: dict) -> dict[str, str]:
return {item["name"]: item.get("value", "") for item in container.get("env", [])}
def _mounts(container: dict) -> list[dict]:
return container.get("volumeMounts", [])
def test_worker_hux_topology_is_all_or_nothing() -> None:
"""A partial Worker HUX rollout (wiring without the sidecar) never ships."""
pod = _pod()
if _hux_active():
return
assert not any(item["name"].startswith("hux") for item in pod["containers"])
assert not any(
item["name"] == "init-hux-runtime" for item in pod.get("initContainers", [])
)
assert not any(item["name"].startswith("hux-") for item in pod["volumes"])
for container in pod["containers"]:
assert not any(name.startswith("HUX_") for name in _env(container))
assert WEBUI_IMAGE not in AGENT.read_text(encoding="utf-8")
def test_worker_hux_sidecar_is_loopback_only_on_the_reviewed_webui_image() -> None:
"""One reviewed WebUI artifact serves chat and Worker; loopback is the only path."""
_require_activation()
pod = _pod()
hux = _named(pod["containers"], "hux")
values = _env(hux)
raw = AGENT.read_text(encoding="utf-8")
assert hux["image"].startswith(WEBUI_IMAGE + ":")
assert "@sha256:" in hux["image"]
# Exactly one WebUI consumer in this Deployment, on the Flux-managed line.
assert raw.count(WEBUI_MARKER) == 1
marked_line = next(line for line in raw.splitlines() if WEBUI_MARKER in line)
assert hux["image"] in marked_line
# The same reviewed image line as the chat tenants: the repo-wide Flux
# Setters run (update.path services/hermes) rewrites both files together.
chat_pod = yaml.safe_load(CHAT.read_text(encoding="utf-8"))["spec"]["template"][
"spec"
]
assert _named(chat_pod["containers"], "webui")["image"] == hux["image"]
assert hux["command"] == ["/opt/hermes/.venv/bin/python", "-m", "hux.server"]
assert values["PYTHONPATH"] == "/opt/hermes-hux"
assert values["PYTHONDONTWRITEBYTECODE"] == "1"
assert values["HUX_BIND"] == "127.0.0.1"
assert values["HUX_PORT"] == "8790"
assert values["HUX_TENANT_SLOT"] == WORKER_SLOT
assert values["HUX_DATA_ROOT"] == "/var/lib/hux/store"
# Foundation-only start: widening the Worker flag set is a deliberate,
# reviewed change gated on the WORKER-PLAN lifecycle checks, so this pin
# is updated in the same commit that turns each card on.
assert {flag for flag in values["HUX_FLAGS"].split(",") if flag} == {
"hux.foundation"
}
assert hux["securityContext"]["readOnlyRootFilesystem"] is True
assert hux["securityContext"]["capabilities"]["drop"] == ["ALL"]
assert hux["securityContext"]["runAsUser"] == 10000
for probe in ("readinessProbe", "livenessProbe"):
assert "tcpSocket" not in hux[probe]
command = " ".join(hux[probe]["exec"]["command"])
assert "127.0.0.1" in command
assert "8790" in command
assert "/healthz" in command
# The chat canary's transient exit-137s were probe kills under a 2s
# budget; the Worker ships with the corrected 5s budget from day one.
assert hux[probe]["timeoutSeconds"] >= 5
# Loopback only: no Service, proxy upstream, or NetworkPolicy exposes 8790.
assert "8790" not in (SERVICE / "service.yaml").read_text(encoding="utf-8")
assert "8790" not in (SERVICE / "oauth2-proxy.yaml").read_text(encoding="utf-8")
assert "port: 8790" not in (SERVICE / "networkpolicy.yaml").read_text(
encoding="utf-8"
)
def test_worker_hux_store_is_a_private_durable_subtree() -> None:
"""The Worker owns its own store subtree and never shares chat's claim."""
_require_activation()
pod = _pod()
hux = _named(pod["containers"], "hux")
hermes = _named(pod["containers"], "hermes")
# The store lives on the durable hermes-agent-home claim under the fixed
# "hux" subtree (Deployment pod names churn, so no $(POD_NAME) scoping).
assert {
"name": "home",
"mountPath": "/var/lib/hux",
"subPath": "hux",
} in _mounts(hux)
assert not any("subPathExpr" in item for item in _mounts(hux))
# The agent gets only its read-only key/context views of that subtree;
# ledger records are reachable from the agent only through loopback HTTP.
assert {
"name": "home",
"mountPath": "/run/hermes-hux-context",
"subPath": "hux/context",
"readOnly": True,
} in _mounts(hermes)
assert {
"name": "home",
"mountPath": "/run/hermes-hux-subject",
"subPath": "hux/binding",
"readOnly": True,
} in _mounts(hermes)
for container in pod["containers"]:
if container["name"] == "hux":
continue
assert not any(
item.get("mountPath") == "/var/lib/hux" for item in _mounts(container)
)
if container["name"] != "hermes":
assert not any(
item["name"].startswith("hux-") for item in _mounts(container)
)
volumes = {item["name"]: item for item in pod["volumes"]}
assert volumes["hux-worker-key"]["emptyDir"]["medium"] == "Memory"
# Single surface, single operator: no relay key and no evidence trust on
# the Worker instance — those trusts fail closed by absence.
assert "hux-relay-key" not in volumes
assert "hux-evidence-key" not in volumes
raw = AGENT.read_text(encoding="utf-8")
assert "hermes-chat-hux-data" not in raw
def test_worker_hux_init_provisions_durable_identity_and_rotating_key() -> None:
"""Identity survives pod replacement; the transport key rotates with it."""
_require_activation()
pod = _pod()
init = _named(pod["initContainers"], "init-hux-runtime")
script = init["args"][0]
assert 'worker_root="/hux-data/hux"' in script
assert "${HOSTNAME}" not in script
assert "$(POD_NAME)" not in script
assert 'HUX_INIT_SLOT="slot-100"' in script
assert "chown -R" not in script
assert 'if [ ! -e "${worker_root}/context/context-key" ]' in script
assert "bs=32 count=1" in script
assert 'chmod 0600 "${worker_root}/context/context-key"' in script
assert 'b"hux.subject.id.v1\\0" + slot.encode("ascii")' in script
assert 'target = root / "binding/subject"' in script
assert "os.O_EXCL" in script
assert "or stat.S_IMODE(info.st_mode) != 0o440" in script
assert "target=/hux-worker/worker-key" in script
assert "chmod 0400" in script
assert "relay" not in script
assert init["securityContext"]["capabilities"] == {
"drop": ["ALL"],
"add": ["CHOWN", "DAC_OVERRIDE", "FOWNER"],
}
assert {"name": "home", "mountPath": "/hux-data"} in _mounts(init)
assert {"name": "hux-worker-key", "mountPath": "/hux-worker"} in _mounts(init)
def test_worker_hux_hook_env_is_file_backed_and_observe_only() -> None:
"""The agent hook is wired for observation: file-backed keys, enforcement 0."""
_require_activation()
pod = _pod()
hermes = _env(_named(pod["containers"], "hermes"))
assert hermes["HUX_BASE_URL"] == "http://127.0.0.1:8790"
assert hermes["HUX_RUNTIME_ENABLED"] == "1"
# Observe-only pin: flipping enforcement on the Worker is its own gated
# change (approvals need a human surface this instance does not have yet).
assert hermes["HUX_TOOL_ENFORCEMENT"] == "0"
assert hermes["HUX_TENANT_SLOT"] == WORKER_SLOT
assert hermes["HUX_WORKER_KEY_FILE"] == "/run/hermes-hux-worker/worker-key"
assert hermes["HUX_SUBJECT_FILE"] == "/run/hermes-hux-subject/subject"
assert hermes["HUX_CONTEXT_KEY_FILE"] == "/run/hermes-hux-context/context-key"
assert hermes["HUX_TIMEOUT_SECONDS"] == "3"
forbidden = {"HUX_WORKER_KEY", "HUX_RELAY_KEY", "HUX_ROUTER_KEY", "HUX_SUBJECT"}
for container in pod["containers"]:
assert not forbidden & set(_env(container))
def test_worker_hux_runtime_plugin_is_staged_but_inert() -> None:
"""The vendored hook package is mounted, yet nothing activates it."""
_require_activation()
pod = _pod()
hermes = _named(pod["containers"], "hermes")
plugin = _named(pod["volumes"], "hux-runtime-plugin")["configMap"]
items = {item["key"]: item["path"] for item in plugin["items"]}
assert plugin["name"] == "hermes-hux-runtime-plugin"
assert {
"hux-hook-init.py": "hux_hook/__init__.py",
"hux-hook-client.py": "hux_hook/client.py",
"hux-hook-hooks.py": "hux_hook/hooks.py",
}.items() <= items.items()
assert {
"name": "hux-runtime-plugin",
"mountPath": "/opt/data/plugins/hux-runtime",
"readOnly": True,
} in _mounts(hermes)
rendered = KUSTOMIZATION.read_text(encoding="utf-8")
assert "hux-hook-client.py=plugins/hux-runtime/hux_hook/client.py" in rendered
# Staged, not active: the activation commit adds hux-runtime to
# plugins.enabled (docs/hux/WORKER-PLAN.md); until then the wiring is inert.
configmap = yaml.safe_load(AGENT_CONFIG.read_text(encoding="utf-8"))
config = yaml.safe_load(configmap["data"]["config.yaml"])
assert "hux-runtime" not in config["plugins"]["enabled"]
def test_worker_hux_build_bindings_use_flux_setters() -> None:
"""Sidecar build provenance is bound by the same Flux setters as chat."""
_require_activation()
raw = AGENT.read_text(encoding="utf-8")
hux = _env(_named(_pod()["containers"], "hux"))
assert raw.count(TAG_MARKER) == 1
assert raw.count(DIGEST_MARKER) == 1
release = re.fullmatch(
r"git-([0-9a-f]{40})-build-[1-9][0-9]*-release", hux["HUX_IMAGE_TAG"]
)
assert release is not None
assert hux["HUX_IMAGE_DIGEST"].startswith("sha256:")
image = _named(_pod()["containers"], "hux")["image"]
assert image.split(":git-", 1)[1].split("@", 1)[0] == hux[
"HUX_IMAGE_TAG"
].removeprefix("git-")
assert image.endswith("@" + hux["HUX_IMAGE_DIGEST"])