Skip to content

feat(seer): Mirror last_triggered_at to SeerRun on autofix triggers#115611

Open
trevor-e wants to merge 4 commits into
masterfrom
telkins/seer-run-mirror-last-triggered
Open

feat(seer): Mirror last_triggered_at to SeerRun on autofix triggers#115611
trevor-e wants to merge 4 commits into
masterfrom
telkins/seer-run-mirror-last-triggered

Conversation

@trevor-e
Copy link
Copy Markdown
Member

Dual-write the last-triggered timestamp to SeerRun at the three existing sites that stamp the Group.seer_autofix_last_triggered / Group.seer_explorer_autofix_last_triggered cache columns:

  • seer/autofix/autofix.py — autofix trigger
  • seer/endpoints/group_autofix_update.py — autofix update endpoint
  • seer/autofix/on_completion_hook.py — agent-based autofix step completion

Part of the ongoing SeerRun / SeerAgentRun mirror rollout. Reads still come from the Group cache columns — this PR only keeps SeerRun.last_triggered_at in sync so we can shift the read paths later without a backfill gap.

Each pair of writes is wrapped in transaction.atomic(using=router.db_for_write(Group)) so the two timestamps land together; both models are @cell_silo_model and resolve to the same DB. When the matching SeerRun row hasn't been mirrored yet (mirror isn't at 100%), the filter().update() is a silent no-op.

The update endpoint uses request.data.get("run_id") and guards with isinstance(run_id, int) so a missing/malformed run_id doesn't accidentally filter(seer_run_state_id=None) and update unrelated rows (the column is null=True).

Dual-write the last-triggered timestamp to SeerRun alongside the existing
Group cache columns (seer_autofix_last_triggered,
seer_explorer_autofix_last_triggered) so SeerRun.last_triggered_at stays
accurate during the SeerRun/SeerAgentRun mirror rollout. Reads continue
to come from the Group columns; this only keeps the new model in sync
so we can shift reads later without backfill gaps.

Each pair of writes is wrapped in transaction.atomic(using=...) so the
Group and SeerRun timestamps land together. When the matching SeerRun
row hasn't been mirrored yet, the filter().update() is a silent no-op.

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label May 14, 2026
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.

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 acf644f. Configure here.

Comment thread src/sentry/seer/autofix/autofix.py Outdated
trevor-e and others added 2 commits May 14, 2026 18:40
_call_autofix can return None (run.seer_run_state_id is nullable, and the
response.json() fallback path may not include run_id). Without an
isinstance(run_id, int) guard, filter(seer_run_state_id=None) generates
WHERE seer_run_state_id IS NULL and could update unrelated mirror rows
that haven't been backfilled yet.

Mirrors the guard already in place in group_autofix_update.py.

Co-Authored-By: Claude <noreply@anthropic.com>
@trevor-e trevor-e marked this pull request as ready for review May 14, 2026 22:48
@trevor-e trevor-e requested a review from a team as a code owner May 14, 2026 22:48
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.

1 participant