atlas-iac/testing/tests/test_hermes_hux_ui_onboarding.py
jenkins b66c762f5d hermes(webui): add HUX card UI models with contract-locked suites
Standalone per-card browser model/security/view modules for HUX-01..10
plus node+pytest suites that read the hux.v1 contract schemas directly.
Reconciled drift found on integration: the activity model now accepts
all 32 hux.event.v1 kinds (delegation.*, memory.suppressed,
memory.retrieval_removed, budget.exhausted, side_effect.*), the
autonomy model carries the external_side_effect capability, and the
foundation boundary test now asserts the shipped static HUX surface
exists on disk and that images never bake activated HUX_FLAGS.

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

118 lines
4.5 KiB
Python

"""Executable and static quality gates for the isolated HUX-09 frontend."""
from __future__ import annotations
import json
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
ONBOARDING = ROOT / "dockerfiles" / "hermes-webui-hux" / "onboarding"
def test_hux_onboarding_node_suite_and_coverage():
"""Suggestion validation and transport remain above the repository gate."""
result = subprocess.run(
[
"node",
"--test",
"--experimental-strip-types",
"--experimental-test-coverage",
"--test-coverage-lines=95",
"--test-coverage-functions=95",
"--test-coverage-branches=95",
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/client.ts",
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/model.ts",
"--test-coverage-include=dockerfiles/hermes-webui-hux/onboarding/security.ts",
"testing/tests/test_hermes_hux_ui_onboarding.mjs",
],
cwd=ROOT,
check=False,
capture_output=True,
text=True,
timeout=30,
)
assert result.returncode == 0, result.stdout + result.stderr
def test_hux_onboarding_matches_schema_and_is_inert():
"""HUX-09 consumes the shared schema without entering a live image."""
schema = json.loads(
(ROOT / "services/hermes/contracts/hux/suggestion.schema.json").read_text(
encoding="utf-8"
)
)
model = (ONBOARDING / "model.ts").read_text(encoding="utf-8")
for value in schema["$defs"]["suggestion"]["properties"]["kind"]["enum"]:
assert f'"{value}"' in model
for value in schema["$defs"]["suggestion"]["properties"]["action"][
"properties"
]["type"]["enum"]:
assert f'"{value}"' in model
for value in schema["$defs"]["suggestion"]["properties"]["trigger"][
"properties"
]["context"]["enum"]:
assert f'"{value}"' in (ONBOARDING / "security.ts").read_text(
encoding="utf-8"
)
assert "dockerfiles/hermes-webui-hux/onboarding" not in (
ROOT / "dockerfiles/Dockerfile.hermes-webui"
).read_text(encoding="utf-8")
def test_hux_onboarding_ui_is_accessible_restrained_and_not_persistent():
"""The card stays optional, dismissible, scoped and keyboard accessible."""
component = (ONBOARDING / "OnboardingSuggestions.tsx").read_text(
encoding="utf-8"
)
client = (ONBOARDING / "client.ts").read_text(encoding="utf-8")
contracts = (ONBOARDING / "contracts.ts").read_text(encoding="utf-8")
styles = (ONBOARDING / "styles.css").read_text(encoding="utf-8")
assert "if (!enabled || !evaluation" in component
assert "Optional next step" in component
assert "Not now" in component and "Don&apos;t suggest this again" in component
assert "Why am I seeing this?" in component
assert 'role="status"' in component and 'aria-live="polite"' in component
assert 'role="alert"' in component
assert "dangerouslySetInnerHTML" not in component
assert all(
token not in client
for token in ("localStorage", "sessionStorage", "indexedDB", "document.cookie")
)
assert 'credentials: "same-origin"' in client and 'cache: "no-store"' in client
assert "seenClaims" in client and "activeClaims" in client
assert "MUST NOT be accepted" in contracts and "single-use claim_id" in contracts
assert "never_again" in contracts and "cooldown_seconds" in contracts
assert ".hux-onboarding" in styles
assert "body" not in styles and ":root" not in styles
assert "focus-visible" in styles and "prefers-reduced-motion" in styles
def test_hux_onboarding_sources_are_bounded_and_endpoint_only():
"""The slice defines backend needs but cannot mutate runtime wiring."""
sources = sorted(ONBOARDING.glob("*"))
assert {path.name for path in sources} == {
"OnboardingSuggestions.tsx",
"client.ts",
"contracts.ts",
"index.ts",
"model.ts",
"security.ts",
"styles.css",
"types.ts",
}
for path in sources:
assert len(path.read_text(encoding="utf-8").splitlines()) <= 500
contracts = (ONBOARDING / "contracts.ts").read_text(encoding="utf-8")
assert "POST /hux/v1/onboarding/evaluate" in contracts
assert (
"POST /hux/v1/onboarding/suggestions/{sug_id}/decisions" in contracts
)
assert "MUST NOT write suppression state" in contracts
assert "A decision never performs" in contracts