Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/sentry/features/temporary.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,6 @@ def register_temporary_features(manager: FeatureManager) -> None:
manager.add("organizations:seer-wizard", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable the Seer issues view
manager.add("organizations:seer-issue-view", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable Autofix to use Seer Agent instead of legacy Celery pipeline
manager.add("organizations:autofix-on-explorer", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable autofix introspection for early stopping of autofix runs
manager.add("organizations:seer-autofix-introspection", OrganizationFeature, FeatureHandlerStrategy.FLAGPOLE, api_expose=True)
# Enable Seer Workflows in Slack (released, kept until overrides are removed)
Expand Down
8 changes: 2 additions & 6 deletions src/sentry/search/snuba/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.utils import timezone
from django.utils.functional import SimpleLazyObject

from sentry import features, quotas
from sentry import quotas
from sentry.api.event_search import SearchFilter
from sentry.db.models.manager.base_query_set import BaseQuerySet
from sentry.exceptions import InvalidSearchQuery
Expand Down Expand Up @@ -595,11 +595,7 @@ def _get_queryset_conditions(
"issue.type": QCallbackCondition(lambda types: Q(type__in=types)),
"issue.priority": QCallbackCondition(lambda priorities: Q(priority__in=priorities)),
"issue.seer_actionability": QCallbackCondition(seer_actionability_filter),
"issue.seer_last_run": ScalarCondition(
"seer_explorer_autofix_last_triggered"
if features.has("organizations:autofix-on-explorer", organization)
else "seer_autofix_last_triggered"
),
"issue.seer_last_run": ScalarCondition("seer_explorer_autofix_last_triggered"),
"issue.id": QCallbackCondition(
lambda ids: Q(id__in=[int(v) for v in (ids if isinstance(ids, list) else [ids])])
),
Expand Down
19 changes: 1 addition & 18 deletions src/sentry/seer/agent/client_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,24 +208,7 @@ def has_seer_agent_access_with_detail(
if not has_access:
return False, error

feature_names = [
# Access to seer agent
"organizations:seer-explorer",
# Access to seer agent powered autofix
"organizations:autofix-on-explorer",
]

batch_features = features.batch_has(
feature_names,
organization=organization,
actor=actor,
)

if batch_features is None:
return False, "Feature flag not enabled"

org_features = batch_features.get(f"organization:{organization.id}", {})
if not any(bool(org_features.get(feature_name)) for feature_name in feature_names):
if not features.has("organizations:seer-explorer", organization, actor=actor):
return False, "Feature flag not enabled"

# Check open team membership (the agent requires this for context)
Comment on lines 208 to 214
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: Removing the organizations:autofix-on-explorer flag check will revoke Seer agent access for organizations that don't also have the organizations:seer-explorer flag enabled.
Severity: HIGH

Suggested Fix

Before removing the check for the organizations:autofix-on-explorer flag, verify that all organizations with this flag also have the organizations:seer-explorer flag enabled. Alternatively, run a migration script to enable seer-explorer for all organizations that currently have autofix-on-explorer set to true.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/seer/agent/client_utils.py#L208-L214

Potential issue: The function `has_seer_agent_access_with_detail()` is being changed to
only check for the `organizations:seer-explorer` feature flag, removing a check for the
`organizations:autofix-on-explorer` flag. Previously, access was granted if either flag
was enabled. This change will cause a regression for any organization that has
`autofix-on-explorer=True` but `seer-explorer=False`. These organizations will lose
access to Seer agent functionality, including autofix via Slack and direct API
endpoints, because the access check will now incorrectly return `False`.

Did we get this right? 👍 / 👎 to inform future reviews.

Expand Down
39 changes: 7 additions & 32 deletions src/sentry/seer/autofix/issue_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from sentry.locks import locks
from sentry.models.group import Group
from sentry.net.http import connection_from_url
from sentry.seer.autofix.autofix import _get_trace_tree_for_event, trigger_legacy_autofix
from sentry.seer.autofix.autofix import _get_trace_tree_for_event
from sentry.seer.autofix.autofix_agent import (
AutofixStep,
NoSeerQuotaException,
Expand Down Expand Up @@ -53,7 +53,6 @@
from sentry.taskworker.namespaces import seer_tasks
from sentry.users.models.user import User
from sentry.users.services.user.model import RpcUser
from sentry.users.services.user.service import user_service
from sentry.utils.cache import cache
from sentry.utils.locking import UnableToAcquireLock

Expand Down Expand Up @@ -177,41 +176,17 @@ def _trigger_autofix_task(
}
)

user: User | AnonymousUser | RpcUser | None = None
if user_id:
user = user_service.get_user(user_id=user_id)
if user is None:
logger.warning(
"_trigger_autofix_task.user_not_found",
extra={"group_id": group_id, "user_id": user_id},
)
user = AnonymousUser()
else:
user = AnonymousUser()

# Route to agent-based autofix if both feature flags are enabled
run_id: int | None = None
if features.has("organizations:autofix-on-explorer", group.organization):
try:
run_id = trigger_autofix_agent(
group=group,
step=AutofixStep.ROOT_CAUSE,
referrer=referrer,
run_id=None,
stopping_point=stopping_point,
)
except NoSeerQuotaException:
pass
else:
response = trigger_legacy_autofix(
try:
run_id = trigger_autofix_agent(
group=group,
event_id=event_id,
user=user,
step=AutofixStep.ROOT_CAUSE,
referrer=referrer,
auto_run_source=auto_run_source,
run_id=None,
stopping_point=stopping_point,
)
run_id = response.data.get("run_id")
except NoSeerQuotaException:
pass

if run_id and SeerAutofixOperator.has_access(organization=group.project.organization):
SeerOperatorAutofixCache.migrate(from_group_id=group_id, to_run_id=run_id)
Expand Down
Loading
Loading