Add batch closure ladder analytics and runner (sprint 253)

This commit is contained in:
Bill
2026-02-26 15:48:33 -07:00
parent 28b29dfd30
commit b6c91c9d64
8 changed files with 158 additions and 2 deletions

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env python3
import argparse
import json
from pathlib import Path
from typing import Dict
def load_json(path: Path):
with path.open("r", encoding="utf-8") as f:
return json.load(f)
def main() -> int:
p = argparse.ArgumentParser(description="Aggregate closure ladder outcomes.")
p.add_argument("--runs-root", default="logs/taskitem_runs")
p.add_argument("--include-glob", default="TEST_ONLY_*closure_ladder*")
p.add_argument("--out", required=True)
args = p.parse_args()
root = Path(args.runs_root)
summaries = sorted(root.glob(f"{args.include_glob}/closure_ladder_summary.json"))
mode_counts: Dict[str, int] = {}
status_counts: Dict[str, int] = {}
rows = []
for s in summaries:
try:
j = load_json(s)
except Exception:
continue
mode = str(j.get("selected_mode", ""))
status = str(j.get("status", "unknown"))
mode_counts[mode] = mode_counts.get(mode, 0) + 1
status_counts[status] = status_counts.get(status, 0) + 1
rows.append({
"run_id": s.parent.name,
"status": status,
"selected_mode": mode,
"selected_run": str(j.get("selected_run", "")),
})
out = {
"status": "ok",
"record_count": len(rows),
"status_counts": status_counts,
"selected_mode_counts": mode_counts,
"records": rows,
}
with Path(args.out).open("w", encoding="utf-8") as f:
json.dump(out, f, indent=2, sort_keys=True)
f.write("\n")
print(json.dumps({"status": "ok", "record_count": len(rows), "out": args.out}, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,35 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SPEC_LIST_FILE="${1:-}"
OUT_DIR="${2:-$ROOT_DIR/logs/taskitem_runs/TEST_ONLY_native_profile_closure_ladder_batch_$(date +%Y%m%d_%H%M%S)}"
if [[ -z "$SPEC_LIST_FILE" ]]; then
echo "usage: $0 <spec_list_file> [out_dir]" >&2
exit 2
fi
if [[ ! -f "$SPEC_LIST_FILE" ]]; then
echo "error: spec list not found: $SPEC_LIST_FILE" >&2
exit 2
fi
mkdir -p "$OUT_DIR"
while IFS= read -r spec; do
[[ -z "$spec" ]] && continue
[[ "$spec" =~ ^# ]] && continue
if [[ ! -f "$spec" ]]; then
echo "skip missing spec: $spec" >&2
continue
fi
safe_name="$(basename "$spec" | sed 's/[^A-Za-z0-9._-]/_/g')"
run_out="$OUT_DIR/$safe_name"
mkdir -p "$run_out"
"$ROOT_DIR/tools/mcp/run_native_profile_closure_ladder.sh" "$spec" "$run_out" >/dev/null || true
done < "$SPEC_LIST_FILE"
python3 "$ROOT_DIR/tools/mcp/analyze_closure_ladder_outcomes.py" \
--runs-root "$OUT_DIR" \
--include-glob "*" \
--out "$OUT_DIR/closure_ladder_batch_summary.json" >/dev/null
jq -n --arg out_dir "$OUT_DIR" --argjson summary "$(cat "$OUT_DIR/closure_ladder_batch_summary.json")" '{status:"ok", out_dir:$out_dir, summary:$summary}'