Conversation
…on issues Extract filter logic from kick_off_seer_automation into two helper functions that return skip reasons. This enables a single metrics.incr and logger.info call per filtered issue, giving visibility into why issues are being skipped (e.g. fixability too low, issue too old, no connected repos, already triggered). Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
Replace bare str return type with a SeerAutomationSkipReason Literal union for type safety on skip reason values. Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
src/sentry/tasks/post_process.py
Outdated
| ) | ||
| logger.info( | ||
| "seer.automation.filtered", | ||
| extra={"group_id": group.id, "reason": skip_reason, "tier": "seat_based"}, |
There was a problem hiding this comment.
Maybe could have organization_id on the logger call just to have that to hand
There was a problem hiding this comment.
I removed the logger call for now since I think this is called for every occurrence which might be too high-volume. I don't see other logs in this path.
| # Check if summary exists in cache | ||
| if group.times_seen_with_pending < 10: | ||
| generate_issue_summary_only.delay(group.id) | ||
| else: |
There was a problem hiding this comment.
I think we never get to this case now:
if group.times_seen_with_pending < 10:
generate_issue_summary_only.delay(group.id)
because we also check this in _get_seat_based_seer_automation_skip_reason and early return if that returns non-zero.
There was a problem hiding this comment.
Updated to be if skip_reason is not None which _get_seat_based_seer_automation_skip_reason should return None in this case and pass.
Move SeerAutomationSkipReason, get_default_seer_automation_skip_reason, and get_seat_based_seer_automation_skip_reason into a new src/sentry/seer/autofix/trigger.py file. This makes the trigger decision logic self-contained and easier to follow. Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
Move lazy imports to top-level in trigger.py since there are no circular dependency concerns. Pass the locks manager from post_process.py rather than recreating it. Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Restore original comments in trigger.py and post_process.py. Use `if skip_reason is not None` instead of `if skip_reason` for clarity. Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
Revert to lazy imports in trigger.py to match original post_process.py behavior and avoid mock patching issues. Move the >= 10 no-summary rate limit check back to kick_off_seer_automation to avoid a TOCTOU race from reading the cache twice. Refs AIML-2686 Co-Authored-By: Claude <noreply@anthropic.com>
…NCE_THRESHOLD Co-Authored-By: Claude <noreply@anthropic.com>
…on (#111638) Adds granular `metrics.incr("seer.automation.filtered")` at every filter point in `kick_off_seer_automation()`, with specific `reason` and `tier` tags. Previously ~14 return points silently skipped issues with no observability. Extracts filter logic from `kick_off_seer_automation()` into `src/sentry/seer/autofix/trigger.py` with two helper functions (`get_default_seer_automation_skip_reason`, `get_seat_based_seer_automation_skip_reason`) that return typed skip reasons. The generic `not_eligible` reason is broken down into 5 specific sub-reasons via `get_seer_automation_ineligibility_reason()`: - `not_eligible.issue_category_ineligible` - `not_eligible.gen_ai_feature_disabled` - `not_eligible.ai_features_hidden` - `not_eligible.scanner_not_enabled` - `not_eligible.no_budget` This builds on #111486 which added the initial metrics/refactor — that PR has already been merged. This PR adds the `not_eligible` breakdown and moves the eligibility functions from `utils.py` to `trigger.py` to consolidate trigger decision logic. Refs AIML-2686 --------- Co-authored-by: Claude <noreply@anthropic.com>

Extracts the filter logic from
kick_off_seer_automation()into two helper functions (_get_default_seer_automation_skip_reasonand_get_seat_based_seer_automation_skip_reason) that return a string reason when an issue is skipped. This enables a singlemetrics.incrandlogger.infocall per filtered issue instead of silent returns.Previously, ~14 return points in this function silently dropped issues with no observability. Only the 3 rate-limit paths emitted any signal. Now every skip reason is tagged and visible:
already_has_fixability_score,not_eligible,lock_already_held,rate_limited(default tier)summary_already_cached,summary_already_dispatched,already_triggered,issue_too_old,fixability_too_low,automation_already_dispatched,no_connected_repos(seat-based tier)Metric:
seer.automation.filteredwithreasonandtiertags.Refs AIML-2686