← back to Codex Review 2026 04 30

all-night.sh

107 lines

#!/usr/bin/env bash
# Sequential round-3 POKE+APPLY across all FIX BEFORE SHIP projects.
# Verifies pm2 health between each iteration. Logs to all-night.log.
set -uo pipefail
ROOT="$HOME/Projects/codex-review-2026-04-30"
LOG="$ROOT/all-night.log"
PROMPT="$(cat $ROOT/POKE_APPLY_PROMPT.txt)"

# Round-3 candidates: projects with applied changes that had FIX BEFORE SHIP rereview
PROJECTS=(
  Designer-Wallcoverings
  Hormuzy
  jill-website
  Ken
  lawyer-directory-builder
  Letsbegin
  malden-house
  Norma
  site-factory
  stayclaim
  the-ai-factory
  trademarks-copyright
  VictoryStays
  visual-factory
  yolo-agent
)

echo "=== all-night round-3 start $(date -Iseconds) ===" >> "$LOG"

pm2_health() {
  pm2 jlist 2>/dev/null | python3 -c "
import json,sys,time
d=json.load(sys.stdin)
n=time.time()*1000
bad=[]
for p in d:
  e=p['pm2_env']
  s=e.get('status'); r=e.get('restart_time',0) or 0
  u=int((n-e.get('pm_uptime',n))/1000) if e.get('pm_uptime') else 0
  # Tolerate intentionally stopped am-recrawl
  if p['name']=='am-recrawl' and s=='stopped': continue
  if s != 'online' or (r>50) or (r>5 and u<120):
    bad.append(f\"{p['name']}({s},r={r})\")
print(';'.join(bad) if bad else 'OK')
"
}

for P in "${PROJECTS[@]}"; do
  SRC="$HOME/Projects/$P"
  OUT="$ROOT/$P"
  echo "[$(date +%H:%M:%S)] === $P ===" | tee -a "$LOG"

  HEALTH=$(pm2_health)
  if [ "$HEALTH" != "OK" ]; then
    echo "[$(date +%H:%M:%S)] PM2 UNHEALTHY before $P: $HEALTH — pausing 60s" | tee -a "$LOG"
    sleep 60
    HEALTH=$(pm2_health)
    if [ "$HEALTH" != "OK" ]; then
      echo "[$(date +%H:%M:%S)] STILL UNHEALTHY: $HEALTH — skipping $P" | tee -a "$LOG"
      continue
    fi
  fi

  # Stage all prior context for codex
  for f in review.md CHANGES.md CHANGES2.md rereview.md; do
    if [ -f "$OUT/$f" ]; then
      target="CODEX_$(echo "$f" | sed 's/\.md/_PRIOR.md/')"
      cp "$OUT/$f" "$SRC/$target" 2>/dev/null || true
    fi
  done
  # Also stage the project's own CHANGES.md (which is what was actually applied to source)
  [ -f "$SRC/CHANGES.md" ] && cp "$SRC/CHANGES.md" "$SRC/CODEX_CHANGES.md"
  [ -f "$SRC/CHANGES2.md" ] && cp "$SRC/CHANGES2.md" "$SRC/CODEX_CHANGES2.md"
  [ -f "$OUT/review.md" ] && cp "$OUT/review.md" "$SRC/CODEX_REVIEW.md"
  [ -f "$OUT/rereview.md" ] && cp "$OUT/rereview.md" "$SRC/CODEX_REREVIEW.md"

  START=$(date +%s)
  cd "$SRC"
  codex exec --skip-git-repo-check --sandbox workspace-write \
    --output-last-message "$OUT/CHANGES3.md" \
    "$PROMPT" > "$OUT/round3.log" 2>&1 || true
  RC=$?
  END=$(date +%s)
  echo "[$(date +%H:%M:%S)] $P round-3 rc=$RC dur=$((END-START))s" | tee -a "$LOG"

  # Cleanup staged context
  rm -f "$SRC/CODEX_REVIEW.md" "$SRC/CODEX_REREVIEW.md" "$SRC/CODEX_CHANGES.md" "$SRC/CODEX_CHANGES2.md"
  rm -f "$SRC/CODEX_review_PRIOR.md" "$SRC/CODEX_CHANGES_PRIOR.md" "$SRC/CODEX_CHANGES2_PRIOR.md" "$SRC/CODEX_rereview_PRIOR.md"

  # Health check after edits
  HEALTH_AFTER=$(pm2_health)
  echo "[$(date +%H:%M:%S)] $P pm2 after: $HEALTH_AFTER" | tee -a "$LOG"

  # Brief pause between projects to be nice to API
  sleep 15
done

echo "=== all-night round-3 done $(date -Iseconds) ===" >> "$LOG"

# Final summary
echo "" >> "$LOG"
echo "=== final summary ===" >> "$LOG"
for P in "${PROJECTS[@]}"; do
  applied=$(awk '/^## Round 3 Applied/{f=1; next} /^## /{f=0} f && /^- / && !/None/' "$HOME/Projects/$P/CHANGES3.md" 2>/dev/null | wc -l | xargs)
  printf "%-28s round-3 applied=%s\n" "$P" "$applied" >> "$LOG"
done