"""Permanent, secret-free synthetic monitoring for the governed Gitea surface.""" from __future__ import annotations import json import re import urllib.error import urllib.request from dataclasses import dataclass from pathlib import Path from typing import Any import yaml # type: ignore[import-untyped] _GITEA_READY_URL = "http://connector-gitea:8080/health/ready" _FINGERPRINT = re.compile(r"^[0-9a-f]{64}$") _MAX_RESPONSE_BYTES = 32 * 1024 @dataclass(frozen=True) class SyntheticSnapshot: tool_count: int capability_fingerprint: str upstream: str def expected_gitea_wire_tools(catalog_root: Path) -> frozenset[str]: names: set[str] = set() for path in sorted((catalog_root / "tools").glob("*.yaml")): value = yaml.safe_load(path.read_text(encoding="utf-8")) spec = value.get("spec", {}) if isinstance(value, dict) else {} if spec.get("connectorType") != "gitea": continue name = spec.get("connectorToolName", spec.get("canonicalName")) if not isinstance(name, str) or not name: raise ValueError("Gitea catalog carries an invalid connector tool name") names.add(name) if not names: raise ValueError("Gitea synthetic monitor has no expected tools") return frozenset(names) class GiteaSyntheticMonitor: """Probe upstream reachability and detect capability drift every worker cycle.""" def __init__(self, catalog_root: Path) -> None: self.expected_tools = expected_gitea_wire_tools(catalog_root) self._baseline_fingerprint: str | None = None def probe(self) -> SyntheticSnapshot: request = urllib.request.Request( # noqa: S310 - fixed internal allowlisted endpoint _GITEA_READY_URL, headers={"Accept": "application/json"}, method="GET", ) try: with urllib.request.urlopen(request, timeout=5) as response: # noqa: S310 raw = response.read(_MAX_RESPONSE_BYTES + 1) status = int(response.status) except (OSError, urllib.error.URLError) as exc: raise RuntimeError("Gitea synthetic readiness probe failed") from exc if status != 200 or len(raw) > _MAX_RESPONSE_BYTES: raise RuntimeError("Gitea synthetic readiness response is invalid") try: payload: Any = json.loads(raw) except (UnicodeDecodeError, json.JSONDecodeError) as exc: raise RuntimeError("Gitea synthetic readiness response is invalid") from exc if not isinstance(payload, dict): raise RuntimeError("Gitea synthetic readiness response is invalid") fingerprint = payload.get("capabilityFingerprint") tool_count = payload.get("toolCount") if ( payload.get("status") != "ready" or payload.get("upstream") != "reachable" or not isinstance(tool_count, int) or tool_count != len(self.expected_tools) or not isinstance(fingerprint, str) or not _FINGERPRINT.fullmatch(fingerprint) ): raise RuntimeError("Gitea synthetic capability contract drifted") if self._baseline_fingerprint is not None and fingerprint != self._baseline_fingerprint: raise RuntimeError("Gitea synthetic capability fingerprint changed unexpectedly") self._baseline_fingerprint = fingerprint return SyntheticSnapshot( tool_count=tool_count, capability_fingerprint=fingerprint, upstream="reachable", )