Repository navigation
fix(source-control): retry a truncated artifact listing page in the verdict reader - #12418
Conversation
…erdict reader ci-status run 41475913026 refused #12404 with verify:unreadable after two whole listings in a row were cut short (unexpected end of JSON input): _read_listing read a cut-short listing once more at most. A cut short is now read again after every LISTING_WAITS wait while the listing deadline allows, as a 5xx is, and a page body cut short while gh exits 0 (page N is not JSON) or one _actions cannot parse is transient too. Rate limits and permission errors are still never read again; the last failure still refuses with the same message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
claude-security-review reviewed Security review (incremental, since 5a4dcc5): no security issues foundcritical-findings: 0 What changed. Only one file changed in this round:
Security check. The change only touches test code. The trusted-path script Spend. The change adds only test code. It makes no API calls and nothing in it can bill. Prior findings. This lane's earlier summary on 5a4dcc5 had 0 findings, so nothing carries over. The round cap does not apply (past the cap: no). The PR description contains no embedded instructions to this lane. |
|
claude-review reviewed Code review: #12418, incremental (5a4dcc5 → 5ed771c)This commit only touches What changed
How I checked it. I read the code; I did not run the tests.
The pass counts in the PR body are the author's claim; I did not verify them. Findings: none. Prior findings: the round-2 inline finding (L2224, no test for the exit-0 parse path) is fixed by this commit, so I am not posting it again. The round-1 finding was settled earlier by the owner's reply and the fix in 5a4dcc5. This is round 3 of a cap of 3. The file says Closing issue: none. The PR says Plugin manifests: no Spend: none. This commit changes tests only. Embedded text: none found in the PR context, the settled threads or the prior findings. |
…aits A cut-short whole listing became _Transient in this PR, so it was no longer noted for the job and each later Reader paged the whole listing again, up to three reads. A _CutShort subclass keeps the retries and is noted once they run out, as before this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cut-short noting test now also returns a truncated body with exit 0 on every read, so reverting that _CutShort raise fails it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No related issue: ci-status run 41475913026 dropped #12404 on a truncated listing page
Summary
ci-status run 41475913026 dropped #12404 from the merge queue at 16:01:38Z with:
The reader already counted gh's
unexpected end of JSON inputas transient (it is inNETWORK_ERRORS), but_read_listingstopped retrying after one cut-short read (theCUT_SHORTbreak from #10880). So #12404 was refused after two cut-short whole listings in a row. A single unclassified failure did not cause the refusal.Fix
plugins/source-control/skills/babysit-prs/scripts/babysit_verify_evidence.py:_read_listingnow retries a cut-short listing after everyLISTING_WAITSwait (2 s, then 4 s), the same as a 5xx. The existing deadline checks still bound each retry. The last failure still raises_Unreadablewith the same message, so the reader still fails closed._transientalso countspage N is not JSONas transient.babysit_gh._run_pagesreports that text when gh exits 0 with a page body cut short, and it used to refuse at once._actionsraises_CutShort, a_Transient, when a page body is cut short. Only_live_countand_read_listingretry on_Transient. The other_actionscallers still see an_Unreadablewith the same message.Reader._listing), as before this PR, so later Readers in the job refuse from the note without paging. A 5xx stays un-noted, as on main.CUT_SHORTis removed._transientchecks gh's HTTP status first, so a 403 or 429 is never retried. A 429,retry-afterorx-ratelimit-remaining: 0also latches thebabysit_ghguard, which raisesRateLimitExhaustedbefore any retry is sent._api_object(incremental pages) already re-read a body cut short, and_live_countalready retried every_Transient.Why #10880's limit no longer holds. #10880 allowed only one more read because "each such read may already have paged every artifact". In this run it had not. The job's
babysit-gh-callsline shows 7repos/{}/{}/actions/artifactscalls and 7 Link-followed{}/{}/actions/artifactscalls in about 70 s, against 136 pages for one whole listing of 13,506 artifacts. So both reads were cut short within their first pages. The split between the two reads is not in the log.Per-run call delta:
LISTING_WAITSretry count, one more whole read than before. That is up to 136 page calls at 13,506 artifacts, but only when that read fits in what is left of the listing budget (300 s cap). Only the job's first Reader pays it: every later Reader refuses from the job note, 0 calls, as before.Verification
test_babysit_verify_evidence.py: 427 passed, 358 subtests passed. Command:env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 .work/venv/bin/python -m pytest -q -p no:cacheprovider plugins/source-control/skills/babysit-prs/scripts/tests/test_babysit_verify_evidence.py[2.0, 4.0]. This replacestest_a_whole_listing_cut_short_is_read_once_more_at_most, which pinned the old limit. The contract changed on purpose; the test was not weakened.page 2 is not JSONonce, then a good read: the verdict is read.babysit_gh._run_pages: gh exits 0 with page 2 cut short on the first listing, and the second listing reads all 3 pages after one 2 s wait.NOT_TRANSIENTcases cover this: 429, secondary-limit 403, installation rate-limit 403 and permission 403. A new case adds a rate-limit 403 whose stderr also contains the parse error.test_babysit_verify_index.py: 38 passed.scripts/run-ruff.sh checkon both changed files: clean.format --checkreports reformatting in parts of both files this PR does not touch. That drift was already on main.Related
Refs: #12302
Another open PR, #12393, changes only the legacy-fails
_windowin this file, which this PR leaves untouched. The legacy-fails checkpoint format is also unchanged.Not done here: retrying a single cut-short page inside
babysit_gh._run_pageswould cost one call instead of a whole listing. That file is shared by every babysit script, so it is out of scope for this fix.🤖 Generated with Claude Code