"""Bulk cross-check of chronology.md rows. Run from repo root: uv run python scripts/audit/check_chronology_rows.py """ from __future__ import annotations import subprocess import sys from pathlib import Path # Add repo root to path so we can import the helper sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent)) from scripts.audit.generate_chronology import walk_track_folders # noqa: E402 rows = walk_track_folders(Path("conductor")) errors: list[str] = [] checked = 0 for i, row in enumerate(rows): checked += 1 folder_relpath = row["folder_link"] track_id = row["track_id"] folder = Path(folder_relpath) if not folder.is_dir(): errors.append(f"Row {i+2} [{track_id}]: folder does not exist: {folder_relpath}") continue try: result = subprocess.run( ["git", "log", "--reverse", "--format=%h", "--", folder_relpath], capture_output=True, text=True, timeout=30, check=False, ) actual_init = result.stdout.strip().splitlines()[0] if result.stdout.strip() else "" if row["init_sha"] != actual_init: errors.append( f"Row {i+2} [{track_id}]: init_sha mismatch: row={row['init_sha']!r} actual={actual_init!r}" ) except Exception as exc: errors.append(f"Row {i+2} [{track_id}]: init_sha check failed: {exc}") try: result = subprocess.run( ["git", "log", "-1", "--format=%h", "--", folder_relpath], capture_output=True, text=True, timeout=30, check=False, ) actual_end = result.stdout.strip() if row["end_sha"] != actual_end: errors.append( f"Row {i+2} [{track_id}]: end_sha mismatch: row={row['end_sha']!r} actual={actual_end!r}" ) except Exception as exc: errors.append(f"Row {i+2} [{track_id}]: end_sha check failed: {exc}") date = row["date"] if date and not (len(date) == 10 and date[4] == "-" and date[7] == "-"): errors.append(f"Row {i+2} [{track_id}]: bad date format: {date!r}") if not row["status"]: errors.append(f"Row {i+2} [{track_id}]: empty status") if not row["summary"]: errors.append(f"Row {i+2} [{track_id}]: empty summary") print(f"Checked: {checked} rows") print(f"Errors: {len(errors)}") if errors: print("All errors:") for e in errors: print(f" {e}")