Repository navigation
Description
Finding
Line coverage on main @ 88241f4 is 100 % in every file of src/cronJobs/ and src/plugins/ under both suites (npm run test:coverage: 163 files / 2206 tests, 100 % lines / 99.75 % branches; npm run test:coverage:e2e: 83 files / 502 tests, src/cronJobs 100 % lines / 98.03 % branches, src/plugins 100 % lines / 98.93 % branches), so there is no coverage gap to file. The question left is whether the tests pin what they execute. A single-operator mutation probe over src/cronJobs/{sweep,lgtm,labelSync,handleCronJob}.ts and src/plugins/{ownersLabel,blunderbuss,requireMatchingLabel,lgtmBinding}.ts (258 mutants: ||/&&, ===/!==, </<=, >/>=, true/false, ??/||, ! removal, + 1/+ 0), each first run against the module's own test file and every survivor then re-run with npx vitest related <file> --run, leaves four non-equivalent survivors, all in src/cronJobs/sweep.ts, the same cluster #513 did not touch:
-
sweep.ts:163—requestOwnersReviewers(…, { explicit: false, … })mutated toexplicit: truepasses all 4 related files / 77 tests.explicit: falseis what makes the sweep honourblunderbuss.ignore_authors(andignore_drafts; the sweep's own draft check at line 153 masks that half). No sweep test configuresignore_authors, so a regression would have the scheduled job request reviewers on every dependabot pull request while thepull_requesthandler still skips them, and nothing would notice. -
sweep.ts:178—new Date(pr.updated_at) >= sincemutated to>survives: no candidate is ever updated exactly at the start of the window, so whether the window is closed or open atsinceis unpinned. -
sweep.ts:179— the second<inconst exhausted = items.length < pageSize || new Date(items[items.length - 1].updated_at) < sincemutated to<=survives: a full page whose oldest entry sits exactly onsincewould wrongly be treated as the last page and the next page never fetched.keeps paging while a full page is still inside the window(sweep.test.ts:154) has its oldest entry 100 s inside the window, not on the edge. -
sweep.ts:149—new Date(pr.created_at) < plugins.sincemutated to<=survives: a pull request opened exactly atsinceis fresh (gets reviewers) today, and nothing says so.
Survivors judged equivalent or unobservable, needing no test: ??→|| on blunderbuss.ts:31,33,35,174, sweep.ts:141,153, labelSync.ts:133 (the left operand is validated >= 1, a boolean, or an array/null, so || and ?? agree); blunderbuss.ts:58 (remaining === 0 yields an empty sample either way); required: true on every core.getInput('github-token') (the harness always sets the token); lgtm.ts:163 (return false on a gate miss feeds progress.jobsDone, which cronLgtm returns and handleCronJobs discards, so nothing at the action level can observe it — if that counter is meant to be read it should be logged, which is a src/ decision outside this lane). Everything else that survived its own file — including lgtmBinding.ts:38 (hasLgtmLabel's ===) and requireMatchingLabel.ts:252 (isBot's ||) — is killed transitively by vitest related (handleCronJob.test.ts:118-130 already pins the once: true dedupe for both sweep.ts:117 and lgtm.ts:166).
Recommendation
Add four cases to __tests__/cronJobTest/sweep.test.ts; no src/ change:
- in
sweep candidates: a pull request updated exactly atago(hour)is a candidate; a full page of 100 whose oldest entry is updated exactly atago(hour)is followed by apage=2request (assert onservePulls'slistCalls). - in
sweep on a repository with OWNERS files: a pull request created exactly atago(hour)gets arequested_reviewersPOST; withprowYaml('blunderbuss:\n ignore_authors:\n - Dave\n')a fresh pull request bydavegets none andcore.debugsaysblunderbuss: ignoring pull request by dave.
Verified locally: with these cases the :149, :163 and :179 mutants each fail 1 test and the :178 mutant fails 3.
Priority
- Impact: medium (
ignore_authorson the scheduled job; the window edge on the paginated listing) - Effort: low
Decision taken by hive: one issue because one PR to one test file closes all four boxes; lgtm.ts:163 is recorded here rather than pinned, since pinning a value nothing reads would be a test of dead output. The probe harness is not proposed for CI, for the reason #513 gives.
Filed by quality agent (hold-gated mode)
🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 88241f4
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88
Activity
github-actions commentedon Oct 19, 2026
Please add a kind label with
/kind feature,/kind failing-testor/kind cleanup.