#!/usr/bin/env bash # restore-jit-perf.sh — print recovery state for the JIT perf regression investigation. # # This is a substrate investigation, not a steady-state loop. It runs as a Claude # Code instance inside a tmux session named `jit-perf`, operating in a git worktree # at /root/rose-ash-bugs/jit-perf on branch bugs/jit-perf. Unlike language loops, # this one does NOT push (per the plan, push to architecture only after Phase 5 # passes; never push to main). # # Usage: # bash plans/restore-jit-perf.sh # status snapshot # bash plans/restore-jit-perf.sh --print # also cat the plan # set -uo pipefail cd "$(dirname "$0")/.." WT="/root/rose-ash-bugs/jit-perf" echo "=== jit-perf investigation state ===" echo if [ -d "$WT" ]; then echo "Worktree: $WT" echo "Branch: $(git -C "$WT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '?')" echo "HEAD: $(git -C "$WT" log -1 --oneline 2>/dev/null || echo '?')" else echo "Worktree: MISSING ($WT)" echo " Recreate with:" echo " git worktree add /root/rose-ash-bugs/jit-perf -b bugs/jit-perf architecture" fi echo echo "=== Recent commits on substrate paths + plan ===" if [ -d "$WT" ]; then git -C "$WT" log -15 --oneline -- spec/ hosts/ocaml/lib/ hosts/javascript/ lib/tcl/test.sh plans/jit-perf-regression.md 2>/dev/null \ || echo " (none yet)" else echo " (worktree missing)" fi echo echo "=== Current phase progress ===" if [ -f plans/jit-perf-regression.md ]; then awk '/^### Phase / {phase=$0; print " " phase; phase_seen=1; next} /^- \[/ && phase_seen { print " " $0 } /^## [^#]/ {phase_seen=0}' plans/jit-perf-regression.md \ | head -60 else echo " plans/jit-perf-regression.md NOT found" fi echo echo "=== Phase 1 perf-table progress (look for entries in plan Progress log) ===" if [ -f plans/jit-perf-regression.md ]; then awk '/^## Progress log/{flag=1;next} /^## /{flag=0} flag{print " "$0}' plans/jit-perf-regression.md \ | grep -v '^ *$' \ | head -20 else echo " (no plan)" fi echo echo "=== Bisect state (Phase 2) ===" if [ -d "$WT" ] && [ -f "$WT/.git/BISECT_LOG" ]; then echo " ✓ bisect in progress" git -C "$WT" bisect log 2>/dev/null | tail -10 | sed 's/^/ /' else echo " (no bisect underway)" fi echo echo "=== Pre-regression baseline candidate ===" # Heuristic: the architecture→loops/tcl merge that brought R7RS+JIT+env-as-value # (commit a32561a0 per the plan's hypothesis section). The first-bad commit will # be at or after this point. echo " Suggested BASELINE_GOOD anchor (per plan hypotheses): pre-a32561a0" git log --oneline a32561a0^..a32561a0 2>/dev/null | sed 's/^/ /' || echo " (anchor commit not found locally)" echo echo "=== Tcl test.sh watchdog (the 30× witness) ===" if [ -f "$WT/lib/tcl/test.sh" ]; then grep -E 'timeout|TIMEOUT|deadline' "$WT/lib/tcl/test.sh" 2>/dev/null | head -3 | sed 's/^/ /' else echo " (test.sh not found)" fi echo echo "=== Substrate (sx_server.exe) ===" if [ -x hosts/ocaml/_build/default/bin/sx_server.exe ]; then echo " ✓ main repo build present" fi if [ -x "$WT/hosts/ocaml/_build/default/bin/sx_server.exe" ]; then echo " ✓ worktree build present (good — bisect needs per-commit builds)" else echo " ✗ worktree has no _build yet (Phase 1 can use main; Phase 2 bisect needs its own)" fi echo echo "=== Other active loops (perf measurements will be noisy while these run) ===" for s in lib-guest minikanren ocaml datalog; do if tmux has-session -t "$s" 2>/dev/null; then echo " ⚠ $s session running" fi done | head -10 echo echo "=== tmux session 'jit-perf' ===" if command -v tmux >/dev/null && tmux has-session -t jit-perf 2>/dev/null; then echo " ✓ session live" echo " Attach: tmux attach -t jit-perf" echo " Last 8 visible lines:" tmux capture-pane -t jit-perf -p 2>/dev/null \ | grep -v '^[[:space:]]*$' \ | tail -8 \ | sed 's/^/ /' else echo " ✗ session not running" fi echo echo "=== Plan ===" [ -f plans/jit-perf-regression.md ] \ && echo " plans/jit-perf-regression.md" \ || echo " plan NOT found" echo echo "=== To respawn ===" cat <<'EOF' If the worktree is missing: git worktree add /root/rose-ash-bugs/jit-perf -b bugs/jit-perf architecture # patch .mcp.json — fresh worktrees have no _build/, so the relative # mcp_tree path fails. Use the main repo's binary: sed -i 's|"./hosts/ocaml/_build/default/bin/mcp_tree.exe"|"/root/rose-ash/hosts/ocaml/_build/default/bin/mcp_tree.exe"|' \ /root/rose-ash-bugs/jit-perf/.mcp.json If the tmux session died: tmux new-session -d -s jit-perf -c /root/rose-ash-bugs/jit-perf tmux send-keys -t jit-perf 'claude' Enter # wait for the Claude UI box, accept MCP servers, then: tmux send-keys -t jit-perf 'You are the JIT perf regression investigation runner. Read /root/rose-ash/plans/jit-perf-regression.md in full. Resume from the first unchecked phase. Worktree: /root/rose-ash-bugs/jit-perf on branch bugs/jit-perf. Never push to main or architecture (push only after Phase 5 passes per the plan). Other loops (minikanren, ocaml, datalog) may be running — measurements will be noisy; if noise obscures signal, stop and ask before pausing them.' Enter Enter This is an investigation, not a loop — phases need human-in-the-loop decisions (which hypothesis to chase, what fix to apply). The agent should stop and report at phase boundaries, not push through autonomously. If you need a quiet machine for measurements, pause the language loops: tmux send-keys -t minikanren C-c tmux send-keys -t ocaml C-c tmux send-keys -t datalog C-c Resume them after phase completion by attaching and unsticking each. EOF if [ "${1:-}" = "--print" ]; then echo echo "=== Plan contents ===" [ -f plans/jit-perf-regression.md ] && cat plans/jit-perf-regression.md fi