diff --git a/.github/workflows/agents-issue-optimizer.yml b/.github/workflows/agents-issue-optimizer.yml index dd625514c..77b507db9 100644 --- a/.github/workflows/agents-issue-optimizer.yml +++ b/.github/workflows/agents-issue-optimizer.yml @@ -1,5 +1,13 @@ name: Agents Issue Optimizer +# The recursion guard below correlates prior runs by issue number via `displayTitle`. +# workflow_dispatch runs otherwise display the bare workflow name, so the guard matched +# nothing and reported 0 for an issue it was re-running every minute. Pin the issue +# number into the run name so both trigger types are correlatable. +run-name: >- + Agents Issue Optimizer #${{ + github.event.issue.number || inputs.issue_number }} + on: issues: types: [labeled] @@ -140,14 +148,17 @@ jobs: '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \ || date -u -v-1H '+%Y-%m-%dT%H:%M:%SZ') + # `gh run list` defaults to 20 runs, which a tight loop exhausts inside the + # window; ask for enough history to actually see the recursion. # shellcheck disable=SC2016 count=$(gh run list \ --workflow=agents-issue-optimizer.yml \ + --limit 100 \ --json conclusion,createdAt,displayTitle \ | jq --arg cutoff "$one_hour_ago" \ --arg issue "#$ISSUE_NUMBER" \ '[.[] | select(.createdAt > $cutoff - and (.displayTitle | contains($issue))) + and (.displayTitle | endswith($issue))) ] | length') echo "Optimizer runs for issue #$ISSUE_NUMBER in last hour: $count" diff --git a/config/template-drift-allowlist.txt b/config/template-drift-allowlist.txt index 328f94aac..4835ee874 100644 --- a/config/template-drift-allowlist.txt +++ b/config/template-drift-allowlist.txt @@ -113,9 +113,9 @@ reason = Intentional divergence re-baselined 2026-06-30: root and consumer guard [pair.11] main = .github/workflows/agents-issue-optimizer.yml template = templates/consumer-repo/.github/workflows/agents-issue-optimizer.yml -main_sha256 = d14dacb2a76447d35295a5d8a4da1e9a56a545323f87413fd76cf0654e8cf116 -template_sha256 = 05ad7bff15067f0827e136559145e3c13e0372b538889ac78281ce47658cefce -reason = Intentional divergence re-baselined 2026-08-08c: root remains in-tree (scripts/langchain + .github/scripts/issue_format.py); consumer vendors those via Workflows sparse-checkout under workflows-scripts/. Shared behavioral contract this round: concurrency includes inputs.issue_number for workflow_dispatch dedupe, cancel-safe (failure()||cancelled()) agents:format lease release, issue_dedup wrapped in set +e/set -e so advisory failures cannot abort under bash -e, and visible non-zero exit warnings. Do not align wholesale — that would strip consumer action pins/token setup. +main_sha256 = ae9a2d80a47ad995f4ce1a0681a7c8b236518b2c1337370d11578e4059ae7489 +template_sha256 = d5469b188c5e757d2f8a289e40c066961047d8a9625ae32413c2959c7a824c21 +reason = Intentional divergence re-baselined 2026-08-08c: root remains in-tree (scripts/langchain + .github/scripts/issue_format.py); consumer vendors those via Workflows sparse-checkout under workflows-scripts/. Shared behavioral contract this round: concurrency includes inputs.issue_number for workflow_dispatch dedupe, cancel-safe (failure()||cancelled()) agents:format lease release, issue_dedup wrapped in set +e/set -e so advisory failures cannot abort under bash -e, and visible non-zero exit warnings. Re-baselined 2026-08-08d: both surfaces now set a `run-name` carrying `#` so the recursion guard can correlate workflow_dispatch runs, match prior runs with `endswith` instead of `contains`, and pass `--limit 100` to `gh run list` (see #2991). Do not align wholesale — that would strip consumer action pins/token setup. [pair.12] main = .github/workflows/agents-keepalive-loop-reporter.yml diff --git a/templates/consumer-repo/.github/workflows/agents-issue-optimizer.yml b/templates/consumer-repo/.github/workflows/agents-issue-optimizer.yml index c75bb5243..b84c664e9 100644 --- a/templates/consumer-repo/.github/workflows/agents-issue-optimizer.yml +++ b/templates/consumer-repo/.github/workflows/agents-issue-optimizer.yml @@ -1,5 +1,13 @@ name: Agents Issue Optimizer +# The recursion guard below correlates prior runs by issue number via `displayTitle`. +# workflow_dispatch runs otherwise display the bare workflow name, so the guard matched +# nothing and reported 0 for an issue it was re-running every minute. Pin the issue +# number into the run name so both trigger types are correlatable. +run-name: >- + Agents Issue Optimizer #${{ + github.event.issue.number || inputs.issue_number }} + on: issues: types: [labeled] @@ -171,14 +179,17 @@ jobs: '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null \ || date -u -v-1H '+%Y-%m-%dT%H:%M:%SZ') + # `gh run list` defaults to 20 runs, which a tight loop exhausts inside the + # window; ask for enough history to actually see the recursion. # shellcheck disable=SC2016 count=$(gh run list \ --workflow=agents-issue-optimizer.yml \ + --limit 100 \ --json conclusion,createdAt,displayTitle \ | jq --arg cutoff "$one_hour_ago" \ --arg issue "#$ISSUE_NUMBER" \ '[.[] | select(.createdAt > $cutoff - and (.displayTitle | contains($issue))) + and (.displayTitle | endswith($issue))) ] | length') echo "Optimizer runs for issue #$ISSUE_NUMBER in last hour: $count"