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.
56 KiB
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:
- creazione e registrazione di un workspace parallelo a PSD;
- inserimento di Source Evidence e generazione delle Curated Evidence strutturate;
- revisione, validazione, commit, acquisizione commit-addressed e inventario;
- indicizzazione dense + BM25 in Qdrant;
- ricerca tipizzata e uso nei processi core F1-F8;
- inserimento incrementale, modifica e riacquisizione;
- rename, relink, rimozione, orphan e retirement;
- idempotenza, retention, concorrenza, recovery e fallimenti parziali;
- 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 patterncurated/**/*.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:
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:
- preparare i tre testi descritti nella sezione 6;
- leggere integralmente ogni diff delle Curated Evidence e confrontarlo con la source;
- decidere sulle ambiguità, sui review item, sul rename, sul relink e sul retirement;
- usare Workspace Management per update, validate e test connections;
- 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:
- creare scaffold, descriptor, catalog entry ed evaluation set;
- eseguire i due CLI
thtcorretti, Git e le verifiche read-only; - raccogliere commit SHA, revision, run ID, generation e inventario Qdrant;
- confrontare before/after e segnalare ogni violazione degli oracle;
- predisporre e validare le probe assistite di runtime e inventory descritte nelle sezioni 7 e 16;
- indurre fault controllati soltanto nel laboratorio isolato e ripristinare i servizi;
- 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:
disambiguationerewriting.
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_linkingesql_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:
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:
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
"$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
"$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:
"$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:
"$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:
"$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
- Aggiungere soltanto D1 e D2 in
source/. - Eseguire
evidence prepareda worktree concurated/emanifest.yamlpuliti. - 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. - 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.
- Dopo ogni
prepare,curated/emanifest.yamlsono dirty e un altroprepareè 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 rieseguireprepare. Ripetere se necessario e non correggere i marker a mano. - Creare
evaluation.yamldopo aver conosciuto gli ID. Il contratto richiede almeno una query per ciascun profilolexical,semanticemixed; 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. - Eseguire prima
EVIDENCE_PROBE validate-fixture, poievidence validate; entrambi devono uscire0, mentre solo il secondo esponepublishable=trueper il corpus. - Committare localmente lo stato finale valido. Solo ora, da worktree pulito, rieseguire
preparesenza modifiche:modelCalls=0,changed=[], entrambe le source inunchangede nessun diff. - Pushare la testa valida della revisione G1; aggiornare il repository dalla UI. Eventuali commit intermedi restano una review trail e non devono contenere secret.
- Eseguire inspect, vector inspect, dry-run e preprocess reale.
- 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
bm25con modifieridfè presente senza perdita del dense unnamed. - Punti schema preesistenti nella collection lab sono invariati.
- Un secondo preprocess identico restituisce
unchangede non crea punti duplicati.
11. Ciclo G2 — inserimento incrementale di D3
- Aggiungere soltanto D3.
- Eseguire prepare/review/validate.
- Verificare una sola model call, un solo nuovo ID e D1/D2 invariati.
- Aggiungere all'evaluation query lexical, semantic o mixed per D3 e per la domanda composita;
eseguire
validate-fixtureoltre aevidence validate. - Commit, push, UI update, dry-run e preprocess reale.
- 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à.
- Verificare che il manifest ACTIVE elenchi tutte e tre le unità.
- 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.
- 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.
- 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.
- Prima di
prepare, eseguirevalidate: deve rilevare il drift di hash/provenienza e bloccare. - Eseguire
prepare: una model call, D1 inchanged, D2/D3 inunchanged. L'ID D1 resta identico; source hash e contenuto canonico cambiano. - Aggiornare le query nominali dell'evaluation per la nuova formulazione, mantenendo i profili
lexical,semantic,mixede una query per ogni ID importante. - Aggiungere poi un caso G3-bad strutturalmente valido: un'ulteriore query
mixedcon expected ID D1 esistente, ma purposesql_generation, che non appartiene a D1 (disambiguation/rewriting). Non usare ID inventati e non eliminare gli altri profili. Eseguirevalidate-fixture: deve restituire0; eseguire separatamenteevidence validate, il cui exit0non costituisce prova sulla fixture. Se uno dei due fallisce, ridisegnare il caso prima del test. - Revisionare, committare G3-bad, pushare, usare Update workspace repository e registrare la nuova registry active revision. L'Evidence ACTIVE generation deve essere ancora G2.
- 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.
- Tentare il preprocess G3-bad mentre la sessione è resumable: atteso
preprocessing_conflict; nessuna candidate generation né modifica ad ACTIVE. - 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.
- 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 dettaglioNOT OBSERVABLE. - Correggere la fixture assegnando a D1 un purpose ammesso, rieseguire
validate-fixtureeevidence validate, committare G3-fix, pushare e aggiornare di nuovo il repository. - 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.
- 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.
- 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.
- Rimuovere il file source D2.
- Eseguire
prepare: D2 deve diventare orphan; l'unità non viene cancellata automaticamente. - Eseguire
validate: exit3,orphaned_unite/osource_no_longer_supports_unit; nessuna pubblicazione ammessa. - 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. - Da quel worktree pulito, il reviewer decide il retirement ed esegue
evidence resolve ... --retire. - Aggiornare
evaluation.yaml: eliminare o sostituire ogni query che attende D2, mantenendo almeno un caso per ciascun profilolexical,semantic,mixed, la copertura dei purpose ancora attivi e query dedicate a D1/D3. - Eseguire
validate-fixtureeevidence validatecon exit0, committare la risoluzione G4-fix, pushare la testa valida, fare UI update e preprocess. - 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
- Rinominare la source D1 senza cambiare un byte.
- Eseguire
prepare. - Atteso: riconoscimento univoco tramite hash, ID stabile, nessuna ristrutturazione non necessaria.
- Pubblicare e verificare citation/provenienza sul nuovo path.
14.2 G6 — relink esplicito
- Rimuovere il source path corrente di D1, eseguire
preparee verificare l'orphan convalidateexit3; creare un commit locale G6-orphan. Questo passaggio è necessario: aggiungere prima il nuovo file trasformerebbe il caso in rename/hash match, non in relink. - Dal commit G6-orphan creare un worktree/branch negativo separato. Aggiungere e committare una
source priva dell'exact excerpt, poi lanciare
resolve --source: atteso exit1con findingsupporting_excerpt_missing. Il relink può essere applicato, mavalidate/publish devono restare bloccati; non unire questa variante. - Nel worktree principale, ancora pulito sul commit G6-orphan, aggiungere il nuovo file source con
gli exact excerpt necessari e committarlo senza eseguire
prepare. - Eseguire
evidence resolve ... --source source/<nuovo-path>. - Verificare stesso ID, nuovo source file/hash, rimozione dell'orphan e assenza del finding.
- 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.
- 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. - 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.
- S3 — proposta: chiedere un calcolo non presente nel corpus e lasciare che la sessione proponga
una formula. Deve restare
formula_proposalsession-only: nessun file curated, manifest, punto Qdrant o IDevidence:viene creato. - 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.
preparenon deve obbedire alla frase né produrre leakage/tool action; aggiungere una query evaluation dedicata al nuovo ID, eseguirevalidate-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. - 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:
"$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:
"$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:
- leggere
ACTIVEe il generation manifest; - estrarre
document_generations; - costruire la pointer view dalle coppie esatte
(document_id, vector_generation)didocument_generations, anche cross-revision, per provare quali punti fisici supportano il puntatore Evidence; - costruire l'active runtime view aggiungendo
workspace_id=psd-evidence-labe laworkspace_revisionpinnata, replicando tutti i predicati runtime prima del limit; - acquisire separatamente tutti i punti retained del workspace e raggrupparli per Evidence ID,
document ID, vector generation e
workspace_revision; ogni punto deve avererecord_kind=evidenceekind=evidence; - verificare gli otto payload index richiesti:
content_hash,document_id,kind,record_key,record_kind,vector_generation,workspace_id,workspace_revision; - 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:
"$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 != finalizede 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/omanifest.yamlprima di prepare; - una di tre ristrutturazioni fallisce: nessuna applicazione parziale.
18.2 Descriptor e materializzazione
evidence.schema_versionomesso: 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 URIs3://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.yamlo 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_tableeschema_column; - punti
memoryesolved_questioneventualmente 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:
- HTTP reale: redirect, cache, timeout, byte limit, SSRF e rebind;
- 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 edevaluation.yamldella revisione che pubblicò la generation; provare sia ACTIVE sia una generation retained;- un cambio controllato di
kinddella 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:
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.pyetest_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.pye, 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 rebuildpuò 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:
- G1-G6 completano con gli oracle documentati;
- ID stabili, hash, provenance, revision e generation sono coerenti;
- l'inserimento incrementale non reprocessa documenti invariati;
- la modifica non è visibile prima dell'atomic switch, la versione precedente resta recuperabile e la nuova lo è dopo; nessuno split-brain registry/Evidence;
- orphan blocca, retirement/relink sono espliciti e auditabili;
- nessun record retained/obsolete viene restituito come attivo;
- retrieval copre tutti i purpose, verifica l'outcome
availablevuoto e non mescola workspace/revision; - le sessioni S1, S2, S3 e S5 coprono accettazione, rifiuto, proposta session-only e pinning; S1 contiene cinque receipt e decisioni/citation corrette;
- il conflict di sessione G3 e l'evaluation failure lasciano ACTIVE consistente;
- retention/GC e non regressione Schema/Memory/solved sono verificati;
- nessun secret o path non sicuro attraversa i confini;
- 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:
- salvare hash del report, registry active revision, Evidence ACTIVE/generation manifest, inventory Qdrant e stato delle sessioni;
- 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;
- finalizzare tutte le sessioni lab ancora resumable e archiviarle dove la superficie lo consente, senza riaprire sessioni già chiuse;
- nella UI ripristinare
psd-clinicalcome workspace selezionato e le impostazioni originarie; eseguire Validate workspace source, Test workspace connections e una nuova query canary PSD; - 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;
- 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;
- 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
# 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.mde modulo runtime Evidence;harness/tht/evidence/eharness/tht/cli/search_cmd.py.