iamrahulreddy's picture
Release L31H14+ code, results, and SAE checkpoint
938f0c7 verified
Raw
History Blame Contribute Delete
5.14 kB
"""Bundle verification for completed run folders."""
from __future__ import annotations
import csv
import hashlib
import json
import zipfile
from pathlib import Path
REQUIRED_FILES = [
"RUN_CARD.json",
"config/resolved_config.json",
"logs/events.jsonl",
]
DATA_CSVS = [
"data/head_recovery.csv",
"data/logit_lens.csv",
"data/gradient_attribution.csv",
]
OPTIONAL_CSVS = [
"data/ablation_results.csv",
"data/source_results.csv",
"summaries/candidate_heads.csv",
"summaries/ablation_summary.csv",
"summaries/source_summary.csv",
]
SUMMARY_FILES = [
"summaries/run_summary.json",
]
def verify_bundle(run_dir: Path) -> bool:
"""Verify a completed run bundle. Prints pass/fail for each check. Returns True if all pass."""
run_dir = Path(run_dir)
print(f"\n=== Verifying: {run_dir} ===")
ok = True
# 1. Directory exists
if not run_dir.is_dir():
print(f" [FAIL] Directory not found: {run_dir}")
return False
# 2. Required files
for rel in REQUIRED_FILES:
path = run_dir / rel
if path.exists():
print(f" [OK] {rel}")
else:
print(f" [FAIL] Missing: {rel}")
ok = False
# 3. At least one summary JSON
for rel in SUMMARY_FILES:
path = run_dir / rel
if path.exists():
try:
json.loads(path.read_text(encoding="utf-8"))
print(f" [OK] {rel} (valid JSON)")
except Exception as exc:
print(f" [FAIL] {rel} - JSON parse error: {exc}")
ok = False
else:
print(f" [WARN] Missing (optional): {rel}")
# 4. Raw JSON files
raw_dir = run_dir / "raw"
if raw_dir.is_dir():
raw_jsons = list(raw_dir.glob("*.json"))
if raw_jsons:
for f in raw_jsons:
try:
json.loads(f.read_text(encoding="utf-8"))
print(f" [OK] raw/{f.name} (valid JSON)")
except Exception as exc:
print(f" [FAIL] raw/{f.name} - JSON parse error: {exc}")
ok = False
else:
print(" [WARN] raw/ directory is empty")
else:
print(" [WARN] raw/ directory not found")
# 5. Core CSV files
for rel in DATA_CSVS:
path = run_dir / rel
if path.exists():
row_count = _count_csv_rows(path)
if row_count > 0:
print(f" [OK] {rel} ({row_count} rows)")
else:
print(f" [FAIL] {rel} is empty (0 rows)")
ok = False
else:
print(f" [WARN] Missing (may be absent for ablation/source-only runs): {rel}")
# 6. Optional CSVs
for rel in OPTIONAL_CSVS:
path = run_dir / rel
if path.exists():
row_count = _count_csv_rows(path)
print(f" [OK] {rel} ({row_count} rows)")
# 7. Integrity file
integrity_path = run_dir / "integrity.json"
if integrity_path.exists():
try:
integrity = json.loads(integrity_path.read_text(encoding="utf-8"))
files = integrity.get("files", {})
mismatches = []
for rel_path, file_info in files.items():
actual = run_dir / rel_path
if actual.exists():
expected_hash = file_info["sha256"] if isinstance(file_info, dict) else file_info
actual_hash = hashlib.sha256(actual.read_bytes()).hexdigest()
if actual_hash != expected_hash:
mismatches.append(rel_path)
if mismatches:
print(f" [FAIL] Checksum mismatches: {mismatches}")
ok = False
else:
print(f" [OK] integrity.json ({len(files)} checksums verified)")
except Exception as exc:
print(f" [WARN] integrity.json - parse error: {exc}")
else:
print(" [WARN] integrity.json not found")
# 8. Zip file
zip_search_roots = [run_dir.parent, run_dir.parent.parent, Path.cwd()]
zips = []
seen_roots = set()
for root in zip_search_roots:
resolved = root.resolve()
if resolved in seen_roots:
continue
seen_roots.add(resolved)
zips.extend(root.glob(f"{run_dir.name}*.zip"))
if zips:
zip_path = zips[0]
try:
with zipfile.ZipFile(zip_path) as zf:
names = zf.namelist()
print(f" [OK] Archive: {zip_path.name} ({len(names)} files)")
except Exception as exc:
print(f" [FAIL] Archive {zip_path.name} - {exc}")
ok = False
else:
print(" [INFO] No run archive found")
status = "PASS" if ok else "FAIL"
print(f"\n Result: {status}\n")
return ok
def _count_csv_rows(path: Path) -> int:
try:
with path.open(newline="", encoding="utf-8") as f:
reader = csv.reader(f)
rows = sum(1 for _ in reader)
return max(0, rows - 1) # subtract header
except Exception:
return -1