Findings layer: contenitori tipizzati e audit della risposta per /correlation #3
No reviewers
Labels
No labels
Doing
P1: critical
P2: important
P3: useful
P4: nice to have
P5: reminder
To Do
bug
invalid
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
peacelink/mcp-peacedata!3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "findings-layer"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Findings layer — contenitori tipizzati e audit della risposta
Proposta, non un cambio di comportamento: additiva, stdlib pura, niente si
attiva da solo. Serve a chiudere il secondo fallimento, dopo quello aritmetico.
Il problema
La MR precedente ha tolto al modello l'ARITMETICA: il coefficiente lo calcola
il motore, il modello lo cita. Resta però l'INQUADRAMENTO. Con numeri veri, il
modello decide comunque cosa mettere in apertura, cosa seppellire e cosa
significhi un coefficiente — e decide male, perché giudicare l'ordine di
grandezza è esattamente ciò in cui i modelli sono peggiori, mentre scegliere e
ordinare fra alternative date è ciò in cui sono bravi.
Scrivere le frasi in Python non è la soluzione: la prosa preconfezionata è
per-caso, cresce senza limite e soprattutto non può sapere cosa è stato
CHIESTO. La rilevanza non è una proprietà del risultato, è una relazione fra
risultato e domanda.
Quindi: il motore calcola la SALIENZA (quanto è grande, quanto è preciso,
supera una soglia) — calcolabile e testabile; il modello inferisce la
RILEVANZA (quale di questi risponde a QUESTA domanda, in che ordine).
Come
Ogni verdetto diventa uno o più
Finding: ilplaindel motore, i numeri cheautorizza, la salienza (dimensioni separate, mai mescolate in un punteggio
unico), e i due campi portanti —
constraint(cosa NON può essere affermato)e
would_change(cosa cambierebbe la risposta). I contenitori viaggiano incard["findings"], il campoinstructionesistente è esteso, nulla è rimosso.audit()verifica una risposta contro i suoi contenitori, in due zone:CITATA — i
plaindei motori, testuali. Possono dire tutto, comprese lenegazioni causali: le ha scritte il motore, sono già vere.
LIBERA — la prosa del modello. Qui l'intero vocabolario di attribuzione è
rifiutato, SENZA eccezione per la negazione.
Una versione precedente provava a verificare il SIGNIFICATO con il match di
stringhe e falliva in entrambe le direzioni sui transcript reali: una negazione
contiene le parole di ciò che nega («non è evidenza di una sorgente comune»
veniva segnalata), mentre una parafrasi passava indisturbata («la cokeria è
all'origine di entrambi»). Nessuna lista di frasi risolve. Si fa quindi con il
linguaggio causale ciò che i motori hanno fatto con l'aritmetica: si toglie la
possibilità invece di controllare il risultato.
Conseguenza voluta: a volte il controllo vieta una frase vera. È la direzione
giusta in cui sbagliare — un verificatore che fallisce verso il silenzio è
difendibile, uno che fallisce verso l'affermazione è inutile.
Cosa è verificato, e cosa no
Verificato (21 invarianti offline, examples/findings_test.py):
«Pearson r ≈ 0,72 … indica una sorgente comune» viene ora intercettato su
entrambi gli assi, senza che nessuno legga;
sources=), altrimentiil controllo segnalerebbe ogni cifra vera citata da E-PRTR;
meglio rumorosi che silenziosi. In produzione l'errore finisce in
findings_errornel payload, mai in un tool rotto per il lettore;noveltyresta None ovunque: richiede una linea di base storica, einventare un punteggio sarebbe esattamente il peccato che questo modulo
esiste per impedire.
NON verificato: che i contenitori migliorino davvero l'inquadramento. Nessun
modello è ancora stato eseguito contro questo payload. È un'ipotesi, e va
misurata prima di essere creduta.
Proposta: shadow mode
audit()non può girare qui: il server MCP passa i dati AL modello e non vedemai la prosa che torna. Il punto di innesto è l'assistant, dopo la generazione.
Primo passo suggerito, rischio zero: chiamare
audit(), scrivereaudit_log_line()nel log, non cambiare nulla di ciò che il lettore vede. Ilbackend è pensato per la redazione, quindi un umano è già nel ciclo. Dopo
qualche decina di domande reali il log dice il tasso di segnalazione e quale
asse scatta — e la decisione se applicarlo (rigenerare / bloccare / segnalare
in redazione) si prende su dati invece che su fiducia.
Cosa NON c'è in questa MR
Il collegamento di
audit()nell'assistant. È una scelta tua e sta in un altrorepo: qui c'è la libreria pronta e i contenitori nel payload.
File
findings.py nuovo, radice, accanto ai motori. stdlib pura.
domains/correlation.py import, helper _attach_findings, due chiamate,
_QUOTE_RULE esteso (nulla rimosso)
examples/findings_test.py nuovo, 21 invarianti, offline
CLAUDE.md / README.md una riga ciascuno
examples/correlation_endpoints_test.py continua a passare tutte le invarianti,
live comprese.