atlas-iac/services/hermes/scripts/execution_pool_project.py
2026-09-01 20:43:50 -03:00

155 lines
6.2 KiB
Python

#!/usr/bin/env python3
"""Canonical Atlas project and Git-ref policy for distributed execution."""
from __future__ import annotations
import json
import os
import re
import stat
import subprocess
from pathlib import Path
from typing import Any
DATA_ROOT = Path(os.environ.get("HERMES_HOME", "/opt/data"))
PROJECT_ROOT = DATA_ROOT / "workspace/projects"
BOARD_ROOT = DATA_ROOT / "kanban/boards"
ATLAS_REPO = re.compile(
r"https://scm\.bstein\.dev/titan/(?P<repo>[A-Za-z0-9][A-Za-z0-9_.-]{0,99})\.git\Z"
)
SAFE_PREFIXES = frozenset(
{"feature", "fix", "chore", "docs", "test", "refactor", "wt", "review", "hermes", "handoff"}
)
IDENTIFIER = re.compile(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,127}\Z")
GIT = "/usr/bin/git"
MAX_BOARD_BYTES = 64 * 1024
REPOSITORY_ALIASES = {"titan-iac": "atlas-iac"}
class ProjectPolicyError(ValueError):
"""Canonical project metadata or a requested ref failed closed."""
def _task_value(task: Any, name: str, default: Any = None) -> Any:
return getattr(task, name, default)
def _run_git(workdir: Path, *arguments: str) -> str:
completed = subprocess.run(
[GIT, "-C", str(workdir), *arguments],
check=False,
stdin=subprocess.DEVNULL,
capture_output=True,
text=True,
timeout=30,
env={
"HOME": "/nonexistent",
"PATH": "/usr/bin:/bin",
"GIT_CONFIG_NOSYSTEM": "1",
"GIT_TERMINAL_PROMPT": "0",
},
)
if completed.returncode:
raise ProjectPolicyError("canonical project Git metadata is unavailable")
return completed.stdout.strip()
def validate_branch(value: object, *, feature: bool) -> str:
"""Validate a complete local branch name with Git and a reviewed namespace."""
if not isinstance(value, str) or not value or len(value) > 200:
raise ProjectPolicyError("branch name exceeds the safe limit")
if not value.isascii() or value.startswith("-"):
raise ProjectPolicyError("branch name must be canonical ASCII")
prefix = value.split("/", 1)[0]
if feature and ("/" not in value or prefix not in SAFE_PREFIXES):
raise ProjectPolicyError("task branch is outside the reviewed namespace")
completed = subprocess.run(
[GIT, "check-ref-format", f"refs/heads/{value}"],
check=False,
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=10,
env={"PATH": "/usr/bin:/bin", "GIT_CONFIG_NOSYSTEM": "1"},
)
if completed.returncode:
raise ProjectPolicyError("branch name is not a valid Git ref")
return value
def _read_board(board: str) -> dict[str, Any]:
if not IDENTIFIER.fullmatch(board):
raise ProjectPolicyError("board slug is invalid")
path = BOARD_ROOT / board / "board.json"
descriptor = os.open(path, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0))
try:
info = os.fstat(descriptor)
if not stat.S_ISREG(info.st_mode) or not 0 < info.st_size <= MAX_BOARD_BYTES:
raise ProjectPolicyError("board registry entry is not a bounded regular file")
raw = os.read(descriptor, MAX_BOARD_BYTES + 1)
finally:
os.close(descriptor)
try:
value = json.loads(raw)
except (UnicodeError, json.JSONDecodeError) as error:
raise ProjectPolicyError("board registry entry is malformed") from error
if not isinstance(value, dict) or value.get("slug") != board or value.get("archived") is True:
raise ProjectPolicyError("board registry identity is unavailable or archived")
return value
def resolve_project(board: str) -> tuple[str, str, Path]:
"""Resolve repo and base exclusively from the canonical board registry.
A board may be created before its primary checkout. In that case the
Atlas repository naming contract and ``main`` are the registry defaults;
once a checkout exists, its credential-free origin and remote HEAD must
agree with that identity. This keeps a missing checkout from silently
routing work to some other project's repository.
"""
entry = _read_board(board)
raw_workdir = entry.get("default_workdir")
if not isinstance(raw_workdir, str) or not Path(raw_workdir).is_absolute():
raise ProjectPolicyError("board default_workdir is missing")
workdir = Path(raw_workdir).resolve(strict=False)
project_root = PROJECT_ROOT.resolve(strict=True)
try:
workdir.relative_to(project_root)
except ValueError as error:
raise ProjectPolicyError("board workdir is outside the Atlas project registry") from error
repository = REPOSITORY_ALIASES.get(board, board)
remote = f"https://scm.bstein.dev/titan/{repository}.git"
if not ATLAS_REPO.fullmatch(remote):
raise ProjectPolicyError("board repository identity is invalid")
if not workdir.exists():
return remote, "main", workdir
if not workdir.is_dir():
raise ProjectPolicyError("board checkout is not a directory")
checkout_remote = _run_git(workdir, "remote", "get-url", "origin")
if "@" in checkout_remote or checkout_remote != remote:
raise ProjectPolicyError("board origin disagrees with the Atlas registry")
try:
base = _run_git(workdir, "symbolic-ref", "--short", "refs/remotes/origin/HEAD")
if not base.startswith("origin/"):
raise ProjectPolicyError("origin HEAD is not canonical")
base = base.removeprefix("origin/")
except ProjectPolicyError:
base = "main"
return remote, validate_branch(base, feature=False), workdir
def resolve_assignment(board: str, task: Any) -> tuple[str, str, str]:
"""Resolve the exact repo/base and safe task branch for one board task."""
repo, base, _workdir = resolve_project(board)
task_id = str(_task_value(task, "id", "") or "")
if not IDENTIFIER.fullmatch(task_id):
raise ProjectPolicyError("task identity is invalid")
branch = str(_task_value(task, "branch_name", "") or f"wt/{task_id}")
return repo, validate_branch(branch, feature=True), base
def distributed_workspace_eligible(task: Any) -> bool:
"""Only pathless tasks migrate; an existing worktree stays with its local owner."""
return not str(_task_value(task, "workspace_path", "") or "").strip()