From 880715f9172ef285fe751de5d3f3dbd5e18d4e66 Mon Sep 17 00:00:00 2001 From: tend-agent <270458913+tend-agent@users.noreply.github.com> Date: Fri, 7 Aug 2026 08:39:17 +0000 Subject: [PATCH 1/4] fix(token-report): raise the per-workflow run limit, and say when it's hit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gh run list returns newest-first and stops at --limit silently, so a workflow busier than 100 runs in the window has its oldest runs dropped and their tokens counted as zero. Measured: tend-mention returns 100 against a true 116 over the current 24h window, so 14% of the runs are missing from a total that review-runs records as a complete accounting. Raise the per-workflow limit to 500 and warn when a workflow comes back exactly at it — a count landing on the limit is the only symptom of truncation visible without re-querying total_count, and raising the limit alone would just move the cliff. --- plugins/tend-ci-runner/scripts/token-report.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/plugins/tend-ci-runner/scripts/token-report.sh b/plugins/tend-ci-runner/scripts/token-report.sh index 7ac4f87d..1bc43b21 100755 --- a/plugins/tend-ci-runner/scripts/token-report.sh +++ b/plugins/tend-ci-runner/scripts/token-report.sh @@ -58,11 +58,23 @@ if [ ${#WORKFLOWS[@]} -eq 0 ]; then exit 0 fi -# Collect all completed runs across workflows +# Collect all completed runs across workflows. +# +# `gh run list` returns newest-first and silently stops at --limit, so a +# workflow busier than the limit drops the *oldest* runs in the window and the +# totals below under-report with nothing marking the shortfall. The limit is +# per workflow, not per report, so it only has to clear the busiest one; a +# repo's chattiest workflow can run several times an hour. Warn on an exact-hit +# rather than silently trusting it — a count landing precisely on the limit is +# the one symptom of truncation visible without re-querying. +RUN_LIMIT=500 ALL_RUNS="[]" for wf in "${WORKFLOWS[@]}"; do runs=$(gh run list "${repo_args[@]}" --workflow "$wf" --created ">=$SINCE" --status completed \ - --json databaseId,conclusion,createdAt,name --limit 100 2>/dev/null || echo "[]") + --json databaseId,conclusion,createdAt,name --limit "$RUN_LIMIT" 2>/dev/null || echo "[]") + if [ "$(echo "$runs" | jq 'length')" -eq "$RUN_LIMIT" ]; then + echo >&2 "WARNING: '$wf' returned exactly $RUN_LIMIT runs — the window is likely truncated and the totals below under-report it." + fi ALL_RUNS=$(echo "$ALL_RUNS" "$runs" | jq -s 'add | unique_by(.databaseId)') done From 84867c63cf6e21df35c62be50c58c72ccbbfce89 Mon Sep 17 00:00:00 2001 From: tend-agent <270458913+tend-agent@users.noreply.github.com> Date: Fri, 7 Aug 2026 08:49:37 +0000 Subject: [PATCH 2/4] fix(token-report): warn on a failed fetch too, and size the limit for the 168h default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review on this PR found the guard incomplete in two ways. A failed `gh run list` resolved to `[]` via `|| echo`, which the new truncation guard reads as "0 runs, not truncated" — so an API blip drops a whole workflow from the totals with no marker, the same silent under-report at full strength. Branch on the exit status and warn. 500 also left no headroom at the script's own documented 168h default: tend-mention returns 497 over that window today, so a default-argument call would trip the truncation warning within a day. The limit only bounds the listing call, which pages internally, so headroom is free — the per-run download loop costs what the window holds either way. --- .../tend-ci-runner/scripts/token-report.sh | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/plugins/tend-ci-runner/scripts/token-report.sh b/plugins/tend-ci-runner/scripts/token-report.sh index 1bc43b21..1eb936f5 100755 --- a/plugins/tend-ci-runner/scripts/token-report.sh +++ b/plugins/tend-ci-runner/scripts/token-report.sh @@ -64,16 +64,26 @@ fi # workflow busier than the limit drops the *oldest* runs in the window and the # totals below under-report with nothing marking the shortfall. The limit is # per workflow, not per report, so it only has to clear the busiest one; a -# repo's chattiest workflow can run several times an hour. Warn on an exact-hit -# rather than silently trusting it — a count landing precisely on the limit is -# the one symptom of truncation visible without re-querying. -RUN_LIMIT=500 +# repo's chattiest workflow can run several times an hour, and at this script's +# own documented 168 h default that already reaches the high hundreds. Sized +# well past that: the limit only bounds the listing call, which pages +# internally, so headroom here is free — the per-run `gh run download` loop +# below costs what the window actually holds, whatever this number is. +# +# Warn rather than trust, in both directions. A count landing on the limit is +# the only symptom of truncation visible without re-querying `.total_count`, +# and a failed fetch is the same silent under-report at full strength: it drops +# every run of that workflow, and a length of 0 is not an exact-limit hit, so +# the truncation guard alone would pass straight over it. +RUN_LIMIT=2000 ALL_RUNS="[]" for wf in "${WORKFLOWS[@]}"; do - runs=$(gh run list "${repo_args[@]}" --workflow "$wf" --created ">=$SINCE" --status completed \ - --json databaseId,conclusion,createdAt,name --limit "$RUN_LIMIT" 2>/dev/null || echo "[]") - if [ "$(echo "$runs" | jq 'length')" -eq "$RUN_LIMIT" ]; then - echo >&2 "WARNING: '$wf' returned exactly $RUN_LIMIT runs — the window is likely truncated and the totals below under-report it." + if ! runs=$(gh run list "${repo_args[@]}" --workflow "$wf" --created ">=$SINCE" --status completed \ + --json databaseId,conclusion,createdAt,name --limit "$RUN_LIMIT" 2>/dev/null); then + echo >&2 "WARNING: 'gh run list' for '$wf' failed — its runs are absent from the totals below." + runs="[]" + elif [ "$(echo "$runs" | jq 'length')" -ge "$RUN_LIMIT" ]; then + echo >&2 "WARNING: '$wf' returned $RUN_LIMIT runs, the fetch limit — older runs in the window are missing and the totals below under-report it." fi ALL_RUNS=$(echo "$ALL_RUNS" "$runs" | jq -s 'add | unique_by(.databaseId)') done From dfad80eb7d3ad58f368293f7f9c99bf04609aac8 Mon Sep 17 00:00:00 2001 From: tend-agent <270458913+tend-agent@users.noreply.github.com> Date: Fri, 7 Aug 2026 08:59:42 +0000 Subject: [PATCH 3/4] fix(token-report): cap the run limit at the API's 1000 ceiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Actions runs endpoint stops paginating at 1000 whatever total_count says, so RUN_LIMIT=2000 made the truncation guard unreachable — the larger constant bought no runs and cost the warning. 1000 is the largest reachable value and trips the guard exactly at the ceiling. --- plugins/tend-ci-runner/scripts/token-report.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/tend-ci-runner/scripts/token-report.sh b/plugins/tend-ci-runner/scripts/token-report.sh index 1eb936f5..521ccf72 100755 --- a/plugins/tend-ci-runner/scripts/token-report.sh +++ b/plugins/tend-ci-runner/scripts/token-report.sh @@ -65,17 +65,17 @@ fi # totals below under-report with nothing marking the shortfall. The limit is # per workflow, not per report, so it only has to clear the busiest one; a # repo's chattiest workflow can run several times an hour, and at this script's -# own documented 168 h default that already reaches the high hundreds. Sized -# well past that: the limit only bounds the listing call, which pages -# internally, so headroom here is free — the per-run `gh run download` loop -# below costs what the window actually holds, whatever this number is. +# own documented 168 h default that already reaches the high hundreds. Capped +# at 1000 because that is the ceiling: the Actions runs endpoint stops +# paginating there whatever `total_count` says, so a larger constant is +# unreachable and would only make the guard below unable to fire. # # Warn rather than trust, in both directions. A count landing on the limit is # the only symptom of truncation visible without re-querying `.total_count`, # and a failed fetch is the same silent under-report at full strength: it drops # every run of that workflow, and a length of 0 is not an exact-limit hit, so # the truncation guard alone would pass straight over it. -RUN_LIMIT=2000 +RUN_LIMIT=1000 ALL_RUNS="[]" for wf in "${WORKFLOWS[@]}"; do if ! runs=$(gh run list "${repo_args[@]}" --workflow "$wf" --created ">=$SINCE" --status completed \ From 578f0f189e24889fedf1df7318da00567c564ff2 Mon Sep 17 00:00:00 2001 From: tend-agent <270458913+tend-agent@users.noreply.github.com> Date: Fri, 7 Aug 2026 09:01:23 +0000 Subject: [PATCH 4/4] fix(token-report): say the ceiling is the API's, and that raising the limit won't help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The truncation warning called 1000 'the fetch limit', which reads as a tunable and invites exactly the 2000 bump the previous commit reverted. Name it as the Actions API's pagination ceiling and point at the lever that does work — narrowing HOURS. --- plugins/tend-ci-runner/scripts/token-report.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tend-ci-runner/scripts/token-report.sh b/plugins/tend-ci-runner/scripts/token-report.sh index 521ccf72..29fb5921 100755 --- a/plugins/tend-ci-runner/scripts/token-report.sh +++ b/plugins/tend-ci-runner/scripts/token-report.sh @@ -83,7 +83,7 @@ for wf in "${WORKFLOWS[@]}"; do echo >&2 "WARNING: 'gh run list' for '$wf' failed — its runs are absent from the totals below." runs="[]" elif [ "$(echo "$runs" | jq 'length')" -ge "$RUN_LIMIT" ]; then - echo >&2 "WARNING: '$wf' returned $RUN_LIMIT runs, the fetch limit — older runs in the window are missing and the totals below under-report it." + echo >&2 "WARNING: '$wf' returned $RUN_LIMIT runs, the Actions API's pagination ceiling — older runs in the window are unreachable and the totals below under-report it. Narrow HOURS to bring the window under the ceiling; raising RUN_LIMIT cannot help." fi ALL_RUNS=$(echo "$ALL_RUNS" "$runs" | jq -s 'add | unique_by(.databaseId)') done