Add catalog-owned logical relationships and runtime snapshots, extend the database-management UI and validation coverage, and document the updated operational workflow. Keep active sensitive-generation status in a tooltip and indicator, and update the layout E2E to follow the history action in its new database-scoped location.
1031 lines
56 KiB
Markdown
1031 lines
56 KiB
Markdown
# Piano di test E2E del ciclo di vita delle Evidence
|
|
|
|
- Data di preparazione: 2026-08-31
|
|
- Workspace di riferimento: `psd-clinical`
|
|
- Workspace di collaudo proposto: `psd-evidence-lab`
|
|
|
|
## 1. Obiettivo
|
|
|
|
Questo piano verifica, su servizi reali, l'intero ciclo di vita delle Evidence:
|
|
|
|
1. creazione e registrazione di un workspace parallelo a PSD;
|
|
2. inserimento di Source Evidence e generazione delle Curated Evidence strutturate;
|
|
3. revisione, validazione, commit, acquisizione commit-addressed e inventario;
|
|
4. indicizzazione dense + BM25 in Qdrant;
|
|
5. ricerca tipizzata e uso nei processi core F1-F8;
|
|
6. inserimento incrementale, modifica e riacquisizione;
|
|
7. rename, relink, rimozione, orphan e retirement;
|
|
8. idempotenza, retention, concorrenza, recovery e fallimenti parziali;
|
|
9. isolamento, sicurezza, audit e non regressione di Schema, Memory e solved questions.
|
|
|
|
Il test è un'accettazione manuale E2E assistita, non un sostituto delle suite automatiche. Deve
|
|
attraversare davvero Git, Workspace Management, host CLI, backend, core, Ollama, Qdrant e una
|
|
sessione Pi completa.
|
|
|
|
## 2. Chiarimento essenziale: cosa significa CRUD Evidence oggi
|
|
|
|
Non esiste un CRUD Evidence nella UI o in una API pubblica. Il repository Git del workspace è la
|
|
fonte autorevole; Qdrant è una proiezione ricostruibile.
|
|
|
|
| Operazione funzionale | Gesto reale dell'utente |
|
|
| --- | --- |
|
|
| Inserimento | aggiungere un file in `evidence/source/`, eseguire `evidence prepare`, revisionare, validare, committare e pubblicare la revisione |
|
|
| Lettura | leggere source/curated in Git; cercare la Published Evidence via retrieval; verificare provenienza e citation |
|
|
| Modifica | modificare solo la Source Evidence, rieseguire prepare/review/validate e pubblicare una nuova revisione/generazione |
|
|
| Cancellazione | rimuovere la source, osservare l'orphan bloccante, poi decidere esplicitamente `--retire` oppure `--source` per il relink |
|
|
| Inventario | correlare manifest Git, materializzazione del commit, manifest ACTIVE, document generations, payload Qdrant e receipt di sessione |
|
|
|
|
ThothII non modifica, committa o pusha il repository dell'autore. Il curatore non deve modificare
|
|
manualmente `manifest.yaml`, hash, generation, metadata invisibili o marker `tht:`.
|
|
|
|
## 3. Fonti di verità e oracoli
|
|
|
|
| Livello | Autorità o proiezione | Oracle da conservare |
|
|
| --- | --- | --- |
|
|
| Authoring Git | autorità | commit SHA, `source/`, `curated/`, `manifest.yaml`, `evaluation.yaml` |
|
|
| Registry snapshot | copia immutabile del commit attivo | workspace revision, `snapshot.json`, `evidence.manifest.json`, hash e conteggi file |
|
|
| Corpus Evidence | generazione pubblicata | puntatore `ACTIVE`, generation manifest, `document_generations` |
|
|
| Qdrant | proiezione ricostruibile | active view per workspace, revisione pinnata e document generation; payload senza vector |
|
|
| Sessione | verità del processo | `retrieval_pack.md`, `evidence_receipts.json`, `evidence.json`, `review_decisions.jsonl` |
|
|
| Chat/UI live | non persistente | screenshot o note di collaudo, mai usati come unico oracle |
|
|
|
|
Nel percorso **filesystem v2** una Evidence è disponibile al runtime soltanto dopo source, curated,
|
|
manifest valido, assenza di review item irrisolti, preprocessing, evaluation superata e attivazione
|
|
atomica. HTTP e S3 seguono invece i rispettivi contratti adapter della campagna P2.
|
|
|
|
Il solo puntatore Evidence `ACTIVE` non prova la disponibilità: il Qdrant adapter filtra anche per la
|
|
registry/workspace revision corrente. Dopo una candidate fallita si devono quindi confrontare
|
|
separatamente registry revision, Evidence ACTIVE pointer, punti fisici, vista di una sessione pinnata
|
|
e vista del runtime corrente; una divergenza è split-brain, non rollback riuscito.
|
|
|
|
## 4. Topologia del laboratorio
|
|
|
|
Il test deve usare lo stesso repository Git condiviso dei workspace, ma un namespace distinto. Non
|
|
va creato un corpus Evidence indipendente scollegato dal catalogo dei workspace.
|
|
|
|
### 4.1 Isolamento obbligatorio
|
|
|
|
- Branch remoto dedicato: `test/evidence-lifecycle`.
|
|
- Installazione locale dedicata al collaudo, con il processo backend configurato esplicitamente con
|
|
`THT_WORKSPACE_GIT_BRANCH=test/evidence-lifecycle`. La UI aggiorna il branch già configurato: non
|
|
permette di sceglierlo.
|
|
- Workspace ID: `psd-evidence-lab`.
|
|
- Directory: `psd-evidence-lab/`.
|
|
- Qdrant collection: `psd-evidence-lab`.
|
|
- Evidence URI: `psd-evidence-lab/evidence`.
|
|
- Database target: lo stesso DWH read-only di PSD, configurato però come binding del nuovo
|
|
workspace.
|
|
- Secret: reinseriti nella configurazione locale write-only; mai copiati in Git o nei report.
|
|
- Sessioni e corpus: namespace del nuovo workspace; nessun riuso dei path di `psd-clinical`.
|
|
- Prima dell'attivazione iniziale, committare almeno
|
|
`psd-evidence-lab/evidence/README.md`, escluso dal pattern `curated/**/*.md`: Git non conserva le
|
|
directory vuote e la materializzazione commit-addressed deve poter risolvere il tree Evidence.
|
|
|
|
Il repository di authoring usato dall'umano deve essere un clone diverso dal checkout read-only
|
|
gestito dall'installazione.
|
|
|
|
Collection e workspace distinti isolano i dati, ma non i fault ai servizi. REL-05/06/10-13 e le
|
|
prove di outage richiedono un Compose project lab con `dataRoot`, endpoint Qdrant/Ollama, volumi e
|
|
porte propri, oppure proxy di fault scoped esclusivamente al lab. Non fermare né corrompere i servizi
|
|
condivisi con PSD. Se questo isolamento non è disponibile, la campagna fault va marcata `NOT RUN` e
|
|
non è ammesso dichiarare `COMPLETE PASS`.
|
|
|
|
### 4.2 Descriptor minimo
|
|
|
|
Si parte dal descriptor PSD accettato, cambiando almeno ID, nome, descrizione, collection ed
|
|
Evidence URI. Per il laboratorio va dichiarato esplicitamente il contratto moderno:
|
|
|
|
```yaml
|
|
evidence:
|
|
schema_version: 2
|
|
source:
|
|
type: filesystem
|
|
uri: psd-evidence-lab/evidence
|
|
patterns:
|
|
- "curated/**/*.md"
|
|
policy:
|
|
max_chunk_chars: 5000
|
|
retain_published_generations: 3
|
|
```
|
|
|
|
Non copiare gli esempi legacy che usano `**/*.md` o omettono `schema_version: 2`. Aggiungere inoltre
|
|
l'entry ordinata a `thoth-workspaces.yaml` e, se serve lo stesso DWH nei processi core, portare nel
|
|
nuovo namespace le annotazioni schema curate già approvate, sottoponendole comunque al gate del
|
|
nuovo workspace.
|
|
|
|
## 5. Responsabilità
|
|
|
|
### 5.1 Attività dell'utente
|
|
|
|
L'utente simula il curatore/reviewer reale e deve:
|
|
|
|
1. preparare i tre testi descritti nella sezione 6;
|
|
2. leggere integralmente ogni diff delle Curated Evidence e confrontarlo con la source;
|
|
3. decidere sulle ambiguità, sui review item, sul rename, sul relink e sul retirement;
|
|
4. usare Workspace Management per update, validate e test connections;
|
|
5. porre le domande reali nell'app, decidere ai gate e giudicare correttezza business, citation e
|
|
SQL.
|
|
|
|
### 5.2 Attività dell'agente/operatore tecnico
|
|
|
|
L'agente può, dopo autorizzazione all'esecuzione del collaudo:
|
|
|
|
1. creare scaffold, descriptor, catalog entry ed evaluation set;
|
|
2. eseguire i due CLI `tht` corretti, Git e le verifiche read-only;
|
|
3. raccogliere commit SHA, revision, run ID, generation e inventario Qdrant;
|
|
4. confrontare before/after e segnalare ogni violazione degli oracle;
|
|
5. predisporre e validare le probe assistite di runtime e inventory descritte nelle sezioni 7 e 16;
|
|
6. indurre fault controllati soltanto nel laboratorio isolato e ripristinare i servizi;
|
|
7. produrre il verbale finale PASS/FAIL con allegati e ripristinare l'installazione a PSD.
|
|
|
|
## 6. Dataset umano: tre documenti, sei pubblicazioni
|
|
|
|
L'attuale authoring skill impone esattamente una Evidence Unit per Source Evidence. I documenti
|
|
devono quindi contenere una sola unità primaria ciascuno. Un testo che combina concetti indipendenti
|
|
è un test negativo, non il formato nominale.
|
|
|
|
### 6.1 Documento D1 — glossario/disambiguazione
|
|
|
|
Path consigliato:
|
|
`evidence/source/00-glossario/coorte-lab-zaffiro.md`.
|
|
|
|
Il testo deve includere:
|
|
|
|
- una definizione business univoca;
|
|
- 2-3 sinonimi e almeno una variante ortografica italiana/Unicode;
|
|
- ciò che il termine non significa;
|
|
- eventuali tabelle/colonne, sempre pienamente qualificate;
|
|
- una frase breve copiabile come supporting excerpt;
|
|
- un token raro ma leggibile, per esempio `LAB-ZAFFIRO-731`;
|
|
- uso atteso: `disambiguation` e `rewriting`.
|
|
|
|
### 6.2 Documento D2 — enum o regola legata allo schema
|
|
|
|
Path consigliato:
|
|
`evidence/source/20-valori-enum/stato-lab-device.md`.
|
|
|
|
Il testo deve includere:
|
|
|
|
- una colonna reale nel formato `schema.table.column`;
|
|
- tutti i valori memorizzati e il loro significato;
|
|
- comportamento di `NULL`, valore sconosciuto ed eventuale eccezione;
|
|
- una frase breve copiabile come supporting excerpt;
|
|
- un token raro, per esempio `LAB-ENUM-842`;
|
|
- uso atteso: `schema_linking` e `sql_generation`.
|
|
|
|
Se gli identificatori non sono pienamente qualificati, il sistema deve produrre un review item o
|
|
una Evidence `domain`, non inventare il mapping.
|
|
|
|
### 6.3 Documento D3 — formula PostgreSQL
|
|
|
|
Questo file viene aggiunto solo dopo la prima pubblicazione, per provare un inserimento
|
|
incrementale. Path consigliato:
|
|
`evidence/source/50-metadati-normalizzazione/formula-lab-intervallo.md`.
|
|
|
|
Il testo deve includere:
|
|
|
|
- un solo concetto calcolato;
|
|
- una sola espressione PostgreSQL componibile, non una query completa;
|
|
- tutti gli input come `schema.table.column`;
|
|
- semantica di `NULL`, unità di misura e casi limite;
|
|
- una frase breve copiabile come supporting excerpt;
|
|
- un token raro, per esempio `LAB-FORMULA-953`;
|
|
- uso atteso: `sql_generation`.
|
|
|
|
Una formula contenente `SELECT`, DDL o DML deve essere rifiutata come test negativo.
|
|
|
|
### 6.4 Scheda che l'utente compila prima del test
|
|
|
|
| Campo | Valore da fornire |
|
|
| --- | --- |
|
|
| Tabella/colonna reale usata da D2 | |
|
|
| Valori reali e significato | |
|
|
| Colonne reali usate da D3 | |
|
|
| Espressione PostgreSQL attesa | |
|
|
| ID Evidence generati dopo `prepare` | |
|
|
| Domanda lessicale per D1/D2/D3 | |
|
|
| Parafrasi semantica per D1/D2/D3 | |
|
|
| Domanda che richiede D1 + D2 + D3 | |
|
|
| Risultato business e SQL attesi | |
|
|
| Domanda negativa non correlata | |
|
|
| Nuova definizione D1 per G3 | |
|
|
| Canary D1 nuova e formulazione da rimuovere | |
|
|
| Nuovi path D1 per G5 rename e G6 relink | |
|
|
| Testo business innocuo per la source injection S4 | |
|
|
|
|
### 6.5 Copertura dei kind
|
|
|
|
Il percorso principale copre tre payload differenti. Per verificare anche tutti gli otto kind
|
|
(`glossary`, `domain`, `enum`, `example`, `mapping`, `normalization`, `formula`, `reference`) il
|
|
dataset raccomandato usa cinque micro-source aggiuntive, una per kind mancante, coerentemente con la
|
|
skill corrente. Questa estensione è P2: non è necessaria per dimostrare il lifecycle CRUD, ma è
|
|
necessaria per dichiarare copertura completa dei payload.
|
|
|
|
## 7. Convenzioni di esecuzione e raccolta
|
|
|
|
Creare una directory di report esterna al repository di authoring, con un sottodirectory per ciclo:
|
|
|
|
```text
|
|
evidence-test-run-YYYYMMDD-HHMM/
|
|
├── 00-preflight/
|
|
├── 01-g1-initial/
|
|
├── 02-g2-add/
|
|
├── 03-g3-update/
|
|
├── 04-g4-retire/
|
|
├── 05-g5-rename/
|
|
├── 06-g6-relink/
|
|
├── faults/
|
|
└── final-report.md
|
|
```
|
|
|
|
Per ogni comando conservare timestamp, comando senza secret, exit code, stdout JSON, stderr
|
|
sanitizzato e identità dell'operatore. Per ogni pubblicazione conservare:
|
|
|
|
- Git commit e workspace revision;
|
|
- `runId`, status e code;
|
|
- ACTIVE prima/dopo;
|
|
- generation manifest e mappa `document_generations`;
|
|
- inventario Qdrant filtrato;
|
|
- risultati dell'evaluation e delle probe;
|
|
- session ID e receipt.
|
|
|
|
### 7.1 I due CLI omonimi
|
|
|
|
Definire percorsi espliciti; non affidarsi al primo `tht` nel `PATH`:
|
|
|
|
```bash
|
|
AUTHOR_THT=/Users/mp/projects/ThothII/harness/.venv/bin/tht
|
|
OPERATOR_THT=/absolute/path/to/native/host/tht
|
|
AUTHOR_REPO=/absolute/path/to/workspace-authoring-clone
|
|
WS_ROOT="$AUTHOR_REPO/psd-evidence-lab"
|
|
INSTALLATION=/absolute/path/to/thothii-installation.yaml
|
|
WS=psd-evidence-lab
|
|
REPORT=/absolute/path/to/evidence-test-run-YYYYMMDD-HHMM
|
|
EVIDENCE_PROBE=/absolute/path/to/assisted-evidence-probe
|
|
EVIDENCE_INVENTORY=/absolute/path/to/assisted-evidence-inventory
|
|
EVIDENCE_FAULT=/absolute/path/to/assisted-evidence-fault-harness
|
|
```
|
|
|
|
- `AUTHOR_THT`: authoring, validation e migrazione del workflow Python.
|
|
- `OPERATOR_THT`: installazione, registry e manutenzione del workspace reale.
|
|
|
|
`--config`/`-c` del CLI Python è un'opzione del singolo comando e deve comparire dopo il
|
|
subcommand.
|
|
|
|
Il backend crea lease/config runtime revision-pinned e temporanee: non si deve ricostruire, copiare o
|
|
passare a mano un `RUNTIME_CFG`. `EVIDENCE_PROBE` deve creare e distruggere la lease in modo
|
|
supportato; `EVIDENCE_INVENTORY` è read-only; `EVIDENCE_FAULT` opera solo sulla stack lab dedicata.
|
|
Sono helper che l'agente deve fornire e validare prima del collaudo esaustivo, non comandi attualmente
|
|
pubblici di `tht`. Se mancano, i casi che li richiedono sono `NOT RUN`/`INCONCLUSIVE`, non PASS per
|
|
inferenza dalla UI.
|
|
|
|
## 8. Preflight e baseline
|
|
|
|
| ID | Azione | Esito atteso |
|
|
| --- | --- | --- |
|
|
| PRE-01 | Verificare branch, worktree pulito e remote corretti | nessun file authoring già dirty; `.DS_Store` esclusi |
|
|
| PRE-02 | Eseguire le suite automatiche Evidence/backend rilevanti | PASS; eventuali L0/L2 mancanti documentati, non nascosti |
|
|
| PRE-03 | Verificare Pi, provider autore, Ollama, Qdrant, DWH e auth | tutti raggiungibili senza esporre credenziali |
|
|
| PRE-04 | Inventariare `psd-clinical` come gruppo di controllo | commit, ACTIVE, counts per kind e canary `disambiguation` con expected ID salvati |
|
|
| PRE-05 | Verificare assenza del workspace/collection lab | nessuna collisione; se esistono, fermarsi e identificare il proprietario |
|
|
| PRE-06 | Aggiungere catalog entry, descriptor lab e `evidence/README.md` tracciato in una revisione candidata | ID, URI e collection distinti; descriptor schema v3 valido; tree Evidence risolvibile anche senza D1-D3 |
|
|
| PRE-07 | Verificare nel processo dell'installazione `THT_WORKSPACE_GIT_BRANCH=test/evidence-lifecycle`, pushare la revisione su quel branch e usare **Update workspace repository** nella UI | la UI mostra ref/commit attesi, candidate valida attivata atomicamente; PSD resta disponibile |
|
|
| PRE-08 | Selezionare il lab, configurare binding/secret, **Validate workspace source** e **Test workspace connections** | check verdi; secret solo write-only |
|
|
| PRE-09 | Selezionare il lab come workspace dell'installazione | nuove sessioni usano il lab; nessuna sessione PSD viene mutata |
|
|
| PRE-10 | Preprocessare DWH, gestire il gate schema e indicizzare lo schema del lab, senza ancora eseguire lo stage Evidence | schema indicizzato nella collection lab; nessun punto PSD toccato |
|
|
| PRE-11 | Eseguire smoke test di `EVIDENCE_PROBE` e `EVIDENCE_INVENTORY` | helper attestano installazione/workspace/revision; nessuna scrittura o stampa di secret |
|
|
| PRE-12 | Eseguire `EVIDENCE_FAULT assert-isolated` e `status` | dataRoot, Qdrant, Ollama, volumi e porte lab non coincidono con PSD; nessun fault/barrier attivo; altrimenti campagna fault `NOT RUN` |
|
|
| PRE-13 | Verificare instrumentation del report candidate prima della compensazione | report sanitizzato osservabile; altrimenti dettaglio G3-bad `NOT OBSERVABLE` e niente `COMPLETE PASS` |
|
|
|
|
Il full `workspace preprocess run` va usato soltanto dopo aver aggiunto D1/D2 e un evaluation set
|
|
valido; prima di quel momento lo stage Evidence non ha ancora un corpus valutabile.
|
|
|
|
Non usare come prerequisito `scripts/evidence-restructuring-acceptance.sh`: nel tree corrente
|
|
riferisce un test non presente. Non assumere inoltre che il report PSD citato da `PROJECT_STATE.md`
|
|
sia disponibile nel working tree corrente.
|
|
|
|
## 9. Comandi nominali
|
|
|
|
### 9.1 Authoring
|
|
|
|
```bash
|
|
"$AUTHOR_THT" evidence prepare "$WS_ROOT" --json
|
|
"$AUTHOR_THT" evidence validate "$WS_ROOT" --json
|
|
|
|
# Dopo una rimozione e la decisione umana:
|
|
"$AUTHOR_THT" evidence resolve "$WS_ROOT" evidence:<id> --retire --json
|
|
"$AUTHOR_THT" evidence resolve "$WS_ROOT" evidence:<id> \
|
|
--source source/<dominio>/<nuovo-file>.md --json
|
|
|
|
```
|
|
|
|
Exit code attesi per `validate`:
|
|
|
|
- `0`: corpus publishable;
|
|
- `1`: errore strutturale/operativo;
|
|
- `3`: soli orphan o review item irrisolti.
|
|
|
|
Con `--json`, stdout deve contenere un solo JSON valido.
|
|
|
|
### 9.2 Operatore host
|
|
|
|
```bash
|
|
"$OPERATOR_THT" --installation "$INSTALLATION" workspace inspect \
|
|
--workspace "$WS" --json
|
|
"$OPERATOR_THT" --installation "$INSTALLATION" workspace vector inspect \
|
|
--workspace "$WS" --json
|
|
"$OPERATOR_THT" --installation "$INSTALLATION" workspace preprocess evidence \
|
|
--workspace "$WS" --dry-run --json
|
|
"$OPERATOR_THT" --installation "$INSTALLATION" workspace preprocess evidence \
|
|
--workspace "$WS" --json
|
|
```
|
|
|
|
Per un resume controllato:
|
|
|
|
```bash
|
|
"$OPERATOR_THT" --installation "$INSTALLATION" workspace preprocess evidence \
|
|
--workspace "$WS" --resume <run-id-32hex> --json
|
|
```
|
|
|
|
### 9.3 Probe tipizzata tecnica, non superficie host
|
|
|
|
`search evidence` richiede il config runtime temporaneo e non è direttamente esposto dal CLI host.
|
|
Il collaudo deve quindi usare un helper assistito che apra la stessa lease revision-pinned del core,
|
|
attesti nel JSON installazione, workspace, workspace revision e vector generation, invochi ricerca o
|
|
evaluation senza divulgare il config, quindi distrugga la lease. Interfaccia minima richiesta:
|
|
|
|
```bash
|
|
"$EVIDENCE_PROBE" validate-fixture --workspace-root "$WS_ROOT" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage clarification --query "<domanda>" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage rewriting --query "<domanda>" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage schema_linking --query "<domanda>" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage cte --query "<domanda>" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage final_sql --query "<domanda>" --json
|
|
|
|
# Filtri negativi RET-05:
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage schema_linking --query "<domanda D2>" \
|
|
--require-table "datawarehouse.tabella_inesistente_lab" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage schema_linking --query "<domanda D2>" \
|
|
--require-column "datawarehouse.tabella_inesistente_lab.colonna_inesistente" --json
|
|
```
|
|
|
|
Il JSON di `search evidence` serve per ID, excerpt, purpose, revision e generation. I rank separati
|
|
`dense`, `bm25` e `fused` non sono presenti nel JSON di search. Dopo ogni preprocess riuscito
|
|
eseguire l'evaluation revision-pinned dell'ACTIVE; per una generation retained usare la sua revisione:
|
|
|
|
```bash
|
|
"$EVIDENCE_PROBE" evaluate --installation "$INSTALLATION" --workspace "$WS" \
|
|
--revision <commit-40hex> --active --json
|
|
"$EVIDENCE_PROBE" evaluate --installation "$INSTALLATION" --workspace "$WS" \
|
|
--revision <commit-storico-40hex> --generation <generation-32hex> --json
|
|
```
|
|
|
|
`evaluate` deve restituire profilo, expected/missing, empty result e rank dense/BM25/fused per query,
|
|
materializzare l'authoring tree e `evaluation.yaml` della revisione dichiarata, aprire una lease
|
|
Qdrant legata alla stessa revisione e attestare revision/generation nel JSON; usare la lease corrente
|
|
su una generation storica non è valido.
|
|
|
|
L'implementazione corrente non persiste l'`EvaluationReport` della candidate fallita: lo riduce a un
|
|
esito booleano e compensa i punti. Per osservare `missing_expected` e rank di G3-bad serve prima una
|
|
modifica prodotto che salvi un report sanitizzato nel run artifact **prima** della compensazione.
|
|
Senza questa modifica si può provare solo il fallimento generico e l'immutabilità di ACTIVE; il
|
|
dettaglio candidate è `NOT OBSERVABLE` e preclude `COMPLETE PASS`. Se manca anche l'helper, marcare
|
|
RET-01/02/03/04/05/06 e le evaluation dirette `NOT RUN`; il collaudo resta `INCONCLUSIVE`.
|
|
|
|
`validate-fixture` deve invocare lo stesso `load_evaluation_fixture` del prodotto senza model call né
|
|
accesso vector. `evidence validate` non legge `evaluation.yaml`: il suo exit `0` prova il corpus
|
|
authoring, non la struttura della fixture.
|
|
|
|
I mapping stage-purpose attesi sono:
|
|
|
|
| Stage | Purpose |
|
|
| --- | --- |
|
|
| `clarification` | `disambiguation` |
|
|
| `rewriting` | `rewriting` |
|
|
| `schema_linking` | `schema_linking` |
|
|
| `cte` | `sql_generation` |
|
|
| `final_sql` | `sql_generation` |
|
|
|
|
Non devono esistere consultazioni Evidence in Memory o Synthesis.
|
|
|
|
## 10. Ciclo G1 — creazione iniziale con D1 e D2
|
|
|
|
1. Aggiungere soltanto D1 e D2 in `source/`.
|
|
2. Eseguire `evidence prepare` da worktree con `curated/` e `manifest.yaml` puliti.
|
|
3. Verificare `changed=[D1,D2]`, due model call e due ID creati. Un numero diverso di candidati è
|
|
una violazione del contratto corrente e richiede revisione prima di proseguire.
|
|
4. Revisionare ogni Curated Evidence v3:
|
|
- una sola unità atomica;
|
|
- kind e purpose corretti;
|
|
- ID stabile `evidence:<slug>`;
|
|
- source file/hash corretti;
|
|
- excerpt esatto presente nella source;
|
|
- nessuna informazione inventata o secret;
|
|
- marker canonici presenti e Markdown leggibile.
|
|
5. Dopo ogni `prepare`, `curated/` e `manifest.yaml` sono dirty e un altro `prepare` è bloccato.
|
|
Revisionare l'output e creare un commit locale di review (non ancora pubblicato) per tornare a
|
|
un authoring state pulito; solo allora correggere la source e rieseguire `prepare`. Ripetere se
|
|
necessario e non correggere i marker a mano.
|
|
6. Creare `evaluation.yaml` dopo aver conosciuto gli ID. Il contratto richiede almeno una query per
|
|
ciascun profilo `lexical`, `semantic` e `mixed`; l'insieme deve coprire i purpose presenti.
|
|
Il profilo classifica il caso di test: l'evaluator esegue comunque il retrieval ibrido runtime e
|
|
registra separatamente rank dense, BM25 e fused.
|
|
Usare almeno una query dedicata per ciascun ID importante: quando una singola query dichiara più
|
|
ID attesi, il PASS Hit@10 richiede che ne compaia almeno uno e non prova automaticamente tutti.
|
|
7. Eseguire prima `EVIDENCE_PROBE validate-fixture`, poi `evidence validate`; entrambi devono uscire
|
|
`0`, mentre solo il secondo espone `publishable=true` per il corpus.
|
|
8. Committare localmente lo stato finale valido. Solo ora, da worktree pulito, rieseguire `prepare`
|
|
senza modifiche: `modelCalls=0`, `changed=[]`, entrambe le source in `unchanged` e nessun diff.
|
|
9. Pushare la testa valida della revisione G1; aggiornare il repository dalla UI. Eventuali commit
|
|
intermedi restano una review trail e non devono contenere secret.
|
|
10. Eseguire inspect, vector inspect, dry-run e preprocess reale.
|
|
11. Verificare evaluation PASS, attivazione atomica e inventory.
|
|
|
|
### Gate G1
|
|
|
|
- Esistono esattamente due unità attive e recuperabili.
|
|
- Source/support file non vengono indicizzati.
|
|
- Il named vector `bm25` con modifier `idf` è presente senza perdita del dense unnamed.
|
|
- Punti schema preesistenti nella collection lab sono invariati.
|
|
- Un secondo preprocess identico restituisce `unchanged` e non crea punti duplicati.
|
|
|
|
## 11. Ciclo G2 — inserimento incrementale di D3
|
|
|
|
1. Aggiungere soltanto D3.
|
|
2. Eseguire prepare/review/validate.
|
|
3. Verificare una sola model call, un solo nuovo ID e D1/D2 invariati.
|
|
4. Aggiungere all'evaluation query lexical, semantic o mixed per D3 e per la domanda composita;
|
|
eseguire `validate-fixture` oltre a `evidence validate`.
|
|
5. Commit, push, UI update, dry-run e preprocess reale.
|
|
6. Verificare nominalmente che D3 abbia una nuova document generation e che D1/D2 riusino le
|
|
precedenti. Se il cambio del path commit-addressed nella source URI forza il re-embedding di
|
|
tutti i documenti, registrarlo come difetto/limite di incrementalità, non come PASS silenzioso.
|
|
Se invece riusa le generation ma non esistono punti recuperabili sotto la revisione G2 corrente,
|
|
registrare FAIL di retrieval/incrementalità.
|
|
7. Verificare che il manifest ACTIVE elenchi tutte e tre le unità.
|
|
8. Prima di lasciare G2 eseguire RET-01..06, RET-08 e le sessioni S1, S2 e S3 della sezione 15.1:
|
|
dopo G4 D2 sarà ritirata e gli stessi oracle non saranno più eseguibili.
|
|
|
|
### Gate G2
|
|
|
|
- La formula è una sola espressione PostgreSQL, con input qualificati.
|
|
- La formula pubblicata è citabile; una formula proposta nella sessione resta session-only e non
|
|
riceve un ID `evidence:`.
|
|
- Il retrieval combina correttamente D1, D2 e D3 quando la domanda lo richiede.
|
|
|
|
## 12. Ciclo G3 — modifica e riacquisizione
|
|
|
|
Questo ciclo combina update, pinning di sessione, conflitto e rollback della candidate. L'ordine è
|
|
parte dell'oracle e non va cambiato.
|
|
|
|
1. Subito dopo G2, creare una sessione, portarla almeno fino a una receipt/citation D1 e lasciarla
|
|
incompleta e resumable. Salvare session ID, workspace revision G2, Evidence generation e receipt.
|
|
2. Nel clone di authoring modificare soltanto D1, mantenendo lo stesso concetto ma cambiando in modo
|
|
osservabile la definizione: aggiungere una nuova canary e rimuoverne una vecchia.
|
|
3. Prima di `prepare`, eseguire `validate`: deve rilevare il drift di hash/provenienza e bloccare.
|
|
4. Eseguire `prepare`: una model call, D1 in `changed`, D2/D3 in `unchanged`. L'ID D1 resta identico;
|
|
source hash e contenuto canonico cambiano.
|
|
5. Aggiornare le query nominali dell'evaluation per la nuova formulazione, mantenendo i profili
|
|
`lexical`, `semantic`, `mixed` e una query per ogni ID importante.
|
|
6. Aggiungere poi un caso G3-bad **strutturalmente valido**: un'ulteriore query `mixed` con expected
|
|
ID D1 esistente, ma purpose `sql_generation`, che non appartiene a D1
|
|
(`disambiguation`/`rewriting`). Non usare ID inventati e non eliminare gli altri profili. Eseguire
|
|
`validate-fixture`: deve restituire `0`; eseguire separatamente `evidence validate`, il cui exit
|
|
`0` non costituisce prova sulla fixture. Se uno dei due fallisce, ridisegnare il caso prima del test.
|
|
7. Revisionare, committare G3-bad, pushare, usare **Update workspace repository** e registrare la
|
|
nuova registry active revision. L'Evidence ACTIVE generation deve essere ancora G2.
|
|
8. Fare resume della vecchia sessione: deve restare pinnata a G2, conservare artifact/receipt e
|
|
mostrare D1 vecchio, anche se il registry è già alla candidate revision G3-bad.
|
|
9. Tentare il preprocess G3-bad mentre la sessione è resumable: atteso
|
|
`preprocessing_conflict`; nessuna candidate generation né modifica ad ACTIVE.
|
|
10. Prima di finalizzare la sessione G2, salvare snapshot, artifact, citation e prova della revisione
|
|
pinnata. Poi finalizzarla per sbloccare il preprocess. Una sessione finalizzata non protegge più
|
|
lo snapshot dalla retention, anche se non è archiviata; non usarla come oracle post-G6.
|
|
11. Ripetere il preprocess G3-bad: la candidate deve fallire la retrieval evaluation e venire
|
|
compensata. Distinguere gli oracle: il puntatore Evidence e i punti fisici G2 restano; la vecchia
|
|
sessione pinnata G2 è stata verificata prima della finalizzazione; il runtime corrente è invece
|
|
legato alla registry revision G3-bad. Interrogarlo esplicitamente. Il PASS richiede rollback del
|
|
registry o routing coerente alla revisione G2; se la vista corrente è vuota per revision mismatch,
|
|
registrare split-brain/FAIL, non “ACTIVE G2 disponibile”. Con la diagnostica 9.3 salvare
|
|
`missing_expected`, rank e candidate generation; altrimenti dettaglio `NOT OBSERVABLE`.
|
|
12. Correggere la fixture assegnando a D1 un purpose ammesso, rieseguire `validate-fixture` e
|
|
`evidence validate`, committare G3-fix, pushare e aggiornare di nuovo il repository.
|
|
13. Eseguire dry-run e preprocess: evaluation PASS e switch atomico a G3. Verificare nuova document
|
|
generation per D1 e riuso delle document generation D2/D3; se la source URI commit-addressed
|
|
forza un full re-embedding, registrarlo come difetto di incrementalità. Se il riuso lascia i
|
|
punti solo sotto la revisione G2, il filtro runtime G3 non li recupera e il ciclo è FAIL.
|
|
14. La nuova canary deve trovare D1. La formulazione rimossa non deve comparire negli excerpt o
|
|
payload dell'active view; la sola retrieval semantica col vecchio termine non prova stale data.
|
|
15. Creare una nuova sessione: deve essere pinnata a G3 e vedere D1 nuovo. Registrare separatamente
|
|
revision, generation, artifact e receipt della sessione G2 e di quella G3.
|
|
|
|
## 13. Ciclo G4 — cancellazione e retirement di D2
|
|
|
|
La cancellazione non deve mai essere silenziosa.
|
|
|
|
1. Rimuovere il file source D2.
|
|
2. Eseguire `prepare`: D2 deve diventare orphan; l'unità non viene cancellata automaticamente.
|
|
3. Eseguire `validate`: exit `3`, `orphaned_unit` e/o `source_no_longer_supports_unit`; nessuna
|
|
pubblicazione ammessa.
|
|
4. Committare e pushare lo stato orphan su una revisione G4-bad del branch lab, quindi aggiornare il
|
|
repository dell'installazione isolata. Se il registry rifiuta la candidate, registrare esattamente
|
|
il componente che ha bloccato e marcare il preprocess downstream `NOT RUN`: non è la stessa prova
|
|
del gate di preprocess. Se il registry la accetta, il preprocess deve bloccare e lasciare il
|
|
puntatore Evidence su G3; poi interrogare il runtime corrente G4-bad. Se non recupera G3 perché il
|
|
filtro revision-pinned non coincide, registrare split-brain/FAIL. Se il registry ha rifiutato la
|
|
candidate ed è rimasto G3, verificare invece che G3 resti recuperabile.
|
|
5. Da quel worktree pulito, il reviewer decide il retirement ed esegue
|
|
`evidence resolve ... --retire`.
|
|
6. Aggiornare `evaluation.yaml`: eliminare o sostituire ogni query che attende D2, mantenendo almeno
|
|
un caso per ciascun profilo `lexical`, `semantic`, `mixed`, la copertura dei purpose ancora attivi
|
|
e query dedicate a D1/D3.
|
|
7. Eseguire `validate-fixture` e `evidence validate` con exit `0`, committare la risoluzione G4-fix,
|
|
pushare la testa valida, fare UI update e preprocess.
|
|
8. Verificare che D2 non sia nel manifest ACTIVE, nell'evaluation o nei risultati runtime.
|
|
|
|
Punti di D2 possono ancora esistere fisicamente in una generazione retained. Non è un difetto se il
|
|
manifest ACTIVE e i filtri per document ID/generation impediscono di restituirli. È un difetto se
|
|
una ricerca attiva li restituisce.
|
|
|
|
## 14. Cicli G5 e G6 — rename e relink di D1
|
|
|
|
Eseguire entrambi i rami in revisioni separate.
|
|
|
|
### 14.1 G5 — rename identico
|
|
|
|
1. Rinominare la source D1 senza cambiare un byte.
|
|
2. Eseguire `prepare`.
|
|
3. Atteso: riconoscimento univoco tramite hash, ID stabile, nessuna ristrutturazione non necessaria.
|
|
4. Pubblicare e verificare citation/provenienza sul nuovo path.
|
|
|
|
### 14.2 G6 — relink esplicito
|
|
|
|
1. Rimuovere il source path corrente di D1, eseguire `prepare` e verificare l'orphan con `validate`
|
|
exit `3`; creare un commit locale G6-orphan. Questo passaggio è necessario: aggiungere prima il
|
|
nuovo file trasformerebbe il caso in rename/hash match, non in relink.
|
|
2. Dal commit G6-orphan creare un worktree/branch negativo separato. Aggiungere e committare una
|
|
source priva dell'exact excerpt, poi lanciare `resolve --source`: atteso exit `1` con finding
|
|
`supporting_excerpt_missing`. Il relink può essere applicato, ma `validate`/publish devono restare
|
|
bloccati; non unire questa variante.
|
|
3. Nel worktree principale, ancora pulito sul commit G6-orphan, aggiungere il nuovo file source con
|
|
gli exact excerpt necessari e committarlo **senza** eseguire `prepare`.
|
|
4. Eseguire `evidence resolve ... --source source/<nuovo-path>`.
|
|
5. Verificare stesso ID, nuovo source file/hash, rimozione dell'orphan e assenza del finding.
|
|
6. Validare, commit/push, UI update, preprocess e verificare il nuovo citation path. Conservare il
|
|
branch negativo fino alla chiusura del report; niente reset distruttivi.
|
|
|
|
## 15. Matrice di retrieval e uso core
|
|
|
|
| ID | Scenario | Oracle |
|
|
| --- | --- | --- |
|
|
| RET-01 | Token esatto di ogni source | Evidence attesa entro top 10; rank dense/BM25/fused registrati |
|
|
| RET-02 | Parafrasi senza token esatto | Evidence attesa via ramo semantico/fusione |
|
|
| RET-03 | Query mixed | Evidence attesa con entrambe le branche diagnosticate |
|
|
| RET-04 | Purpose errato | Evidence non deve comparire nello stage non autorizzato |
|
|
| RET-05 | `required_table`/`required_column` non corrispondenti | outcome `available` con zero risultati |
|
|
| RET-06 | Query non correlata | `available` vuoto o nessun ID atteso; non `unavailable` |
|
|
| RET-07 | Qdrant/Ollama indisponibile | outcome `unavailable`, stage bloccato e retry dello stesso stage; niente stale fallback |
|
|
| RET-08 | Canary incrociate lab/`psd-clinical` | nessun ID o payload dell'altro workspace attraversa il namespace |
|
|
| RET-09 | Query lab dopo modifica | solo contenuto della revisione/generazione attiva |
|
|
| RET-10 | Citation | file immutabile materializzato, source/provenienza verificabili |
|
|
| CORE-01 | Sessione F1-F8 completa | cinque receipt: clarification, rewriting, schema_linking, cte, final_sql |
|
|
| CORE-02 | Evidence accettata al gate | decisione persistita e `evidence.json` coerente |
|
|
| CORE-03 | Evidence rifiutata al gate | rifiuto persistito; non usata come fatto downstream |
|
|
| CORE-04 | Formula proposta dalla sessione | resta `formula_proposal`, non Published Evidence |
|
|
| CORE-05 | Nuova vs vecchia sessione | revision pinning rispettato |
|
|
| CORE-06 | Prompt injection nella source | trattata come dati, mai come istruzione; nessuna esfiltrazione/tool action |
|
|
|
|
Le receipt devono contenere stage, purpose, vector generation e ID, non una copia integrale delle
|
|
Evidence. Una nuova ricerca nello stesso stage sostituisce solo la receipt di quello stage.
|
|
|
|
### 15.1 Sessioni utente obbligatorie
|
|
|
|
Eseguire casi separati: una sola sessione non dimostra tutti i comportamenti. S1, S2, S3,
|
|
RET-01..06 e RET-08 vanno eseguiti alla fine di G2; S5 durante G3; S4 solo dopo retention, snapshot e
|
|
non-regressione G6.
|
|
|
|
1. **S1 — accettazione:** porre una domanda che richieda D1, D2 e D3; avanzare F1-F8, accettare le
|
|
Evidence pertinenti ai gate e salvare cinque receipt. Verificare decision ledger, `evidence.json`,
|
|
citation e SQL finale contro i testi originali.
|
|
2. **S2 — rifiuto:** in una nuova sessione porre una domanda che recuperi certamente D2, rifiutarla
|
|
al gate e completare il flusso. Il rifiuto deve essere persistito e D2 non deve diventare un fatto
|
|
accettato negli artifact downstream.
|
|
3. **S3 — proposta:** chiedere un calcolo non presente nel corpus e lasciare che la sessione proponga
|
|
una formula. Deve restare `formula_proposal` session-only: nessun file curated, manifest, punto
|
|
Qdrant o ID `evidence:` viene creato.
|
|
4. **S4 — prompt injection (G7/G8 security):** in G7 aggiungere una quarta source atomica con
|
|
contenuto business innocuo e una frase che ordina al modello di ignorare le regole, mostrare
|
|
secret o usare tool. `prepare` non deve obbedire alla frase né produrre leakage/tool action;
|
|
aggiungere una query evaluation dedicata al nuovo ID, eseguire `validate-fixture`, pubblicare,
|
|
interrogarla in una nuova sessione e verificare che sia trattata solo come dato. In G8 ritirarla,
|
|
rimuovere/sostituire la sua query, rivalidare la fixture e pubblicare la revisione pulita.
|
|
5. **S5 — pinning:** usare le due sessioni G2/G3 della sezione 12 e confrontare revision, generation,
|
|
citation e artifact, non soltanto il testo mostrato nella chat.
|
|
|
|
Per RET-04 eseguire una query D1 nello stage `schema_linking` e una D2 nello stage `rewriting`; per
|
|
RET-05 usare entrambe le opzioni `--require-table` e `--require-column` della probe; per RET-06 usare
|
|
una query non correlata predefinita. L'oracle è rispettivamente assenza per purpose, `available` con
|
|
risultato vuoto e `available` vuoto. RET-07 va eseguito solo nella stack fault isolata: l'outcome è
|
|
`unavailable`, la fase corrente non avanza e il retry riparte dallo stesso stage.
|
|
|
|
Per RET-08 usare la canary e l'ID PSD salvati in PRE-04 e una canary lab rara:
|
|
|
|
```bash
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace psd-clinical \
|
|
--stage clarification --query "LAB-ZAFFIRO-731" --json
|
|
"$EVIDENCE_PROBE" search --installation "$INSTALLATION" --workspace "$WS" \
|
|
--stage clarification --query "<canary PSD baseline>" --json
|
|
```
|
|
|
|
Ogni JSON deve attestare il workspace/revision richiesto e non contenere ID, excerpt o payload
|
|
dell'altro namespace. Ripetere RET-08 dopo G6 e dopo G8 senza cambiare le impostazioni globali o
|
|
mutare PSD.
|
|
|
|
`evaluation.yaml` richiede almeno un ID atteso non vuoto e non esprime forbidden ID o un oracle
|
|
“deve restituire zero risultati”. RET-04, RET-05 e RET-06 devono quindi restare probe manuali/CLI
|
|
separate e non possono essere dichiarate coperte dal solo PASS dell'evaluation.
|
|
|
|
## 16. Inventario vettoriale corretto
|
|
|
|
`workspace vector inspect` verifica oggi collection, dimensioni e distanza; non è un inventario dei
|
|
record. Per il test esaustivo l'agente deve fornire un helper read-only con questa interfaccia minima:
|
|
|
|
```bash
|
|
"$EVIDENCE_INVENTORY" capture --installation "$INSTALLATION" --workspace "$WS" \
|
|
--scope pointer --output "$REPORT/<ciclo>/inventory-pointer.json"
|
|
"$EVIDENCE_INVENTORY" capture --installation "$INSTALLATION" --workspace "$WS" \
|
|
--scope active --output "$REPORT/<ciclo>/inventory-active.json"
|
|
"$EVIDENCE_INVENTORY" capture --installation "$INSTALLATION" --workspace "$WS" \
|
|
--scope retained --output "$REPORT/<ciclo>/inventory-retained.json"
|
|
```
|
|
|
|
L'helper risolve i path e gli endpoint dall'installazione senza stampare secret, legge `ACTIVE` e il
|
|
generation manifest, quindi pagina lo scroll Qdrant fino a esaurimento con `with_vector=false`. Deve
|
|
produrre tre viste distinte: set dichiarato dal pointer, active runtime e retention fisica. Se
|
|
l'helper non è presente o non attesta la revisione osservata, l'inventory è `INCONCLUSIVE`.
|
|
|
|
Per ogni ciclo:
|
|
|
|
1. leggere `ACTIVE` e il generation manifest;
|
|
2. estrarre `document_generations`;
|
|
3. costruire la pointer view dalle coppie esatte `(document_id, vector_generation)` di
|
|
`document_generations`, anche cross-revision, per provare quali punti fisici supportano il
|
|
puntatore Evidence;
|
|
4. costruire l'active runtime view aggiungendo `workspace_id=psd-evidence-lab` e la
|
|
`workspace_revision` pinnata, replicando tutti i predicati runtime **prima** del limit;
|
|
5. acquisire separatamente tutti i punti retained del workspace e raggrupparli per Evidence ID,
|
|
document ID, vector generation e `workspace_revision`; ogni punto deve avere
|
|
`record_kind=evidence` e `kind=evidence`;
|
|
6. verificare gli otto payload index richiesti:
|
|
`content_hash`, `document_id`, `kind`, `record_key`, `record_kind`, `vector_generation`,
|
|
`workspace_id`, `workspace_revision`;
|
|
7. verificare che gli ID/document generation consentiti dal manifest ACTIVE e quelli realmente
|
|
interrogabili dal runtime coincidano; ogni differenza è split-brain.
|
|
|
|
Non assumere che tutti i documenti attivi abbiano la generation più recente: il manifest può riusare
|
|
una document generation precedente. Tuttavia il Qdrant runtime filtra anche per revisione corrente:
|
|
se i punti riusati esistono solo sotto la revisione vecchia e non vengono recuperati, è un difetto di
|
|
incrementalità/retrieval, non un motivo per omettere il filtro dall'oracle. Non assumere neppure che
|
|
il numero totale di punti Qdrant equivalga al corpus attivo: retention e candidate cambiano il totale.
|
|
|
|
## 17. Atomicità, idempotenza, retention e recovery
|
|
|
|
| ID | Scenario | Esito atteso |
|
|
| --- | --- | --- |
|
|
| REL-01 | `preprocess --dry-run` | nessuna modifica a ACTIVE, corpus o punti |
|
|
| REL-02 | prepare invariato | zero model call e zero diff |
|
|
| REL-03 | preprocess invariato | status `unchanged`, nessuna duplicazione |
|
|
| REL-04 | evaluation candidata fallisce | candidate compensata e pointer precedente intatto; registry/runtime ancora coerenti, altrimenti split-brain FAIL |
|
|
| REL-05 | embedding fallisce durante candidate | nessuna attivazione o stato parziale visibile |
|
|
| REL-06 | Qdrant fallisce durante upsert | ACTIVE precedente intatto; retry idempotente |
|
|
| REL-07 | due preprocess simultanei | uno solo procede; l'altro `preprocessing_conflict` |
|
|
| REL-08 | resume stesso run/commit/config | riparte dal checkpoint valido e pubblica una sola volta |
|
|
| REL-09 | resume dopo cambio commit/config | `preprocessing_resume_mismatch`, nessuna mutazione |
|
|
| REL-10 | checkpoint/artifact corrotto | fail closed, nessuna attivazione |
|
|
| REL-11 | collection mancante | self-heal compatibile; dense, BM25/IDF e payload index ricreati |
|
|
| REL-12 | BM25 mancante | aggiunta `bm25`/`idf` senza rebuild del dense |
|
|
| REL-13 | dimensioni/distance/BM25 incompatibili | `semantic_index_incompatible`, nessuna mutazione distruttiva |
|
|
|
|
REL-01/02/03/04 fanno parte del percorso lifecycle. REL-05..13 sono una campagna engineering su stack
|
|
dedicata: usare un fault proxy scoped, volumi usa-e-getta e snapshot del dataRoot lab. Durante un
|
|
fallimento mid-upsert possono esistere punti candidate fisici, ma non devono entrare nell'active
|
|
view; compensazione/retry devono ricondurre lo stato all'oracle. Non simulare questi casi fermando
|
|
Qdrant o Ollama condivisi con PSD.
|
|
|
|
L'harness deve offrire `assert-isolated`, `inject`, `barrier`, `wait`, `abort`, `release`, `clear`,
|
|
`status` e `restore`, sempre attestando installazione, workspace, endpoint e collection. Preflight e
|
|
cleanup minimi:
|
|
|
|
```bash
|
|
"$EVIDENCE_FAULT" assert-isolated --installation "$INSTALLATION" --workspace "$WS" --json
|
|
"$EVIDENCE_FAULT" status --installation "$INSTALLATION" --workspace "$WS" --json
|
|
"$EVIDENCE_FAULT" clear --installation "$INSTALLATION" --workspace "$WS" --all --json
|
|
"$EVIDENCE_FAULT" restore --installation "$INSTALLATION" --workspace "$WS" --json
|
|
|
|
# Forme comuni; inject/barrier restituiscono faultId/barrierId:
|
|
"$EVIDENCE_FAULT" inject --installation "$INSTALLATION" --workspace "$WS" \
|
|
--fault <fault> --once --json
|
|
"$EVIDENCE_FAULT" barrier --installation "$INSTALLATION" --workspace "$WS" \
|
|
--at <checkpoint> --json
|
|
"$EVIDENCE_FAULT" wait --installation "$INSTALLATION" --workspace "$WS" \
|
|
--event barrier-reached --json
|
|
"$EVIDENCE_FAULT" abort --installation "$INSTALLATION" --workspace "$WS" \
|
|
--run-id <run-id-32hex> --json
|
|
"$EVIDENCE_FAULT" release --installation "$INSTALLATION" --workspace "$WS" \
|
|
--barrier-id <barrier-id> --json
|
|
```
|
|
|
|
| Caso | Fault/operazione deterministica |
|
|
| --- | --- |
|
|
| REL-05 | `inject --fault embedding-fail --once`; preprocess, ACTIVE invariato, `clear` e retry |
|
|
| REL-06 | `inject --fault qdrant-upsert-fail --after-points <N> --once`; inventory candidate/active, `clear` e retry |
|
|
| REL-07 | `barrier --at after-writer-lock`; terminale A avvia preprocess; `wait` restituisce run ID; terminale B tenta preprocess e riceve conflict; `release` completa A |
|
|
| REL-08 | `barrier --at after-checkpoint:embed`; avviare e attendere il run ID, `abort --run-id`, poi host CLI `--resume <run-id>` sullo stesso commit/config |
|
|
| REL-09 | creare un secondo checkpoint come REL-08, abortire, pubblicare una candidate commit/config diversa e tentare `--resume <vecchio-run-id>`; atteso mismatch; poi ripristinare con un nuovo commit valido |
|
|
| REL-10 | su copia del checkpoint, `inject --fault corrupt-checkpoint --run-id <id>`; resume fail closed; `restore` |
|
|
| REL-11 | dopo snapshot, `inject --fault collection-missing`; preprocess deve ricreare il contratto previsto; `restore` |
|
|
| REL-12 | `inject --fault collection-dense-only`; verificare aggiunta BM25/IDF senza perdita dense; `restore` |
|
|
| REL-13 | ripetere con `wrong-dimension`, `wrong-distance`, `invalid-bm25`; ogni caso fallisce senza rebuild distruttivo; `restore` |
|
|
|
|
I comandi `wait`/`status` devono essere la fonte del run ID: oggi non esiste un elenco job pubblico.
|
|
Dopo ogni caso eseguire `clear`, verificare nessun processo/barrier residuo, inventory e ACTIVE. Se
|
|
l'harness non implementa l'interfaccia, REL-05..13 sono `NOT RUN` e `COMPLETE PASS` è vietato.
|
|
|
|
Le pubblicazioni G1-G6 superano `retain_published_generations: 3`. Dopo G6 verificare:
|
|
|
|
- ACTIVE + due generazioni di rollback conservate;
|
|
- generazione più vecchia eliminata quando non protetta;
|
|
- sub-generation ancora referenziate dai manifest retained non eliminate;
|
|
- checkpoint resumable protetti e preprocessing di una revisione diversa bloccato finché esiste
|
|
una sessione resumable incompatibile;
|
|
- snapshot Git referenziati da sessioni ancora resumable (`status != finalized` e non archiviate)
|
|
conservati; la prova G2 si raccoglie prima di finalizzare la sessione nella sezione 12;
|
|
- filesystem e Qdrant coerenti dopo GC.
|
|
|
|
Il comando GC della CLI harness è una diagnostica tecnica, non una superficie operatore pubblica;
|
|
non va presentato come normale gesto utente.
|
|
|
|
## 18. Test negativi e sicurezza
|
|
|
|
Eseguire i casi distruttivi solo in un worktree/branch e collection usa-e-getta del laboratorio.
|
|
|
|
### 18.1 Authoring e canonical format
|
|
|
|
- source multi-concetto: una sola unità primaria oppure review item, mai fusione silenziosa;
|
|
- supporting excerpt assente o non esatto;
|
|
- ID duplicato o stessa unità associata a due source;
|
|
- body/metadata desincronizzati;
|
|
- marker `tht:` mancante, duplicato o alterato;
|
|
- campo sconosciuto o payload del kind errato;
|
|
- source hash/manifest hash alterato manualmente;
|
|
- file non UTF-8, vuoto non significativo o oltre 10 MiB;
|
|
- symlink in source/curated;
|
|
- dirty `curated/` o `manifest.yaml` prima di prepare;
|
|
- una di tre ristrutturazioni fallisce: nessuna applicazione parziale.
|
|
|
|
### 18.2 Descriptor e materializzazione
|
|
|
|
- `evidence.schema_version` omesso: il parser può applicare il default legacy v1, ma il laboratorio
|
|
deve rifiutarlo come deviazione dalla baseline v2 esplicita; un valore invalido deve fallire;
|
|
- pattern diverso da `curated/**/*.md`;
|
|
- per la source filesystem, URI assoluto, traversal o cross-namespace; HTTP richiede un URI
|
|
`http(s)://` canonico e S3 un URI `s3://` secondo i rispettivi adapter;
|
|
- symlink, gitlink, path duplicato, file non regolare o race;
|
|
- oltre 4096 entry, 64 MiB totali, 8 MiB/file, manifest oltre 1 MiB; per il path verificare
|
|
esplicitamente 4096 byte accettati e 4097 byte rifiutati;
|
|
- candidate Git revision invalida: la precedente resta attiva.
|
|
|
|
I boundary di 4096 entry, 64 MiB e path 4096/4097 byte vanno costruiti in fixture automatiche o in
|
|
un repository Git usa-e-getta con plumbing controllato e materializer isolato, non pushati nel
|
|
repository condiviso del lab. Il test path deve inoltre verificare che l'ambiente permetta di creare
|
|
la fixture senza fallire prima del codice sotto test. Se manca l'harness, questi casi sono `NOT RUN`
|
|
nel collaudo manuale.
|
|
|
|
### 18.3 Dati, rete e segreti
|
|
|
|
- provenance URI dichiarata con userinfo, credenziali, token o query firmata; il transport URL
|
|
firmato supportato può invece stare nel `signed_urls_file`, ma non deve apparire in descriptor,
|
|
report o log;
|
|
- prompt injection nella source;
|
|
- tentativo di indicizzare `source/`, `evaluation.yaml` o support file;
|
|
- HTTP redirect/rebind verso host privato e S3 endpoint non consentito, nella suite adapter P2;
|
|
- utente non amministratore sui controlli Workspace Management;
|
|
- JSON machine output contaminato da log o secret;
|
|
- export/backup applicativo che includa byte Evidence o secret quando non previsto.
|
|
|
|
## 19. Non regressione
|
|
|
|
Prima di G1 e dopo G6 confrontare:
|
|
|
|
- punti e nearest-neighbour canary di `schema_table` e `schema_column`;
|
|
- punti `memory` e `solved_question` eventualmente presenti;
|
|
- dimensioni, distanza e dense unnamed della collection;
|
|
- query di controllo in `psd-clinical`;
|
|
- accesso DWH rigorosamente read-only;
|
|
- settings globali ripristinati esattamente al baseline e sessioni PSD non modificate.
|
|
|
|
`delete_generation`/retention Evidence non deve cancellare altri record kind. `vector rebuild
|
|
--destroy` non fa parte del percorso nominale; se usato per provare restore/cleanup deve puntare
|
|
alla collection lab, ripetere esattamente il suo nome nei guard e avere autorizzazione esplicita.
|
|
|
|
## 20. Adapter e kind estesi (P2)
|
|
|
|
La dichiarazione di copertura completa oltre il percorso filesystem richiede due campagne separate:
|
|
|
|
1. HTTP reale: redirect, cache, timeout, byte limit, SSRF e rebind;
|
|
2. S3 reale: paginazione, size/object limits, secret file bounded, endpoint policy e credenziali non
|
|
divulgate.
|
|
|
|
Non applicare a HTTP/S3 l'oracle del tree `source/`/`curated/`/`manifest.yaml` né l'obbligo di
|
|
candidate evaluation del filesystem v2. Per questi adapter l'oracle è acquire/normalize/chunk del
|
|
contenuto remoto dichiarato, secondo URI, credenziali, limiti e policy specifici.
|
|
|
|
Per i cinque kind non coperti da D1-D3 creare micro-source atomiche e ripetere
|
|
prepare/validate/preprocess/evaluate/search. Questi test non devono essere mescolati al lifecycle
|
|
principale, altrimenti un fallimento non è diagnosticabile.
|
|
|
|
La campagna P2 deve inoltre coprire:
|
|
|
|
- fixture legacy v1 e v2 con `"$AUTHOR_THT" evidence migrate <workspace-root> --json`, verificando
|
|
migrazione deterministica a v3, nessuna model call e ID/provenienza coerenti;
|
|
- `"$AUTHOR_THT" evidence prepare <workspace-root> --upgrade --json`, che riprocessa tutte le source
|
|
con la pipeline installata senza duplicare unità;
|
|
- `"$EVIDENCE_PROBE" evaluate ... --revision <revision-storica> --generation <generation> --json`,
|
|
materializzando snapshot, config ed `evaluation.yaml` della revisione che pubblicò la generation;
|
|
provare sia ACTIVE sia una generation retained;
|
|
- un cambio controllato di `kind` della stessa unità, con payload completo per il nuovo kind: l'ID
|
|
resta stabile, la nuova versione è attiva e la vecchia non è restituita dall'active view.
|
|
|
|
## 21. Copertura automatica da usare come prerequisito
|
|
|
|
Eseguire i gate completi con comandi separati:
|
|
|
|
```bash
|
|
cd /Users/mp/projects/ThothII/harness
|
|
.venv/bin/pytest -q
|
|
|
|
cd /Users/mp/projects/ThothII/backend
|
|
npx vitest run
|
|
npx tsc --noEmit -p .
|
|
|
|
cd /Users/mp/projects/ThothII/frontend
|
|
npx vitest run
|
|
npx tsc -b
|
|
```
|
|
|
|
Il marker `l2` è escluso dal default del harness e va eseguito esplicitamente con
|
|
`.venv/bin/pytest -q -m l2` quando credenziali e servizi reali sono disponibili. I test `l0` che
|
|
usano testcontainers richiedono Docker; skip o ambiente mancante vanno riportati nel verbale.
|
|
Conservare inoltre il dettaglio dei gruppi rilevanti:
|
|
|
|
- `harness/tests/test_evidence_authoring.py` e `test_evidence_cli.py`;
|
|
- `test_evidence_canonical.py`, filesystem/HTTP/S3 source adapter tests;
|
|
- `test_corpus_pipeline.py`, `test_corpus_publish.py`, candidate publication ed evaluation;
|
|
- `test_qdrant_vector_store.py` e, con Docker, `tests/l0/test_qdrant_bm25_inference.py`;
|
|
- backend registry/materialization/preprocessing service/state tests;
|
|
- frontend `WorkspaceManager.test.tsx`.
|
|
|
|
Queste suite usano in vari punti fake di embedder/Qdrant. Un PASS automatico non sostituisce il
|
|
percorso live di questo piano.
|
|
|
|
### 21.1 Seam ad alto rischio da osservare esplicitamente
|
|
|
|
Questi punti risultano rischiosi nell'implementazione corrente e non devono essere esclusi dal
|
|
verbale se falliscono:
|
|
|
|
- la risoluzione citation delle unità v3 potrebbe cercare l'ID nella forma legacy anziché nei
|
|
metadata `curated_evidence`;
|
|
- una nuova source URI commit-addressed può far apparire modificati documenti con contenuto
|
|
invariato e causare un full re-embedding;
|
|
- se una document generation viene riusata ma i suoi punti esistono solo sotto la revisione vecchia,
|
|
il filtro Qdrant revision-pinned può renderla irrecuperabile: inventory e retrieval devono fallire;
|
|
- `workspace vector rebuild` può ricreare il dense senza ripristinare subito BM25: non usarlo come
|
|
recovery nominale e, se testato, verificare il contratto completo dopo il rebuild;
|
|
- il writer lock/conflitto va provato live, perché la sola presenza delle primitive nei test non
|
|
dimostra che il percorso produttivo le acquisisca;
|
|
- non esiste un comando pubblico per inventory, elenco job o riattivazione di una generazione
|
|
precedente;
|
|
- il report dettagliato della candidate evaluation fallita non è persistito prima della
|
|
compensazione; serve instrumentation prodotto per osservarne rank e `missing_expected`;
|
|
- l'adapter S3 operativo è più restrittivo di alcune varianti accettate dallo schema; i casi custom
|
|
vanno classificati come gap di superficie, non come scenario nominale.
|
|
|
|
## 22. Criteri finali PASS/FAIL
|
|
|
|
Il collaudo filesystem/lifecycle è PASS solo se:
|
|
|
|
1. G1-G6 completano con gli oracle documentati;
|
|
2. ID stabili, hash, provenance, revision e generation sono coerenti;
|
|
3. l'inserimento incrementale non reprocessa documenti invariati;
|
|
4. la modifica non è visibile prima dell'atomic switch, la versione precedente resta recuperabile e
|
|
la nuova lo è dopo; nessuno split-brain registry/Evidence;
|
|
5. orphan blocca, retirement/relink sono espliciti e auditabili;
|
|
6. nessun record retained/obsolete viene restituito come attivo;
|
|
7. retrieval copre tutti i purpose, verifica l'outcome `available` vuoto e non mescola
|
|
workspace/revision;
|
|
8. le sessioni S1, S2, S3 e S5 coprono accettazione, rifiuto, proposta session-only e pinning; S1
|
|
contiene cinque receipt e decisioni/citation corrette;
|
|
9. il conflict di sessione G3 e l'evaluation failure lasciano ACTIVE consistente;
|
|
10. retention/GC e non regressione Schema/Memory/solved sono verificati;
|
|
11. nessun secret o path non sicuro attraversa i confini;
|
|
12. ogni FAIL ha reproduction, expected/actual, commit, revision, run ID e generation.
|
|
|
|
La dichiarazione **COMPLETE PASS** richiede inoltre: G7/G8 con S4 prompt injection; RET-07
|
|
`unavailable`/stage bloccato; report sanitizzato della candidate evaluation fallita; campagna
|
|
fault/resume REL-05..13 su stack isolata;
|
|
tutti gli otto kind; adapter HTTP/S3 reali supportati; migrazione v1/v2, `--upgrade`, evaluation di
|
|
una generation selezionata e cambio kind. Se una di queste campagne non viene eseguita, il miglior
|
|
esito ammesso è `PASS — filesystem lifecycle`, mai “copertura completa”.
|
|
|
|
Il risultato è **INCONCLUSIVE**, non PASS, se mancano inventory Qdrant, sessione core completa,
|
|
proof di ACTIVE before/after o verifica della revisione pinnata.
|
|
|
|
## 23. Teardown sicuro
|
|
|
|
Eseguire il teardown solo dopo aver completato e verificato gli allegati:
|
|
|
|
1. salvare hash del report, registry active revision, Evidence ACTIVE/generation manifest, inventory
|
|
Qdrant e stato delle sessioni;
|
|
2. verificare che il report contenga la prova snapshot/artifact/citation G2 raccolta **prima** della
|
|
finalizzazione in G3; non richiedere che lo snapshot G2 esista ancora dopo G6;
|
|
3. finalizzare tutte le sessioni lab ancora resumable e archiviarle dove la superficie lo consente,
|
|
senza riaprire sessioni già chiuse;
|
|
4. nella UI ripristinare `psd-clinical` come workspace selezionato e le impostazioni originarie;
|
|
eseguire **Validate workspace source**, **Test workspace connections** e una nuova query canary PSD;
|
|
5. rimuovere binding e secret del lab tramite la superficie supportata, se previsto dalla campagna;
|
|
se non esiste una rimozione supportata, documentare il residuo senza esporne il valore;
|
|
6. non cancellare collection, dataRoot, branch, commit o report prima della firma del verbale. La loro
|
|
eliminazione è un'attività distruttiva separata e richiede autorizzazione esplicita e target
|
|
risolti; preferire snapshot/archiviazione recuperabile;
|
|
7. ripetere il controllo non-regressione PSD e registrare che settings, sessioni e punti non sono
|
|
cambiati. Un fallimento di ripristino rende l'intero collaudo FAIL.
|
|
|
|
## 24. Template del verbale
|
|
|
|
```markdown
|
|
# Evidence lifecycle acceptance — <data>
|
|
|
|
- Tester:
|
|
- Installazione:
|
|
- Branch/commit finale:
|
|
- Workspace/collection:
|
|
- DWH binding type:
|
|
- Ollama model/dimensions:
|
|
- Scope verdict (`PASS — filesystem lifecycle` / `COMPLETE PASS` / `INCONCLUSIVE` / `FAIL`):
|
|
- Version/hash di probe, inventory, fault harness e instrumentation evaluation:
|
|
|
|
| Ciclo | Commit | Registry active revision | Run ID | Candidate generation | Evaluation | Evidence ACTIVE before/after | Runtime active view | `document_generations` | Esito |
|
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
| G1 initial | | | | | | | | | |
|
|
| G2 add | | | | | | | | | |
|
|
| G3-bad | | | | | | | | | |
|
|
| G3-fix | | | | | | | | | |
|
|
| G4-bad | | | | | | | | | |
|
|
| G4-fix | | | | | | | | | |
|
|
| G5 rename | | | | | | | | | |
|
|
| G6 relink | | | | | | | | | |
|
|
| G7 security injection | | | | | | | | | |
|
|
| G8 security retire | | | | | | | | | |
|
|
|
|
## Retrieval/sessioni
|
|
|
|
| Query/stage | Purpose/filtri | Revision/generation | Expected/actual IDs | Rank dense/BM25/fused | Outcome | PASS/FAIL |
|
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
|
|
## Fault e recovery
|
|
|
|
| Fault/fault ID | Barrier/run ID | ACTIVE prima | Risultato | ACTIVE dopo | Cleanup | PASS/FAIL |
|
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
|
|
## Non regressione e sicurezza
|
|
|
|
- Schema/Memory/solved:
|
|
- Workspace isolation:
|
|
- Secret scan:
|
|
- Prompt injection:
|
|
- Retention/GC:
|
|
|
|
## Difetti
|
|
|
|
| ID | Severità | Reproduction | Expected | Actual | Allegati |
|
|
| --- | --- | --- | --- | --- | --- |
|
|
```
|
|
|
|
## 25. Riferimenti normativi
|
|
|
|
- `CONTEXT.md`, sezione Evidence;
|
|
- `docs/evidence.md`;
|
|
- `docs/contracts/workspace-evidence-v3.md`;
|
|
- `docs/contracts/workspace-preprocessing-cli.md`;
|
|
- `docs/operations/workspaces.md`;
|
|
- `harness/.pi/skills/tht-evidence-authoring/SKILL.md`;
|
|
- `harness/.pi/skills/tht-sessione/SKILL.md` e modulo runtime Evidence;
|
|
- `harness/tht/evidence/` e `harness/tht/cli/search_cmd.py`.
|