diff --git a/gardener/gardener-poll.sh b/gardener/gardener-poll.sh index 43aa8db..c218ce1 100755 --- a/gardener/gardener-poll.sh +++ b/gardener/gardener-poll.sh @@ -3,8 +3,14 @@ # gardener-poll.sh — Cron wrapper for the gardener agent # # Cron: daily (or 2x/day). Handles lock management, escalation reply -# injection for dev sessions, and files an action issue for backlog -# grooming via formulas/run-gardener.toml (picked up by action-agent). +# injection, and delegates backlog grooming to gardener-agent.sh. +# +# Grooming (delegated to gardener-agent.sh): +# - Duplicate titles / overlapping scope +# - Missing acceptance criteria +# - Stale issues (no activity > 14 days) +# - Blockers starving the factory +# - Tech-debt promotion / dust bundling # ============================================================================= set -euo pipefail @@ -36,6 +42,12 @@ trap 'rm -f "$LOCK_FILE"' EXIT log "--- Gardener poll start ---" +# Gitea labels API requires []int64 — look up the "backlog" label ID once +# Falls back to the known Codeberg repo ID if the API call fails +BACKLOG_LABEL_ID=$(codeberg_api GET "/labels" 2>/dev/null \ + | jq -r '.[] | select(.name == "backlog") | .id' 2>/dev/null || true) +BACKLOG_LABEL_ID="${BACKLOG_LABEL_ID:-1300815}" + # ── Check for escalation replies from Matrix ────────────────────────────── ESCALATION_REPLY="" if [ -s /tmp/gardener-escalation-reply ]; then @@ -74,7 +86,7 @@ if [ -s /tmp/gardener-escalation-reply ]; then log "All escalation entries were stale — discarded" fi fi -# ESCALATION_REPLY is used below when constructing the action issue body +export ESCALATION_REPLY # ── Inject human replies into needs_human dev sessions (backup to supervisor) ─ HUMAN_REPLY_FILE="/tmp/dev-escalation-reply" @@ -118,38 +130,9 @@ Instructions: break # only one reply to deliver done -# ── Backlog grooming (file action issue for run-gardener formula) ───────── -# shellcheck source=../lib/file-action-issue.sh -source "$FACTORY_ROOT/lib/file-action-issue.sh" +# ── Backlog grooming (delegated to gardener-agent.sh) ──────────────────── +log "Invoking gardener-agent.sh for backlog grooming" +bash "$SCRIPT_DIR/gardener-agent.sh" "${1:-}" || log "WARNING: gardener-agent.sh exited with error" -ESCALATION_CONTEXT="" -if [ -n "${ESCALATION_REPLY:-}" ]; then - ESCALATION_CONTEXT=" - -## Pending escalation replies - -Human responses to previous gardener escalations. Process these FIRST. -Format: '1a 2c 3b' means question 1→option (a), 2→option (c), 3→option (b). - -${ESCALATION_REPLY}" -fi - -_DESCRIPTION="Periodic gardener housekeeping run. The action-agent reads \`formulas/run-gardener.toml\` -and executes the steps: preflight, grooming, blocked-review, -AGENTS.md update, and commit-and-pr.${ESCALATION_CONTEXT}" - -ISSUE_BODY=$(build_formula_issue_body "run-gardener" "opus" "$_DESCRIPTION" "gardener-poll.sh") - -_rc=0 -file_action_issue "run-gardener" "action: run-gardener — periodic housekeeping" "$ISSUE_BODY" || _rc=$? -case "$_rc" in - 0) log "Filed action issue #${FILED_ISSUE_NUM} for run-gardener formula" - matrix_send "gardener" "Filed action #${FILED_ISSUE_NUM}: run-gardener — periodic housekeeping" 2>/dev/null || true - ;; - 1) log "Open run-gardener action issue already exists — skipping" ;; - 2) log "ERROR: 'action' label not found — cannot file gardener issue" ;; - 4) log "ERROR: issue body contains potential secrets — skipping" ;; - *) log "WARNING: failed to create action issue for run-gardener (rc=$_rc)" ;; -esac log "--- Gardener poll done ---" diff --git a/gardener/gardener-run.sh b/gardener/gardener-run.sh index 5410ba9..8ee6493 100755 --- a/gardener/gardener-run.sh +++ b/gardener/gardener-run.sh @@ -45,11 +45,16 @@ fi log "--- Gardener run start ---" # ── File action issue for run-gardener formula ──────────────────────────── -_DESCRIPTION="Periodic gardener housekeeping run. The action-agent reads \`formulas/run-gardener.toml\` -and executes the steps: preflight, grooming, blocked-review, -AGENTS.md update, and commit-and-pr." +ISSUE_BODY="--- +formula: run-gardener +model: opus +--- -ISSUE_BODY=$(build_formula_issue_body "run-gardener" "opus" "$_DESCRIPTION" "gardener-run.sh") +Periodic gardener housekeeping run. The action-agent reads \`formulas/run-gardener.toml\` +and executes the steps: preflight, grooming, blocked-review, +AGENTS.md update, and commit-and-pr. + +Filed automatically by \`gardener-run.sh\`." _rc=0 file_action_issue "run-gardener" "action: run-gardener — periodic housekeeping" "$ISSUE_BODY" || _rc=$? diff --git a/lib/file-action-issue.sh b/lib/file-action-issue.sh index 2568fa2..f9458b5 100644 --- a/lib/file-action-issue.sh +++ b/lib/file-action-issue.sh @@ -4,9 +4,6 @@ # Usage: source this file, then call file_action_issue. # Requires: codeberg_api() from lib/env.sh, jq, lib/secret-scan.sh # -# build_formula_issue_body -# Outputs a standard issue body with TOML frontmatter to stdout. -# # file_action_issue <body> # Sets FILED_ISSUE_NUM on success. # Returns: 0=created, 1=duplicate exists, 2=label not found, 3=API error, 4=secrets detected @@ -15,15 +12,6 @@ # shellcheck source=secret-scan.sh source "$(dirname "${BASH_SOURCE[0]}")/secret-scan.sh" -# build_formula_issue_body <formula_name> <model> <description> <source_script> -# Builds a standard issue body with TOML frontmatter for formula-driven action issues. -# Outputs the body to stdout. -build_formula_issue_body() { - local formula_name="$1" model="$2" description="$3" source_script="$4" - printf -- '---\nformula: %s\nmodel: %s\n---\n\n%s\n\nFiled automatically by `%s`.' \ - "$formula_name" "$model" "$description" "$source_script" -} - file_action_issue() { local formula_name="$1" title="$2" body="$3" FILED_ISSUE_NUM=""