docs(evidence): finalize ticketed restructuring specification
This commit is contained in:
@@ -111,7 +111,7 @@ una parte specializzata determinata da `kind`.
|
||||
|
||||
```yaml
|
||||
schema_version: 1
|
||||
id: formula:fascia-pediatrica
|
||||
id: evidence:fascia-pediatrica
|
||||
title: Fascia pediatrica
|
||||
kind: formula
|
||||
purposes:
|
||||
@@ -128,6 +128,8 @@ language: it
|
||||
provenance:
|
||||
source_file: source/10-domini-clinici/paziente.md
|
||||
source_sha256: sha256:0123456789abcdef...
|
||||
supporting_excerpts:
|
||||
- Per fascia pediatrica si intendono i pazienti con età inferiore a 18 anni.
|
||||
review_items: []
|
||||
```
|
||||
|
||||
@@ -139,6 +141,23 @@ I campi hanno ruoli diversi:
|
||||
- `provenance` permette di risalire al testo di origine;
|
||||
- `review_items` rende visibili i dubbi ancora da risolvere.
|
||||
|
||||
Ogni unità contiene da uno a cinque `supporting_excerpts`, ciascuno lungo al massimo
|
||||
1.000 caratteri. Sono citazioni brevi che il validatore deve ritrovare nel sorgente dopo
|
||||
la stessa normalizzazione meccanica. Provano la tracciabilità, non la correttezza
|
||||
semantica: il revisore umano deve comunque verificare che sostengano davvero il
|
||||
contenuto ristrutturato.
|
||||
|
||||
Ogni `review_item` contiene soltanto:
|
||||
|
||||
```yaml
|
||||
code: ambiguous_source_statement
|
||||
message: Il sorgente non chiarisce se l'età sia calcolata alla data di ricovero.
|
||||
field: formula.sql # opzionale
|
||||
```
|
||||
|
||||
Non possiede stato, autore o timestamp. Tutti i review item bloccano la pubblicazione;
|
||||
il curatore corregge il documento e rimuove l'item, mentre Git conserva la storia.
|
||||
|
||||
### 4.2 Tipi iniziali
|
||||
|
||||
| `kind` | Contenuto | Esempio d'uso |
|
||||
@@ -155,6 +174,28 @@ I campi hanno ruoli diversi:
|
||||
Un URL che documenta un'altra Evidence appartiene alla sua `provenance`. Un URL che
|
||||
deve essere recuperato come risposta autonoma è invece una Evidence `reference`.
|
||||
|
||||
Ogni Evidence Unit possiede un solo `kind`, scelto in base ai campi strutturati che ne
|
||||
definiscono il contenuto principale. `purposes` e `applies_to` possono invece avere più
|
||||
valori. Quando parti dello stesso sorgente hanno identità e regole di validazione
|
||||
indipendenti, vengono prodotte unità distinte; non si duplica un'unità soltanto perché è
|
||||
utile in più fasi del workflow.
|
||||
|
||||
La classificazione procede dai contenuti più strutturati a quelli più generali:
|
||||
`formula`, `enum`, `mapping`, `normalization`, `glossary`, `domain`, `example` e
|
||||
`reference`. `domain` è il tipo di ripiego per una regola del dominio che non soddisfa
|
||||
uno schema più specifico; `reference` si applica soltanto quando il collegamento deve
|
||||
essere restituito come contenuto autonomo.
|
||||
|
||||
L'identificatore non incorpora il `kind`: una riclassificazione conserva l'ID, mentre
|
||||
una vera divisione semantica assegna nuovi ID alle nuove unità. Un rinominamento
|
||||
univocamente riconoscibile del Source Evidence tramite hash aggiorna la provenienza e
|
||||
conserva gli ID esistenti.
|
||||
|
||||
Un nuovo identificatore usa la forma leggibile `evidence:<slug>`, viene assegnato una
|
||||
sola volta e non viene ricalcolato da titolo, percorso o hash. Le collisioni ricevono un
|
||||
suffisso deterministico. Dopo la prima pubblicazione cambiare ID equivale a ritirare
|
||||
l'unità esistente e crearne una nuova.
|
||||
|
||||
### 4.3 Dati specifici per tipo
|
||||
|
||||
La parte specializzata è una unione discriminata: ogni `kind` ammette e richiede campi
|
||||
@@ -189,7 +230,9 @@ enum:
|
||||
|
||||
I tipi restano quindi sfruttabili sia in validazione sia in ricerca. Una formula non è
|
||||
un semplice testo etichettato: possiede obbligatoriamente un concetto, le colonne di
|
||||
input e SQL valido come contenuto strutturato.
|
||||
input e una singola espressione PostgreSQL componibile. `SELECT`, `WITH`, DDL e DML come
|
||||
statement completi non sono Formula Evidence; una query completa documentata appartiene
|
||||
a `example`. Le formule legacy incompatibili diventano review item durante la migrazione.
|
||||
|
||||
## 5. Pre-processing dei testi sorgente
|
||||
|
||||
@@ -213,6 +256,11 @@ Il sistema:
|
||||
|
||||
Un sorgente invariato non viene nuovamente elaborato.
|
||||
|
||||
Se la `pipeline_version` del manifest non è compatibile con quella installata, il
|
||||
normale `prepare` termina senza scrivere. Il curatore può scegliere esplicitamente
|
||||
`prepare --upgrade`, esclusivamente su un repository pulito, per rielaborare tutti i
|
||||
sorgenti e revisionare il diff completo.
|
||||
|
||||
### 5.2 Normalizzazione deterministica
|
||||
|
||||
Prima del modello vengono normalizzati soltanto aspetti meccanici:
|
||||
@@ -235,6 +283,11 @@ Per ogni sorgente cambiato il modello riceve:
|
||||
- le precedenti Evidence curate derivate da quel sorgente;
|
||||
- gli identificatori già assegnati.
|
||||
|
||||
Per un'unità già esistente il modello può restituire soltanto uno degli identificatori
|
||||
ricevuti. Per una nuova unità non propone l'ID: il preparatore assegna una sola volta
|
||||
`evidence:<slug>` e l'eventuale suffisso deterministico. Un identificatore sconosciuto
|
||||
prodotto dal modello rende la risposta non valida.
|
||||
|
||||
Può:
|
||||
|
||||
- assegnare titoli;
|
||||
@@ -242,6 +295,7 @@ Può:
|
||||
- separare un sorgente in più Evidence Unit;
|
||||
- riordinare e riscrivere per chiarezza;
|
||||
- compilare campi strutturati con fatti presenti nel sorgente.
|
||||
- citare da uno a cinque brevi estratti del sorgente che sostengono ciascuna unità.
|
||||
|
||||
Non può:
|
||||
|
||||
@@ -250,8 +304,19 @@ Non può:
|
||||
- risolvere silenziosamente un'ambiguità;
|
||||
- cancellare un'unità precedentemente revisionata.
|
||||
|
||||
Se il sorgente esiste ancora ma non sostiene più un'unità precedente, il modello la
|
||||
restituisce come retirement candidate con il `review_item`
|
||||
`source_no_longer_supports_unit`. Il curatore decide se eliminarla o riscriverla; fino a
|
||||
quel momento la pubblicazione resta bloccata.
|
||||
|
||||
Quando una precedente unità viene realmente divisa in più unità autonome, le nuove
|
||||
unità ricevono nuovi ID e la precedente rimane una retirement candidate finché il
|
||||
curatore non la ritira esplicitamente.
|
||||
|
||||
Pi viene usato in modalità non interattiva e senza strumenti di scrittura. È un
|
||||
dettaglio interno del comando, non una nuova tipologia di sessione ThothII.
|
||||
Timeout, uscita non valida o JSON malformato interrompono il comando con un errore
|
||||
attribuito al sorgente. La prima versione non esegue retry automatici.
|
||||
|
||||
### 5.4 Validazione deterministica
|
||||
|
||||
@@ -261,6 +326,7 @@ L'output del modello non viene scritto direttamente. Viene prima controllato:
|
||||
- unicità e stabilità degli identificatori;
|
||||
- appartenenza alle enumerazioni ammesse;
|
||||
- esistenza e hash del sorgente;
|
||||
- presenza nel sorgente normalizzato di ogni `supporting_excerpt`;
|
||||
- correttezza sintattica di URL, tabelle, colonne e SQL dove applicabile;
|
||||
- assenza di credenziali;
|
||||
- coerenza tra directory e `kind`;
|
||||
@@ -277,31 +343,60 @@ Esistono tre esiti.
|
||||
Un dubbio reale può essere mantenuto soltanto se il revisore lo trasforma in una
|
||||
limitazione esplicita del contenuto e svuota `review_items`.
|
||||
|
||||
## 6. Aggiornamenti incrementali e protezione delle correzioni umane
|
||||
### 5.5 Applicazione atomica
|
||||
|
||||
La precedente versione curata è un input, non un file usa-e-getta. In questo modo il
|
||||
modello può proporre una modifica minima senza ricominciare da zero.
|
||||
Tutti gli output dei sorgenti cambiati vengono costruiti e validati in un'area
|
||||
temporanea. Soltanto quando l'intero batch è valido, il comando sostituisce insieme i
|
||||
documenti interessati e `manifest.yaml`. Un singolo errore lascia il worktree invariato
|
||||
e il rapporto limitato elenca tutti i problemi rilevati. Non esiste successo parziale.
|
||||
|
||||
## 6. Aggiornamenti incrementali e revisione delle correzioni umane
|
||||
|
||||
La precedente versione curata è un input, non un file usa-e-getta. Il modello deve
|
||||
proporre una modifica minima senza ricominciare da zero, ma questa istruzione non viene
|
||||
presentata come una garanzia semantica. La garanzia è Git: la versione precedente resta
|
||||
recuperabile, ogni variazione è visibile nel diff e nessuna proposta diventa Published
|
||||
Evidence senza una nuova revisione umana.
|
||||
|
||||
Il comando:
|
||||
|
||||
- si rifiuta di operare se `evidence/curated/` o `evidence/manifest.yaml` contengono
|
||||
modifiche Git non salvate;
|
||||
- mantiene gli ID associati a contenuti che rappresentano ancora la stessa unità;
|
||||
- riconosce come rinominato un sorgente nuovo che corrisponde univocamente all'hash di
|
||||
un sorgente rimosso e ne aggiorna la provenienza senza cambiare gli ID;
|
||||
- mostra come diff le variazioni proposte;
|
||||
- non modifica i file derivati da sorgenti invariati;
|
||||
- segnala come orfana un'unità il cui sorgente è stato rimosso;
|
||||
- non elimina mai automaticamente un'unità orfana.
|
||||
- non elimina mai automaticamente un'unità orfana;
|
||||
- blocca la pubblicazione finché ogni unità orfana non viene eliminata, ricollegata o
|
||||
ricondotta a un sorgente ripristinato.
|
||||
|
||||
Git fornisce confronto, revisione, cronologia e recupero. Non viene introdotto un
|
||||
database di authoring parallelo.
|
||||
|
||||
Orfani e retirement candidate vengono risolti senza modificare manualmente il manifest:
|
||||
|
||||
```text
|
||||
tht evidence resolve <evidence-id> --retire
|
||||
tht evidence resolve <evidence-id> --source <source-path>
|
||||
```
|
||||
|
||||
Le due azioni sono mutuamente esclusive, richiedono un worktree pulito e aggiornano
|
||||
atomicamente file curato e manifest. `--retire` rimuove l'unità dal corpus di authoring;
|
||||
`--source` aggiorna provenienza e hash soltanto verso un sorgente esistente. Entrambe
|
||||
lasciano un diff Git recuperabile, senza commit o pubblicazione automatica. Se l'unità
|
||||
deve essere riscritta, il curatore modifica invece il documento e poi esegue
|
||||
`validate`.
|
||||
|
||||
## 7. Revisione e pubblicazione
|
||||
|
||||
Il flusso di pubblicazione è:
|
||||
|
||||
```text
|
||||
prepare → revisione Git → validate → merge → attivazione workspace
|
||||
→ preprocess evidence → nuova generazione Qdrant attiva
|
||||
→ preprocess evidence candidata → evaluate candidata
|
||||
→ pubblicazione atomica della generazione Qdrant
|
||||
```
|
||||
|
||||
### 7.1 Approvazione umana
|
||||
@@ -321,11 +416,17 @@ La prima versione non crea automaticamente branch, commit o pull request.
|
||||
|
||||
Una Curated Evidence diventa Published Evidence soltanto quando:
|
||||
|
||||
- appartiene a una revisione Git approvata e pulita;
|
||||
- appartiene a una revisione Git pulita che ha superato il processo umano di revisione;
|
||||
- la revisione è stata attivata dal registry di ThothII;
|
||||
- non contiene `review_items` irrisolti;
|
||||
- il manifest non contiene unità orfane;
|
||||
- l'intero corpus supera la validazione;
|
||||
- la generazione Qdrant viene pubblicata atomicamente.
|
||||
- la Candidate Evidence Generation supera il gate top-10;
|
||||
- la generazione Qdrant viene quindi pubblicata atomicamente.
|
||||
|
||||
Il runtime non tenta di ricostruire come sia avvenuta l'approvazione Git e il manifest
|
||||
non contiene un flag `approved`. Il confine verificabile di pubblicazione è la
|
||||
combinazione di revisione attiva, validazione superata e generazione Evidence attiva.
|
||||
|
||||
Il descriptor filesystem deve indicizzare solo `curated/**/*.md`. I sorgenti e i file
|
||||
di supporto restano materializzati per tracciabilità, ma non entrano nell'indice.
|
||||
@@ -337,15 +438,27 @@ L'indicizzazione continua a usare il meccanismo già implementato dal modulo Evi
|
||||
1. legge la radice materializzata della revisione Git attiva;
|
||||
2. valida nuovamente tutte le Evidence;
|
||||
3. costruisce Evidence Fragment secondo sezioni semantiche;
|
||||
4. genera le rappresentazioni dense;
|
||||
5. chiede a Qdrant di generare la rappresentazione lessicale BM25;
|
||||
6. carica i punti con la nuova `vector_generation`;
|
||||
7. verifica manifest, conteggi e leggibilità;
|
||||
8. rende attiva la nuova generazione;
|
||||
9. conserva le generazioni precedenti previste dalla policy.
|
||||
4. verifica il vettore dense predefinito già usato da Schema e Memory;
|
||||
5. aggiunge in modo non distruttivo il vettore sparse `bm25` se manca;
|
||||
6. genera le rappresentazioni dense degli Evidence Fragment;
|
||||
7. chiede a Qdrant di generare per gli stessi frammenti la rappresentazione lessicale
|
||||
BM25;
|
||||
8. carica i punti con la nuova `vector_generation`;
|
||||
9. verifica manifest, conteggi e leggibilità;
|
||||
10. rende attiva la nuova generazione;
|
||||
11. conserva le generazioni precedenti previste dalla policy.
|
||||
|
||||
Se uno dei passaggi fallisce, la generazione precedente rimane attiva. I punti caricati
|
||||
parzialmente vengono compensati secondo il meccanismo transazionale già esistente.
|
||||
L'eventuale configurazione `bm25` già aggiunta rimane: è compatibile con i punti dense
|
||||
esistenti e non richiede rollback. Se `bm25` esiste con una configurazione diversa da
|
||||
`modifier: idf`, la procedura fallisce senza modificarla.
|
||||
|
||||
L'upgrade non ricrea la collezione. I record `schema_table`, `schema_column`, `memory` e
|
||||
`solved_question` restano invariati e continuano a usare il vettore dense predefinito.
|
||||
Soltanto gli Evidence Fragment ricevono anche `bm25`. Durante la finestra fra aggiunta
|
||||
del vettore e pubblicazione della prima candidata ibrida, Evidence è `unavailable`, ma
|
||||
Schema e Memory continuano a funzionare.
|
||||
|
||||
## 9. Qdrant spiegato senza presupporre conoscenze vettoriali
|
||||
|
||||
@@ -381,6 +494,12 @@ Qdrant 1.18.2 può generare questa rappresentazione direttamente sul server usan
|
||||
`qdrant/bm25`; per il corpus italiano si passa `language: italian` sia durante il
|
||||
caricamento sia durante la ricerca. Non serve aggiungere FastEmbed o un nuovo servizio.
|
||||
|
||||
Un test L0 avvia esattamente l'immagine Qdrant dichiarata da `compose.yaml`, crea una
|
||||
collezione temporanea, indicizza due testi italiani mediante `qdrant/bm25`, verifica una
|
||||
ricerca lessicale e infine elimina la collezione. Questo rende controllabile la capacità
|
||||
locale richiesta prima di qualunque migrazione reale. Se la prova fallisce non esiste
|
||||
un fallback silenzioso a un motore diverso.
|
||||
|
||||
Il nome “sparse” significa soltanto che, tra moltissime parole possibili, ogni testo ne
|
||||
usa poche. Qdrant mantiene anche l'IDF: una parola rara pesa più di una parola presente
|
||||
quasi ovunque.
|
||||
@@ -433,14 +552,32 @@ fragment_ordinal
|
||||
|
||||
I metadati hanno due usi:
|
||||
|
||||
- workspace, revisione e generazione sono filtri obbligatori di sicurezza;
|
||||
- tipo, scopo e ambito orientano la ricerca oppure diventano filtri quando il chiamante
|
||||
formula una richiesta esplicita.
|
||||
- workspace, revisione, generazione e purpose sono filtri obbligatori;
|
||||
- tipo, concetti, tabelle e colonne diventano filtri soltanto quando il chiamante li
|
||||
dichiara vincolanti; altrimenti contribuiscono al testo della query e alla spiegazione
|
||||
del risultato.
|
||||
|
||||
Durante la generazione SQL, per esempio, `formula` e `mapping` ricevono priorità, ma una
|
||||
regola `domain` molto pertinente può ancora apparire. Se il workflow chiede
|
||||
esplicitamente soltanto formule, `evidence_kind=formula` diventa invece un filtro
|
||||
vincolante.
|
||||
La prima versione non aggiunge bonus automatici per `kind` o `applies_to`. Durante la
|
||||
generazione SQL una Formula Evidence viene imposta soltanto quando il workflow richiede
|
||||
esplicitamente `kind=formula`; negli altri casi dense, BM25 e RRF determinano l'ordine.
|
||||
|
||||
Quando concetti, tabelle o colonne non sono vincoli, il modulo costruisce un solo testo
|
||||
deterministico, identico per dense e BM25:
|
||||
|
||||
```text
|
||||
Domanda: <domanda originale>
|
||||
Concetti: <valori deduplicati e ordinati>
|
||||
Tabelle: <valori deduplicati e ordinati>
|
||||
Colonne: <valori deduplicati e ordinati>
|
||||
```
|
||||
|
||||
Le righe vuote sono omesse. La domanda conserva formulazione e ordine originali; il
|
||||
renderer applica soltanto Unicode NFC, converte CRLF e CR in `\n`, rimuove gli spazi
|
||||
esterni e rifiuta una domanda vuota. Non cambia maiuscole, punteggiatura o spazi interni.
|
||||
Ai valori contestuali applica NFC e `strip`, elimina stringhe vuote e duplicati esatti e
|
||||
li ordina per valore Unicode senza `lower()` o `casefold()`: gli identificatori
|
||||
PostgreSQL quotati possono essere sensibili alle maiuscole. In questo modo due richieste
|
||||
equivalenti non cambiano per effetto dell'ordine occasionale dei metadati.
|
||||
|
||||
### 9.7 Perché non creare una collezione per tipo
|
||||
|
||||
@@ -448,9 +585,10 @@ Una domanda spesso attraversa più tipi: una formula può dipendere da un mappin
|
||||
enum e da una regola di dominio. Collezioni separate richiederebbero più interrogazioni,
|
||||
fusione applicativa e più operazioni di manutenzione.
|
||||
|
||||
La soluzione usa la collezione semantica già posseduta dal workspace e aggiunge vettori
|
||||
denominati `dense` e `bm25`. I payload indicizzati distinguono i tipi. È più semplice e
|
||||
permette a Qdrant di eseguire ricerca ibrida e filtri nella stessa Query API.
|
||||
La soluzione usa la collezione semantica già posseduta dal workspace, conserva il suo
|
||||
vettore dense predefinito e aggiunge soltanto il vettore sparse denominato `bm25`. I
|
||||
payload indicizzati distinguono i tipi. È più semplice, evita di ricostruire Schema e
|
||||
Memory e permette a Qdrant di eseguire ricerca ibrida e filtri nella stessa Query API.
|
||||
|
||||
### 9.8 Perché indicizzare frammenti ma restituire unità
|
||||
|
||||
@@ -458,9 +596,18 @@ Un documento lungo può contenere sezioni diverse. Un unico vettore ne diluirebb
|
||||
significato; frammenti arbitrari di lunghezza fissa spezzerebbero invece formule o
|
||||
regole.
|
||||
|
||||
La divisione segue intestazioni e campi tipizzati. Qdrant trova i frammenti, poi
|
||||
l'Evidence Module li raggruppa per `evidence_id` e restituisce l'unità completa con
|
||||
provenienza e citazione.
|
||||
La divisione segue intestazioni, campi tipizzati e confini di paragrafo. Non divide mai
|
||||
una formula, una coppia valore/significato, un mapping, una regola o un URL. Se uno di
|
||||
questi elementi atomici supera da solo `max_chunk_chars`, la preparazione aggiunge il
|
||||
Review item stabile `atomic_content_too_large` e blocca la pubblicazione: non usa un
|
||||
taglio a dimensione fissa che ne altererebbe il significato. Il limite è quello già
|
||||
presente nella configurazione degli embeddings, pari per default a 4.000 caratteri, e
|
||||
si applica all'intero testo reso che sarà inviato all'embedder, incluse etichette e
|
||||
metadati testuali. Non viene introdotta una seconda impostazione. Qdrant trova i
|
||||
frammenti, poi l'Evidence Module li raggruppa per `evidence_id` e restituisce un solo
|
||||
Evidence Result con i migliori estratti, provenienza, citazione e riferimento al
|
||||
documento completo. Il contenuto completo viene risolto soltanto quando il workflow ne
|
||||
ha bisogno.
|
||||
|
||||
### 9.9 Cosa non introduciamo nella prima versione
|
||||
|
||||
@@ -478,6 +625,7 @@ Riferimenti tecnici ufficiali:
|
||||
- [Qdrant: Text Search](https://qdrant.tech/documentation/search/text-search/)
|
||||
- [Qdrant: server-side BM25](https://qdrant.tech/documentation/inference/inference-bm25/)
|
||||
- [Qdrant: Hybrid Queries e RRF](https://qdrant.tech/documentation/search/hybrid-queries/)
|
||||
- [Qdrant: aggiornamento dello schema dei vettori](https://qdrant.tech/documentation/manage-data/collections/#update-vector-schema)
|
||||
- [Qdrant: payload indexing](https://qdrant.tech/documentation/manage-data/indexing/)
|
||||
- [Qdrant: multitenancy](https://qdrant.tech/documentation/manage-data/multitenancy/)
|
||||
|
||||
@@ -490,19 +638,32 @@ search(
|
||||
query: str,
|
||||
purpose: EvidencePurpose,
|
||||
context: EvidenceSearchContext,
|
||||
) -> list[EvidenceResult]
|
||||
) -> EvidenceSearchOutcome
|
||||
```
|
||||
|
||||
`EvidenceSearchContext` può specificare tabelle, colonne, concetti e, solo quando
|
||||
necessario, tipi obbligatori.
|
||||
`EvidenceSearchContext` può specificare tabelle, colonne e concetti da aggiungere alla
|
||||
query, oltre a vincoli espliciti su tipo, tabelle, colonne o concetti.
|
||||
|
||||
Il modulo rende domanda e contesto una sola volta nel formato `Domanda`, `Concetti`,
|
||||
`Tabelle`, `Colonne` definito sopra e passa esattamente quel testo sia all'embedder dense
|
||||
sia a `qdrant/bm25`.
|
||||
|
||||
`EvidenceSearchOutcome` distingue due stati:
|
||||
|
||||
- `available`, con la generazione interrogata e zero o più `EvidenceResult`;
|
||||
- `unavailable`, senza risultati e con un codice di errore stabile e un messaggio
|
||||
limitato.
|
||||
|
||||
Una lista vuota nello stato `available` significa che la ricerca ha funzionato ma non
|
||||
ha trovato corrispondenze. Non equivale a un errore tecnico.
|
||||
|
||||
Il modulo Evidence possiede interamente:
|
||||
|
||||
- generazione della query dense;
|
||||
- query BM25 con lingua coerente;
|
||||
- filtri su revisione e generazione;
|
||||
- filtri su workspace, revisione, generazione e purpose;
|
||||
- RRF;
|
||||
- preferenze per `kind`, `purpose` e `applies_to`;
|
||||
- vincoli espliciti su `kind` e `applies_to`;
|
||||
- raggruppamento dei frammenti;
|
||||
- risoluzione di provenienza e citazioni;
|
||||
- controllo della revisione attiva.
|
||||
@@ -527,7 +688,33 @@ Questa superficie è usata dal curatore e non dalle sessioni.
|
||||
search → resolve citation → project into session
|
||||
```
|
||||
|
||||
F1, F3 e F4 passano `purpose` e contesto al modulo. Non conoscono collezioni, nomi di
|
||||
Evidence è un contributore degli stage esistenti, non uno stage aggiuntivo. Non emette
|
||||
decisioni, non scrive gli artifact canonici e non modifica il ledger o lo stato del
|
||||
workflow. Lo stage chiamante decide come usare i candidati restituiti.
|
||||
|
||||
L'integrazione usa l'identità semantica dello stage, non il display code:
|
||||
|
||||
| Stage semantico | Display code attuale | Evidence purpose |
|
||||
|---|---:|---|
|
||||
| `clarification` | F1 | `disambiguation` |
|
||||
| `rewriting` | F3 | `rewriting` |
|
||||
| `schema_linking` | F4 | `schema_linking` |
|
||||
| `cte` | F6 | `sql_generation` |
|
||||
| `final_sql` | F7 | `sql_generation` |
|
||||
|
||||
Lo stage `memory` (F2) usa il Memory Module. Lo stage `synthesis` (F5) verifica e
|
||||
riassume lo schema linking già approvato e non avvia una nuova ricerca Evidence.
|
||||
|
||||
Ogni stage elencato esegue una ricerca indipendente con gli input disponibili in quel
|
||||
momento. In particolare `cte` usa domanda riscritta e schema approvato, mentre
|
||||
`final_sql` aggiunge il piano CTE approvato. La prima versione non introduce una cache
|
||||
condivisa fra stage.
|
||||
|
||||
Il chiamante conserva nella sessione una Evidence receipt con stage, purpose,
|
||||
generazione e ID restituiti. Il testo non viene copiato: rimane nel repository del
|
||||
workspace e viene risolto attraverso la provenienza della Published Evidence.
|
||||
|
||||
Gli stage passano `purpose` e contesto al modulo, ma non conoscono collezioni, nomi di
|
||||
vettori, generazioni o sintassi Qdrant.
|
||||
|
||||
Le istruzioni Pi relative alla consultazione delle Evidence vengono spostate in
|
||||
@@ -559,48 +746,73 @@ globale nel workspace.
|
||||
|
||||
- un file non UTF-8, troppo grande o strutturalmente invalido produce un errore chiaro;
|
||||
- un dubbio semantico produce un `review_item`;
|
||||
- un albero Git sporco impedisce la sovrascrittura delle modifiche umane;
|
||||
- un sorgente rimosso produce un'unità orfana, non una cancellazione.
|
||||
- un albero Git sporco impedisce la scrittura di nuove proposte;
|
||||
- un sorgente rimosso produce un'unità orfana, non una cancellazione, e blocca la
|
||||
pubblicazione finché il curatore non la risolve.
|
||||
|
||||
### 13.2 Durante l'indicizzazione
|
||||
|
||||
- la nuova generazione viene preparata senza toccare quella attiva;
|
||||
- la generazione candidata viene interrogata esplicitamente per la valutazione senza
|
||||
renderla visibile alle sessioni;
|
||||
- una valutazione fallita lascia inattiva la candidata;
|
||||
- un caricamento o una verifica falliti non cambiano il puntatore attivo;
|
||||
- i dati parziali vengono rimossi quando possibile e comunque non sono leggibili dal
|
||||
runtime perché manca l'attivazione.
|
||||
|
||||
Poiché la revisione del workspace viene attivata prima di costruire la candidata, il
|
||||
runtime può attraversare una finestra di manutenzione in cui la vecchia generazione non
|
||||
corrisponde alla revisione. In questa finestra la ricerca Evidence è `unavailable` e
|
||||
blocca lo stage chiamante. La prima versione accetta questa degradazione fail-closed
|
||||
invece di introdurre una transazione distribuita fra Git, registry e Qdrant. Se il gate
|
||||
fallisce, l'operatore corregge il corpus oppure ripristina esplicitamente la revisione
|
||||
precedente.
|
||||
|
||||
### 13.3 Durante una sessione
|
||||
|
||||
Una ricerca `available` senza corrispondenze produce una Evidence receipt vuota, viene
|
||||
mostrata come tale e non impedisce allo stage di continuare.
|
||||
|
||||
Se Qdrant, il corpus attivo o la revisione attesa non sono disponibili:
|
||||
|
||||
- il risultato Evidence è vuoto;
|
||||
- viene emesso un avviso esplicito;
|
||||
- l'outcome è `unavailable`, non una lista vuota valida;
|
||||
- viene restituito un codice stabile con un messaggio limitato;
|
||||
- lo stage chiamante resta bloccato e può essere ritentato;
|
||||
- non vengono usate revisioni precedenti;
|
||||
- la sessione può continuare con gli altri meccanismi e con i normali gate umani.
|
||||
- non viene ripetuta la ricerca con un purpose diverso.
|
||||
|
||||
Questo è il comportamento fail-closed già presente e viene preservato.
|
||||
Questo comportamento è fail-closed: un'assenza reale di corrispondenze non ferma il
|
||||
workflow, mentre un guasto non viene mascherato come assenza di conoscenza.
|
||||
|
||||
## 14. Valutazione minima
|
||||
|
||||
`tht evidence evaluate` esegue le domande in `evaluation.yaml` contro l'indice attivo e
|
||||
riporta almeno:
|
||||
`tht evidence evaluate` esegue le domande in `evaluation.yaml` contro una generazione
|
||||
indicata esplicitamente oppure, per il monitoraggio ordinario, contro l'indice attivo.
|
||||
Riporta almeno:
|
||||
|
||||
- quante domande hanno trovato una Evidence attesa nei primi 5 e nei primi 10 risultati;
|
||||
- quali tipi attesi sono mancati;
|
||||
- quali query non hanno prodotto risultati;
|
||||
- per ogni Evidence attesa, la posizione nella graduatoria dense, BM25 e fused;
|
||||
- revisione Git, generazione e configurazione di ricerca usate.
|
||||
|
||||
La prima baseline deve essere salvata prima di regolare pesi o introdurre altri modelli.
|
||||
Il comando non modifica l'indice.
|
||||
Il file classifica ogni domanda come `lexical`, `semantic` o `mixed` e contiene almeno
|
||||
un caso per profilo. L'evaluator esegue i due rami anche separatamente per renderli
|
||||
diagnosticabili, oltre alla ricerca ibrida usata dal runtime. La prima baseline deve
|
||||
essere salvata prima di regolare pesi o introdurre altri modelli. Il comando non
|
||||
modifica l'indice. La valutazione supera il gate minimo soltanto quando ogni query trova
|
||||
almeno una delle Evidence attese nei primi dieci risultati fused. Le posizioni dei
|
||||
singoli rami e `hit@5` restano informative e non bloccano la pubblicazione.
|
||||
|
||||
## 15. Comandi e responsabilità
|
||||
|
||||
| Comando | Dove opera | Scrive |
|
||||
| --- | --- | --- |
|
||||
| `tht evidence prepare <workspace-root>` | clone Git di authoring | `curated/`, `manifest.yaml` |
|
||||
| `tht evidence prepare <workspace-root> [--upgrade]` | clone Git di authoring | `curated/`, `manifest.yaml` |
|
||||
| `tht evidence validate <workspace-root>` | clone Git o CI | nulla |
|
||||
| `tht evidence evaluate ...` | indice attivo | solo rapporto su stdout/JSON |
|
||||
| `tht ... workspace preprocess evidence` | installazione/runtime | nuova generazione corpus e Qdrant |
|
||||
| `tht evidence resolve <id> (--retire | --source <path>)` | clone Git di authoring | unità interessata, `manifest.yaml` |
|
||||
| `tht evidence evaluate ... [--generation <id>]` | generazione candidata o attiva | solo rapporto su stdout/JSON |
|
||||
| `tht ... workspace preprocess evidence` | installazione/runtime | generazione candidata, poi attiva soltanto dopo il gate |
|
||||
|
||||
`prepare` non crea commit. `preprocess evidence` non modifica il repository Git.
|
||||
|
||||
@@ -615,10 +827,15 @@ enum, esempi NLQ, mapping e normalizzazione. La migrazione avviene così:
|
||||
4. importare eventuali formule approvate come `kind: formula`;
|
||||
5. compilare circa venti query in `evaluation.yaml`;
|
||||
6. configurare il descriptor con `patterns: ["curated/**/*.md"]`;
|
||||
7. validare, fare merge e attivare la revisione;
|
||||
8. ricostruire in modo controllato la collezione per il nuovo contratto dense+BM25;
|
||||
9. eseguire `preprocess evidence`;
|
||||
10. salvare la baseline di valutazione e svolgere una verifica umana F1/F3/F4.
|
||||
7. validare, fare merge e attivare la revisione in una finestra di manutenzione;
|
||||
8. registrare conteggi e ID campione di Schema e Memory;
|
||||
9. eseguire `preprocess evidence`, che aggiunge `bm25` senza ricreare la collezione e
|
||||
costruisce la generazione candidata;
|
||||
10. verificare che conteggi, ID campione e ricerche dense di Schema e Memory siano
|
||||
invariati;
|
||||
11. valutare la candidata e pubblicarla soltanto se supera il gate top-10;
|
||||
12. salvare la baseline e svolgere una verifica umana degli stage `clarification`,
|
||||
`rewriting`, `schema_linking`, `cte` e `final_sql`.
|
||||
|
||||
Non serve mantenere v1 e v2 attivi contemporaneamente nel runtime: Git conserva la
|
||||
vecchia revisione e il meccanismo delle generazioni conserva il rollback dell'indice.
|
||||
@@ -630,19 +847,52 @@ La prima versione è completa quando:
|
||||
1. un sorgente poco strutturato produce una o più unità tipizzate senza perdere la
|
||||
provenienza;
|
||||
2. sorgenti invariati sono un no-op;
|
||||
3. modifiche umane non vengono sovrascritte;
|
||||
4. un `review_item` impedisce l'indicizzazione;
|
||||
5. tutte le otto varianti hanno validazione specifica;
|
||||
6. le formule approvate sono ricercate tramite lo stesso modulo delle altre Evidence;
|
||||
7. soltanto `curated/**/*.md` entra nel corpus runtime;
|
||||
8. la collezione Qdrant espone `dense` e `bm25` e gli indici payload richiesti;
|
||||
9. la Query API esegue i due prefetch e la fusione RRF;
|
||||
10. risultati di frammenti della stessa unità vengono raggruppati;
|
||||
11. una revisione o generazione non corrispondente restituisce zero Evidence e un
|
||||
avviso;
|
||||
12. il set di valutazione produce un rapporto ripetibile;
|
||||
13. una sessione completa continua a funzionare anche con Evidence non disponibili;
|
||||
14. documentazione e comandi descrivono lo stesso contratto.
|
||||
3. ogni modifica proposta a contenuti revisionati è recuperabile e visibile nel diff
|
||||
Git prima della pubblicazione;
|
||||
4. ogni unità cita brevi estratti verificabili del proprio sorgente;
|
||||
5. gli ID nuovi sono assegnati dal codice e il modello può soltanto riutilizzare ID
|
||||
precedenti esplicitamente forniti;
|
||||
6. il batch di preparazione è tutto-o-niente e non esegue retry automatici;
|
||||
7. un `review_item` impedisce l'indicizzazione;
|
||||
8. un'unità orfana blocca la pubblicazione finché non viene risolta;
|
||||
9. un'unità non più sostenuta dal proprio sorgente diventa una retirement candidate e
|
||||
blocca la pubblicazione;
|
||||
10. il comando `resolve` ritira o ricollega un'unità con un diff Git recuperabile;
|
||||
11. tutte le otto varianti hanno validazione specifica e un solo `kind` primario;
|
||||
12. una riclassificazione conserva l'ID e un rinominamento univoco del sorgente conserva
|
||||
gli ID delle unità collegate;
|
||||
13. ogni ID usa `evidence:<slug>`, non viene ricalcolato automaticamente e non contiene
|
||||
il kind;
|
||||
14. ogni Formula Evidence contiene una sola espressione PostgreSQL componibile;
|
||||
15. le formule approvate sono ricercate tramite lo stesso modulo delle altre Evidence;
|
||||
16. soltanto `curated/**/*.md` entra nel corpus runtime;
|
||||
17. la collezione Qdrant conserva il dense predefinito e aggiunge `bm25` con IDF senza
|
||||
ricostruzione distruttiva;
|
||||
18. la Query API esegue i due prefetch e la fusione RRF;
|
||||
19. risultati di frammenti della stessa unità diventano un solo Evidence Result con
|
||||
estratti e riferimento al documento completo;
|
||||
20. una ricerca disponibile può restituire zero Evidence, mentre una revisione o
|
||||
generazione non corrispondente produce `unavailable` e blocca lo stage;
|
||||
21. ogni ricerca applica il purpose come filtro obbligatorio e non usa bonus impliciti
|
||||
per kind o ambito;
|
||||
22. la generazione candidata diventa attiva soltanto quando ogni query recupera almeno
|
||||
una Evidence attesa nei primi dieci risultati; il rapporto include anche `hit@5`;
|
||||
23. i cinque stage mappati interrogano Evidence indipendentemente, mentre `memory` e
|
||||
`synthesis` non lo invocano;
|
||||
24. ogni ricerca disponibile conserva una ricevuta minima senza duplicare il testo;
|
||||
25. una sessione completa riprende dopo la finestra fail-closed mediante retry o
|
||||
rollback esplicito;
|
||||
26. conteggi, ID campione e ricerche dense dimostrano che Schema e Memory non cambiano
|
||||
durante l'upgrade;
|
||||
27. una prova L0 dimostra `qdrant/bm25` sull'immagine locale effettivamente dichiarata;
|
||||
28. dense e BM25 ricevono lo stesso testo di query deterministico;
|
||||
29. nessun elemento atomico viene spezzato per rispettare la dimensione dei frammenti;
|
||||
30. la valutazione copre casi lessicali, semantici e misti e mostra separatamente i tre
|
||||
ranking;
|
||||
31. il testo reso di ogni frammento rispetta il solo `max_chunk_chars` esistente;
|
||||
32. la query conserva maiuscole, punteggiatura e spazi interni e non altera gli
|
||||
identificatori PostgreSQL sensibili alle maiuscole;
|
||||
33. documentazione e comandi descrivono lo stesso contratto.
|
||||
|
||||
## 18. Decisioni rinviate
|
||||
|
||||
|
||||
Reference in New Issue
Block a user