Skip to content

feat(autofix): Add analytics events for autofix phase start and completion#112098

Merged
chromy merged 1 commit intomasterfrom
chromy/feat/autofix-phase-analytics
Apr 7, 2026
Merged

feat(autofix): Add analytics events for autofix phase start and completion#112098
chromy merged 1 commit intomasterfrom
chromy/feat/autofix-phase-analytics

Conversation

@chromy
Copy link
Copy Markdown
Contributor

@chromy chromy commented Apr 2, 2026

Add per-phase analytics events for the autofix pipeline so we can track
when each phase (root cause, solution, code changes, impact assessment,
triage) starts and completes.

Each phase gets its own event class (ai.autofix.root_cause.started,
ai.autofix.root_cause.completed, etc.) plus a dedicated
ai.autofix.pr_created.completed event. All events include group_id,
referrer, organization_id, and project_id.

Started events are recorded in trigger_autofix_explorer when a phase kicks
off. Completed events are recorded in AutofixOnCompletionHook._send_step_webhook
when the on-completion hook fires.

Also fixes double-counting of ai.autofix.code_changes.completed: when
current_step is CODE_CHANGES and repo_pr_states is populated, the
hook was firing both AiAutofixCodeChangesCompletedEvent (from
STEP_CONFIGS) and AiAutofixPrCreatedCompletedEvent. Since
push_changes passes on_completion_hook in its payload, the hook fires
again after PR creation — meaning the code-changes event was recorded both
when coding finished and when the PR was created. The fix gates the
STEP_CONFIGS completed event on webhook_action_type != PR_CREATED so
only the PR-created event fires in that path.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Backend Test Failures

Failures on 65e2209 in this run:

tests/sentry/seer/autofix/test_autofix_agent.py::TestTriggerAutofixExplorer::test_trigger_autofix_explorer_passes_group_id_in_metadatalog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/seer/autofix/test_autofix_agent.py:350: in test_trigger_autofix_explorer_passes_group_id_in_metadata
    trigger_autofix_explorer(
src/sentry/seer/autofix/autofix_agent.py:233: in trigger_autofix_explorer
    event_cls(
E   TypeError: AiAutofixRootCauseStartedEvent.__init__() got an unexpected keyword argument 'organization_id'
tests/sentry/seer/autofix/test_autofix_agent.py::TestTriggerAutofixExplorer::test_trigger_autofix_explorer_passes_project_to_clientlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/seer/autofix/test_autofix_agent.py:329: in test_trigger_autofix_explorer_passes_project_to_client
    trigger_autofix_explorer(
src/sentry/seer/autofix/autofix_agent.py:233: in trigger_autofix_explorer
    event_cls(
E   TypeError: AiAutofixRootCauseStartedEvent.__init__() got an unexpected keyword argument 'organization_id'
tests/sentry/seer/autofix/test_autofix_agent.py::TestTriggerAutofixExplorer::test_trigger_autofix_explorer_sends_started_webhook_for_all_stepslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/seer/autofix/test_autofix_agent.py:285: in test_trigger_autofix_explorer_sends_started_webhook_for_all_steps
    trigger_autofix_explorer(
src/sentry/seer/autofix/autofix_agent.py:233: in trigger_autofix_explorer
    event_cls(
E   TypeError: AiAutofixRootCauseStartedEvent.__init__() got an unexpected keyword argument 'organization_id'
tests/sentry/seer/autofix/test_autofix_agent.py::TestTriggerAutofixExplorer::test_trigger_autofix_explorer_sends_started_webhook_for_continued_runlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/seer/autofix/test_autofix_agent.py:305: in test_trigger_autofix_explorer_sends_started_webhook_for_continued_run
    result = trigger_autofix_explorer(
src/sentry/seer/autofix/autofix_agent.py:233: in trigger_autofix_explorer
    event_cls(
E   TypeError: AiAutofixSolutionStartedEvent.__init__() got an unexpected keyword argument 'organization_id'

Copy link
Copy Markdown
Member

@trevor-e trevor-e left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but might want to wait for Tony's review.

Comment thread src/sentry/seer/autofix/autofix_agent.py Outdated
Comment thread src/sentry/seer/autofix/on_completion_hook.py Outdated
Comment thread src/sentry/analytics/events/autofix_events.py
Comment thread src/sentry/seer/autofix/autofix_agent.py Outdated
@chromy chromy force-pushed the chromy/feat/autofix-phase-analytics branch from c3ac170 to 9a5f34f Compare April 2, 2026 17:24
@chromy chromy marked this pull request as ready for review April 2, 2026 17:24
@chromy chromy requested review from a team as code owners April 2, 2026 17:24
@chromy chromy force-pushed the chromy/feat/autofix-phase-analytics branch from 9a5f34f to f431887 Compare April 2, 2026 17:55
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Code changes completed event fires spuriously on PR creation
    • Modified analytics event firing logic to only fire AiAutofixPrCreatedCompletedEvent when webhook_action_type is PR_CREATED, preventing duplicate AiAutofixCodeChangesCompletedEvent from inflating analytics counts.

Create PR

Or push these changes by commenting:

@cursor push 38e57f1b9a
Preview (38e57f1b9a)
diff --git a/src/sentry/seer/autofix/on_completion_hook.py b/src/sentry/seer/autofix/on_completion_hook.py
--- a/src/sentry/seer/autofix/on_completion_hook.py
+++ b/src/sentry/seer/autofix/on_completion_hook.py
@@ -237,16 +237,6 @@
             metrics.incr(
                 "autofix.explorer.complete", tags={"step": current_step.value, "referrer": referrer}
             )
-            completed_event_cls = STEP_CONFIGS[current_step].completed_event
-            if completed_event_cls is not None and referrer is not None:
-                analytics.record(
-                    completed_event_cls(
-                        organization_id=organization.id,
-                        project_id=group.project_id,
-                        group_id=group.id,
-                        referrer=referrer,
-                    )
-                )
             if webhook_action_type == SeerActionType.PR_CREATED and referrer is not None:
                 analytics.record(
                     AiAutofixPrCreatedCompletedEvent(
@@ -256,6 +246,17 @@
                         referrer=referrer,
                     )
                 )
+            elif webhook_action_type != SeerActionType.PR_CREATED:
+                completed_event_cls = STEP_CONFIGS[current_step].completed_event
+                if completed_event_cls is not None and referrer is not None:
+                    analytics.record(
+                        completed_event_cls(
+                            organization_id=organization.id,
+                            project_id=group.project_id,
+                            group_id=group.id,
+                            referrer=referrer,
+                        )
+                    )
 
     @classmethod
     def _maybe_trigger_supergroups_embedding(

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread src/sentry/seer/autofix/on_completion_hook.py
Comment on lines +42 to +59
@analytics.eventclass("ai.autofix.impact_assessment.started")
class AiAutofixImpactAssessmentStartedEvent(AiAutofixPhaseEvent):
pass


@analytics.eventclass("ai.autofix.impact_assessment.completed")
class AiAutofixImpactAssessmentCompletedEvent(AiAutofixPhaseEvent):
pass


@analytics.eventclass("ai.autofix.triage.started")
class AiAutofixTriageStartedEvent(AiAutofixPhaseEvent):
pass


@analytics.eventclass("ai.autofix.triage.completed")
class AiAutofixTriageCompletedEvent(AiAutofixPhaseEvent):
pass
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These shouldn't be in use in production so I would expect they never fire

Comment thread src/sentry/seer/autofix/on_completion_hook.py
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0e0a05a. Configure here.

Comment thread src/sentry/analytics/events/autofix_events.py Outdated
Comment thread src/sentry/seer/autofix/on_completion_hook.py Outdated
…etion

Record per-phase analytics events when each autofix pipeline phase
(root_cause, solution, code_changes) starts and completes. Each phase
gets its own event class so they can be queried independently. Events
include group_id, referrer, organization_id, and project_id.

Started events fire in trigger_autofix_explorer, completed events fire
in the on_completion_hook webhook handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Agent transcript: https://claudescope.sentry.dev/share/botteEgndhtvdoXxpJ2frzQPLVabdvt8jNcgx9NaA3k
@chromy chromy force-pushed the chromy/feat/autofix-phase-analytics branch from 0e0a05a to f98a76a Compare April 7, 2026 12:51
@chromy chromy merged commit 01a1fc9 into master Apr 7, 2026
59 checks passed
@chromy chromy deleted the chromy/feat/autofix-phase-analytics branch April 7, 2026 19:21
george-sentry pushed a commit that referenced this pull request Apr 9, 2026
…etion (#112098)

Add per-phase analytics events for the autofix pipeline so we can track
when each phase (root cause, solution, code changes, impact assessment,
triage) starts and completes.

Each phase gets its own event class (`ai.autofix.root_cause.started`,
`ai.autofix.root_cause.completed`, etc.) plus a dedicated
`ai.autofix.pr_created.completed` event. All events include `group_id`,
`referrer`, `organization_id`, and `project_id`.

Started events are recorded in `trigger_autofix_explorer` when a phase
kicks
off. Completed events are recorded in
`AutofixOnCompletionHook._send_step_webhook`
when the on-completion hook fires.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants