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
[torchci] AI advisor: stable-hash sanity cap + ci-no-td outage-guard bypass (#8223)
## Problem
The Dr.CI AI-advisor auto-dispatch has an **outage guard**
(`maxNewFailures`, `=8` for `pytorch/pytorch`) that bails a PR
**entirely** — dispatches *nothing* — when its NEW-failure count exceeds
the threshold. A flood of new failures is usually an outage, so the
guard is sound for normal PRs.
But it is **all-or-nothing**, and it misfires on PRs that are *expected*
to fail broadly. A `ci-no-td` PR disables Target Determination and runs
the full test suite, so a large failure count is normal there, not an
outage. The guard then suppresses every verdict.
Concrete case: pytorch/pytorch#188251 (a Triton-hash re-land,
`ci-no-td`) got **4 verdicts** dispatched in early Dr.CI passes (while
≤8 failures), then ballooned to **42 distinct failing jobs**. Every
subsequent pass tripped the guard and dispatched nothing — the verdict
count froze at 4 instead of covering the real failures.
## Change
- **`OUTAGE_GUARD_BYPASS_LABELS` (`["ci-no-td"]`)** — PRs with such a
label skip the outage bail. The full-suite failure flood is expected,
not an outage signal.
- **`maxDispatchPerPr` sanity ceiling** (default `32`;
`pytorch/pytorch=32`) — a hard cap on advisor analyses fanned out per PR
head, so bypassing the outage guard can't fan out unbounded. When more
failures are eligible than the remaining budget, the dispatched subset
is chosen by a **stable hash salted with the head SHA**: the selection
is consistent across cron passes, and the cap holds **cumulatively**
(already-recorded signals consume the budget, so successive passes top
up toward 32 rather than each re-picking a fresh 32).
- **`advisor_pr_state` query** now also returns `labels.name`;
`getPullRequestMeta` surfaces `labels`. The PR-state lookup is reordered
to run after dedup (still paid only when there is fresh work to
dispatch) so labels are available to the bypass decision.
Non-`ci-no-td` behavior is unchanged: ≤ `maxNewFailures` dispatches all
(the 32 cap never bites); a flood still bails as an outage.
## Test plan
`yarn jest test/advisorDispatch.test.ts` — all green. New/updated
coverage:
- `stableHashSelect`: determinism for a given salt, bounds (`n<=0` →
`[]`, `n>=len` → all), salt-sensitivity (different head SHA → different
subset), subset-monotonicity (a smaller pick ⊆ a larger pick of the same
set).
- `ci-no-td` PR over the max does **not** bail and caps to
`maxDispatchPerPr` (32) via stable hash.
- Cumulative cap: 30 already-recorded + 10 fresh → only 2 new dispatched
(32 − 30).
- The outage-bail test updated for the new ordering (dedup + PR-state
are read before the bail; still dispatches nothing for a non-bypass
flood).
Also: `tsc --noEmit` clean, `eslint` clean, `prettier --check` clean.
🤖 Drafted with iz2 on behalf of @izaitsevfb.
---------
Co-authored-by: Ivan <izaitsevfb@meta.com>
0 commit comments