"""Shared run-app domain naming (used by the conftest fixtures and the orchestrator). Domain = "-<6hex(recipe|pr|ref)>.ci.commoninternet.net" — short enough for Docker's 64-char swarm config/secret name limit, unique per run, collision-safe across recipes (DECISIONS.md). """ from __future__ import annotations import hashlib import time def _short(s: str, n: int = 8) -> str: return "".join(c for c in s if c.isalnum())[:n] or "local" def app_domain(recipe: str, pr: str = "0", ref: str | None = None) -> str: ref = ref or ("local" + str(int(time.time()))) tag = _short(recipe, 4).lower() h = hashlib.sha1(f"{recipe}|{pr}|{ref}".encode()).hexdigest()[:6] return f"{tag}-{h}.ci.commoninternet.net"