#!/usr/bin/env bash # auto-phase.sh — run the full phased pipeline, no LLM in the loop. # # Processes every file in .agent/phases/todo/ in alphanumerical order. # Each phase runs in its own pi process (fresh context); on failure the # executor's session is resumed for up to MAX_FIX_ATTEMPTS fixer rounds. # A phase moves to .agent/phases/complete/ only after the child exits 0 # AND .agent/validate.sh passes. Stops at the first phase that cannot be # completed — re-run this script to continue where it stopped. # # Env: see SKILL.md (MAX_FIX_ATTEMPTS, PHASE_MODEL, PHASE_THINKING, # PHASE_COMMIT, PI_TRUST, FRESH_FIX). set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/lib.sh" # Make interruptions visible: state stays in .agent/phases/todo, and the # failed executor's session is still resumable on the next run. trap 'echo; echo "✗ ERROR: interrupted (SIGINT) — ${phase:-the pipeline} is left in $PHASE_TODO/; re-run to continue where it stopped" >&2; exit 130' INT trap 'echo; echo "✗ ERROR: interrupted (SIGTERM) — ${phase:-the pipeline} is left in $PHASE_TODO/; re-run to continue where it stopped" >&2; exit 143' TERM cd "$(find_root)" || die "no .agent/phases/todo found in this or parent directories (run /to-phase or /audit-create first)" build_pi_args delivered=() while phase="$(next_phase)"; do [[ -n "$phase" ]] || break if ! execute_phase "$phase"; then echo "✗ ERROR: pipeline stopped — $phase FAILED after $MAX_FIX_ATTEMPTS attempts" >&2 echo " fix the issues above, then re-run this script to continue where it stopped" >&2 exit 1 fi delivered+=("$phase") done echo echo "✓ pipeline done — ${#delivered[@]} phase(s) delivered this run: ${delivered[*]:-none}" remaining="$(ls -1 "$PHASE_TODO" 2>/dev/null | grep -cE '^[0-9]' || true)" echo " remaining in $PHASE_TODO/: $remaining"