#!/usr/bin/env python3 """Sprint 5 regression checks for v0.12 changes. Checks are non-destructive and default to dry-run behavior. """ from __future__ import annotations import argparse import subprocess import sys from pathlib import Path REPO_ROOT = Path(__file__).resolve().parent.parent def run(cmd: list[str]) -> tuple[int, str]: proc = subprocess.run( cmd, cwd=REPO_ROOT, check=False, capture_output=True, text=True, ) out = (proc.stdout or "") + (proc.stderr or "") return proc.returncode, out def check(name: str, cmd: list[str], must_contain: list[str] | None = None) -> bool: print(f"[check] {name}") print(" $ " + " ".join(cmd)) rc, out = run(cmd) if rc != 0: print(f" FAIL: exit={rc}") if out.strip(): print(" output:") print(" " + out.strip().replace("\n", "\n ")) return False for token in must_contain or []: if token not in out: print(f" FAIL: missing token '{token}'") return False print(" PASS") return True def main() -> int: parser = argparse.ArgumentParser(description="Run Sprint 5 regression checks") parser.add_argument("project", help="Project slug or path for finalize dry-run") args = parser.parse_args() checks = [ ( "model profiles list", ["uv", "run", "python", "scripts/dr.py", "models", "--list"], ["medium", "premium", "simple"], ), ( "search gateway dry-run", [ "uv", "run", "python", "scripts/search.py", "GLP-1 obesity", "--profile", "china_market", "--dry-run", ], ["news:", "general:", "query_rewritten:"], ), ( "phase4 finalize dry-run", [ "uv", "run", "python", "scripts/dr.py", "finalize", args.project, "--model-profile", "medium", "--dry-run", ], ["Phase 4 pipeline done"], ), ] ok = True for name, cmd, tokens in checks: ok = check(name, cmd, tokens) and ok if not ok: print("\nSprint 5 regression: FAILED") return 1 print("\nSprint 5 regression: PASSED") return 0 if __name__ == "__main__": raise SystemExit(main())