jbostock's picture
Initial: SFT adapter + analysis artefacts (welfare-axis experiment)
4d55467 verified
Raw
History Blame Contribute Delete
1.96 kB
"""Shared logging helpers.
Per CLAUDE.md:
- Always log config + git commit ID before running anything.
- Use timestamps in folder names.
- Save more rather than less.
"""
from __future__ import annotations
import json
import os
import platform
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
def _git_commit(repo_dir: Path) -> str:
try:
out = subprocess.run(
["git", "-C", str(repo_dir), "rev-parse", "HEAD"],
capture_output=True,
text=True,
check=True,
)
sha = out.stdout.strip()
except Exception as e: # noqa: BLE001
sha = f"<no-git: {e!s}>"
try:
dirty = subprocess.run(
["git", "-C", str(repo_dir), "status", "--porcelain"],
capture_output=True,
text=True,
check=True,
)
if dirty.stdout.strip():
sha = f"{sha}-dirty"
except Exception: # noqa: BLE001
pass
return sha
def make_run_dir(name: str, config: dict[str, Any], root: Path | None = None) -> Path:
"""Create logs/<ts>_<name>/ with git_commit.txt, config.json, env.json.
Returns the directory.
"""
repo = Path(__file__).resolve().parent.parent
root = root or (repo / "logs")
ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H%M%SZ")
run_dir = root / f"{ts}_{name}"
run_dir.mkdir(parents=True, exist_ok=True)
(run_dir / "git_commit.txt").write_text(_git_commit(repo) + "\n")
(run_dir / "config.json").write_text(json.dumps(config, indent=2, default=str))
(run_dir / "env.json").write_text(
json.dumps(
{
"python": sys.version,
"platform": platform.platform(),
"argv": sys.argv,
"cwd": os.getcwd(),
"started_utc": ts,
},
indent=2,
)
)
return run_dir