from __future__ import annotations
import re
import sys
from dataclasses import dataclass
from pathlib import Path, PurePath
BASELINE = "ci/baselines/daemon-spawners.txt"
SCAN_DIRS = ("tests", "tools")
SCAN_SUFFIXES = (".rs", ".py")
SPAWN_MARKERS = (
re.compile(r'cargo_bin\(\s*"openlatch"'),
re.compile(r'"daemon"\s*,\s*"start"'),
re.compile(r"daemon\s+start\b"),
re.compile(r"ensure_daemon|spawn_daemon|HermeticDaemon"),
)
MECHANISM_MARKERS = {
"model-relay-default-port-pin": re.compile(r"OPENLATCH_MODEL_RELAY_DEFAULT_PORT"),
"model-relay-free-port": re.compile(
r'OPENLATCH_MODEL_RELAY_PORT"?\s*[,\]]?\s*[:=,]\s*.*free_port|'
r'setdefault\(\s*"OPENLATCH_MODEL_RELAY_PORT"'
),
"model-relay-disabled": re.compile(r'OPENLATCH_MODEL_RELAY_ENABLED"?\s*[,:=]\s*"?false'),
"no-model-relay-flag": re.compile(r"--no-model-relay"),
"no-daemon": None,
}
PIN_NEEDS_REMOVAL = re.compile(r'env_remove\(\s*"OPENLATCH_MODEL_RELAY_PORT"')
def rel_to(path: PurePath, root: PurePath) -> str:
return path.relative_to(root).as_posix()
@dataclass(frozen=True)
class Violation:
path: str
problem: str
hint: str
def parse_baseline(root: Path) -> tuple[dict[str, tuple[str, str]], list[Violation]]:
path = root / BASELINE
if not path.exists():
return {}, [
Violation(BASELINE, "baseline file is missing", "restore it from version control")
]
entries: dict[str, tuple[str, str]] = {}
problems: list[Violation] = []
for lineno, raw in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
line = raw.split("#", 1)[0].strip()
if not line:
continue
parts = [p.strip() for p in line.split("|")]
if len(parts) < 2:
problems.append(
Violation(
f"{BASELINE}:{lineno}",
f"malformed entry: {raw!r}",
"format is `path | mechanism | optional reason`",
)
)
continue
target, mechanism = parts[0], parts[1]
reason = parts[2] if len(parts) > 2 else ""
if mechanism not in MECHANISM_MARKERS:
problems.append(
Violation(
f"{BASELINE}:{lineno}",
f"unknown mechanism {mechanism!r}",
"one of: " + ", ".join(sorted(MECHANISM_MARKERS)),
)
)
continue
if mechanism == "no-daemon" and not reason:
problems.append(
Violation(
f"{BASELINE}:{lineno}",
f"`no-daemon` claimed for {target} with no reason",
"state what the file does with the binary instead, so the next "
"reader can tell when it stops being true",
)
)
continue
entries[target] = (mechanism, reason)
return entries, problems
COMMENT_PREFIXES = ("//", "#", "*", "/*")
def _spawns(text: str) -> bool:
for raw in text.splitlines():
line = raw.strip()
if not line or line.startswith(COMMENT_PREFIXES):
continue
if any(m.search(line) for m in SPAWN_MARKERS):
return True
return False
def spawners(root: Path) -> list[Path]:
found: list[Path] = []
for d in SCAN_DIRS:
base = root / d
if not base.is_dir():
continue
for p in sorted(base.rglob("*")):
if p.suffix not in SCAN_SUFFIXES or not p.is_file():
continue
if "__pycache__" in p.parts or ".venv" in p.parts:
continue
try:
text = p.read_text(encoding="utf-8", errors="replace")
except OSError:
continue
if _spawns(text):
found.append(p)
return found
def check(root: Path) -> list[Violation]:
entries, violations = parse_baseline(root)
found = spawners(root)
found_rel = {rel_to(p, root) for p in found}
def covering_entry(rel: str) -> tuple[str, tuple[str, str]] | None:
if rel in entries:
return rel, entries[rel]
for key, val in entries.items():
if rel.startswith(key.rstrip("/") + "/"):
return key, val
return None
for p in found:
rel = rel_to(p, root)
entry = covering_entry(rel)
if entry is None:
violations.append(
Violation(
rel,
"can spawn the client binary but is not in the baseline",
"add `path | mechanism | reason` to "
f"{BASELINE}, or stop it from starting a daemon",
)
)
continue
key, (mechanism, _) = entry
marker = MECHANISM_MARKERS[mechanism]
if marker is None:
continue
if key == rel:
hay = p.read_text(encoding="utf-8", errors="replace")
proven = bool(marker.search(hay))
else:
proven = any(
marker.search(q.read_text(encoding="utf-8", errors="replace"))
for q in (root / key).rglob("*")
if q.suffix in SCAN_SUFFIXES
and q.is_file()
and "__pycache__" not in q.parts
)
if not proven:
violations.append(
Violation(
rel,
f"baseline claims `{mechanism}` but its marker is gone",
"restore the mechanism, or update the baseline to the one "
"actually in force",
)
)
elif mechanism == "model-relay-default-port-pin" and key == rel:
hay = p.read_text(encoding="utf-8", errors="replace")
if not PIN_NEEDS_REMOVAL.search(hay):
violations.append(
Violation(
rel,
"pins OPENLATCH_MODEL_RELAY_DEFAULT_PORT but never removes "
"an inherited OPENLATCH_MODEL_RELAY_PORT",
'add `.env_remove("OPENLATCH_MODEL_RELAY_PORT")` — an '
"explicit value overrides the default, and a sandboxed "
"shell exports one",
)
)
for target in sorted(entries):
covered = target in found_rel or any(
r.startswith(target.rstrip("/") + "/") for r in found_rel
)
if not covered and not (root / target).exists():
violations.append(
Violation(
target,
"baseline names a path that no longer exists",
f"remove the entry from {BASELINE}",
)
)
return violations
def main(argv: list[str]) -> int:
if len(argv) > 2:
print(f"usage: {argv[0]} [repo-root]", file=sys.stderr)
return 2
for stream in (sys.stdout, sys.stderr):
reconfigure = getattr(stream, "reconfigure", None)
if reconfigure is not None:
reconfigure(encoding="utf-8", errors="replace")
root = Path(argv[1] if len(argv) == 2 else ".").resolve()
if not (root / "Cargo.toml").exists():
print(f"{root} is not the repo root (no Cargo.toml)", file=sys.stderr)
return 2
violations = check(root)
if not violations:
n = len(spawners(root))
print(f"daemon isolation: clean ({n} daemon-spawning file(s) accounted for)")
return 0
print("::error::a daemon could be started against the developer's own install:\n")
for v in violations:
print(f" {v.path}")
print(f" {v.problem}")
print(f" → {v.hint}\n")
print(f"{len(violations)} violation(s).")
print(
"A daemon on the DEFAULT model-relay port owns the machine's agent "
"wiring and rewrites ~/.claude/settings.json — see this script's "
"docstring for the mechanisms that prevent it."
)
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv))