|
|
|
@@ -60,8 +60,8 @@ del_autopilot_label() {
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# drop machine-readable markers: DELEGATE / CLOSE_ISSUE / MERGE_PR / APPROVE / HALT / BOUNCE, and the
|
|
|
|
|
# BEGIN_SUBTASKS..END_SUBTASKS and BEGIN_PR_DESCRIPTION..END_PR_DESCRIPTION blocks (the PR
|
|
|
|
|
# drop machine-readable markers: DELEGATE / CLOSE_ISSUE / MERGE_PR / RETRO / APPROVE / HALT / BOUNCE,
|
|
|
|
|
# and the BEGIN_SUBTASKS..END_SUBTASKS and BEGIN_PR_DESCRIPTION..END_PR_DESCRIPTION blocks (the PR
|
|
|
|
|
# description is published separately).
|
|
|
|
|
reply=$(awk '
|
|
|
|
|
/^[[:space:]]*BEGIN_SUBTASKS/{s=1}
|
|
|
|
@@ -69,6 +69,7 @@ reply=$(awk '
|
|
|
|
|
/^[[:space:]]*DELEGATE:[[:space:]]*@/{next}
|
|
|
|
|
/^[[:space:]]*CLOSE_ISSUE[[:space:]]*$/{next}
|
|
|
|
|
/^[[:space:]]*MERGE_PR[[:space:]]*$/{next}
|
|
|
|
|
/^[[:space:]]*RETRO[[:space:]]*$/{next}
|
|
|
|
|
/^[[:space:]]*APPROVE[[:space:]]*$/{next}
|
|
|
|
|
/^[[:space:]]*HALT([_ ]AUTOPILOT)?[[:space:]]*$/{next}
|
|
|
|
|
/^[[:space:]]*BOUNCE:[[:space:]]*@/{next}
|
|
|
|
@@ -113,13 +114,18 @@ if [ "$MODE" != "pr" ]; then
|
|
|
|
|
[ -z "$dev" ] && [ -n "$PRN" ] && dev=$(curl -sS "${hdr[@]}" "$API/pulls/$PRN" | jq -r '.user.login // "junior"')
|
|
|
|
|
dest="${PRN:-$NUM}"
|
|
|
|
|
post_to "$dest" "$reply$activity" # recommendations, on the PR
|
|
|
|
|
# Bounce budget: count prior "fix attempt" markers on the PR thread; stop after 3.
|
|
|
|
|
prior=$(curl -sS "${hdr[@]}" "$API/issues/$dest/comments?limit=100" | jq -r 'if type=="array" then [.[]|select(.body|test("fix attempt"))]|length else 0 end' 2>/dev/null); prior=${prior:-0}
|
|
|
|
|
# Bounce budget: count prior bounce TRIGGERS on the PR thread — only @qa-authored comments
|
|
|
|
|
# matching the exact "(fix attempt N/3)" template. A loose substring match would also count
|
|
|
|
|
# review text QUOTING our own templates (seen on PR #84: the counter jumped 1/3 → 3/3 because
|
|
|
|
|
# a qa review quoted publish.sh lines containing the phrase), halving the fix budget.
|
|
|
|
|
prior=$(curl -sS "${hdr[@]}" "$API/issues/$dest/comments?limit=100" | jq -r 'if type=="array" then [.[]|select(.user.login=="qa")|select(.body|test("^@[a-z]+ please address my review above and update PR #[0-9?]+ \\(fix attempt [0-9]+/3\\)\\.$"))]|length else 0 end' 2>/dev/null); prior=${prior:-0}
|
|
|
|
|
if [ "$prior" -ge 3 ]; then
|
|
|
|
|
[ "$AUTOPILOT" = "true" ] && del_autopilot_label "$ISSN"
|
|
|
|
|
post_to "$ISSN" "🛑 Still not right after 3 fix attempts on PR #${PRN:-?} — handing to @ffaerber (details on the PR)."
|
|
|
|
|
else
|
|
|
|
|
n=$((prior + 1))
|
|
|
|
|
# NOTE: this template and the counter regex above MUST stay in sync — if you reword one,
|
|
|
|
|
# reword the other, or the count resets to 0 and the 3-round cap stops working.
|
|
|
|
|
trig "$dest" "@${dev:-junior} please address my review above and update PR #${PRN:-?} (fix attempt $n/3)."
|
|
|
|
|
fi
|
|
|
|
|
elif grep -qiE '^[[:space:]]*HALT([_ ]AUTOPILOT)?[[:space:]]*$' /tmp/agent_out.md; then
|
|
|
|
@@ -203,6 +209,27 @@ if [ "$MODE" != "pr" ]; then
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# --- @pm RETRO: open a retrospective issue for this thread (maintainer asked for a retro) ---
|
|
|
|
|
# Creates a retro issue pointing at this issue + its PR and triggers @senior on it (has gitea-api
|
|
|
|
|
# to read both threads). The retro produces a LEARNINGS.md PR via the NORMAL choreography (senior →
|
|
|
|
|
# pm → qa → merge), and run-agent.sh injects LEARNINGS.md into every future prompt — closing the loop.
|
|
|
|
|
if [ "$NAME" = "pm" ] && grep -qiE '^[[:space:]]*RETRO[[:space:]]*$' /tmp/agent_out.md; then
|
|
|
|
|
PRN=$(curl -sS "${hdr[@]}" "$API/pulls?state=all&limit=50" \
|
|
|
|
|
| jq -r --arg br "ai/issue-$ISSN" 'if type=="array" then ([.[]|select(.head.ref==$br)] | sort_by(.number) | last | .number // empty) else empty end' 2>/dev/null)
|
|
|
|
|
rbody=$(printf 'Retrospective for issue #%s%s.\n\nRead the FULL issue thread%s using the gitea-api skill (issue comments%s and the PR diff). Identify what went wrong, slow, or needed human correction — missed wiring, review misses, bounced rounds, unclear delegation, missing context.\n\nThen APPEND the distilled learnings to `LEARNINGS.md` at the repo root (create it with a short header if missing). Rules for entries:\n- 3 to 6 bullets max, each ONE line: `symptom -> rule for next time`.\n- Concrete and checkable (name the file/step/marker), not generic advice.\n- Do not repeat an existing bullet; refine it instead.\n- Do not rewrite unrelated parts of the file.\n\nThese learnings are injected into every future agent prompt, so quality over quantity.' \
|
|
|
|
|
"$ISSN" "${PRN:+ / PR #$PRN}" "${PRN:+ and PR #$PRN thread}" "${PRN:+, PR comments}")
|
|
|
|
|
rnum=$(curl -sS -X POST "${hdr[@]}" "$API/issues" \
|
|
|
|
|
-d "$(jq -nc --arg t "retro: issue #$ISSN" --arg b "$rbody" '{title:$t,body:$b}')" | jq -r '.number // empty')
|
|
|
|
|
if [ -n "$rnum" ]; then
|
|
|
|
|
echo "opened retro issue #$rnum"
|
|
|
|
|
post_to "$ISSN" "📝 Opened retro issue #$rnum."
|
|
|
|
|
trig "$rnum" "@senior please run this retrospective per the issue body."
|
|
|
|
|
else
|
|
|
|
|
echo "retro issue creation failed"
|
|
|
|
|
fi
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# --- @pm delegation: hand the build to a dev, or hand the finished PR to @qa for review ---
|
|
|
|
|
# Only an explicit 'DELEGATE: @<agent>' line acts (never a prose mention). Fires via the PAT (TTOK)
|
|
|
|
|
# so a new run starts; the built-in token cannot. Everything posts on the ISSUE — @pm never touches
|
|
|
|
|