feat(night-shift): Trigger autofix for fixable candidates and add dry run mode#113056
feat(night-shift): Trigger autofix for fixable candidates and add dry run mode#113056
Conversation
… run mode Night shift triage now triggers autofix automation for candidates identified as fixable. Each autofix run uses a dedicated NIGHT_SHIFT referrer so this cohort can be tracked separately from the regular automation flow. Also adds a dry run toggle to the Seer admin page so staff can run triage without triggering actual autofixes, useful for evaluating triage output without side effects like autofix run timestamps. Co-Authored-By: Claude <noreply@anthropic.com>
|
🚨 Warning: This pull request contains Frontend and Backend changes! It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently. Have questions? Please ask in the |
Sentry Snapshot Testing
|
Backend Test FailuresFailures on
|
…lity Night shift already performs its own agentic assessment of fixability, so the stopping point should honor the user's configured preference without also applying the fixability score as a lower bound. Extract _get_user_stopping_point_preference helper and add get_user_stopping_point for callers that need just the preference. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Thread the preferences dict already loaded by _get_eligible_projects through to the autofix trigger loop instead of re-fetching per candidate. Also move autofix triggering after the candidates_selected log statement. Co-Authored-By: Claude <noreply@anthropic.com>
This was an HTTP call to Seer per candidate. The downstream autofix trigger handles duplicate runs, so the pre-flight check is unnecessary overhead for the small candidate counts night shift produces. Co-Authored-By: Claude <noreply@anthropic.com>
Use auto_run_source_map and referrer_map instead of magic strings and direct enum references, consistent with how run_automation does it. Co-Authored-By: Claude <noreply@anthropic.com>
- test_triggers_autofix_for_fixable_candidates: verifies autofix task is dispatched with correct referrer for AUTOFIX candidates - test_dry_run_skips_autofix: verifies dry run saves candidates to DB but does not dispatch autofix - test_skips_autofix_for_non_autofix_candidates: verifies root_cause_only candidates do not trigger autofix - Fix _get_eligible_projects test to unpack the new tuple return Co-Authored-By: Claude <noreply@anthropic.com>
…_point Inline the preference-reading logic back into get_automation_stopping_point to keep the diff minimal. Night shift reads the stopping point from the already bulk-loaded preferences dict so this helper is not needed. 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.
Reviewed by Cursor Bugbot for commit 1b5add6. Configure here.
| "night_shift.autofix_trigger_failed", | ||
| extra={"group_id": group.id, "organization_id": organization.id}, | ||
| ) | ||
| return False |
There was a problem hiding this comment.
Missing existing autofix run check before triggering
Medium Severity
_trigger_autofix_for_candidate dispatches _trigger_autofix_task without first checking whether an autofix run already exists for the group. The regular automation flow in run_automation calls get_autofix_state(group_id=..., organization_id=...) and returns early if a run exists. The PR description states "Per candidate, we check for an existing autofix run" but this guard is absent from the implementation. This can cause duplicate autofix runs for the same group, wasting resources and potentially creating conflicting state.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 1b5add6. Configure here.
There was a problem hiding this comment.
There's slight potential for a race condition but not a big deal right now. Our issues query checks that the field is null.
| autofix_triggered = 0 | ||
| if not dry_run: | ||
| for c in candidates: | ||
| if c.action == TriageAction.AUTOFIX: |
There was a problem hiding this comment.
Did we want to handle ROOT_CAUSE_ONLY or leave it out for now?
There was a problem hiding this comment.
Yea spoke offline and going to ignore for now.


Night shift triage now triggers autofix automation for candidates identified as fixable by the agentic triage strategy. Each autofix run carries a dedicated
NIGHT_SHIFTreferrer (AutofixReferrer.NIGHT_SHIFT+auto_run_source="night_shift") so this cohort can be tracked and evaluated separately from the regular post-process/alert automation flow.Per candidate, we check for an existing autofix run and resolve the user's configured stopping point before dispatching
_trigger_autofix_task. Unlike the regular automation flow, we skip the fixability-score-based stopping point since night shift already performed its own agentic assessment — only the user's project preference is honored as an upper bound. Quota and feature flag checks are handled downstream bytrigger_autofix/trigger_autofix_explorer.Also adds a dry run toggle to the Seer admin page (
/_admin/seer/). When enabled, night shift runs triage and logs candidates as usual but skips autofix triggering — useful for evaluating triage quality without side effects like autofix run timestamps that prevent re-runs.Changes
issue_summary.py: WireNIGHT_SHIFTintoauto_run_source_mapandreferrer_map. Extract_get_user_stopping_point_preferencehelper and addget_user_stopping_pointfor callers that need just the user preference without fixability scoring.cron.py: Add_trigger_autofix_for_candidate()helper, loop inrun_night_shift_for_org, acceptdry_runkwarg, useget_user_stopping_pointfor stopping point.admin_night_shift_trigger.py: Passdry_runflag through to the task.seerAdminPage.tsx: Add dry run checkbox to the night shift trigger form.