Skip to content

Read an email campaign's shortlist at the revision admission pinned - #405

Merged
egeozin merged 1 commit into
mainfrom
fix/email-shortlist-revision
Oct 13, 2026
Merged

egeozin merged 1 commit into
mainfrom
fix/email-shortlist-revision

Conversation

@egeozin

@egeozin egeozin commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

What and why

prepare_email_campaign found outreach/email/SHORTLIST.csv through canonical_file_history(limit=1), which scans only limit * 4 = 4 commits. Once four unrelated commits had landed, every campaign failed with "project state has no email shortlist revision", even though the shortlist was there.

Admission already pins where it found the shortlist: the campaign's required artifact prerequisite records {"path", "revision"} in run.prerequisite_evidence, refreshed after a settled wait. The campaign now reads the shortlist at that revision:

  • Retries are stable. If an earlier attempt already created the outreach_campaigns row, the retry reuses its source_commit_sha, so create_email_campaign's idempotency check still matches, including for a run already in flight during a deploy.
  • Older runs keep the old lookup. Runs admitted before artifact evidence existed fall back to the history scan.
  • It reads what was admitted. Edits to the shortlist after admission don't change a campaign that's already running.

pinned_artifact_revision(evidence, path) in workflow_prerequisites.py reads a satisfied pin for one path and returns None otherwise.

Verification

  • A new activity test in test_email_outreach.py covers both the admission pin and a recorded retry. Its fake storage refuses canonical_file_history, so the test fails on main and passes with the fix.
  • A unit test for pinned_artifact_revision covers satisfied, unmet, other-path, malformed and legacy evidence.
  • ruff format --check, ruff check and lint-imports are clean.
  • Ran serially against a disposable local Postgres 14: test_email_outreach, test_email_campaign_temporal, test_workflow_prerequisites, test_prerequisite_wait, test_code_authors. All passed except test_prerequisite_wait::test_answer_page_holds_in_temporal_until_its_prerequisite_finishes. That test fails the same way on unmodified main in this local environment and doesn't touch this code.

🤖 Generated with Claude Code

The campaign looked for outreach/email/SHORTLIST.csv by scanning only the
last four commits on the project branch. Once four unrelated commits had
landed, every campaign failed with "project state has no email shortlist
revision".

Admission already pins the revision where it found the shortlist in the
run's prerequisite evidence. The campaign now reads the shortlist there, a
retry keeps the revision an earlier attempt recorded, and only runs
admitted before that evidence existed fall back to the old lookup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@egeozin
egeozin requested a review from a team as a code owner October 13, 2026 07:24
@egeozin
egeozin merged commit d016c63 into main Oct 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant