Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """Evaluator-blind structural audit for the additive Hugging Face candidate.""" | |
| from __future__ import annotations | |
| import hashlib | |
| import json | |
| import re | |
| import sys | |
| from pathlib import Path | |
| from urllib.parse import unquote | |
| TEXT_SUFFIXES = { | |
| ".csv", | |
| ".css", | |
| ".html", | |
| ".js", | |
| ".json", | |
| ".lock", | |
| ".md", | |
| ".py", | |
| ".svg", | |
| ".toml", | |
| ".txt", | |
| } | |
| MUTABLE_ENTRYPOINTS = {"README.md", "logbook.json", "pages/index.md"} | |
| LINK_RE = re.compile(r"!?\[[^\]]*\]\(([^)]+)\)") | |
| SECRET_PATTERNS = { | |
| "hugging_face_token": re.compile(r"\bhf_[A-Za-z0-9]{20,}\b"), | |
| "github_token": re.compile(r"\bgithub_pat_[A-Za-z0-9_]{20,}\b"), | |
| "bearer_token": re.compile(r"\bBearer\s+[A-Za-z0-9._~-]{16,}\b", re.IGNORECASE), | |
| "aws_access_key": re.compile(r"\bAKIA[0-9A-Z]{16}\b"), | |
| } | |
| def sha256(path: Path) -> str: | |
| return hashlib.sha256(path.read_bytes()).hexdigest() | |
| def flatten_pages(node: dict) -> dict[str, str]: | |
| pages: dict[str, str] = {} | |
| for child in node.get("children", []): | |
| pages[child["slug"]] = child["file"] | |
| pages.update(flatten_pages(child)) | |
| return pages | |
| def parse_judged_manifest(path: Path) -> dict[str, str]: | |
| result = {} | |
| for line in path.read_text().splitlines(): | |
| digest, relative = line.split(" ", 1) | |
| result[relative] = digest | |
| return result | |
| def resolve_link(space: Path, source: Path, raw_target: str, routes: dict[str, str]) -> Path | None: | |
| target = raw_target.strip().split(" ", 1)[0].strip("<>") | |
| if target.startswith(("http://", "https://", "mailto:")) or target == "": | |
| return None | |
| if target.startswith("#/"): | |
| slug = target[2:].split("#", 1)[0] | |
| if slug not in routes: | |
| raise ValueError(f"unknown route {target} from {source.relative_to(space)}") | |
| return space / routes[slug] | |
| if target.startswith("#"): | |
| return None | |
| target = unquote(target.split("#", 1)[0].split("?", 1)[0]) | |
| return (source.parent / target).resolve() | |
| def main() -> None: | |
| if len(sys.argv) != 4: | |
| raise SystemExit( | |
| "usage: audit_candidate_space.py CANDIDATE_DIR JUDGED_MANIFEST OUTPUT_DIR" | |
| ) | |
| space = Path(sys.argv[1]).resolve() | |
| judged_manifest_path = Path(sys.argv[2]).resolve() | |
| output = Path(sys.argv[3]).resolve() / "release" | |
| output.mkdir(parents=True, exist_ok=True) | |
| failures: list[str] = [] | |
| try: | |
| logbook = json.loads((space / "logbook.json").read_text()) | |
| except (OSError, json.JSONDecodeError) as exc: | |
| raise SystemExit(f"invalid candidate logbook: {exc}") | |
| routes = flatten_pages(logbook["root"]) | |
| routes[logbook["root"]["slug"]] = logbook["root"]["file"] | |
| children = logbook["root"].get("children", []) | |
| if not children or children[0].get("slug") != "current-cumulative-verification": | |
| failures.append("current_cumulative_not_first") | |
| judged = parse_judged_manifest(judged_manifest_path) | |
| candidate_paths = { | |
| path.relative_to(space).as_posix(): path | |
| for path in space.rglob("*") | |
| if path.is_file() | |
| } | |
| missing_old_paths = sorted(set(judged) - set(candidate_paths)) | |
| if missing_old_paths: | |
| failures.append("judged_file_set_not_subset") | |
| changed_historical_pages = [] | |
| for relative, expected in judged.items(): | |
| if relative.startswith("pages/") and relative != "pages/index.md": | |
| path = candidate_paths.get(relative) | |
| if path is not None and sha256(path) != expected: | |
| changed_historical_pages.append(relative) | |
| if changed_historical_pages: | |
| failures.append("historical_page_changed") | |
| json_failures = [] | |
| for relative, path in candidate_paths.items(): | |
| if path.suffix == ".json": | |
| try: | |
| json.loads(path.read_text()) | |
| except (UnicodeDecodeError, json.JSONDecodeError): | |
| json_failures.append(relative) | |
| if json_failures: | |
| failures.append("invalid_json") | |
| opened: list[str] = [] | |
| broken_links: list[dict[str, str]] = [] | |
| queue = [space / "README.md", space / "pages/index.md"] | |
| seen: set[Path] = set() | |
| while queue: | |
| source = queue.pop(0).resolve() | |
| if source in seen: | |
| continue | |
| seen.add(source) | |
| if not source.is_file() or space not in source.parents: | |
| broken_links.append({"source": "entrypoint", "target": str(source)}) | |
| continue | |
| opened.append(source.relative_to(space).as_posix()) | |
| if source.suffix not in {".md", ".html"}: | |
| continue | |
| text = source.read_text(errors="strict") | |
| for raw_target in LINK_RE.findall(text): | |
| try: | |
| resolved = resolve_link(space, source, raw_target, routes) | |
| except ValueError: | |
| broken_links.append( | |
| {"source": source.relative_to(space).as_posix(), "target": raw_target} | |
| ) | |
| continue | |
| if resolved is None: | |
| continue | |
| if not resolved.is_file() or (resolved != space and space not in resolved.parents): | |
| broken_links.append( | |
| {"source": source.relative_to(space).as_posix(), "target": raw_target} | |
| ) | |
| continue | |
| if resolved.suffix in {".md", ".html"}: | |
| queue.append(resolved) | |
| elif resolved.relative_to(space).as_posix() not in opened: | |
| opened.append(resolved.relative_to(space).as_posix()) | |
| if broken_links: | |
| failures.append("broken_reachable_links") | |
| cumulative = (space / "pages/current-cumulative-verification/page.md").read_text() | |
| visibility_rows = {} | |
| for line in cumulative.splitlines(): | |
| match = re.match(r"\|\s*([1-5])\s*\|(.+)\|", line) | |
| if match and "Canonical page" not in line: | |
| cells = [cell.strip() for cell in line.strip().strip("|").split("|")] | |
| if len(cells) == 9: | |
| visibility_rows[match.group(1)] = cells | |
| if set(visibility_rows) != set("12345"): | |
| failures.append("visibility_matrix_claim_rows") | |
| elif any( | |
| any(value in {"", "No", "Missing", "INCONCLUSIVE"} for value in row[1:]) | |
| for row in visibility_rows.values() | |
| ): | |
| failures.append("visibility_matrix_missing_cell") | |
| required_opened = { | |
| "README.md", | |
| "pages/index.md", | |
| "pages/current-cumulative-verification/page.md", | |
| "pages/current-claim-3-celeba-verification/page.md", | |
| "pages/current-claim-4-molecular-verification/page.md", | |
| "code/run_logdiff.py", | |
| "code/check_baseline_artifacts.py", | |
| "code/check_claim3_release.py", | |
| "code/check_claim4_evidence.py", | |
| "code/audit_candidate_space.py", | |
| "environment/pyproject.toml", | |
| "environment/uv.lock", | |
| "evidence/run-07daf77f-summary.json", | |
| } | |
| missing_from_traversal = sorted(required_opened - set(opened)) | |
| if missing_from_traversal: | |
| failures.append("required_evidence_not_reachable") | |
| changed_or_new = [] | |
| for relative, path in sorted(candidate_paths.items()): | |
| if relative not in judged or sha256(path) != judged[relative]: | |
| changed_or_new.append(relative) | |
| non_text_uploads = [ | |
| relative for relative in changed_or_new if Path(relative).suffix not in TEXT_SUFFIXES | |
| ] | |
| if non_text_uploads: | |
| failures.append("non_text_candidate_change") | |
| secret_hits = [] | |
| for relative in changed_or_new: | |
| path = candidate_paths[relative] | |
| if path.suffix not in TEXT_SUFFIXES: | |
| continue | |
| text = path.read_text(errors="strict") | |
| for name, pattern in SECRET_PATTERNS.items(): | |
| if pattern.search(text): | |
| secret_hits.append({"path": relative, "pattern": name}) | |
| if secret_hits: | |
| failures.append("secret_pattern") | |
| candidate_manifest = [ | |
| f"{sha256(path)} {relative}" for relative, path in sorted(candidate_paths.items()) | |
| ] | |
| upload_allowlist = [ | |
| relative | |
| for relative in changed_or_new | |
| if Path(relative).suffix in TEXT_SUFFIXES | |
| and relative not in {"release/candidate_manifest.sha256", "release/upload_allowlist.txt"} | |
| ] | |
| (output / "candidate_manifest.sha256").write_text("\n".join(candidate_manifest) + "\n") | |
| (output / "upload_allowlist.txt").write_text("\n".join(upload_allowlist) + "\n") | |
| result = { | |
| "checker": "evaluator-blind candidate traversal and release audit", | |
| "status": "PASS" if not failures else "FAIL", | |
| "failures": failures, | |
| "canonical_entrypoint": "README.md -> pages/index.md -> current cumulative verification", | |
| "files_opened": opened, | |
| "conclusions_not_verified": [], | |
| "broken_links": broken_links, | |
| "missing_from_traversal": missing_from_traversal, | |
| "judged_manifest_entries": len(judged), | |
| "candidate_file_entries": len(candidate_paths), | |
| "old_file_set_subset": not missing_old_paths, | |
| "missing_old_paths": missing_old_paths, | |
| "historical_pages_unchanged": not changed_historical_pages, | |
| "changed_historical_pages": changed_historical_pages, | |
| "json_files_checked": sum(path.suffix == ".json" for path in candidate_paths.values()), | |
| "invalid_json_files": json_failures, | |
| "visibility_claim_rows": len(visibility_rows), | |
| "non_text_uploads": non_text_uploads, | |
| "secret_hits": secret_hits, | |
| "upload_allowlist_entries": len(upload_allowlist), | |
| } | |
| (output / "candidate_audit.json").write_text(json.dumps(result, indent=2) + "\n") | |
| print(json.dumps(result, indent=2)) | |
| if failures: | |
| raise SystemExit(1) | |
| if __name__ == "__main__": | |
| main() | |