#!/usr/bin/env python3 """Validate the no-live Vision package Docker build context.""" from __future__ import annotations import json import re from pathlib import Path ROOT = Path(__file__).resolve().parents[1] DOCKERFILE = ROOT / "Dockerfile" DOCKERIGNORE = ROOT / ".dockerignore" WORKBOARD = ROOT / "WORKBOARD.yaml" REQUIRED_DOCKER_SNIPPETS = [ "FROM python:3.12-slim", "SVRNTY_VISION_HOST=0.0.0.0", "SVRNTY_VISION_PORT=8094", "COPY pyproject.toml README.md ./", "COPY src ./src", "python -m pip install --no-cache-dir .", "USER vision", "EXPOSE 8094", "HEALTHCHECK", "http://127.0.0.1:8094/healthz", 'CMD ["python", "-m", "svrnty_vision.server"]', ] REQUIRED_IGNORE = { ".git", ".venv", "__pycache__", "outputs", "worktrees", "tests", "candidate-manifests", } FORBIDDEN_PATTERNS = [ re.compile(r"sk-[A-Za-z0-9_-]{20,}"), re.compile(r"AIza[0-9A-Za-z_-]{20,}"), re.compile(r"\b(?:ck|cs)_[0-9A-Za-z]{20,}"), re.compile(r"(?i)\b[A-Z0-9_]*(?:PASS|PASSWORD|SECRET|TOKEN|KEY)[A-Z0-9_]*\s*=\s*[^`\s#]{8,}"), ] def main() -> int: errors: list[str] = [] dockerfile = DOCKERFILE.read_text(encoding="utf-8") if DOCKERFILE.is_file() else "" dockerignore = DOCKERIGNORE.read_text(encoding="utf-8") if DOCKERIGNORE.is_file() else "" workboard = WORKBOARD.read_text(encoding="utf-8") if WORKBOARD.is_file() else "" if not dockerfile: errors.append("missing:Dockerfile") if not dockerignore: errors.append("missing:.dockerignore") for snippet in REQUIRED_DOCKER_SNIPPETS: if snippet not in dockerfile: errors.append(f"dockerfile_missing:{snippet}") ignore_rows = {line.strip() for line in dockerignore.splitlines() if line.strip() and not line.startswith("#")} for row in sorted(REQUIRED_IGNORE - ignore_rows): errors.append(f"dockerignore_missing:{row}") if "SVRNTY-VISION-WORK-004" not in workboard: errors.append("workboard_missing:SVRNTY-VISION-WORK-004") if "Package Docker Build Context" not in workboard: errors.append("workboard_missing:Package Docker Build Context") combined = "\n".join([dockerfile, dockerignore, workboard]) for pattern in FORBIDDEN_PATTERNS: if pattern.search(combined): errors.append(f"value_pattern_found:{pattern.pattern}") result = { "ok": not errors, "validator": "vision-package-docker-context-no-live", "checked": ["Dockerfile", ".dockerignore", "WORKBOARD.yaml"], "errors": errors, "warnings": [], } print(json.dumps(result, indent=2)) return 0 if result["ok"] else 1 if __name__ == "__main__": raise SystemExit(main())