Files
ThothII/docs/prd/2026-08-09-workspace-preprocessing-prd.md
T

534 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PRD — Preprocessing per-workspace su ThothII (Qdrant + Git workspace registry)
**Status:** PRD in revisione — decisioni D1–D9 chiuse il 2026-08-09; i piani P1–P10 partiranno solo dopo
revisione e conferma del proprietario
**Data:** 2026-08-09
**Autore:** analisi dello stato attuale (branch `codex/git-workspace-registry`) + decisioni con il proprietario
**Uso:** riferimento stabile di requisiti e decisioni; da ogni punto nascerà un piano separato in
`docs/superpowers/plans/` (sez. 11) — questo documento non è un piano di lavoro
---
## 1. Contesto
ThothII è passato da un indice semantico **pgvector sul server PSD** (descrizioni di tabelle/colonne,
evidence e memory embeddate nella stessa istanza Postgres del DWH, lettura via RPC `search_similar`,
scrittura via REST dedicato o loading diretto) a un'architettura con:
- **infrastruttura semantica interna obbligatoria**: Qdrant + Ollama (`qwen3-embedding:0.6b`, 1024 dim,
cosine) come servizi Compose privati; una **collection Qdrant per workspace**, con schema/evidence/memory
separati dal payload `kind`;
- **workspace definito da un descriptor schema-v3 in un repo Git esterno** (id, DWH, collection, LLM
policy, diagnostics), con binding DWH locali all'installazione;
- **config harness renderizzata dal backend** a runtime (`runtime_identity` + `resources.vector` +
`resources.embeddings` + `roots` sotto `<dataRoot>/sessions/<wsId>/`).
La **macchina di preprocessing** (comandi, job a generazioni con publish atomico, adapter Qdrant, corpus
evidence, FK, memory) **esiste già ed è testata**: `tht preprocess evidence|dwh`, `tht vector init|index-schema`,
`tht schema introspect|suggest-fks|check`, `tht evidence extract|index`, `tht lsh build`, memory/solved.
Esistono job Compose fixture (`deploy/compose.preprocess.yaml` + `deploy/workspaces/preprocess-{dwh,evidence}.yaml`)
e uno smoke (`scripts/preprocess-smoke.sh`).
### Il problema
Il preprocessing **non è collegato al workspace reale del registry**:
1. i job fixture usano una collection fissa (`preprocess-evidence`), un workspace_id derivato dal nome
file (`preprocess-evidence`) e roots sotto `/data/workspaces/preprocess-*`, che **non coincidono** con
quelli del runtime (`<dataRoot>/sessions/<wsId>/`);
2. il backend **non espone alcun modo** di eseguire `tht preprocess` contro la config renderizzata di un
workspace (nessun endpoint, nessuno script, nessun comando documentato);
3. il **descriptor v3 e la config renderizzata non hanno la sezione `evidence`**: non c'è un posto canonico
dove dichiarare da dove arrivano le evidence di un workspace;
4. l'**ammissione sessione** (`ThtRunner.qdrantEnsure`) richiede la collection già esistente con 1024/cosine
e 8 payload keyword-index, ma **nessuno la crea esplicitamente** (`tht vector init` fallisce se manca);
5. le **generazioni `.tht-dwh` sono legate a un fingerprint della config completa** (`OWNER.json`:
workspace_id + config_fingerprint + input_fingerprint): se il preprocessing non usa la config identica a
quella renderizzata dal runtime, a runtime la generazione viene **rifiutata**;
6. la **cura FK** (`annotations.yaml`) è manuale e vive nel runtime artifacts; il registry **non sincronizza**
file dal repo ai roots runtime;
7. i **vecchi embedding pgvector (nomic 768d) non sono riusabili** (modello e dimensioni cambiati): serve
re-indicizzare i contenuti PSD.
**Sintesi:** la parte "motore" è pronta; manca il **collegamento per-workspace** (config, esecuzione,
bootstrap, sorgente evidence) e la **documentazione operator**.
---
## 2. Obiettivo
Rendere l'attuale versione di ThothII (Qdrant + workspace su repo esterno) **configurabile e utilizzabile**
per un workspace reale, inclusa l'intera catena di preprocessing: **tabelle/colonne (catalogo + embedding),
FK (cura), evidence (sorgente → corpus → embedding), memory/solved**, con un flusso operator riproducibile,
documentato e verificato da smoke end-to-end.
### Obiettivi secondari
- O1. Un solo modo canonico di eseguire il preprocessing per un workspace (niente più fixture "speciali").
- O2. Il preprocessing è **idempotente e ripristinabile**: rerun senza duplicati, publish atomico, GC.
- O3. Nessun segreto/endpoint entra nel repository registry né nei descriptor (invariante attuale preservato).
- O4. Il flusso è **documentato nei manuali operator** (`local/server-workspace-registry.md`) e coperto da
smoke automatici.
- O5. La **migrazione PSD** è definita (cosa si riusa, cosa si rigenera, cosa si esporta dal pgvector).
- O6. Ogni piano tecnico definisce, dove applicabile, un **goal automatico di processo completo**: da stato
pulito costruisce un ambiente isolato, simula il flusso end-to-end entro lo scope del piano e lo porta a
successo con un integration test riproducibile.
- O7. Dopo il successo automatico, un **percorso manuale separato** permette al reviewer di ripetere il
processo attraverso le interfacce reali, comprenderne l'architettura e approvare gli artefatti.
## 3. Non-obiettivi (fuori scope di questo PRD)
- Riscrivere il workflow NL→SQL o i gate (F1..F8) — restano invariati.
- Cambiare modello/architettura semantica (Qdrant/Ollama/1024/cosine) — già deciso e verificato.
- Rifare la UI di gestione workspace oltre a quanto già esiste.
- Il **deploy reale sul server PSD** (VPN, credenziali, portale, auth upstream): è un progetto operativo
separato che userà questo PRD come prerequisito tecnico.
- Supportare di nuovo pgvector o endpoint embedding esterni come percorso operativo.
- Il **comando di preprocessing avviabile dalla GUI**: è una release futura (fuori scope della release 0,
che è CLI sul host — vedi D2).
---
## 4. Utenti
| Utente | Esigenza |
| --- | --- |
| **Operatore/amministratore** (chi installa e cura un workspace) | Configurare DWH+evidence, eseguire il preprocessing, curare le FK, verificare lo stato, fare backup/restore. |
| **Autore ETL / curatore dominio** (es. il cliente PSD) | Mantenere evidence e annotazioni FK nel namespace del workspace nel repository registry con un flusso semplice. |
| **Reviewer umano** (usa l'app) | Vede search pack con tabelle/evidence/solved corretti: la qualità del retrieval dipende dal preprocessing. |
| **Sviluppatore ThothII** | Comandi/endpoint deterministici, testabili, senza sorprese di configurazione. |
---
## 5. Scenario target (end-to-end)
1. **Setup repo**: l'operatore usa un **unico repository Git registry** per tutti i workspace e crea
`workspaces/<id>.yaml` (schema-v3: DWH, collection, LLM policy) insieme al tree curato
`workspace-content/<id>/evidence/`; descriptor e contenuti sono pubblicati nello stesso commit.
2. **Installazione**: `.env` + bindings `THT_WS_*` + secrets; `up` dello stack (frontend/core/qdrant/embedding).
3. **Registry**: pull → validazione → snapshot attivo; diagnostic DWH verdi.
4. **Preprocessing DWH**: introspezione (physical.yaml: tabelle/colonne/descrizioni/esempi/eligibility) +
LSH; generazione pubblicata sotto `.tht-dwh` del workspace.
5. **Cura FK**: `tht schema suggest-fks` → revisione umana → `annotations.yaml` (check senza orfani);
versionata dove deciso (vedi D5).
6. **Indice schema**: `tht vector index-schema` → record schema nella collection del workspace; la
collection, se inesistente, viene creata all'ammissione (self-heal) o dal primo write (vedi D4).
7. **Preprocessing evidence**: `tht preprocess evidence` → corpus generation (chunk+embed) nella collection
(kind `evidence`) + manifest ACTIVE nel corpus root del workspace.
8. **Memory/solved**: promozioni F8 (`memory promote/save-one`) e finalize (`solved-index`) scrivono nella
collection (kind `memory`).
9. **Uso**: nuova sessione → admission verde (collection+Ollama) → F1 `search pack` con tabelle, evidence e
solved del workspace; F4/F6 con FK curate.
10. **Operatività**: backup/restore volumi (Qdrant, corpus, `.tht-dwh`, registry), update, ripristino da
outage.
---
## 6. Requisiti funzionali
### RF1 — Configurazione per-workspace
- RF1.1 Un workspace del registry deve poter dichiarare **tutto ciò che serve al preprocessing** in un unico
posto canonico: DWH (già nel descriptor), **sorgente evidence completa** (protocollo/tipo, URI, parametri
non-secret), eventuali policy di chunk/retention.
- RF1.2 I segreti (password, API key, CA) restano fuori dal repo e dal descriptor (invariante attuale).
- RF1.3 La config harness usata dal preprocessing deve essere **derivata dalla stessa renderizzazione del
runtime** (stesso workspace_id, stessi roots, stessa configurazione effettiva).
- RF1.4 La configurazione (descriptor + bindings + config renderizzata) deve **prevedere i tre trasporti
DWH**: `postgres_direct`, `rest_api`, `ssh_tunnel`. PSD usa `rest_api`; altri database potranno usare
direct o tunnel.
- RF1.5 Il registry usa **un unico repository Git** per più workspace. Per una sorgente evidence
`filesystem`, l'URI è relativa alla root del repository ed è confinata lessicalmente a
`workspace-content/<workspace_id>/`; path assoluti, traversal (`..`) e riferimenti al namespace di un
altro workspace sono invalidi. Descriptor e sorgente devono essere risolti dalla **stessa revisione Git**.
### RF2 — Preprocessing DWH (tabelle/colonne)
- RF2.1 Comando/azione per eseguire `introspect` + `lsh` per un workspace del registry, contro la sua config
effettiva, con output JSON e resume.
- RF2.2 La CLI di preprocessing raggiunge il DWH **con il trasporto dichiarato dal workspace** (direct,
REST o tunnel SSH), come il runtime.
- RF2.3 Il catalogo risultante (`physical.yaml`) alimenta: cache `tht schema introspect`, render mschema
(F1/F4), record schema per l'embedding (RF4).
- RF2.4 Refreshing esplicito quando il DWH cambia (`--refresh`/nuova generazione), senza invalidare le
sessioni esistenti (generazioni + ACTIVE pointer, già implementato).
### RF3 — FK
- RF3.1 Flusso curato per-workspace: `tht schema suggest-fks` (+ `--from-sql`, `--assume`, `--write`),
revisione umana, `tht schema check` (zero orfani).
- RF3.2 Le FK curate devono essere **disponibili a runtime** (sezione `【Foreign keys】` del render mschema,
usata da F4/F6) e **versionate nel repository registry** (D5).
- RF3.3 Nessuna FK derivata dal modello: il modello usa solo la lista curata (contratto SKILL invariato).
### RF4 — Indice semantico schema + bootstrap collection
- RF4.1 `tht vector index-schema` embedda i record schema (tabella+colonna, con descrizioni/esempi/sinonimi)
nella collection del workspace (kind `schema`), idempotente (hash → upsert solo del cambiato).
- RF4.2 **Bootstrap della collection**: se inesistente all'ammissione sessione, il runtime la crea
(self-heal) con 1024/cosine + i payload keyword-index richiesti (`content_hash, document_id, kind,
record_key, record_kind, vector_generation, workspace_id, workspace_revision`).
- RF4.3 La **CLI deve poter cancellare e ricreare** la collection di un workspace (rebuild esplicito con
guardie di sicurezza e conferma).
- RF4.4 Prima di una sessione, l'ammissione resta invariata (collection compatibile + Ollama).
### RF5 — Evidence
- RF5.1 Sorgente evidence dichiarabile per-workspace nel descriptor (protocollo/tipo + URI). Per PSD è un
**tree di file `.md` versionato nell'unico repository registry**, sotto
`workspace-content/psd/evidence/`; in generale ogni workspace usa
`workspace-content/<workspace_id>/evidence/`. HTTP manifest e S3 restano opzioni del motore per sorgenti
esterne.
- RF5.2 `tht preprocess evidence` per-workspace: discover → acquire → normalize/chunk → embed → upsert
(kind `evidence`, payload `document_id`/`vector_generation`) → publish ACTIVE nel corpus root del workspace,
con resume e dry-run (già implementato nel motore).
- RF5.3 GC/retention delle generazioni evidence (filesystem + punti Qdrant) con le policy esistenti.
- RF5.4 A runtime la ricerca evidence è filtrata dalla generazione ACTIVE e dal workspace_id (già
implementato: `ActiveEvidenceSearcher`); il flusso RF5 deve garantire che il corpus ACTIVE appartenga al
workspace giusto.
### RF6 — Memory e domande risolte
- RF6.1 `memory promote/save-one` (F8) e `memory solved-index` (finalize) scrivono nella collection del
workspace (kind `memory`/`solved_question`) — verificare end-to-end con Qdrant e risolvere i TODO residui
in `memory_cmd.py`.
- RF6.2 Il registro JSONL resta la fonte canonica; Qdrant è proiezione di ricerca (invariante attuale).
### RF7 — Migrazione PSD
- RF7.1 Definire cosa si **riusa** (physical.yaml, annotations.yaml con le ~228 FK curate, le 895 evidence
`.md`), cosa si **rigenera** (tutti gli embedding, modello diverso) e cosa si **esporta** dal pgvector del
server prima della dismissione.
- RF7.2 La migrazione è un'operazione documentata e rieseguibile, non un one-shot nel codice.
### RF8 — Operatività e documentazione
- RF8.1 Manuali operator aggiornati con la sequenza completa per-workspace (config → preprocess → cura →
verifica → uso → backup/restore).
- RF8.2 La documentazione di progetto spiega **cos'è `.tht-dwh`** (generazioni, `OWNER.json`, `ACTIVE`,
vincolo di fingerprint) in modo comprensibile per l'operatore (D3).
- RF8.3 Smoke end-to-end automatico (workspace nuovo → tutto il ciclo → sessione reale → cleanup) che
sostituisce/completa `preprocess-smoke.sh` (oggi solo fixture).
- RF8.4 Backup/restore coprono Qdrant (già `vector-backup.sh`/`vector-restore.sh`), corpus, `.tht-dwh` e
registry.
- RF8.5 Ogni piano successivo traduce il proprio risultato operativo in un **process goal** verificabile da
un integration test completo per quello scope; eventuali interventi umani iniziali o intermedi sono
ammessi solo se inevitabili, espliciti, documentati e riprendibili.
- RF8.6 Ogni process goal automatico riuscito è seguito, quando utile, da un walkthrough manuale su un
ambiente nuovo e separato; automazione e accettazione umana producono evidenze distinte.
---
## 7. Requisiti non funzionali
- **RNF1 Sicurezza**: nessun segreto in repo/descriptor/config renderizzata/log; la CLI di preprocessing
(D2) non espone credenziali, non le logga e non le scrive negli artefatti.
- **RNF2 Determinismo/idempotenza**: rerun del preprocessing = zero duplicati (hash content), publish
atomico, generazioni immutabili (già nel motore).
- **RNF3 Robustezza**: degradazione controllata (workspace senza evidence o senza collection funziona, con
warning); errori sanitizzati; nessun fallimento che corrompa la generazione attiva.
- **RNF4 Isolamento per-workspace**: ogni filtro Qdrant legato a workspace_id; rifiuto di namespace
conflittuali (già implementato nell'adapter).
- **RNF5 Compatibilità**: il preprocessing deve funzionare con la config renderizzata dal backend
(fingerprint `OWNER.json` compatibile) — è il vincolo chiave di design (vedi D3).
- **RNF6 Performance**: introspezione ~minuti (non nel path di sessione), embedding batch, LSH boundato;
il retrieval a runtime non cambia i costi attuali.
- **RNF7 Manutenibilità**: nessun fork dei fixture; un solo percorso canonico (O1).
- **RNF8 Integration-first**: il successo di un piano tecnico richiede un'esecuzione completa da ambiente
pulito, senza retry automatici che mascherino errori; ogni fallimento viene diagnosticato, corretto alla
radice e seguito da una nuova esecuzione completa.
- **RNF9 Evidenza e cleanup**: ogni ambiente simulato ha identità/ownership esplicita, risorse univoche,
segreti fittizi, report machine-readable e leggibile, scansione anti-secret e cleanup confinato alle sole
risorse possedute dal run.
---
## 8. Standard di esecuzione e verifica — integration-first
Questo standard si applica a P1 e, **ovunque sia tecnicamente significativo**, a tutti i piani successivi.
Un piano che non possa applicarlo deve motivare esplicitamente l'eccezione e definire il verifier più vicino
possibile al processo reale.
### S1 — Goal automatico di processo
- Ogni piano definisce il **processo completo entro il proprio scope**, con punto iniziale pulito, input,
componenti attraversati, risultato osservabile e criteri di successo.
- Il goal non è "far passare alcuni test", ma **simulare con successo il processo operativo** che la feature
deve rendere possibile. Per P1 il confine completo è Git → registry → API → snapshot/docs → render →
`tht config check`; estrazione evidence e Qdrant appartengono ai piani successivi.
- Durante l'esecuzione il goal resta aperto fino a una prova integrale verde. Se l'ambiente agentico supporta
goal persistenti, l'esecutore lo registra all'inizio e lo completa soltanto dopo l'evidenza finale.
### S2 — Ambiente di integrazione isolato
- Il test costruisce dipendenze controllate sotto `.artifacts/<plan>/<run-id>/`: repository Git simulati,
checkout, roots runtime, secret fixture, richieste/risposte, log e output.
- Ogni run usa identità e nomi univoci e un manifest di ownership; non usa credenziali, repository o dati
reali salvo quando il piano dichiara esplicitamente un gate L2.
- I servizi reali appartenenti allo scope vengono attraversati tramite le loro interfacce normali; quelli
esterni o non ancora nello scope sono sostituiti da fixture fedeli e deterministiche.
### S3 — Contratto di successo
- Il test parte da stato pulito, esegue il processo una volta senza retry automatici, termina con exit code
zero e produce `report.json` più un report leggibile.
- Un fallimento richiede diagnosi della causa, test regressivo/correzione e una nuova esecuzione completa da
stato pulito; ripetere alla cieca non costituisce progresso verso il goal.
- Il gate finale comprende determinismo/idempotenza pertinenti, scansione anti-secret, verifica degli
artefatti e prova del cleanup confinato. Gli artefatti possono essere conservati con `--keep` per review.
### S4 — Interventi umani inevitabili
- Passi umani iniziali o intermedi sono ammessi solo quando non simulabili in modo affidabile (per esempio
accesso approvato a un sistema reale o review di contenuto curato).
- Ogni passo umano dichiara precondizioni, istruzioni, evidenza richiesta, criterio di decisione e checkpoint
di ripresa; l'automazione copre e verifica tutto ciò che precede e segue il checkpoint.
- Un intervento umano non può essere sostituito da un'assunzione silenziosa né rendere non riproducibile il
resto del processo.
### S5 — Walkthrough manuale successivo
- Dopo il goal automatico verde, il reviewer ripete il processo in un **ambiente nuovo e separato**, usando
le interfacce reali e una guida passo-passo che spiega componente, stato letto, artefatto prodotto e
invariante verificata.
- Il walkthrough serve a comprensione architetturale e accettazione; non sostituisce l'integration test e non
ne riusa lo stato già mutato.
- Lo stato di consegna distingue almeno `automated integration: PASS` e `manual acceptance: PENDING/PASS`.
Un piano non è pienamente accettato finché l'eventuale gate manuale richiesto non è stato deciso dal reviewer.
### S6 — Contenuto obbligatorio dei piani
Ogni piano tecnico riporta, adattandoli al proprio scope:
1. **Automated process goal** e comando unico di esecuzione;
2. topologia dell'ambiente simulato e confini delle dipendenze;
3. asserzioni del full integration test e contratto del report;
4. checkpoint umani inevitabili, oppure dichiarazione esplicita che non ve ne sono;
5. walkthrough/gate manuale successivo, quando utile;
6. evidenze di completamento, retention degli artefatti e cleanup esatto.
---
## 9. Criteri di accettazione (bozza)
1. Da un repository registry vuoto si arriva a una sessione funzionante seguendo **solo i manuali aggiornati**,
senza toccare file fixture.
2. La CLI di preprocessing funziona **sia sul PC/Mac dell'utente sia sul server che ospita il DWH**
(stesso comando, config derivata dal workspace).
3. La configurazione di un workspace dichiara e usa uno dei **tre trasporti DWH** (`postgres_direct`,
`rest_api`, `ssh_tunnel`); PSD usa `rest_api`.
4. Il goal automatico P1 costruisce da zero repository Git simulati e ambiente isolato, attraversa con
HTTP reale il processo Git → registry → validate/publish/read/export → snapshot/docs → render →
`tht config check`, supera casi positivi e negativi senza retry e produce report/artefatti secret-free.
5. Solo dopo il punto 4, un ambiente manuale nuovo avvia il backend su `127.0.0.1:8791` e permette al
reviewer di ripetere ogni chiamata e ispezionare commit, snapshot, ZIP e config renderizzate seguendo una
guida; il gate resta `PENDING` finché il reviewer non lo approva.
6. `search pack` di una domanda reale restituisce tabelle (con descrizioni), evidence della generazione
ACTIVE e solved dello stesso workspace; F4/F6 mostrano le FK curate.
7. `qdrantEnsure`/`ollamaEnsure` verdi all'ammissione; la collection ha esattamente 1024/cosine + gli 8
keyword-index.
8. Rerun del preprocessing: `unchanged` (nessun duplicato); modifica di un'evidence → nuova generazione,
ACTIVE aggiornato, vecchie generazioni in GC.
9. Smoke end-to-end automatico verde in CI con cleanup esatto (stile `preprocess-smoke.sh`).
10. Migrazione PSD documentata e provata almeno in dry-run (re-introspection o riuso catalogo + re-embedding).
11. Ogni piano tecnico successivo include un process goal automatico completo per il proprio scope e un
walkthrough manuale quando utile, oppure documenta l'inevitabile eccezione umana secondo S4.
---
## 10. Decisioni chiuse (2026-08-09)
> La sezione nasceva come "punti di discussione"; le decisioni sono state prese con il proprietario del
> prodotto il 2026-08-09. Ogni punto resta il riferimento del proprio piano (sez. 11). Le opzioni scartate
> sono omesse; la motivazione della scelta è inclusa in ogni punto.
### D1 — Config per-workspace: **c) misto, con sorgente completa nel descriptor**
- Il descriptor v3 guadagna una sezione `evidence` che configura **tutta la lettura della sorgente**:
protocollo/tipo, URI/sorgente, eventuali parametri non-secret.
- Si usa **un unico repository Git registry** per tutti i workspace. Ogni workspace possiede il proprio tree
versionato sotto `workspace-content/<workspace_id>/evidence/`; per PSD il path canonico è
`workspace-content/psd/evidence/`.
- Per `filesystem`, l'URI del descriptor è repo-relative, confinata al namespace dello stesso workspace e
risolta dalla stessa revisione Git del descriptor. Sono vietati path assoluti, traversal e riferimenti al
contenuto di un altro workspace; il controllo reale di symlink/containment durante la materializzazione
appartiene a P6.
- Eventuali segreti (HTTP autenticato, S3) restano in overlay d'installazione — invariante: nessun segreto
nel repo/descriptor.
- P1 applica lo standard integration-first: prima persegue un goal automatico Git→registry→HTTP→render→
harness sotto `.artifacts/p1-integration/<run-id>/`, poi offre un walkthrough manuale separato sotto
`.artifacts/manual-acceptance/p1/`. Non include ancora estrazione, embedding o verifica degli artefatti
`artifacts/evidence` (P2+P6).
### D2 — Esecuzione: **CLI sul host in release 0; GUI in release futura**
- **Release 0**: una **CLI installata con ThothII sul host** — sia il PC/Mac dell'utente sia il server che
ospita il DWH — che esegue **tutta la catena di preprocessing** (DWH introspect+LSH, FK, index-schema,
evidence e quanto serve) per un workspace del registry.
- La CLI deriva la config dal descriptor+bindings con la stessa identità del runtime → soddisfa il vincolo
D3 senza dipendere dal backend.
- **Release futura (fuori scope)**: comando avviabile dalla GUI (endpoint backend da progettare poi).
### D3 — Fingerprint `.tht-dwh`: **accettare il vincolo + documentarlo**
- Le generazioni DWH restano legate alla config effettiva (workspace_id + config_fingerprint +
input_fingerprint in `OWNER.json`).
- La CLI (D2) gira con la config derivata dal descriptor+bindings, quindi identica alla runtime.
- **La documentazione di progetto deve spiegare chiaramente cos'è `.tht-dwh`** (directory delle generazioni
catalogo/LSH, `OWNER.json`, `ACTIVE` pointer, perché il fingerprint protegge da artefatti di un'altra
config) — oggi non è chiaro.
### D4 — Bootstrap collection: **self-heal all'ammissione + CLI delete/recreate**
- Se la collection non esiste all'ammissione sessione, il runtime la crea (1024/cosine + payload
keyword-index) — self-heal.
- La **CLI deve poter cancellare e ricreare le collection** (rebuild esplicito, con guardie di sicurezza).
### D5 — Versioning artifacts curati: **c) misto**
- `annotations.yaml` (cura FK, cura umana) **versionata nel repository registry** e sincronizzata ai roots
runtime (il registry copia il file negli snapshots → sync).
- `physical.yaml` (derivato dall'introspezione) rigenerato localmente, non versionato.
### D6 — Evidence: **a) nell'unico repository registry, con namespace per-workspace**
- Ogni workspace contiene il proprio tree versionato sotto
`workspace-content/<workspace_id>/evidence/`; le dimensioni non sono un vincolo.
- P6 materializza il tree dalla **stessa revisione Git** del descriptor, verifica il containment reale
(inclusi i symlink) e lo rende disponibile al preprocessing senza usare un checkout mobile.
- HTTP/S3 restano opzioni future per sorgenti esterne (il motore le supporta già).
### D7 — Migrazione PSD: **inclusa, con accesso al server**
- Il piano P7 copre: riuso di physical.yaml + annotations.yaml + evidence `.md` dal repository registry; export
dal pgvector del server PSD (accesso disponibile); re-embedding con `qwen3-embedding:0.6b`; dry-run
documentato.
### D8 — Verifica end-to-end: **integration-first + walkthrough manuale; remote Git libero; DWH multi-trasporto**
- Ogni fase adotta lo standard della sez. 8: prima un process goal automatico da ambiente pulito, poi —
quando utile o richiesto — un walkthrough manuale su stato separato. P1 è il primo riferimento concreto.
- Il livello finale del PRD resta: smoke automatico su workspace sintetico (CI) + gate manuale L2 su PSD.
- Il namespace PSD sarà **prima alimentato nel repository registry** (descriptor + evidence + annotations
nello stesso flusso Git), **poi** usato da ThothII. Accesso al server PSD disponibile.
- **Remote Git**: lo creiamo noi, nessun vincolo tecnico (consigliato GitHub via HTTPS; SSH resta
possibile se servirà).
- **Trasporto DWH**: PSD via **REST** (come oggi); **la configurazione deve prevedere le tre modalità** —
`rest_api`, `postgres_direct`, `ssh_tunnel` — perché altri database potrebbero richiedere accesso TCP
diretto o via tunnel. Oggi `ssh_tunnel` è solo diagnostico a runtime: va reso operativo dove serve
(vedi P10).
### D9 — Retention/GC: **confermata**
- Default invariati (`retain_published_generations: 3`, chunk 4000 char), configurabili per-workspace via
la sezione `evidence`/policy del descriptor (D1).
## 11. Mappa dei piani (uno per punto del PRD)
Questo PRD non diventa un unico piano: **ogni decisione/requisito produce un piano separato (P1–P10)** in
`docs/superpowers/plans/`, eseguibile in sequenza o come workstream indipendenti. Il PRD resta il
riferimento stabile (requisiti + decisioni); ogni piano cita il punto di origine e i criteri di
accettazione applicabili (sez. 9) e adotta lo standard integration-first (sez. 8).
| Piano | Punto PRD | Contenuto sintetico | Dipende da |
| --- | --- | --- | --- |
| P1 | D1 | Descriptor v3: sezione `evidence` (protocollo/tipo, URI repo-relative sotto `workspace-content/<id>/evidence/`) + policy e isolamento namespace; goal automatico Git→registry→HTTP→render→harness, seguito da walkthrough manuale | — |
| P2 | D2 | **CLI di preprocessing sul host (release 0)**: comando per-workspace che esegue l'intera catena (DWH, FK, index-schema, evidence) con la config derivata da descriptor+bindings; funziona su PC/Mac utente e server DWH | P1 |
| P3 | D3 | Vincolo fingerprint `.tht-dwh` (test: preprocess con config identica alla runtime) + **documentazione di progetto su cos'è `.tht-dwh`** | P2 |
| P4 | D4 | Bootstrap collection: **self-heal all'ammissione** (creazione 1024/cosine + keyword-index) + **comandi CLI delete/recreate** con guardie | — |
| P5 | D5 | `annotations.yaml` versionata nel repository registry + sync registry → roots runtime | P1 |
| P6 | D6 | Materializzazione del tree `workspace-content/<id>/evidence/` dalla revisione Git fissata → preprocess; containment reale e protezione da symlink escape | P1 |
| P7 | D7 | Migrazione PSD: riuso catalogo/annotations/evidence, **export pgvector (accesso server)**, re-embedding, dry-run | P1–P6 |
| P8 | D8 | Verifica end-to-end: smoke CI + gate L2 su PSD (**namespace PSD nel repository registry alimentato prima dell'uso**; remote Git a scelta) | P1–P7 |
| P9 | D9 | GC/retention per-workspace: policy configurabili, default invariati | P1 |
| P10 | D8/RF1.4 | Trasporti DWH operativi: rendere `ssh_tunnel` utilizzabile a runtime e nella CLI di preprocessing (oggi solo diagnostico); verifica dei tre trasporti (direct, REST, tunnel) | P1, P2 |
### Standard di verifica obbligatorio del futuro piano P1
P1 è il primo piano che applica integralmente la sez. 8 e deve contenere due task/gate distinti e ordinati.
#### 1. Automated integration goal — complete P1 configuration process
Un comando unico (nome definitivo nel piano, interfaccia indicativa
`./scripts/p1-acceptance.sh integration --keep`) costruisce da zero:
```text
.artifacts/p1-integration/<run-id>/
├── ownership.json
├── remote.git/ # remote bare locale
├── author/ # clone curatore + tree evidence
├── installation/ # checkout, snapshot e stato registry
├── runtime-data/
├── fixture-secrets/
├── requests/ # payload HTTP positivi/negativi
├── responses/
├── rendered/
├── exports/
├── logs/
├── report.json
└── report.md
```
Il test attraversa le interfacce reali appartenenti a P1: Git reale locale, backend Fastify su una porta
loopback temporanea, route HTTP validate/publish/pull/read/export, snapshot/docs/contract, renderer di
produzione e `tht config check`. Verifica anche stessa revisione Git per descriptor/tree, determinismo,
path/protocolli/secret fields invalidi, assenza di leak e cleanup confinato. Non usa frontend, Docker, DWH,
Qdrant o Ollama perché non appartengono allo scope P1.
L'esecuzione non applica retry automatici. In caso di errore l'esecutore diagnostica, aggiunge la copertura
regressiva necessaria, corregge e rilancia l'intero scenario da una nuova root pulita. Il goal è raggiunto
solo con exit code zero e report integralmente verde; con `--keep` le evidenze restano disponibili.
#### 2. Manual acceptance gate — descriptor and rendered configuration artifacts
Dopo il goal automatico verde, il piano prepara uno stato nuovo e indipendente sotto:
```text
.artifacts/manual-acceptance/p1/
├── remote.git/
├── author/
├── installation/
├── runtime-data/
├── requests/
├── responses/
├── output/
├── logs/
└── GUIDE.md
```
Un helper esegue soltanto `prepare/serve/stop/cleanup`; `serve` avvia il backend reale sull'host, senza
Docker e senza frontend, vincolato a `127.0.0.1:8791`. Il reviewer segue `GUIDE.md` ed esegue personalmente
le chiamate HTTP, i comandi Git, l'export ZIP, il doppio rendering, il confronto e `tht config check`, poi
prova i casi invalidi e decide il gate.
Il gate verifica manualmente: sezione `evidence`; pubblicazione/rilettura; commit e snapshot immutabile;
workspace docs/contract; config harness; assenza di segreti; sicurezza protocollo/path e isolamento
cross-workspace; output deterministico. Gli artefatti restano fino alla decisione e il cleanup rimuove solo
la root posseduta dal test.
P1 **non** dichiara di aver generato o validato `artifacts/evidence`: estrazione e mirroring richiedono
P2+P6; record Qdrant, embedding, generazioni ACTIVE e retention appartengono ai piani successivi. Dopo il
goal automatico lo stato è `automated integration: PASS / manual acceptance: PENDING`; P1 diventa pienamente
accettato soltanto dopo la decisione del reviewer.
Ordine consigliato: **P1 → P2 → P3** (catena config/esecuzione), **P4** e **P5/P6** in parallelo dopo P1,
poi **P7 → P8**; P9 può essere assorbito in P1 o restare autonomo; **P10** dopo P1+P2 (necessario solo se un
workspace target richiede davvero il tunnel — per PSD non serve, usa REST).
Ogni piano segue la prassi del repo: TDD, commit scoping, verifica layer (pytest/vitest/tsc/build) e lo
standard della sez. 8; gate deployment e smoke Docker si aggiungono quando appartengono allo scope. Lo stato
traccia separatamente implementazione, automated integration e manual acceptance.
---
## 12. Storico revisioni
| Versione | Data | Contenuto |
| --- | --- | --- |
| v0.1 | 2026-08-09 | Bozza da analisi dello stato attuale (gap preprocessing per-workspace) |
| v0.2 | 2026-08-09 | Decisioni D1–D9 chiuse con il proprietario; mappa piani P1–P10; requisiti RF1–RF8 aggiornati (evidence nel descriptor, CLI sul host, self-heal collection, multi-trasporto DWH) |
| v0.3 | 2026-08-09 | Revisione di coerenza (numerazioni, riferimenti incrociati, header di stato) — pronto per revisione del proprietario |
| v0.4 | 2026-08-09 | D1/D6: repository registry unico, namespace `workspace-content/<id>/evidence/`, pin alla stessa revisione Git e gate manuale P1 con remote locale usa-e-getta sotto `.artifacts/` |
| v0.5 | 2026-08-09 | Standard integration-first per P1–P10: process goal automatico completo da ambiente simulato e pulito, gestione esplicita degli interventi umani inevitabili e walkthrough manuale successivo su stato separato |
---
## 13. Riferimenti
- Stato attuale: `PROJECT_STATE.md` (sezioni "Internal Qdrant + Ollama semantic infrastructure", snapshot
registry) e `AGENTS.md`.
- Design architettura semantica: `docs/plans/2026-08-08-internal-qdrant-ollama-design.md` e relativo piano.
- Registry: `docs/superpowers/specs/2026-08-03-git-workspace-registry-design.md`, manuali
`docs/install/local-workspace-registry.md` / `server-workspace-registry.md`.
- Motore preprocessing: `harness/tht/cli/preprocess_cmd.py`, `harness/tht/corpus/pipeline.py`,
`harness/tht/jobs/dwh_pipeline.py`, `harness/tht/adapters/vector/qdrant.py`,
`harness/tht/vectorstore/records.py`, `harness/tht/cli/{vector,schema,evidence,memory}_cmd.py`.
- Fixture attuali: `deploy/compose.preprocess.yaml`, `deploy/workspaces/preprocess-{dwh,evidence}.yaml`,
`scripts/preprocess-smoke.sh`.
- Ammissione runtime: `backend/src/tht/tht-runner.ts` (`qdrantEnsure`/`ollamaEnsure`),
`backend/src/workspaces/runtime-renderer.ts`.