# Metadata Catalog di ThothII: ricognizione ThothAI e percorso incrementale Data: 2026-08-26 Stato: ricognizione completata; step 1 implementato; scelte tecnologiche degli step successivi deliberatamente rinviate. ## Obiettivo ThothII deve introdurre un contesto amministrativo separato, il **Metadata Catalog**, per gestire il database associato a ciascun workspace, la sua struttura fisica introspezionata e i metadati semantici oggi rappresentati da `schema/annotations.yaml`. Il programma procede per step indipendenti. Il primo step aggiunge soltanto l'accesso dalla sidebar destra a una superficie centrale vuota. Non introduce PostgreSQL, API CRUD, introspezione o integrazioni con il workflow core. Questa analisi usa come riferimento il working tree legacy osservato in `Thoth/ThothAI`. Non è stato verificato che quel contenuto corrisponda a una release o a un tag canonico; i percorsi e i comportamenti descrivono il sorgente disponibile il 2026-08-26. ## Decisioni già confermate 1. Ogni workspace è associato a un solo Workspace Database e ogni Workspace Database appartiene a un solo workspace. 2. Il CRUD non crea né rinomina workspace. Identità e lista ordinata dei workspace restano autorevoli in `thoth-workspaces.yaml`; il catalogo conserva il loro identificatore stabile. 3. La struttura fisica viene acquisita interrogando il database esterno tramite i dati di connessione registrati per il Workspace Database. 4. I contenuti semantici equivalenti a `annotations.yaml` vengono generati con l'AI e conservati nel PostgreSQL interno. 5. Per PSD è prevista l'importazione delle annotations esistenti. Gli altri database partiranno dalla struttura introspezionata e genereranno i metadati semantici da zero. 6. `annotations.yaml` sarà sostituito anche come input del core in uno step futuro. Il repository è in fase di test e non è richiesta la conservazione delle sessioni esistenti durante il cutover. 7. La gestione catalogo resta una superficie separata dal processo NL→SQL. La futura integrazione deve essere esplicita e non deve modificare fasi, gate o semantica del workflow. 8. Il link iniziale è visibile agli utenti con `workspace.manage`, usa stato React locale e non introduce un router. 9. La pagina iniziale è vuota, segue il tema, nasconde l'intera colonna core e non interrompe una sessione live. Le azioni di apertura, resume o creazione sessione riportano al core. ## Correzione del modello mentale corrente `schema/annotations.yaml` non contiene l'intero schema del database. - `physical.yaml` è un artefatto derivato dall'introspezione. Contiene database, schema, timestamp, tabelle, colonne, tipi, nullability, default, primary key, commenti sorgente, esempi, foreign key fisiche e indici. - `annotations.yaml` contiene metadati curati: descrizioni e concetti delle tabelle; descrizioni, sinonimi, concetti, evidence, note e override `eligible` delle colonne; foreign key logiche. - Il rendering M-Schema fonde questi due input. Le annotations prevalgono sui commenti sorgente e le relazioni logiche vengono unite alle foreign key fisiche. La sostituzione del solo file annotations non elimina automaticamente l'introspezione fisica. Il nuovo catalogo dovrà conservare una distinzione esplicita fra fatti osservati nel database e contenuto semantico modificabile. ## Architettura ThothII rilevante ### Autorità e revisionamento attuali Il repository dei workspace contiene: ```text thoth-workspaces.yaml /workspace.yaml /schema/annotations.yaml /evidence/** ``` Il backend legge descriptor e annotations allo stesso commit Git. Durante l'attivazione valida il blob, lo copia atomicamente nello snapshot immutabile della revisione e registra commit, blob ID e digest. Le nuove sessioni vengono legate a quella revisione; resume e SQL salvato riaprono lo stesso snapshot. Punti principali: - `backend/src/workspaces/schema.ts`: descriptor v3 e singolo `dwh.database`/`dwh.schema`; - `backend/src/workspaces/git-repository.ts`: lettura sicura del blob annotations al commit; - `backend/src/workspaces/registry.ts`: validazione e attivazione atomica; - `backend/src/workspaces/annotations-sync.ts`: materializzazione revision-qualified; - `backend/src/workspaces/runtime-config-lease.ts`: binding dello snapshot al runtime; - `harness/tht/mschema/models.py`: contratti `PhysicalSchema` e `Annotations`; - `harness/tht/mschema/render.py`: fusione fisico/semantico; - `harness/tht/cli/vector_cmd.py`: indicizzazione schema in Qdrant. ### Consumatori da preservare al cutover futuro Le annotations incidono oggi su: - override `eligible` prima del campionamento LSH; - suggerimento, controllo e accettazione delle foreign key logiche; - descrizioni, concetti e sinonimi dei record schema in Qdrant; - retrieval delle tabelle e colonne candidate; - rendering M-Schema usato dal gate F4 e dalla generazione SQL; - digest della revisione accettata durante il preprocessing. Il futuro cutover non potrà limitarsi a rimuovere il file: dovrà fornire al core lo stesso contenuto effettivo, con un'identità coerente e test di equivalenza. Poiché non occorre preservare le sessioni di test esistenti, non serve progettare compatibilità con i vecchi manifest, ma resta necessario evitare letture parziali o semanticamente incoerenti. ## Inventario ThothAI ### Modelli legacy I modelli sono definiti in `Thoth/ThothAI/backend/thoth_core/models.py`. #### `SqlDb` Campi di connessione osservati: - `name`; - `db_host`, `db_port`; - `db_type`; - `db_name`, `schema`; - `user_name`, `password`; - `db_mode`; - configurazione SSH e Informix opzionale. Il modello contiene anche scope, JSON dello scope, ERD, direttive, campi GDPR, collegamento a `VectorDb` e numerosi campi di stato/task/log per lavori AI asincroni. I tipi legacy dichiarati sono Informix, MariaDB, MySQL, Oracle, PostgreSQL, SQL Server e SQLite. Questo elenco non costituisce automaticamente un requisito per ThothII: il core corrente supporta PostgreSQL e l'estensione ad altri dialetti dovrà essere decisa separatamente. #### `SqlTable` - `name`; - `description`; - `generated_comment`; - foreign key obbligatoria a `SqlDb`, con cancellazione cascade. #### `SqlColumn` - `original_column_name` e alias `column_name`; - `data_format` normalizzato; - `column_description`; - `generated_comment`; - `value_description`; - stringhe denormalizzate `pk_field` e `fk_field`; - foreign key obbligatoria a `SqlTable`, con cancellazione cascade. #### `Relationship` Contiene quattro foreign key obbligatorie: - `source_table` e `source_column`; - `target_table` e `target_column`. Il form admin verifica che le tabelle appartengano allo stesso database e che ogni colonna appartenga alla tabella selezionata. Il database non impone però gli stessi check. #### `Workspace` ThothAI usa `Workspace.sql_db` come foreign key nullable verso `SqlDb`: un workspace seleziona un solo DB, mentre lo stesso DB può essere riusato da più workspace. ThothII adotterà invece una relazione uno-a-uno: `workspace_id` deve essere unico nel catalogo. ### Lacune dei constraint legacy Non risultano constraint database-level per: - unicità del nome database nel workspace; - unicità `(database, table name)`; - unicità `(table, column name)`; - unicità degli estremi di una relationship; - appartenenza degli estremi della relationship allo stesso database; - corrispondenza fra colonna e tabella dichiarata. ThothII deve applicare queste invarianti sia nel database interno sia nel servizio applicativo. La sola validazione del form non è sufficiente perché API, import e job la possono aggirare. ### Django Admin e UX da replicare concettualmente ThothAI espone il CRUD tramite il Django Admin standard, registrato da `backend/thoth_core/admin.py` e pubblicato su `/admin/`. Capacità utili: - lista database con ricerca per nome, host, tipo, database e schema; - fieldset separati per identità, connessione, autenticazione, SSH e stato; - lista tabelle filtrabile per database; - lista colonne filtrabile in cascata per database e tabella; - lista relazioni con estremi leggibili e filtri per database e tabelle; - form relazione con dropdown dipendenti database → tabella → colonna; - validazione degli estremi prima del salvataggio; - azioni separate per test connessione, introspezione, import/export e generazione AI; - azioni bulk sulle righe selezionate. ThothII deve replicare i contratti di interazione e validazione, non il rendering server-side o i template Django. ### Introspezione legacy `Thoth/ThothAI/backend/thoth_core/dbmanagement.py` usa `thoth-dbmanager` per: 1. costruire l'adapter del dialetto; 2. acquisire tabelle; 3. acquisire e normalizzare colonne e tipi; 4. acquisire relazioni; 5. creare le eventuali colonne mancanti necessarie alle relazioni; 6. aggiornare i campi PK/FK denormalizzati. Il comportamento è principalmente additivo: usa `get_or_create` o controlli `exists`, aggiorna alcuni commenti, ma non riconcilia in modo completo rename, rimozioni o drift. Non va copiato così com'è. Il futuro processo ThothII dovrà almeno distinguere scansione, differenze osservate e applicazione della nuova snapshot. ### Generazione AI legacy ThothAI dispone di azioni e workflow per: - commenti delle tabelle; - commenti delle colonne; - scope del database; - ERD Mermaid; - documentazione del database; - analisi GDPR. Per il requisito attuale sono direttamente rilevanti descrizioni di tabelle e colonne, scope e metadati semantici. ERD, documentazione aggregata e GDPR sono estensioni future, non prerequisiti del CRUD iniziale. La separazione `description`/`generated_comment` del legacy non offre versioning o approvazione robusti. Nei passi successivi andrà deciso se l'output AI è una proposta revisionabile o diventa immediatamente il valore editabile corrente. ### Import ed export legacy ThothAI offre: - CSV di database, tabelle, colonne e relazioni; - export di struttura per workspace; - import mediante `import_db_structure`; - script SQL dei commenti per più dialetti; - aggiornamento delle descrizioni colonna da CSV. Il futuro import PSD dovrà leggere il contratto YAML corrente e convertirlo su chiavi naturali, non riutilizzare gli ID numerici Django. Deve essere idempotente e produrre un report di elementi creati, aggiornati, ignorati o non risolti. ## Comandi osservati in ThothAI ### Backend locale Eseguiti da `Thoth/ThothAI/backend`: ```sh uv sync uv run python manage.py migrate uv run python manage.py createsuperuser uv run python manage.py runserver 8200 uv run pytest ``` Import catalogo legacy: ```sh uv run python manage.py import_db_structure --source local uv run python manage.py load_defaults --only-level 4 --source local ``` Test mirati rilevanti: ```sh uv run pytest tests/test_relational_database_operations.py -v uv run pytest tests/test_ssh_tunnel_configuration.py -v ``` ### Stack Docker legacy ThothAI dichiara `postgres:16-alpine` nel profilo `internal-db`, con volume persistente e healthcheck `pg_isready`. ```sh docker compose --profile internal-db up --build ``` Il wrapper legacy abilita lo stesso profilo quando `POSTGRES_INTERNAL=true`: ```sh POSTGRES_INTERNAL=true ./docker-up.sh ``` Questi comandi documentano il riferimento osservato; non sono comandi di installazione per ThothII. ## Cosa copiare in ThothII ### Parità necessaria - gerarchia Workspace Database → Table → Column; - relazione strutturale fra colonne sorgente e destinazione; - navigazione e filtri dipendenti workspace/database/tabella; - test di connessione separato dal salvataggio; - introspezione esplicita e ripetibile; - descrizioni generate dall'AI ma modificabili dall'utente; - validazione cross-entity delle relazioni; - azioni di import/export senza segreti; - stato leggibile dei job lunghi; - PostgreSQL interno persistente con migrazioni esplicite; - test di CRUD, cardinalità, cascade/restrict, isolamento per workspace e idempotenza. ### Parità semantica con `annotations.yaml` Il modello futuro deve poter rappresentare almeno: - descrizione, concetti e note per tabella; - descrizione, sinonimi, concetti, evidence, note ed `eligible` per colonna; - foreign key logiche; - distinzione fra commento fisico osservato e descrizione curata; - provenienza del contenuto importato o generato. L'eventuale esclusione di uno di questi campi deve essere una decisione esplicita perché cambia rendering, retrieval, LSH o SQL generation. ### Vincoli minimi da progettare - `workspace_id` unico sul Workspace Database; - nome tabella unico nel database e schema appropriato; - nome colonna unico nella tabella; - relationship unica secondo il modello, anche per chiavi composite; - estremi della relationship nello stesso Workspace Database; - appartenenza certa della colonna alla tabella; - mutazioni aggregate transazionali; - gestione esplicita di concorrenza fra CRUD e introspezione. ## Cosa non copiare - Django, Django Admin, Django ORM, DRF, template admin e frontend Next; - modello Workspace legacy e condivisione dello stesso DB fra più workspace; - password o passphrase come normali campi testuali; - password incluse in CSV o export completi; - token SSO inseriti nella query string; - migrazioni generate automaticamente all'avvio; - validazioni presenti soltanto nel form; - `pk_field` e `fk_field` testuali come fonte di verità; - duplicazione di tabella e colonna negli estremi senza constraint coerenti; - introspezione additiva che non segnala rename, delete o drift; - azioni admin che possono mostrare successo dopo output AI non valido; - dipendenza del workflow core dalla disponibilità della UI o del PostgreSQL amministrativo. ## Aspetti di sicurezza da non ereditare L'export legacy della struttura include username e password in chiaro. Il modello conserva inoltre password, passphrase SSH e altri segreti in `CharField`; non è stata trovata cifratura applicativa, nonostante un testo admin affermi il contrario. Per ThothII resta da decidere nello step infrastrutturale quali dati di connessione siano normali metadati e quali siano secret reference. In ogni caso: - nessun endpoint o export deve restituire segreti; - log ed errori devono sanificare DSN e credenziali; - le credenziali di migrazione non devono essere disponibili al runtime CRUD; - il catalogo non deve riusare credenziali del DWH, delle sessioni o di Qdrant; - test connessione e introspezione devono usare timeout e privilegi read-only. ## Percorso incrementale ### Step 1: accesso alla superficie vuota Implementato in questo worktree: - pulsante `Database management` nella sidebar destra; - visibilità legata a `workspace.manage`; - superficie centrale React separata e vuota; - nessun router, endpoint, fetch o stato catalogo; - sessione e SSE conservati in background; - ritorno al core tramite creazione, apertura o resume di una sessione; - test frontend dedicati. Comandi di verifica: ```sh cd frontend npx vitest run src/shell/AppShell.database-management.test.tsx npx vitest run src/shell/AppShell.new-session.test.tsx \ src/shell/AppShell.session-target.test.tsx \ src/shell/AppShell.session-mgmt.test.tsx npx tsc -b ``` ### Step 2: contratto di dominio e schema relazionale Da progettare con un nuovo round decisionale: campi, secret reference, dialetti supportati, namespace/schema, snapshot fisiche, relazioni fisiche/logiche e lifecycle dell'output AI. Nessuna tecnologia ORM o migration tool è stata scelta in questo documento. ### Step 3: PostgreSQL interno e migrazioni Da progettare separatamente dal core: servizio, volume, ruoli runtime/migrator/backup, health e readiness dedicati, backup/restore e diagnostica. La sua indisponibilità non dovrà cambiare `core /health` o interrompere una sessione. ### Step 4: API CRUD Contratti HTTP, autorizzazione, paginazione, filtri, errori, optimistic concurrency e transazioni. Gli endpoint dovranno vivere sotto un namespace catalogo e non riutilizzare le route sessione. ### Step 5: UI CRUD Liste e form per Workspace Database, tabelle, colonne e relazioni, costruiti con React/Vite e il design system ThothII. La gerarchia e i filtri ThothAI sono il riferimento funzionale; Django Admin non è il riferimento tecnologico o visuale. ### Step 6: introspezione Connessione read-only, preview delle differenze, acquisizione di una Physical Schema Snapshot, policy per rename/rimozioni e stato del job. Nessuna chiamata lunga dovrà mantenere aperta una transazione CRUD. ### Step 7: generazione AI dei metadati Generazione di descrizioni e altri campi equivalenti alle annotations, editing umano e gestione esplicita di errori o output non validi. Approvazione/versioning saranno decisi in questo step. ### Step 8: migrazione PSD Import idempotente delle annotations PSD, riconciliazione contro la struttura introspezionata, report degli orfani e confronto semantico con il rendering corrente. Gli altri workspace non ricevono import legacy. ### Step 9: sostituzione dell'input core Rimuovere la dipendenza da `annotations.yaml` soltanto dopo avere un contratto equivalente, test di rendering/search/Qdrant e una policy di disponibilità. Le sessioni di test esistenti possono essere eliminate, ma le nuove sessioni non devono osservare aggiornamenti parziali. ### Step 10: operazioni e accettazione Backup/restore reale, diagnostica, metriche, audit, permessi definitivi, hardening degli export e test di failure isolation fra catalogo e workflow. ## Verifiche del core da conservare per il cutover Comandi attuali rilevanti: ```sh tht --installation /thothii-installation.yaml workspace preprocess dwh \ --workspace --json tht --installation /thothii-installation.yaml workspace schema suggest-fks \ --workspace --json tht --installation /thothii-installation.yaml workspace schema check \ --workspace --json tht --installation /thothii-installation.yaml workspace schema accept \ --workspace --run --yes --json tht --installation /thothii-installation.yaml workspace index-schema \ --workspace --json ``` Suite che documentano il comportamento da preservare: ```sh cd backend npx vitest run test/workspaces-git-annotations.test.ts \ test/registry-annotations.test.ts \ test/annotations-sync.test.ts \ test/workspace-runtime-config-lease.test.ts \ test/workspace-preprocessing-service.test.ts npx tsc --noEmit -p . cd ../harness .venv/bin/pytest -q \ tests/test_annotations_root.py \ tests/test_schema_fk_annotations.py \ tests/test_mschema_render.py \ tests/test_qdrant_cli_commands.py ``` Questi test non implicano che la futura implementazione debba continuare a usare file YAML. Definiscono gli effetti semantici e le guardie da mantenere o sostituire consapevolmente. ## Decisioni rinviate Le seguenti scelte non appartengono allo step 1: - framework del servizio catalogo e libreria di accesso PostgreSQL; - collocazione e protezione delle credenziali dei Workspace Database; - supporto iniziale di dialetti diversi da PostgreSQL; - uno o più schema namespace per database; - policy di reconciliation per rename e delete; - modello delle foreign key composite; - distinzione persistente fra relationship fisiche e logiche; - lifecycle draft/review/approval dell'output AI; - versionamento, audit e rollback; - formato e momento del cutover dal file al database interno; - permission definitiva separata da `workspace.manage`. Ognuna sarà affrontata nel relativo step, senza anticipare scelte tecnologiche nel presente documento.