Code / tools/new_experiment.py
tools/new_experiment.py
81 lines
#!/usr/bin/env python3
# =============================================================================
# Project : modelmap
# File : tools/new_experiment.py
# Purpose : Scaffold a charter-compliant experiment directory (§10 block)
# Author : Simon-Pierre Boucher
# Contact : contact@spboucher.ai
# Website : https://modelmap.io
# Created : 2026-08-12
# Modified : 2026-08-12
# Platform : macOS / Apple Silicon (arm64)
# License : All rights reserved (research code)
# =============================================================================
"""Scaffold an experiment directory with the seven-field scientific block.
Usage:
python3 tools/new_experiment.py experiments/micro/expX_name "one-line purpose"
"""
from __future__ import annotations
import datetime
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
FRONT = """---
project: modelmap
document: {doc}
author: Simon-Pierre Boucher
contact: contact@spboucher.ai
website: https://modelmap.io
created: {date}
status: draft
---
"""
BLOCK = """```text
Hypothesis : (to be registered before the first run)
Falsification criterion : (explicit kill-number, registered in advance)
Method : (including controls)
Baseline / null : (shuffled labels / random directions / random init)
Result : (pending)
Interpretation : (pending — with explicit confidence level)
Next experiment : (pending)
```
"""
def main() -> int:
if len(sys.argv) < 3:
print(__doc__)
return 2
rel, purpose = sys.argv[1], sys.argv[2]
date = datetime.datetime.now(tz=datetime.UTC).date().isoformat()
exp = ROOT / rel
name = exp.name
if exp.exists():
print(f"error: {rel} already exists")
return 1
(exp / "implementation").mkdir(parents=True)
(exp / "results").mkdir()
(exp / "README.md").write_text(
FRONT.format(doc=name, date=date) + f"\n# {name}\n\n{purpose}\n"
)
(exp / "hypothesis.md").write_text(
FRONT.format(doc=f"{name} — hypothesis", date=date)
+ f"\n# Hypothesis — {name}\n\n> {purpose}\n\n" + BLOCK
)
(exp / "analysis.md").write_text(
FRONT.format(doc=f"{name} — analysis", date=date)
+ f"\n# Analysis — {name}\n\n*(pending — written only after results exist)*\n"
)
print(f"scaffolded {rel}")
return 0
if __name__ == "__main__":
sys.exit(main())