Files
DB-cleanup/merge-output/make_findings.py
SofiaandClaude Opus 4.8 ba7529ea50 K&R database cleanup: handoff bundle
Self-contained bundle to continue the case-summary enrichment pass (70/256 done). sources/ holds the 364 .txt dossiers; scripts use relative paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018FJRciSWZc9HftS2edbzBf
2026-09-02 19:49:46 -03:00

163 lines
11 KiB
Python

"""
Fact-check findings from the contradiction pass on cases 456-461.
Written as a script so quoting cannot corrupt the JSON. Every finding carries the
line that evidences it. Absence claims are scoped to the sources on that record.
Nothing here is applied automatically. These are for the website database.
"""
import json
from pathlib import Path
OUT = Path(__file__).resolve().parent / "fact-check-findings.json"
F = [
# ---------------- case 459 : highest severity ----------------
{"case": 459, "severity": "CRITICAL", "field": "victim / summary",
"record": "Names the victims 'Stephanie Mau-Asum and Astrid Robinson'; the summary adds "
"'Stephanie Adriana Mau-Asum (Dutch)' and 'Astrid Robinson Bracho (Venezuelan)'.",
"sources": "None of the four articles names either woman. Geo News: 'the two victims, one "
"from the Netherlands and the other from Venezuela.' ProPakistani calls them "
"'the women', 'the complainant', 'her companion'.",
"why_it_matters": "These are named complainants in an alleged sexual assault. The names are "
"not supported by any source on the record.",
"action": "Remove the names pending a primary source, or record where they came from."},
{"case": 459, "severity": "HIGH", "field": "victim nationality",
"record": "Second victim recorded as Venezuelan.",
"sources": "Geo News and Abb Takk say Venezuela. Daily Pakistan and ProPakistani, both "
"published later on 3 July, say Spain: 'nationals of the Netherlands and Spain'.",
"action": "Sources disagree. Record the disagreement rather than picking a side silently."},
{"case": 459, "severity": "HIGH", "field": "summary (attackers)",
"record": "'Muhammad Raza Dar, his cousin Sikander, and three associates'.",
"sources": "ProPakistani: 'the women were abducted by the suspect, his boss, and three "
"other men'. No source names a Sikander or describes a cousin.",
"action": "Remove the invented name and relationship. Same pattern as case 460's "
"fabricated four-location list."},
{"case": 459, "severity": "HIGH", "field": "summary (political context)",
"record": "'politically sensitive given Dar's family connection to Deputy PM Ishaq Dar'.",
"sources": "No article names Ishaq Dar. Geo News says Dar is 'the grandson of a "
"high-profile political bigwig' and refers to the deputy prime minister without "
"naming him.",
"action": "Remove the name. Naming a serving politician on no source is a legal exposure."},
{"case": 459, "severity": "HIGH", "field": "summary (police action)",
"record": "'Punjab CM suspended SHO Defence C for negligence'.",
"sources": "No article reports any suspension. Geo News reports the opposite emphasis: "
"'Clear directives were issued by the Chief Minister of Punjab to ensure that "
"the police act solely in accordance with the law'.",
"action": "Remove."},
{"case": 459, "severity": "HIGH", "field": "violence_torture",
"record": "States sexual assault of both women as settled fact.",
"sources": "ProPakistani: 'initial police questioning indicated that rape had also taken "
"place, while medical examinations of the victims had been carried out and "
"reports were awaited.' The allegations are also asymmetric: 'her companion was "
"raped multiple times, and that an attempt was also made to rape her'.",
"action": "Mark as alleged and pending medical confirmation. Do not flatten the two "
"victims into one identical claim."},
{"case": 459, "severity": "MEDIUM", "field": "scenario / notes",
"record": "Presented as a straightforward kidnapping after a malicious invitation.",
"sources": "Two of four sources report police investigating a staged kidnapping. Daily "
"Pakistan: 'a staged kidnapping scenario was created to mislead authorities, "
"during which the main suspect reportedly portrayed himself as one of the "
"victims.'",
"action": "Add the alternate police theory. Its absence changes how the case reads."},
# ---------------- case 456 ----------------
{"case": 456, "severity": "HIGH", "field": "summary (violence)",
"record": "'Victim pistol-whipped (coronhada) during abduction'.",
"sources": "No article contains 'coronhada' or describes a pistol-whipping. Serra "
"Noticiario attributes his only injuries to the escape: 'O empresario "
"apresentava apenas escoriacoes causadas pela queda durante a fuga.'",
"action": "Remove. This is a fabricated violence detail contradicted by the one source "
"that addresses his injuries."},
{"case": 456, "severity": "HIGH", "field": "summary (network claim)",
"record": "'Investigation led to broader operation against a drug trafficking and money "
"laundering network in Espirito Santo and Bahia'.",
"sources": "No article makes this claim. An unrelated teaser headline sat inside the Sim "
"Noticias page: 'Gari que movimentou R$ 4 milhoes e alvo de operacao no ES e "
"BA', about a street sweeper in a different case.",
"action": "Remove. The bulk import appears to have absorbed a neighbouring headline as a "
"fact about this case."},
{"case": 456, "severity": "HIGH", "field": "summary (victim record)",
"record": "Victim described as having 'no criminal record'.",
"sources": "No article says anything about the victim's record. Acessa reports the "
"ARRESTED SUSPECT has one: 'Ele possui antecedentes criminais por trafico de "
"drogas.'",
"action": "Remove. A suspect's criminal record has been attached to the victim."},
{"case": 456, "severity": "MEDIUM", "field": "money_wanted / coin_type",
"record": "R$15,000 (~$3,000 USD). coin_type restates the same currency figure instead of "
"naming a coin.",
"sources": "Sim Noticias and A Tribuna say R$15,000. Serra Noticiario says '3.700 USDT "
"(Tether), valor equivalente a aproximadamente R$ 20 mil' and is the only "
"source naming an actual coin.",
"action": "Sources disagree on the amount. Also put USDT in coin_type, which currently "
"holds a fiat figure."},
{"case": 456, "severity": "MEDIUM", "field": "summary (attack structure)",
"record": "'Approximately eight suspects total operating in three coordinated vehicles: "
"white HB20 (blocker), silver Celta (abduction vehicle), and a third vehicle'.",
"sources": "The third vehicle is the victim's own Porsche, under attacker control only "
"after the abduction. No source describes a pre-positioned third car or the "
"per-attacker role breakdown.",
"action": "Correct. Invented specificity."},
{"case": 456, "severity": "LOW", "field": "description / summary",
"record": "'Porsche 718'; self-description 'Forex, crypto and proprietary trading desk'; "
"'seven at large as of June 16, 2026'; 'approximately 82,000 Instagram followers'.",
"sources": "No article gives a Porsche model number. Serra Noticiario supports only "
"'investidor de alto risco'. No article carries the date 16 June. Acessa says "
"'mais de 81 mil seguidores', an open lower bound.",
"action": "Remove the model number, the invented quote and the date; soften the follower "
"figure."},
{"case": 456, "severity": "LOW", "field": "arrests / seizure",
"record": "One arrested; three magazines seized.",
"sources": "Sim Noticias: 'Ate o momento, ninguem foi preso.' Acessa and A Tribuna report "
"one 25-year-old arrested. On the seizure, Acessa and A Tribuna say 'tres "
"carregadores', Serra Noticiario says 'um carregador'.",
"action": "Probably a same-day timing difference on arrests. The magazine count is a "
"genuine source disagreement."},
# ---------------- cases 457 / 458 ----------------
{"case": 457, "severity": "MEDIUM", "field": "notes",
"record": "'The plate led investigators to the same four men later arrested during the "
"Gignac-la-Nerthe incident the same night' — stated as established causation.",
"sources": "Cryptopolitan frames it conditionally: the plate 'podria ser la clave' to a "
"wider network. Journal du Coin and La Provence narrate the two scenes in "
"sequence without asserting the link.",
"action": "Soften to what the sources support."},
{"case": 457, "severity": "LOW", "field": "date",
"record": "13 June 2026.",
"sources": "Journal du Coin and La Provence both say 'samedi 13 juin'. Cryptopolitan says "
"'sabado 14 de junio', which also contradicts itself since 13 June was the "
"Saturday.",
"action": "Record is right; Cryptopolitan is wrong. No change."},
{"case": 458, "severity": "MEDIUM", "field": "kidnappings",
"record": "kidnappings = 1.",
"sources": "Journal du Coin: 'sequestrent deux femmes, dont une sexagenaire.' Two women "
"were held.",
"action": "Schema question, not a data error: does the field count victims or incidents? "
"Settle it and apply consistently, since it affects every aggregate."},
{"case": 458, "severity": "LOW", "field": "sources",
"record": "La Provence is linked to this case.",
"sources": "Its retrievable quarter covers only the sibling case 457. The Gignac material, "
"if any, is behind the paywall.",
"action": "Keep the link, but note it currently evidences 457 rather than 458."},
# ---------------- case 461 ----------------
{"case": 461, "severity": "MEDIUM", "field": "summary (weapons)",
"record": "'Held at gunpoint'; 'Firearms presented during confrontation'.",
"sources": "Hoodline says only 'three armed men' and 'the suspects were armed'. No weapon "
"type is given. The weapons=1 flag is fine; the specificity is not.",
"action": "Soften to 'armed', or source the firearm claim from the NYPD post."},
{"case": 461, "severity": "LOW", "field": "summary (device)",
"record": "'Hardware wallet (Ledger device) demanded'.",
"sources": "Hoodline hedges: 'An attempted stickup over a so-called cryptocurrency "
"ledger'. The brand is not confirmed.",
"action": "Do not assert a brand the source puts in scare quotes."},
]
OUT.write_text(json.dumps(F, ensure_ascii=False, indent=2), encoding="utf-8")
from collections import Counter
print(f"wrote {len(F)} findings -> {OUT.name}")
print(" by severity:", dict(Counter(f["severity"] for f in F)))
print(" by case :", dict(sorted(Counter(f["case"] for f in F).items())))