You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(gate): stop two subsystem failures from becoming wrong auto-verdicts (#9460, #9462) (#9501)
* fix(gate): stop two subsystem failures from becoming wrong auto-verdicts (#9460, #9462)
An unpublishable AI blocker and a stuck visual-capture marker each let a subsystem failure
resolve as a verdict rather than as "cannot determine". pre-merge-checks already models the
correct shape (an unresolvable enforced check -> NEUTRAL -> hold, never a silent auto-merge
bypass); neither of these followed it.
combineReviews (#9460): synthesizeDefect returns null both when nobody flagged anything and
when a real blocker's title is unpublishable, and single/synthesis collapsed both to a clean
pass -- so a blocker phrased with ordinary review vocabulary (reward/ranking/cohort, or a bare
score term) auto-MERGED the change it blocked. single is this deployment's live strategy. Both
strategies now hold; consensus already failed closed and is untouched. Note synthesizeDefect
calls toPublicSafe with no options, so the gate-bearing title is filtered even on a repo in
LOOPOVER_PUBLIC_SCORE_TERMS_ALLOWED_REPOS -- the allowlist never rescued this path.
Visual capture (#9462): scheduleVisualCaptureRetry's budget-exhausted early return only
skipped re-writing visualCaptureRetryPendingSha, leaving the previous attempt's marker standing
forever (the sole other clear needs a successful capture, which by definition never comes). A
permanently-marked head silently disabled the screenshot gate's close -- a permanent bypass out
of what was designed as a temporary deferral. The marker is now cleared on exhaustion, and the
unresolved state is threaded into the planner so the deferral holds the PR rather than falling
through to a merge.
* fix(metrics): register the unpublishable-blocker counter in DEFAULT_METRIC_META (#9460)
The drift guard in test/unit/selfhost-metrics.test.ts requires every literal metric name
emitted from src/ to carry a registered meta entry; the counter added alongside the
combineReviews hold had none, failing the backend coverage suite.
* test(gate): cover the capture-retry marker clear on budget exhaustion (#9462)
The existing #9030 exhaustion test starts from a PR that never had a marker written, so it
exercises the early return but not the defect. This drives the real failing sequence -- attempt
0 errors and writes the marker, then the final attempt exhausts the budget with the pipeline
still failing -- and asserts the marker does not outlive the retries that justified it.
Verified to fail against the unfixed code (expected 'vis62' to be null), so it pins the fix
rather than merely passing alongside it. Closes the codecov/patch gap flagged on the PR.
["loopover_ai_review_unpublishable_blocker_total",{help: "AI reviews where a reviewer named a real blocker whose title could not be published, so the verdict held instead of passing (#9460).",type: "counter"}],
0 commit comments