# Research methodology (instructions given to every research agent)

Goal: for each assigned candidate in the **2026 Brazilian general election (Rio de Janeiro / presidential race, 1st round 4 Oct 2026)**, find *negative news*: investigations, lawsuits, convictions, electoral irregularities, corruption, links to militias/organized crime, violence, harassment, disinformation, hate speech, nepotism/"rachadinha", rejected accounts, ineligibility, and serious controversies — each backed by a link to a credible source.

Today is 2026-10-02. Recent items (2025–2026) matter most, but older serious cases (convictions, major scandals) must be included too.

## Rules (non-negotiable)

1. **Never invent or guess a URL.** Only use URLs that appeared in actual search results or that you opened with WebFetch. If unsure whether a URL is real, drop the item.
2. **Confirm identity.** Many names are common. Match full name + party / city / occupation / known career before attributing anything. If you cannot confirm it's the same person, do not include it (you may mention the doubt in `notes`).
3. **Be precise about legal status.** Distinguish *investigated* vs *charged* vs *defendant* vs *convicted (appealable)* vs *convicted (final)* vs *acquitted / archived / annulled*. If a case was archived or the person was acquitted, either drop it or include it with the correct `status` and say so in the summary. Never present an accusation as a fact.
4. **Credible sources only:** major outlets (G1, O Globo, Folha, Estadão, UOL, CNN Brasil, BBC Brasil, Agência Brasil, Poder360, Metrópoles, Congresso em Foco, piauí, Agência Pública, The Intercept Brasil, Veja, Época, Extra, O Dia, Band, Record, SBT News, Jota, Conjur), official sources (STF, STJ, TSE, TRE-RJ, TJRJ, MPF, MPRJ, PF, TCU, TCE-RJ, Câmara, Senado, ALERJ) and established regional outlets. No anonymous blogs, no partisan propaganda sites, no social-media rumours.
5. **Neutral wording** in Portuguese (pt-BR) for summaries. Factual, no adjectives like "corrupto", "bandido". State what is alleged, by whom, and the current outcome.
6. Prefer **one strong item per distinct case** (avoid 5 links about the same thing). Big politicians: up to ~10 items covering their most serious/different cases. Minor candidates: whatever exists (often 0–2).
7. If nothing negative and credible is found, return `"items": []` and `"summary_pt": "Nenhuma notícia negativa relevante encontrada nas buscas realizadas."` — that is a valid, useful result.
8. Search in Portuguese, using full name and ballot name plus terms like: `investigado`, `denúncia`, `réu`, `condenado`, `processo`, `MPRJ`, `Polícia Federal`, `operação`, `TSE`, `TRE-RJ`, `impugnação`, `ficha limpa`, `inelegível`, `improbidade`, `milícia`, `rachadinha`, `polêmica`, `escândalo`, `cassação`, `contas rejeitadas`, `agressão`, `assédio`, `fake news`.

## Family / political clans (category `familia`)

Political families matter in Rio de Janeiro. **Do not discard news about a candidate's relatives** — classify it instead:

- Relatives in scope: parents, children, siblings, spouses/ex-spouses, and in-laws/cousins **only when politically active
  or when the case involves the candidate's mandate, office, campaign or companies**.
- Use `"category": "familia"` and add two extra fields: `"relation"` (pt-BR, from the candidate's point of view:
  `pai`, `mãe`, `filho`, `filha`, `irmão`, `irmã`, `cônjuge`, `ex-cônjuge`, `sogro`, `cunhado`, `primo`, …) and
  `"relative"` (the relative's name, e.g. `"Anthony Garotinho"`).
- `status` describes **the relative's** case (e.g. the father was `condenado`).
- `summary_pt` must say clearly whose case it is and whether the candidate is or is not personally investigated/accused.
- If the candidate is personally a target in the same case, use the normal category instead (not `familia`).
- Each candidate may also get an optional `"family_pt"` string: one neutral sentence listing politically relevant family
  ties (e.g. `"Filho do ex-governador Anthony Garotinho e da ex-governadora Rosinha Garotinho; irmão de Clarissa Garotinho."`),
  even when no negative news about the relatives was found.

## Tools

- `WebSearch` (use `mode: "standard"`; use `"extended"` only when standard is thin for an important candidate).
- `WebFetch` to open and verify an article when the snippet is ambiguous.
- Kagi search + page extraction (`select:mcp__Kagi_MCP__kagi_search,mcp__Kagi_MCP__kagi_extract`) — **quota exhausted (HTTP 429)**; skip it.
- Search budget is shared by many parallel agents: use `WebSearch` frugally (well-targeted queries). For discovery you can also run
  `python3 /tmp/claude-0/-home-user-electionnator/4e51909d-df1c-5f03-807b-9a33e9dc56f0/scratchpad/search.py "query" -n 8`
  (Google News RSS: prints date | source | headline | a news.google.com link). The news.google.com link is NOT a valid
  source URL — use the headline to find the real article URL (WebSearch the exact headline, or WebFetch the outlet) before citing it.
- `curl` via Bash can open many article pages that WebFetch cannot (e.g. O Globo, G1): `curl -sL -A "Mozilla/5.0" <url> | python3 -c "import sys,re,html;t=sys.stdin.read();print(html.unescape(re.sub(r'<[^>]+>',' ',t))[:6000])"`.

Be efficient: minor candidates ≈ 2–4 searches; major politicians as many as needed.

## Output

Write **one JSON file** with the Write tool to the exact path you were given, then validate it with
`python3 -c "import json,sys; json.load(open(sys.argv[1]))" <path>`.

```json
{
  "batch": "<batch id>",
  "candidates": [
    {
      "sq": "<SQ_CANDIDATO exactly as given — string>",
      "name": "<ballot name>",
      "summary_pt": "1–3 frases neutras resumindo os principais pontos negativos (ou que nada foi encontrado).",
      "items": [
        {
          "title": "Headline as published",
          "url": "https://...",
          "source": "G1",
          "date": "YYYY-MM-DD (or YYYY-MM / YYYY if day unknown)",
          "category": "<one of the categories below>",
          "status": "<one of the statuses below>",
          "summary_pt": "1–2 frases neutras: o que é alegado, por quem, e situação atual."
        }
      ],
      "notes": "optional: homonym caveats, things you could not confirm"
    }
  ]
}
```

`category` (pick the best fit):
`corrupcao` (corrupção, desvio, propina, lavagem ligada a cargo público) ·
`improbidade` (improbidade administrativa, ações civis) ·
`eleitoral` (abuso de poder, compra de votos, caixa 2, propaganda irregular, uso da máquina) ·
`ficha-limpa` (inelegibilidade, impugnação/indeferimento de registro) ·
`crime-organizado` (milícia, tráfico, jogo do bicho, facções) ·
`criminal` (outros crimes: estelionato, fraude, homicídio, etc.) ·
`violencia` (violência doméstica, agressão, ameaça) ·
`assedio` (assédio sexual/moral) ·
`desinformacao` (fake news, ataques às urnas / 8 de janeiro / golpismo) ·
`discriminacao` (racismo, homofobia, misoginia, discurso de ódio, intolerância religiosa) ·
`rachadinha` (rachadinha, funcionários fantasmas, nepotismo) ·
`gestao` (contas rejeitadas, TCE/TCU, má gestão, obras/contratos irregulares) ·
`patrimonio` (patrimônio incompatível, dívidas, sonegação, bens não declarados) ·
`polemica` (declarações/condutas polêmicas sem processo) ·
`familia` (caso envolvendo parente — ver seção acima; exige `relation` e `relative`) ·
`outros`

`status`:
`investigacao` (investigado / inquérito / operação) ·
`denuncia` (denunciado / acusado formalmente / ação proposta) ·
`reu` (réu em ação penal ou de improbidade) ·
`condenado-recorre` (condenado, ainda cabe recurso) ·
`condenado` (condenação definitiva / trânsito em julgado) ·
`absolvido` · `arquivado` · `anulado` (condenação/processo anulado) ·
`cassado` (mandato/registro/diploma cassado) ·
`inelegivel` (declarado inelegível) ·
`registro-indeferido` (registro de candidatura negado pelo TRE/TSE, ainda que caiba recurso) ·
`multa` (multado por tribunal/órgão) ·
`polemica` (sem processo; conduta ou declaração controversa) ·
`outros`

Your final reply to the orchestrator must be SHORT: the file path, how many candidates had ≥1 item, total items, and any important caveats. Do not paste the JSON.
