Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Investigative Leads Generator · DVNS

Generator di piste investigative conservative a partire dalle tabelle di relazione prodotte da investigative-explorer-dvns.

Ogni pista è un segnale quantitativo che merita verifica. Nessuna pista dimostra, suggerisce o implica illecito, spreco, frode o responsabilità individuale.

Consuma le tabelle di relazione prodotte da investigative-explorer-dvns e produce piste conservative, deterministiche e revisionabili.

Cosa fa

  • Prende le tabelle di relazione dell'Explorer e le adatta nel formato atteso dal motore (scripts/adapt_explorer.py)
  • Applica regole dichiarative estremamente caute (YAML)
  • Produce piste in JSON + Markdown con provenienza completa
  • È completamente deterministico (stesso input → stesso output)

Cosa non fa

  • Non stabilisce responsabilità, illeciti o sprechi
  • Non risolve omonimie
  • Non somma perimetri contabili diversi
  • Non usa etichette valutative

Come usarlo (guida passo-passo)

0. Prerequisiti

  • Python 3.10+ installato
  • Le tabelle di relazione dell'Explorer disponibili localmente in <EXPLORE>/data/relations/ (se non le hai, clona/aggiorna investigative-explorer-dvns e genera le relazioni con i suoi script; i file attesi sono ad es. persona_incarico_ente__incarichi_nominativi_shard.csv, awards__affidamenti_diretti.csv, cig_ente__affidamenti_diretti.csv).

1. Installazione

git clone https://github.com/superpios/investigative-leads-generator
cd investigative-leads-generator
pip install -r requirements.txt

2. Adatta le tabelle dell'Explorer → input del generatore

Lo schema dell'Explorer (subject_key, object_key, period, …) è diverso da quello che il motore si aspetta: adapt_explorer.py rinomina i campi in modo esplicito e revisionabile.

python scripts/adapt_explorer.py \
    --relations "<EXPLORE>/data/relations" \
    --output  data/input

Questo scrive in data/input/ tre CSV normalizzati: incarichi.csv, affidamenti_diretti.csv, cig_enti.csv.

3. Genera le piste

python scripts/apply_rules.py \
    --input  data/input \
    --output data/leads \
    --rules  rules/rules_v0.1.yaml

Oppure, equivalente, tramite il wrapper:

python scripts/generate_leads.py

4. Cosa ottieni

In data/leads/:

  • leads_v0.1.json — tutte le piste (una lista di oggetti)
  • LEAD-<REGOLA>-<hash>.md — una pagina Markdown per pista

Ogni pista contiene sempre tutti i campi di docs/FORMATO_PISTA.md (id, title, observed_facts, sources, period, rule_id, why_worth_checking, what_cannot_be_claimed, data_through, snapshot_created_at, explorer_sha, disclaimer). Esempio di title: "Nominativo presente in 5 incarichi su enti diversi – anno 2025".

5. Opzioni

  • Non ci sono flag di data: data_through, snapshot_created_at ed explorer_sha sono derivati deterministicamente dai dati (mai l'orario di esecuzione).
  • Su dati reali dell'Explorer l'esecuzione produce poche piste (es. 7 nell'ultimo test: 3 REGOLA-002, 0 REGOLA-001, 0 REGOLA-003); è voluto: le regole sono conservative.
  • Ogni esecuzione scrive data/leads/manifest.json: input attesi, hash, righe, righe usate/scartate, stato e motivo degli scarti. Input obbligatori mancanti/illeggibili → la pipeline fallisce (exit 1).

Comportamento importante

  • Deterministico: stesso input → stesso output. data_through/snapshot_created_at/explorer_sha derivano dai dati, non da datetime.now().
  • Fail-closed sul contenuto, fail-loud sugli input: un input rotto (file obbligatorio mancante, illeggibile o con colonne mancanti) fa fallire la pipeline e scrive manifest.json con stato failed (exit 1) — così è distinguibile da un vero risultato pari a zero. Con input validi, soglie non superate → zero piste, nessun errore. Nessun dato lascia mai la macchina.

Mappatura Explorer → generatore

Tabella Explorer → colonne generatore
persona_incarico_ente__* person_name=subject_key, entity_id=IPA (o object_key), year=period[:4]
awards__affidamenti_diretti awardee=subject_key, entity_id=IPA (o object_key), award_date=period, procedure_type="affidamento diretto"
cig_ente__affidamenti_diretti cig=subject_key, subject_id=IPA (o object_key)

La provenienza (source_dataset, source_record_id, source_url) è preservata in ogni pista. Dettagli e logica in scripts/adapt_explorer.py e docs/REGOLE_SEGNALAZIONE.md.

Documentazione

File Contenuto
docs/REGOLE_SEGNALAZIONE.md Regole attive + principi vincolanti
docs/FORMATO_PISTA.md Schema obbligatorio di ogni pista
docs/LIMITI.md Limiti metodologici e interpretativi
templates/lead_template.md Template illustrativo (il motore scrive il Markdown inline)

Licenza

GNU Affero General Public License v3.0

Roadmap

  • REGOLA-004 (percentuale di affidamenti diretti su un singolo ente): definita ma non attiva. L'attivazione è prevista solo dopo la calibrazione della soglia sui dati reali e la validazione manuale di almeno 20 piste generate.
  • Ogni nuova regola viene abilitata esclusivamente dopo: aggiornamento di docs/REGOLE_SEGNALAZIONE.md, test quantitativi contro i falsi positivi e validazione manuale di almeno 20 piste.

About

Generatore di piste investigative conservative: regole dichiarative, deterministiche e fail-closed che consumano le tabelle di relazione di investigative-explorer-dvns

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages