PRD for making ThothII (Qdrant + Git workspace registry) configurable and usable per workspace, covering the full preprocessing chain (tables/columns, FK, evidence, memory). Decisions D1-D9 closed with the product owner; plans P1-P10 (one per PRD point) will start only after owner review.
22 KiB
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. 10) — 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 payloadkind; - 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+rootssotto<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:
- 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>/); - il backend non espone alcun modo di eseguire
tht preprocesscontro la config renderizzata di un workspace (nessun endpoint, nessuno script, nessun comando documentato); - 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; - 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 initfallisce se manca); - le generazioni
.tht-dwhsono 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; - la cura FK (
annotations.yaml) è manuale e vive nel runtime artifacts; il registry non sincronizza file dal repo ai roots runtime; - 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 repo workspace 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).
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 la cartella evidence e le annotazioni FK nel repo workspace 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)
- Setup repo: l'operatore crea
workspaces/<id>.yaml(schema-v3: DWH, collection, LLM policy) + la sorgente evidence dichiarata; push. - Installazione:
.env+ bindingsTHT_WS_*+ secrets;updello stack (frontend/core/qdrant/embedding). - Registry: pull → validazione → snapshot attivo; diagnostic DWH verdi.
- Preprocessing DWH: introspezione (physical.yaml: tabelle/colonne/descrizioni/esempi/eligibility) +
LSH; generazione pubblicata sotto
.tht-dwhdel workspace. - Cura FK:
tht schema suggest-fks→ revisione umana →annotations.yaml(check senza orfani); versionata dove deciso (vedi D5). - 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). - Preprocessing evidence:
tht preprocess evidence→ corpus generation (chunk+embed) nella collection (kindevidence) + manifest ACTIVE nel corpus root del workspace. - Memory/solved: promozioni F8 (
memory promote/save-one) e finalize (solved-index) scrivono nella collection (kindmemory). - Uso: nuova sessione → admission verde (collection+Ollama) → F1
search packcon tabelle, evidence e solved del workspace; F4/F6 con FK curate. - 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 usarest_api; altri database potranno usare direct o tunnel.
RF2 — Preprocessing DWH (tabelle/colonne)
- RF2.1 Comando/azione per eseguire
introspect+lshper 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: cachetht 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 repo workspace (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-schemaembedda i record schema (tabella+colonna, con descrizioni/esempi/sinonimi) nella collection del workspace (kindschema), 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
.mdin una directory versionata nel repo del workspace (evidence/); HTTP manifest e S3 restano opzioni del motore per sorgenti esterne. - RF5.2
tht preprocess evidenceper-workspace: discover → acquire → normalize/chunk → embed → upsert (kindevidence, payloaddocument_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) ememory solved-index(finalize) scrivono nella collection del workspace (kindmemory/solved_question) — verificare end-to-end con Qdrant e risolvere i TODO residui inmemory_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-dwhe registry.
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.jsoncompatibile) — è 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).
8. Criteri di accettazione (bozza)
- Da un repo workspace vuoto si arriva a una sessione funzionante seguendo solo i manuali aggiornati, senza toccare file fixture.
- La CLI di preprocessing funziona sia sul PC/Mac dell'utente sia sul server che ospita il DWH (stesso comando, config derivata dal workspace).
- La configurazione di un workspace dichiara e usa uno dei tre trasporti DWH (
postgres_direct,rest_api,ssh_tunnel); PSD usarest_api. search packdi una domanda reale restituisce tabelle (con descrizioni), evidence della generazione ACTIVE e solved dello stesso workspace; F4/F6 mostrano le FK curate.qdrantEnsure/ollamaEnsureverdi all'ammissione; la collection ha esattamente 1024/cosine + gli 8 keyword-index.- Rerun del preprocessing:
unchanged(nessun duplicato); modifica di un'evidence → nuova generazione, ACTIVE aggiornato, vecchie generazioni in GC. - Smoke end-to-end automatico verde in CI con cleanup esatto (stile
preprocess-smoke.sh). - Migrazione PSD documentata e provata almeno in dry-run (re-introspection o riuso catalogo + re-embedding).
9. 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. 10). 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
evidenceche configura tutta la lettura della sorgente: protocollo/tipo, URI/sorgente, eventuali parametri non-secret. - Per PSD la sorgente è un tree di file in una directory versionata nel repo del workspace
(
evidence/, come nella versione precedente). - Eventuali segreti (HTTP autenticato, S3) restano in overlay d'installazione — invariante: nessun segreto nel repo/descriptor.
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,ACTIVEpointer, 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 repo workspace 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) nel repo workspace
- Il workspace contiene la cartella evidence versionata (tree di file); le dimensioni non sono un vincolo.
- 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
.mddal repo workspace; export dal pgvector del server PSD (accesso disponibile); re-embedding conqwen3-embedding:0.6b; dry-run documentato.
D8 — Verifica end-to-end: confermata; remote Git libero; DWH multi-trasporto
- Smoke automatico su workspace sintetico (CI) + gate manuale L2 su PSD.
- Il workspace PSD sarà prima generato come repository ed alimentato (descriptor + evidence + annotations), 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. Oggissh_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 sezioneevidence/policy del descriptor (D1).
10. 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. 8).
| Piano | Punto PRD | Contenuto sintetico | Dipende da |
|---|---|---|---|
| P1 | D1 | Descriptor v3: sezione evidence (protocollo/tipo, URI, sorgente tree nel repo) + policy; validazione contract (backend schema.ts, harness config.py) |
— |
| 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 repo workspace + sync registry → roots runtime |
P1 |
| P6 | D6 | Evidence tree nel repo workspace (path checkout → preprocess) | 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 (workspace repo 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 |
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), gate
deployment (test-*), poi smoke Docker. Lo stato di ogni piano (draft / in corso / fatto) verrà tracciato
in questa sezione man mano che i piani partiranno.
11. 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 |
12. Riferimenti
- Stato attuale:
PROJECT_STATE.md(sezioni "Internal Qdrant + Ollama semantic infrastructure", snapshot registry) eAGENTS.md. - Design architettura semantica:
docs/plans/2026-08-08-internal-qdrant-ollama-design.mde relativo piano. - Registry:
docs/superpowers/specs/2026-08-03-git-workspace-registry-design.md, manualidocs/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.