Skip to content

Suite 45 — ingestion pipeline correctness fixes (45.1-45.4, 45.7-45.10) - #43

Merged
aryavenkatesan merged 1 commit into
mainfrom
all-things-ingestion
Aug 3, 2026
Merged

Suite 45 — ingestion pipeline correctness fixes (45.1-45.4, 45.7-45.10)#43
aryavenkatesan merged 1 commit into
mainfrom
all-things-ingestion

Conversation

@aryavenkatesan

Copy link
Copy Markdown
Collaborator

Nine of ten suite-45 tickets, orchestrated in four batches. 752 tests green, ruff clean, migrations linear (0019 → 0020 → 0021).

What's here

Ticket Change
45.1 prompt_suffix never applied in any scheduled run — new ingestion/prompt_dispatch.py
45.2 TIME_ZONE UTC → America/New_York — digest emails showed every event 4–5h late
45.3 Reject cancelled events pipeline-wide at the standardizer chokepoint
45.4 EventSource.default_town to recover skipped_no_town losses
45.7 blocked_reason/blocked_since + a quarantined health level
45.8 manage.py probe_sources — reachability from the real prod egress path
45.9 Stale scrape_all_sources_task docstring
45.10 Internal-only rename raw_startraw_start_datetime

Findings that changed the tickets

45.2's premise was unverified in the ticket — I reproduced it first. A 9:00 PM ET event rendered Thursday, August 6 · 1:00 AM: wrong time and wrong weekday. USE_TZ=True means storage stays UTC, so no data migration. Swept for double-correction sites; found none.

45.1's root cause was narrower than described. The batch functions already resolved prompt_suffix correctly — the bug was purely that tasks.py and ingest_events.py called them bare. Also: RawEvent.source is non-nullable, so the "orphaned rows" concern was theoretical; the sweep is in as defense-in-depth.

45.3: cancelled is deliberately excluded from CANDIDATE_STATUSES. Unlike skipped_no_town (structural, won't reverse), organizers un-cancel and resubmit. As a dedupe anchor it would silently match the legitimate resubmission as a duplicate and permanently suppress a real event — so it follows the rejected precedent instead.

45.4 keeps resolve_town's fallback-not-override semantics (the PR #42 regression). The fallback resolves per staged event inside the publish loop rather than being threaded from the task, since a batch spans multiple sources.

45.8 hardens beyond spec: a WAF captcha page isn't empty, so it would parse to 0 items and misreport as ok. Any non-2xx is now refused.

Not in this PR

  • 45.5 — executed directly against prod (source id 8 deactivated). Evidence inverted the ticket's guess: across 765 raw events id 8 had 0 unique source_uids vs id 6's 9, making id 8 the strict subset. Deactivated, not deleted, so SourceRun history survives.
  • 45.6 — not built, needs an owner decision. Research overturned the presumed fix: Eventbrite's public events/search API was discontinued Dec 2019 (org-owned events only), so an official integration covers 0 of 4 sources, not 3 of 4. Their WAF captcha also plausibly enforces their own anti-scraping ToS.

Deploy notes

Migration 0021 is a RenameField, and deploy runs migrate before up -d — so for ~30–60s the old containers run old code against the new column. /api/events/direct-submit and the admin RawEvent list would 500 in that window; the public /events/ API doesn't touch RawEvent. A pre-migrate pg_dump is taken automatically.

Post-deploy ops (Neon data — no migration ships these):

  1. Set default_town on prod sources, then manage.py reopen_skipped_towns (18 stranded rows).
  2. Set blocked_reason on the 4 WAF-blocked sources.
  3. Run probe_sources in scrape-workerbackend has no Chromium.

🤖 Generated with Claude Code

….7-45.10)

Nine of ten suite-45 tickets. 752 tests green, ruff clean, migrations linear
(0019 -> 0020 -> 0021).

45.1 prompt_suffix never applied in any scheduled run — the batch functions
  already resolved it correctly; the bug was purely that tasks.py and
  ingest_events.py called them bare. New ingestion/prompt_dispatch.py loops
  per source (all sources, not just active=True, so deactivated sources'
  unprocessed rows aren't stranded) and sweeps leftovers.
45.2 TIME_ZONE UTC -> America/New_York. Reproduced first: a 9:00 PM ET event
  rendered "Thursday, August 6 - 1:00 AM" — wrong time and wrong weekday.
  USE_TZ=True keeps storage UTC, so no data migration. Swept for
  double-correction sites; found none.
45.3 Reject cancelled events pipeline-wide at the standardizer chokepoint,
  matching title only (a description reading "rain date if cancelled" must
  not trip it). Guard runs before the Gemini call. `cancelled` is deliberately
  excluded from CANDIDATE_STATUSES: organizers un-cancel and resubmit, so
  anchoring would silently suppress the legitimate resubmission.
45.4 EventSource.default_town, resolved per staged event inside the publish
  loop rather than threaded from the task — a batch spans multiple sources.
  resolve_town keeps its fallback-not-override semantics (PR #42 regression).
45.7 EventSource.blocked_reason/blocked_since + a `quarantined` health level.
  Quarantined sources keep polling; refused -> ok is how we learn 45.6 landed.
45.8 manage.py probe_sources — fetch-only reachability from the real prod
  egress path, which the DEBUG-gated devtools playground structurally cannot
  test. Surfaces WAF headers; non-2xx is always `refused` so a captcha page
  can't parse to 0 items and misreport as ok.
45.9 scrape_all_sources_task docstring stated a stale roster; now states the
  rule, plus the scrape-worker vs backend container distinction.
45.10 Internal-only rename raw_start/raw_end -> raw_start_datetime/
  raw_end_datetime, removing the third naming. Event.date untouched — no API
  break. Staging->published boundary now documented in ingestion/models.py.

45.5 was executed directly against prod (source id 8 deactivated; evidence
showed it a strict subset of id 6, inverting the ticket's guess). 45.6 is not
built and needs an owner decision — see STATE.md.

Co-Authored-By: Claude <noreply@anthropic.com>
@aryavenkatesan
aryavenkatesan merged commit d66b059 into main Aug 3, 2026
5 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