# Componenti, moduli e flussi Questa pagina completa la [panoramica dell'architettura](overview.md) con la struttura dei moduli e i flussi che attraversano ThothII. I diagrammi descrivono il codice corrente, non un'architettura futura. ## Moduli e dipendenze Il frontend comunica con il backend tramite REST e SSE. Il backend non possiede la persistenza delle sessioni: avvia Pi, invoca la CLI `tht` e inoltra gli eventi. L'harness contiene il workflow, la CLI Python e gli adattatori verso DWH e vector store. ```mermaid flowchart LR FE["frontend/\nReact + Vite"] -->|REST + SSE| BE["backend/\nFastify + TypeScript"] BE -->|RPC stdin/stdout| PI["Pi\n--mode rpc"] BE -->|subprocess\nJSON stdout| THT["harness/tht\nCLI Python"] PI --> EXT["harness/.pi/extensions/\ntht-gate.js"] EXT --> SKILL["harness/.pi/skills/\ntht-sessione"] EXT --> THT THT --> FS["Sessioni e artefatti\nworkspace repository"] THT --> DWH["DWH\nread-only"] THT --> VDB["Qdrant / vector store"] BE --> CFG["settings.json\nworkspace registry"] FE -.->|renderizza widget| EXT ``` Dipendenze principali: | Modulo | Dipende da | Responsabilità | | --- | --- | --- | | `frontend/` | API REST e SSE del backend | UI, widget di gate e transcript in memoria | | `backend/src/` | Pi, `tht`, configurazione e workspace registry | Trasporto, lifecycle delle sessioni e API | | `harness/.pi/` | Pi e `tht phase` | Orchestrazione del workflow e gate human-in-the-loop | | `harness/tht/` | filesystem, DWH e vector store | Persistenza, CLI, evidence, schema e preprocessing | | workspace repository | `source/`, `curated/`, manifest e artefatti | Sorgente versionata delle evidence e output di sessione | ## Sequenza di una sessione Il percorso principale parte da una domanda dell'utente e termina con un evento SSE. Le decisioni del revisore rientrano nello stesso canale e vengono persistite dall'harness. ```mermaid sequenceDiagram actor U as Utente o revisore participant FE as Frontend participant BE as Backend participant PI as Pi RPC participant THT as CLI tht participant WS as Workspace participant DWH as DWH U->>FE: Invia domanda o decisione di gate FE->>BE: POST session / risposta widget BE->>PI: RPC input o prompt di resume PI->>THT: phase/session/evidence commands THT->>WS: Legge e scrive artefatti di fase THT->>DWH: Introspezione o query read-only DWH-->>THT: Schema, risultati o diagnostica THT-->>PI: JSON e stato della fase PI-->>BE: Eventi RPC e widget descriptor BE-->>FE: SSE text_delta, info, ui_request FE-->>U: Testo, artefatto o richiesta di revisione ``` Il backend usa `ThtRunner` per i subprocess della CLI, `PiProcessManager` per un processo Pi per sessione, `SessionBridge` per adattare gli eventi RPC e `SseHub` per distribuirli ai client. ## Classi principali del backend Il diagramma mostra le classi che compongono il ponte tra browser, Pi e `tht`. Le route Fastify ricevono le richieste e delegano a questi servizi. ```mermaid classDiagram class ThtRunner { +buildArgv(command, args) string[] +run(args) Promise~ThtResult~ +sessionShow(id) Promise~unknown~ } class PiProcessManager { -runtimes Map +spawnFor(sessionId, mode) SessionRuntime +resume(sessionId, tht) Promise~SessionRuntime~ +stop(sessionId) Promise~void~ } class SessionBridge { +handleRpcEvent(event) ClientEvent +handleUiResponse(response) Promise~void~ } class SseHub { +subscribe(sessionId) AsyncIterable +publish(sessionId, event) void +close(sessionId) void } class SessionRoutes { +createSession(request) Response +resumeSession(id) Response +postInput(id, input) Response } class WorkspaceRegistry { +list() Workspace[] +resolve(id) Workspace } class SettingsStore { +get() Settings +update(patch) Settings } class App { +buildApp() FastifyInstance } App --> SessionRoutes App --> WorkspaceRegistry App --> SettingsStore SessionRoutes --> PiProcessManager SessionRoutes --> ThtRunner SessionRoutes --> SseHub PiProcessManager --> SessionBridge PiProcessManager --> ThtRunner SessionBridge --> SseHub ``` ## Moduli Python della CLI `tht` La CLI è composta da comandi Typer e da moduli di dominio. `cli/` traduce gli argomenti in operazioni; `evidence/`, `session/`, `db/`, `adapters/` e gli altri package contengono la logica applicativa. ```mermaid flowchart TB MAIN["tht/cli/__init__.py"] --> CMD["tht/cli/*_cmd.py"] CMD --> CONFIG["config.py\nworkspace.py\npaths.py"] CMD --> SESSION["session_cmd.py\nsession/"] CMD --> EVIDENCE["evidence_cmd.py\nevidence/"] CMD --> PRE["preprocess_cmd.py\nevidence/corpus/"] CMD --> PHASE["phase_cmd.py\nphase.py\nworkflow.py"] CMD --> SQL["sql_cmd.py\ndb/\nrest/"] EVIDENCE --> ACQ["evidence/acquisition.py\nadapters/ filesystem/http/s3"] EVIDENCE --> CANON["evidence/canonical.py\ncontracts.py\nmodel.py"] EVIDENCE --> AUTHOR["evidence/authoring.py"] PRE --> PIPE["evidence/corpus/pipeline.py\nchunk.py normalize.py store.py"] PRE --> VECTOR["adapters/vector/qdrant.py"] PRE --> DWH["jobs/dwh_pipeline.py\nadapters/dwh/"] SESSION --> REPO["session/filesystem_repository.py\npostgres_repository.py"] PHASE --> LEDGER["decisions.py\nreview_decisions"] ``` Il comando di operatore `tht` in `tools/tht/` è distinto dalla CLI Python dell'harness. Il primo gestisce installazione, lifecycle, autenticazione e workspace; il secondo esegue il workflow e le operazioni sui dati. ## Workflow a otto fasi e gate La fonte di verità è `harness/workflow.yaml`. La fase corrente si calcola dal decision ledger, non da un campo aggiornato manualmente. ```mermaid flowchart LR F1["F1\nChiarimento"] --> F2["F2\nMemoria"] F2 --> F3["F3\nRiscrittura"] F3 --> F4["F4\nSchema linking\nreviewer_decide"] F4 --> F5["F5\nSintesi"] F5 --> F6["F6\nCTE\nauto o skip"] F6 --> F7["F7\nSQL finale\nreviewer_confirm"] F7 --> F8["F8\nDatamart\nreviewer_decide"] F1 -.->|reviewer_confirm| F1 F3 -.->|reviewer_confirm| F3 F4 -.->|decisioni su tabelle, colonne, evidence| F4 F6 -.->|cte_approved o cte_rejected| F6 F7 -.->|sql_approved o sql_rejected| F7 F8 -.->|datamart_requested o declined| F8 ``` | Fase | Nome | Avanzamento | Artefatti principali | | --- | --- | --- | --- | | F1 | chiarimento | `kind:phase` | decisioni di chiarimento | | F2 | memoria | automatico se vuota | decisioni memoria | | F3 | riscrittura | `kind:phase` | `question.md` | | F4 | schema linking | `reviewer_decide` | `schema_linking.json` | | F5 | sintesi | `kind:phase` | verifica dello schema linking | | F6 | CTE | automatico, oppure skip | `cte_plan.json`, `ctes/`, `cte_tests.json` | | F7 | SQL finale | `kind:phase` dopo `sql_approved` | `sql_final.sql` | | F8 | datamart | `reviewer_decide` | decisione su richiesta o rifiuto | Un `reviewer_select` con decisione incorporata può confermare direttamente. Un `reviewer_decide` registra le scelte multiple. Un `reviewer_confirm` conferma un artefatto o la chiusura della fase. Il modello propone; il revisore decide e il ledger registrato è la fonte dello stato.