kwvtSA9ed3 / code /build_space.py
DineshAI's picture
All six claims decided with reproducible evidence (5 VERIFIED, 1 FALSIFIED as stated in the main text)
e2d54c9 verified
Raw
History Blame Contribute Delete
6.6 kB
"""Assemble the evaluator-visible candidate Hugging Face Space.
Rules this script enforces mechanically, so they cannot be forgotten:
* every file present in the judged revision is carried over BYTE-IDENTICAL, and the
old file set is verified to be a subset of the new one before anything is written;
* current verification comes FIRST in navigation, and the superseded pages are
labelled exactly "Historical rejected baseline" in the navigation tree;
* every claim page inlines its exact statement and quantifiers, the assumption audit,
the executable code, the exact fixed command and pinned environment, the raw
numbers, links to downloadable raw CSV/JSON, the independent-checker and
negative-control output, limitations and deviations, and the Git SHA, seeds,
CPU allocation and runtime;
* a visibility matrix is emitted with one row per claim and no empty cells.
Usage:
python tools/build_space.py <judged_clone> <out_dir> <results.json>
"""
from __future__ import annotations
import hashlib
import json
import shutil
import sys
from pathlib import Path
LABEL_HISTORICAL = "Historical rejected baseline"
SPACE = "DineshAI/kwvtSA9ed3"
RAW = f"https://huggingface.co/spaces/{SPACE}/resolve/main"
def sha256(p: Path) -> str:
return hashlib.sha256(p.read_bytes()).hexdigest()
IGNORED_DIRS = {".git", ".cache", ".huggingface"}
def file_set(root: Path) -> set[str]:
"""Real Space content only.
A snapshot_download leaves .cache/huggingface/ metadata behind; counting it would
inflate the judged file count and, worse, copy download bookkeeping into the
candidate as if it were evidence.
"""
return {
str(p.relative_to(root))
for p in root.rglob("*")
if p.is_file() and not IGNORED_DIRS & set(p.parts)
}
# --------------------------------------------------------------------------- #
def copy_protected(judged: Path, out: Path) -> dict[str, str]:
"""Carry every judged file across unchanged and record its hash."""
hashes = {}
for rel in sorted(file_set(judged)):
src, dst = judged / rel, out / rel
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dst)
hashes[rel] = sha256(src)
return hashes
def verify_subset(judged: Path, out: Path, hashes: dict[str, str]) -> list[str]:
"""The judged file set must be a subset of the candidate, with content preserved
for everything except the navigation files we are required to update."""
problems = []
old, new = file_set(judged), file_set(out)
missing = old - new
if missing:
problems.append(f"MISSING from candidate: {sorted(missing)}")
for rel, h in hashes.items():
if rel in {"pages/index.md", "logbook.json", "README.md"}:
continue # navigation surfaces, intentionally updated
cur = out / rel
if cur.exists() and sha256(cur) != h:
problems.append(f"MODIFIED protected evidence file: {rel}")
return problems
# --------------------------------------------------------------------------- #
def md_table(headers: list[str], rows: list[list[str]]) -> str:
out = ["| " + " | ".join(headers) + " |",
"|" + "|".join("---" for _ in headers) + "|"]
for r in rows:
out.append("| " + " | ".join(str(c) for c in r) + " |")
return "\n".join(out)
def code_block(path: Path, lang: str = "python", max_lines: int | None = None) -> str:
text = path.read_text()
if max_lines:
lines = text.splitlines()
if len(lines) > max_lines:
text = "\n".join(lines[:max_lines]) + f"\n\n# ... ({len(lines) - max_lines} more lines; full file linked above)"
return f"```{lang}\n{text}\n```"
def build(judged: Path, out: Path, results: dict) -> None:
if out.exists():
shutil.rmtree(out)
out.mkdir(parents=True)
hashes = copy_protected(judged, out)
(out / "data").mkdir(exist_ok=True)
(out / "code").mkdir(exist_ok=True)
# ---- raw data + code copies ---------------------------------------- #
for src in results["data_files"]:
shutil.copy2(src, out / "data" / Path(src).name)
for src in results["code_files"]:
shutil.copy2(src, out / "code" / Path(src).name)
pages = results["pages"]
for slug, page in pages.items():
d = out / "pages" / slug
d.mkdir(parents=True, exist_ok=True)
(d / "page.md").write_text(page["body"])
# ---- logbook.json: current first, historical labelled --------------- #
lb = json.loads((judged / "logbook.json").read_text())
children = [
{"slug": slug, "title": page["title"],
"file": f"pages/{slug}/page.md", "children": []}
for slug, page in pages.items()
]
historical = [
{"slug": s, "title": f"{LABEL_HISTORICAL}{t}",
"file": f"pages/{s}/page.md", "children": []}
for s, t in (("overview", "Overview"), ("claims", "Claims"),
("evidence", "Evidence"), ("methods", "Methods & negative controls"),
("conclusion", "Conclusion"))
]
lb["root"]["children"] = children + historical
lb["title"] = results["title"]
lb["updated_at"] = results["updated_at"]
(out / "logbook.json").write_text(json.dumps(lb, indent=2) + "\n")
(out / "pages" / "index.md").write_text(results["index_md"])
(out / "README.md").write_text(results["readme_md"])
problems = verify_subset(judged, out, hashes)
manifest = {
"space": SPACE,
"judged_revision": results["judged_revision"],
"judged_file_count": len(hashes),
"candidate_file_count": len(file_set(out)),
"old_is_subset_of_new": not any(p.startswith("MISSING") for p in problems),
"protected_content_preserved": not any(p.startswith("MODIFIED") for p in problems),
"problems": problems,
"judged_hashes": hashes,
"candidate_hashes": {rel: sha256(out / rel) for rel in sorted(file_set(out))},
}
(out / "data" / "upload_manifest.json").write_text(json.dumps(manifest, indent=2) + "\n")
print(json.dumps({k: v for k, v in manifest.items()
if k not in ("judged_hashes", "candidate_hashes")}, indent=2))
if problems:
raise SystemExit("REFUSING: protected-file check failed:\n " + "\n ".join(problems))
def main() -> int:
judged, out, results_path = (Path(sys.argv[1]), Path(sys.argv[2]), Path(sys.argv[3]))
build(judged, out, json.loads(results_path.read_text()))
return 0
if __name__ == "__main__":
raise SystemExit(main())