SPB Git

spb/localvm-research Public License

Running LLMs larger than memory on a consumer Mac — falsification-driven research: margin-gated deferred refinement, out-of-core verification on Apple Silicon. TR-01 published.

Python 63.2% JavaScript 23.5% CSS 11.8% Shell 0.9% Makefile 0.5%
4.4 KB · 149 lines python
Raw Blame History
1#!/usr/bin/env python32# =============================================================================3#  Project   : localvm-research4#  File      : tools/new_experiment.py5#  Purpose   : Scaffold a header-compliant experiment directory (CLAUDE.md §3, §10)6#  Author    : Simon-Pierre Boucher7#  Contact   : contact@spboucher.ai8#  Created   : 2026-08-119#  Modified  : 2026-08-1110#  Platform  : macOS / Apple Silicon (arm64)11#  License   : All rights reserved (research code)12# =============================================================================13"""Scaffold a new experiment directory with the mandatory structure.1415Creates: README.md, hypothesis.md (seven-field scientific block), benchmark.py,16implementation/, results/, analysis.md — all with conforming author headers.1718Usage:19    python3 tools/new_experiment.py experiments/micro/expX_name "One-line purpose"20    python3 tools/new_experiment.py experiments/candidate_04 "Candidate: ..."21"""2223from __future__ import annotations2425import sys26from datetime import date27from pathlib import Path2829REPO_ROOT = Path(__file__).resolve().parent.parent30TODAY = date.today().isoformat()3132PY_HEADER = """\33# =============================================================================34#  Project   : localvm-research35#  File      : {rel}36#  Purpose   : {purpose}37#  Author    : Simon-Pierre Boucher38#  Contact   : contact@spboucher.ai39#  Created   : {today}40#  Modified  : {today}41#  Platform  : macOS / Apple Silicon (arm64)42#  License   : All rights reserved (research code)43# =============================================================================44"""4546MD_HEADER = """\47---48project: localvm-research49document: {doc}50author: Simon-Pierre Boucher51contact: contact@spboucher.ai52created: {today}53status: draft54---55"""5657HYPOTHESIS_BODY = """58# Hypothesis — {name}5960```text61Hypothesis62  <what we believe and why>6364Falsification criterion65  <the concrete measurable outcome that would prove this wrong>6667Method68  <exact procedure, model(s), data, seeds, measurement points>6970Baseline71  <what this is compared against — no straw men>7273Result74  <filled after the run: numbers, with mean/median/std and run count>7576Interpretation77  <what the numbers mean; alternative explanations considered>7879Next experiment80  <the most informative follow-up given this result>81```82"""8384BENCHMARK_BODY = '''85"""Benchmark entry point for {name}.8687Must embed the hardware manifest in all result output88(see benchmarks/hardware_manifest.py) and write results to89results/{name}/<timestamp>/.90"""9192import sys93from pathlib import Path9495sys.path.insert(0, str(Path(__file__).resolve().parents[{depth}] / "benchmarks"))96from hardware_manifest import collect_manifest  # noqa: E402979899def main() -> None:100    manifest = collect_manifest()101    raise NotImplementedError("experiment not yet implemented")102103104if __name__ == "__main__":105    main()106'''107108109def scaffold(exp_dir: Path, purpose: str) -> None:110    if exp_dir.exists() and any(exp_dir.iterdir()):111        sys.exit(f"error: {exp_dir} already exists and is not empty")112    name = exp_dir.name113    rel = exp_dir.relative_to(REPO_ROOT)114    (exp_dir / "implementation").mkdir(parents=True, exist_ok=True)115    (exp_dir / "results").mkdir(exist_ok=True)116117    def md(doc: str) -> str:118        return MD_HEADER.format(doc=doc, today=TODAY)119120    (exp_dir / "README.md").write_text(121        md(f"{name}/README") + f"\n# {name}\n\n{purpose}\n\nStatus: scaffolded {TODAY}, not yet run.\n"122    )123    (exp_dir / "hypothesis.md").write_text(124        md(f"{name}/hypothesis") + HYPOTHESIS_BODY.format(name=name)125    )126    (exp_dir / "analysis.md").write_text(127        md(f"{name}/analysis") + f"\n# Analysis — {name}\n\n*To be written after results exist. "128        "Must include the seven-field block and the evidence standard of CLAUDE.md §10.*\n"129    )130    depth = len(rel.parts)  # parents[] index up to repo root131    (exp_dir / "benchmark.py").write_text(132        PY_HEADER.format(rel=rel / "benchmark.py", purpose=f"Benchmark runner: {purpose}", today=TODAY)133        + BENCHMARK_BODY.format(name=name, depth=depth)134    )135    print(f"scaffolded {rel} ({purpose})")136137138def main() -> None:139    if len(sys.argv) < 3:140        sys.exit(__doc__)141    exp_dir = (REPO_ROOT / sys.argv[1]).resolve()142    if REPO_ROOT not in exp_dir.parents:143        sys.exit("error: experiment directory must live inside the repository")144    scaffold(exp_dir, sys.argv[2])145146147if __name__ == "__main__":148    main()149