-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrheo-operator.sh
More file actions
executable file
·161 lines (144 loc) · 4.83 KB
/
rheo-operator.sh
File metadata and controls
executable file
·161 lines (144 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env bash
# rheo-operator.sh — Deterministic pipeline operator for Rheo tasks
# Applies the response matrix from HEARTBEAT.md to all rheo/ tasks.
# Usage: rheo-operator.sh [--dry-run]
set -o pipefail
export PATH="$HOME/go/bin:$PATH"
DRY_RUN=false
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
declare -a ACTIONS
declare -a ERRORS
run_cmd() {
if $DRY_RUN; then
ACTIONS+=("DRY-RUN: $1")
return 0
fi
local result
result=$(eval "$1" 2>&1) || true
echo "$result"
}
# Get status
STATUS=$(rheo status 2>&1) || true
# Parse into per-session blocks
TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
# Split status into session files
current_file=""
while IFS= read -r line; do
if [[ "$line" =~ ^Session:\ (rheo/[^ ]+) ]]; then
session="${BASH_REMATCH[1]}"
current_file="$TMPDIR/$(echo "$session" | tr '/' '_')"
echo "$line" > "$current_file"
elif [[ -n "$current_file" && "$line" =~ ^Session: ]]; then
current_file=""
elif [[ -n "$current_file" ]]; then
echo "$line" >> "$current_file"
fi
done <<< "$STATUS"
# Process each rheo session
for session_file in "$TMPDIR"/rheo_*; do
[[ -f "$session_file" ]] || continue
header=$(head -1 "$session_file")
session=$(echo "$header" | grep -oP 'Session: \K[^ ]+')
phase=$(echo "$header" | grep -oP '\(phase: \K[^)]+')
pr_num=$(echo "$header" | grep -oP 'PR: #\K\d+' || true)
block=$(cat "$session_file")
# 1. PAUSED → resume
if echo "$block" | grep -q "PAUSED"; then
result=$(run_cmd "rheo resume '$session'")
if echo "$result" | grep -q "Launched\|launched"; then
ACTIONS+=("Resumed $session: $(echo "$result" | grep -i launch)")
elif echo "$result" | grep -q "No resumable"; then
ACTIONS+=("No resumable runs for $session")
elif $DRY_RUN; then
: # already logged
else
ERRORS+=("Resume failed for $session: $result")
fi
continue
fi
# 2. Ready for PR → review
if [[ "$phase" == "ready for PR" ]]; then
result=$(run_cmd "rheo review '$session'")
if echo "$result" | grep -q "Code review started"; then
ACTIONS+=("Started review: $session")
elif $DRY_RUN; then
:
else
ERRORS+=("Review failed for $session: $result")
fi
continue
fi
# 3. Reviewer done → check verdict
if echo "$phase" | grep -qi "review"; then
if echo "$block" | grep -q "reviewer.*done"; then
# Find latest review file
worktree="$HOME/.rheo/worktrees/$session"
review_file=$(ls "$worktree/.rheo/"review-*.md 2>/dev/null | sort -V | tail -1 || true)
verdict="unknown"
[[ -n "$review_file" ]] && verdict=$(grep -oP 'Verdict: \K\S+' "$review_file" 2>/dev/null || echo "unknown")
if [[ "$verdict" == "NO_CHANGES_NEEDED" && -n "$pr_num" ]]; then
ACTIONS+=("MERGE_CANDIDATE: $session PR #$pr_num (NO_CHANGES_NEEDED)")
elif [[ "$verdict" == "NO_CHANGES_NEEDED" ]]; then
result=$(run_cmd "rheo approve '$session'")
ACTIONS+=("Approved $session (clean review): $result")
elif [[ "$verdict" == "CHANGES_RECOMMENDED" ]]; then
# Use iterate instead of approve — approve can silently fail to advance
result=$(run_cmd "rheo iterate '$session' 'Address reviewer findings'")
if echo "$result" | grep -q "Iteration"; then
ACTIONS+=("Iterated $session (reviewer changes): $result")
else
# Fallback to approve
result=$(run_cmd "rheo approve '$session'")
ACTIONS+=("Approved $session (changes recommended → fix cycle): $result")
fi
fi
fi
continue
fi
# 4. Evaluator done PASS → approve
if echo "$phase" | grep -qi "evaluator"; then
if echo "$block" | grep -q "evaluator.*done.*PASS"; then
result=$(run_cmd "rheo approve '$session'")
ACTIONS+=("Approved evaluator: $session: $result")
elif echo "$block" | grep -q "FAIL_PLAN_MISMATCH"; then
result=$(run_cmd "rheo iterate '$session' 'Address plan mismatch'")
ACTIONS+=("Iterated $session (plan mismatch): $result")
fi
continue
fi
# 5. Running — no action
done
# Output JSON
action_count=${#ACTIONS[@]}
error_count=${#ERRORS[@]}
merge_count=0
for a in "${ACTIONS[@]+"${ACTIONS[@]}"}"; do
[[ "$a" == *MERGE_CANDIDATE* ]] && ((merge_count++)) || true
done
{
echo "{"
echo " \"status\": \"completed\","
echo " \"actions_taken\": $action_count,"
echo " \"merge_candidates\": $merge_count,"
echo " \"errors_count\": $error_count,"
echo " \"actions\": ["
first=true
for a in "${ACTIONS[@]+"${ACTIONS[@]}"}"; do
$first || echo ","
printf ' "%s"' "$(echo "$a" | sed 's/"/\\"/g' | tr '\n' ' ')"
first=false
done
echo ""
echo " ],"
echo " \"errors\": ["
first=true
for e in "${ERRORS[@]+"${ERRORS[@]}"}"; do
$first || echo ","
printf ' "%s"' "$(echo "$e" | sed 's/"/\\"/g' | tr '\n' ' ')"
first=false
done
echo ""
echo " ]"
echo "}"
}