sweep: post a per-head verdict on clean convergence; list past gh's 30-PR cap#39
Merged
Merged
Conversation
…0-PR cap
Root-causes the bunion factory's STUPIFY_FLAKED shipments (6 of 33 tickets
shipped without a review on the final commit):
1. Silent convergence left the newest head unreviewed-looking. When a PR
stupify had already reviewed got a new push and codex found nothing new
(NOOP token), or emitted the fixed-signal with no threads left to resolve,
the sweep posted NOTHING — so no `<!-- stupify:<sha> -->` marker ever
covered the new head. Per-head consumers (the factory's `wait` tool, any
"does a review cover HEAD?" merge gate) read that as "never reviewed" and
timed out. Evidence from stupify-bevyl-ai-bevyl-ai sweep.log:
#6644 @ 6c5f4378 "nothing new — staying silent" (head, never covered)
#6600 @ b48ff4ab "fixed-signal but no open threads — staying silent"
#6596 @ 4d0c0096 "fixed-signal but no open threads — staying silent"
#6598 @ e2049222 "nothing new — staying silent"
Fix: when nothing is outstanding (no open stupify threads), post a
one-line marker-bearing `still ✅` instead of silence. Silence remains
only while stupify's own findings are open (posting a non-✅ note there
would fight a reasoned inline pushback). A stray fixed-signal on a
never-flagged PR still posts nothing, so it can't manufacture approval.
This also restores the header's stated invariant — durable per-head dedup
via the marker — instead of leaning on local reviewed.json (lost on VM
recreation).
2. gh pr list defaults to --limit 30, newest-first. With 129 open PRs on
bevyl-ai/bevyl.ai, every PR past the newest 30 fell off the sweep's radar
entirely — PR #6559 (list position 57) got fresh pushes for two days with
zero sweep log lines. Fix: explicit --limit 500.
3. Upstream the hand-patch running on the bevyl VM: REVIEW_LABEL now also
force-includes bot-authored PRs (the factory authors PRs as a GitHub App;
stock code would silently drop ALL its PRs from scope on redeploy). Set
REVIEW_LABEL=bunion in that deployment's config.env.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The flake, root-caused
On 6 of 33 bunion ready-pit tickets the factory shipped with
STUPIFY_FLAKED: the final commit of the PR never got a stupify review, while every earlier commit was reviewed within minutes of push. The sweep onstupify-bevyl-ai-bevyl-aiwas in fact reviewing every final head promptly — and then deliberately posting nothing:Silence leaves no
<!-- stupify:<sha> -->marker covering the new head. On GitHub the last review keeps pointing at an old commit, so anything that asks "does a stupify review cover HEAD?" — bunion'swaittool, or any per-head merge gate — reads "never reviewed", times out, and treats the reviewer as flaked. It also breaks the header's own stated invariant (durable per-head dedup via the marker): the silent paths lean entirely on localreviewed.json, which dies with the VM.Fix: when nothing is outstanding (no open stupify threads), post a one-line marker-bearing
still ✅instead of staying silent — one short note per pushed head, still converged. Silence remains only while stupify's own findings are open (a fresh non-✅ note there would fight a reasoned inline pushback), and a stray fixed-signal on a never-flagged PR still posts nothing.Second defect: gh's default
--limit 30listPrsrangh pr listwith no--limit, which defaults to 30, newest-first. bevyl-ai/bevyl.ai has 129 open PRs; everything past the newest 30 fell off the sweep's radar entirely — PR #6559 (list position 57) took fresh pushes for two days with zero sweep log lines, not even a skip. Fixed with an explicit--limit 500.Third: upstream the bevyl VM's hand-patch
The deployed
~/.stupify/review-sweep.tsonstupify-bevyl-ai-bevyl-aiis hand-patched to review bot-authored PRs carrying thebunionlabel (the factory authors PRs as a GitHub App). Redeploying stock code would silently drop ALL factory PRs from scope. This PR generalizes the existing force-include:REVIEW_LABELnow also overrides the bot-author exclusion, so that deployment just setsREVIEW_LABEL=bunionin config.env and runs stock code.Verification
bun run typecheckclean,bun test44/44 pass (added a test pinning the convergence note's ✅/marker contract).waittool seesstill ✅+ marker covering head →PASSinstead ofSTUPIFY_FLAKEDon converged-clean pushes (itsparseReviewrequires exactly: stupify login,stupify:<sha>covering the latest code commit,✅in the body).Deploy note: the fix only takes effect once re-deployed to
~/.stupify/review-sweep.tsonstupify-bevyl-ai-bevyl-ai/stupify-octember-stupify, withREVIEW_LABEL=bunionadded to the bevyl config.env (replacing the hand-patch).🤖 Generated with Claude Code