fix(pesacheck_meedan_bridge): Stop retrying fact-checks Check already has - #1210
Conversation
… has Check rejects a repeat of the same fact-check with a PG::UniqueViolation on index_fact_checks_on_signature. The row stayed Pending, so every run retried it and failed again: a 50-article batch against the sandbox left 33 rows retrying forever, one Sentry exception each. post_to_check() now raises DuplicateFactCheckError for that constraint, and the row is marked Duplicate, which is terminal. Duplicates are summarised once in the end-of-run message instead of being reported as exceptions.
|
@claude review |
|
Check with codex also @koechkevin : [P2] Atomically claim pending rows before posting —
|
…ests Review feedback on #1210. - Treat a response as a duplicate only when EVERY GraphQL error is the signature violation; a second, unrelated error no longer marks the row terminally and swallows the real problem - Tolerate odd error shapes (non-dict entries, an explicit null message) instead of raising AttributeError over the response body - Claim a row atomically (Pending -> Posting, compare-and-set) so two overlapping runs can't both post it, and make terminal transitions conditional on Posting so a finished row can't be downgraded - Keep the in-memory feed.status in step with the row, and don't let a failure while recording "Duplicate" replace the duplicate outcome - One post_and_record() for both call sites, so a future one can't silently opt out of duplicate handling - Commit the test suite (42 cases) as a python_tests target, plus a CI workflow that lints, tests and builds the bridge on pull requests
B105 reads the test-only PESACHECK_CHECK_TOKEN value as a credential.
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@claude review |
Why
Check refuses a fact-check whose content it already has:
The bridge treated that as an ordinary failure: the row stayed
Pending, so it was retried on every run, failed again, and reported one Sentry exception each time. The set only ever grows. Posting 50 articles to the sandbox this week left 33 rows retrying forever, which is 33 wasted Check calls and 33 Sentry errors per run, drowning out real failures.What changed
post_to_check()raises a dedicatedDuplicateFactCheckErrorwhen a GraphQL error mentionsindex_fact_checks_on_signature. Any other GraphQL error keeps the existing behaviour.post_to_check_and_update()marks such a rowDuplicate, a terminal status.Pendingrows left over from earlier runs resolve toDuplicatethe next time they are attempted.Posted 0 PesaCheck article(s) to Check: []. Skipped 33 article(s) Check already has: [...].Duplicateadded to the status table, noting the Check ids aren't recorded, so the article has to be found by title if they're needed.VERSION→0.1.22, so merging deploys it.Testing
unittest, run locally): 5 new — a duplicate is marked terminally and not retried, duplicates are summarised rather than reported as errors, a leftoverPendingduplicate resolves,post_to_check()raises the new error for the signature violation, and other GraphQL errors do not become duplicates.pesacheck-tipline-sandboxworkspace, using the database from the 50-article batch that had 33 stuck rows:Duplicatein 22s, 0 exceptions, one summary line.flake8andruff formatpass.Notes
A
Duplicaterow stores nocheck_project_media_id/check_full_url, because the mutation returns nothing on rejection. If we want those recorded, a follow-up could look the item up in Check by URL and backfill the ids.