fix: groom mode excludes umbrellas and respects grooming state#451
Conversation
There was a problem hiding this comment.
AI Automated Review
Full PR review.
Analysis engine: MiniMax-M2.7@https://litellm.jory.dev/v1 (anthropic) — routed smart (risk match: public_route_changes)
PR PR 451 Review: fix — groom mode excludes umbrellas and respects grooming state
Summary
This PR addresses two bugs in the GET /api/agents/[agentName]/next-task?mode=groom endpoint by:
- Adding umbrella issue exclusion (issues with
umbrellalabel or titles starting with "Weekly tech debt audit:") - Respecting grooming state (cooldown window, blocked/not-ready reasons)
Required Checks
✅ verify route access controls are in place
The next-task route at src/app/api/agents/[agentName]/next-task/route.ts (line 27–29) enforces authorization via authorizeRequest(request), returning 401 if unauthorized. This is the same bearer-token auth pattern documented in AGENTS.md for agent endpoints using DISPATCH_AGENT_TOKEN. The groom mode path (mode=groom) uses this same route handler with no auth bypass.
✅ check for unintended public endpoints
No new routes or endpoints are added. This PR only modifies existing filtering logic within the groom mode code path. The query parameters mode=groom and lane were already present; no new public-facing surfaces are introduced.
Changes
src/lib/issue-filters.ts (+39 lines):
buildUmbrellaIssueExclusionWhere()— Prisma clause excluding issues withumbrellalabel or "Weekly tech debt audit:" titles (case-insensitive)applyUmbrellaIssueExclusion()— side-effect helper mirroring the existingapplyRenovateIssueExclusionpatternbuildGroomingStateExclusionWhere(cooldownHours)— Prisma clause excluding recently-groomed issues (default 24h cooldown), issues withblockedReason, and issues withnotReadyReason
src/app/api/agents/[agentName]/next-task/route.ts (+22 lines, -1 line):
- Imports the two new filter helpers
- Applies umbrella exclusion to the groom
issueWhereclause - Merges grooming-state exclusion into the existing
ANDclause - Selects
groomedAt,notReadyReason,blockedReasonfields for downstream use
Standards Compliance
- Code patterns follow existing repository conventions: helper functions in
issue-filters.ts, side-effectapply*wrappers mirroringapplyRenovateIssueExclusion - No secrets committed; no
.envor build artifacts - Error handling uses standard NextResponse JSON responses with proper HTTP status codes
Linked Issue Fit
No linked issue provided; the PR body is self-contained and describes the two bugs clearly.
Evidence Provider Findings
No evidence providers configured for this PR.
Tool Harness Findings
The tool harness verified the final state of both modified files. The authorizeRequest check is confirmed present in the route handler.
CI Results
- Validate: ✅ success
- Docker Build: ✅ success
- PR body states 142 tests pass across
issue-filters,next-taskroute, and groom route
Unknowns / Needs Verification
None identified for this PR. All required checks are satisfiable from the diff and corpus.
What
Two fixes for the
GET /api/agents/\[agentName\]/next-task?mode=groomendpoint:Bug 1: Groom mode didn't exclude umbrella issues
The groom code path only filtered out Renovate issues. Issues with the
umbrellalabel and issues whose title starts with "Weekly tech debt audit:" were never excluded, causing agents to waste grooming cycles on meta/umbrella issues.Fix: Added
applyUmbrellaIssueExclusion()inissue-filters.ts(mirrors the Renovate exclusion pattern) and applied it in the groom candidate Prisma query.Bug 2: Groom mode ignored grooming state
The Prisma query selecting groom candidates didn't check
groomedAt,notReadyReason, orblockedReason. So everyPOST /api/issues/groomwrote successfully but the next call re-surfaced the same issue regardless of what was decided.Fix: Added
buildGroomingStateExclusionWhere()which:blockedReasonornotReadyReasonChanges
src/lib/issue-filters.ts: AddedapplyUmbrellaIssueExclusion(),buildUmbrellaIssueExclusionWhere(), andbuildGroomingStateExclusionWhere()src/app/api/agents/\[agentName\]/next-task/route.ts: Applied umbrella exclusion and grooming state exclusion in the groom mode path; selected grooming state fields in the Prisma queryTesting
npm run build)