From ec061c42d4b19f3c86f33fd7c7155739f46d75c4 Mon Sep 17 00:00:00 2001 From: mptyl Date: Wed, 26 Aug 2026 08:09:06 +0200 Subject: [PATCH] docs: add architecture diagrams and evidence guide --- docs/architecture/components.md | 174 +++++++++++++++++++++++++++++ docs/evidence.md | 189 ++++++++++++++++++++++++++++++++ mkdocs.yml | 2 + 3 files changed, 365 insertions(+) create mode 100644 docs/architecture/components.md create mode 100644 docs/evidence.md diff --git a/docs/architecture/components.md b/docs/architecture/components.md new file mode 100644 index 00000000..3cc11edb --- /dev/null +++ b/docs/architecture/components.md @@ -0,0 +1,174 @@ +# 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. diff --git a/docs/evidence.md b/docs/evidence.md new file mode 100644 index 00000000..b146b5d8 --- /dev/null +++ b/docs/evidence.md @@ -0,0 +1,189 @@ +# Evidence: sorgenti, preparazione e revisione + +Questa pagina descrive il ciclo completo delle Evidence di workspace: dove si trova il materiale originale, come si producono le unità curate, quando diventano disponibili al runtime e quali responsabilità hanno autore e revisore. + +## Regola di pubblicazione + +Il workspace repository è la sorgente versionata. ThothII lo legge, lo valida e pubblica una generazione atomica. Non modifica, committa o pusha il repository dell'autore. + +Una Evidence diventa utilizzabile dal workflow solo quando: + +1. il materiale originale è presente in `source/`; +2. l'unità derivata è presente in `curated/`; +3. il manifest collega unità, sorgente e hash; +4. la validazione non produce errori o review item irrisolti; +5. la pipeline di preprocessing costruisce una generazione indicizzata e la attiva. + +Una proposta generata durante una sessione non è automaticamente Evidence pubblicata. Il modello può proporre una formula o una spiegazione, ma un curatore deve importarla, revisionarla e pubblicarla nel repository prima che un'altra sessione possa recuperarla. + +## Dove deve stare il primo sorgente + +Per il filesystem Evidence v2, il primo sorgente autorevole deve stare nella directory `source/` del repository di workspace. `curated/` contiene il risultato revisionato e indicizzato, non il materiale originale. + +```text +/ +├── source/ # materiale originale, preservato +│ └── /.md +├── curated/ # Evidence Units revisionate +│ └── /.md +├── manifest.yaml # legami, hash e metadati della preparazione +├── evaluation/ # fixture di valutazione del recupero +└── example/ # esempi e materiale di supporto +``` + +Il descriptor del workspace deve dichiarare `evidence.schema_version: 2` e, per una sorgente filesystem, usare esattamente: + +```yaml +evidence: + schema_version: 2 + source: + type: filesystem + uri: "/evidence" + patterns: + - "curated/**/*.md" +``` + +La configurazione storica può esporre `source_root`, per esempio `${THT_DOCS_ROOT}` o `/data`. Per la struttura v2 il pattern runtime deve selezionare solo `curated/**/*.md`. Non bisogna indicizzare direttamente `source/`, mescolare `source/` e `curated/`, usare glob più ampi o includere file non Markdown. + +HTTP e S3 sono adapter distinti. Non usano la struttura filesystem `source/` e `curated/`, ma devono comunque fornire una provenienza stabile, senza credenziali negli URI e con il contratto specifico dell'adapter. + +## Come deve essere fatta un'unità curata + +Le unità Markdown lette dal loader storico della CLI hanno frontmatter YAML. I campi minimi sono `id` e `title`; `tier`, `status`, `sources`, `tables`, `concepts` descrivono il contesto dell'unità. + +```markdown +--- +id: evidence:fascia-pediatrica +title: Fascia pediatrica +tier: structural +status: reviewed +sources: + - source/domain/patient.md +tables: + - patient +concepts: + - concept:patient-age +--- + +Definizione verificata della fascia pediatrica. + +La regola deve essere abbastanza atomica da poter essere citata senza ricostruire +un intero capitolo. Il testo deve distinguere definizione, condizioni e limiti. +``` + +Le unità curate devono essere atomiche, leggibili da un secondo revisore e sostenute dal sorgente. I riferimenti di provenienza devono permettere di risalire al file originale e alla porzione che supporta l'affermazione. Non inserire segreti, token, password o credenziali nei metadati o negli URI. + +La forma canonica moderna conserva anche il tipo di Evidence, la provenienza, gli estratti di supporto, `source_file` e `source_sha256`. Il contratto canonico rifiuta campi sconosciuti, metadati mutabili e URI con credenziali. Gli identificatori devono restare stabili anche quando cambia il tipo di unità. + +## Preparazione: dal sorgente alla generazione attiva + +```mermaid +flowchart TD + SRC["source//*.md\nmateriale originale"] --> PREP["tht evidence prepare\npreparazione candidata"] + PREP --> CAND["curated//*.md\nunità proposte o aggiornate"] + CAND --> VAL["tht evidence validate\ncontrolli di struttura e legami"] + VAL -->|errori o review item| FIX["Correzioni dell'autore\ne revisione"] + FIX --> PREP + VAL -->|publishable| COMMIT["Commit del repository\nauthoring clone"] + COMMIT --> ING["tht preprocess evidence\nnormalizzazione e chunking"] + ING --> BM25["Indice BM25"] + ING --> VEC["Embedding e vector store"] + BM25 --> GEN["Generazione candidata"] + VEC --> GEN + GEN --> EVAL["tht evidence evaluate\nfixture di retrieval"] + EVAL -->|pass| ACT["Generazione attiva"] + EVAL -->|fail| FIX + ACT --> RUNTIME["Ricerca Evidence nel workflow"] +``` + +La preparazione può ristrutturare sorgenti cambiate, ma non pubblica da sola. `prepare` produce una proposta e può indicare il file sorgente coinvolto in caso di errore. `validate` non scrive né pubblica. Il commit è un'azione del curatore nel clone di authoring. Il runtime legge una revisione completa e validata, poi la pipeline crea una generazione versionata. L'attivazione è atomica: una generazione precedente resta disponibile secondo la policy di retention. + +La ricerca runtime usa il recupero ibrido. Il ramo denso usa gli embedding, il ramo BM25 usa la ricerca lessicale e la fusione deterministica ordina i risultati. L'unità pubblicata conserva la provenienza, che il modello deve citare quando usa l'evidence. + +## Responsabilità del creatore + +Il creatore prepara il materiale e rende verificabile ogni unità. In pratica deve: + +- mettere il materiale originale in `source/`, senza sovrascriverne il significato durante la curatela; +- suddividere il contenuto in unità atomiche, una regola o definizione per unità quando possibile; +- assegnare un identificatore stabile e un titolo comprensibile; +- indicare la provenienza, le tabelle e i concetti coinvolti quando sono noti; +- mantenere il testo nella lingua del workspace; +- separare fatti, regole, esempi, formule e limiti; +- riportare gli estratti che sostengono l'unità, senza estendere la conclusione oltre il sorgente; +- eseguire `tht evidence prepare` e `tht evidence validate`; +- risolvere ogni errore e ogni review item prima di proporre il commit; +- fornire al revisore il contesto necessario, inclusi i cambiamenti nel sorgente e il motivo di eventuali rinomini o ritiri. + +Il creatore non deve: + +- scrivere direttamente nel corpus attivo di produzione; +- trattare una proposta del modello come fatto verificato; +- eliminare un'unità solo perché non è più supportata senza registrare il ritiro o il relink; +- inserire credenziali nei metadati, nei file o negli URL di provenienza; +- modificare manualmente manifest, hash o generazioni per far passare la validazione. + +## Responsabilità del revisore + +Il revisore non approva la forma del testo soltanto perché è chiara. Verifica il rapporto tra sorgente, unità e uso previsto. Per ogni unità deve controllare: + +1. che il sorgente indicato esista nella revisione esaminata; +2. che l'estratto sostenga davvero l'affermazione; +3. che l'unità non unisca regole incompatibili o concetti indipendenti; +4. che tabelle, colonne e concetti siano identificati correttamente; +5. che l'identificatore sia stabile e non duplichi un'altra unità; +6. che il testo distingua definizione, condizione, eccezione ed esempio; +7. che non contenga informazioni sensibili o dettagli non presenti nel sorgente; +8. che la valutazione del retrieval copra le query rilevanti e non nasconda risultati vuoti. + +Il revisore può approvare, chiedere modifiche, rigettare, ritirare o riallacciare un'unità a un nuovo sorgente. Un ritiro deve essere esplicito. Un relink deve indicare il nuovo file e deve lasciare una traccia verificabile della decisione. L'approvazione non comporta la pubblicazione immediata: il repository deve passare la validazione e la generazione deve superare la valutazione prima dell'attivazione. + +## Comandi disponibili + +I comandi di authoring operano sul repository di workspace e non pubblicano direttamente. + +```bash +# Prepara le sorgenti cambiate. Non committa e non pubblica. +tht evidence prepare + +# Rielabora tutte le sorgenti con la pipeline installata. +tht evidence prepare --upgrade + +# Valida struttura, manifest, legami e review item. +tht evidence validate + +# Restituisce JSON per CI o strumenti automatici. +tht evidence validate --json + +# Valuta il retrieval su una generazione o sulla generazione attiva. +tht evidence evaluate --config +tht evidence evaluate --config --generation --json + +# Risolve una unità senza pubblicare: ritiro oppure nuovo collegamento al sorgente. +tht evidence resolve evidence: --retire +tht evidence resolve evidence: --source source/domain/nuovo.md + +# Materializza e indicizza una generazione versionata. +tht preprocess evidence --config + +# Esecuzione a secco e ripresa di un job, quando supportate dalla configurazione. +tht preprocess evidence --config --dry-run +tht preprocess evidence --config --resume +``` + +`evidence prepare`, `evidence validate` e `evidence resolve` richiedono il path del repository. `preprocess evidence` usa invece la configurazione del workspace, perché deve conoscere embedding, vector store, policy di retention e artifact directory. + +I codici di uscita sono parte del contratto operativo: `evidence validate` usa `0` quando il corpus è pubblicabile, `1` per errori di validazione e `3` quando restano solo elementi da revisionare o unità orfane. Con `--json`, stdout deve contenere solo JSON valido. + +## Formule e proposte di sessione + +Le formule hanno un formato distinto dalle Evidence documentali. Una formula proposta durante una sessione può essere citata nella proposta corrente, ma non entra nel corpus runtime, non riceve un ID `evidence:` utilizzabile e non scrive nel repository. Per diventare pubblicata deve seguire lo stesso percorso di importazione, revisione e preprocessing delle altre unità. + +## Riferimenti contrattuali + +- [Contratto Workspace Evidence v3](contracts/workspace-evidence-v3.md) +- [Contratto della CLI di preprocessing](contracts/workspace-preprocessing-cli.md) +- [ADR: confine di pubblicazione](adr/0001-evidence-publication-boundary.md) +- [ADR: preparazione atomica e ancorata al sorgente](adr/0006-grounded-atomic-evidence-preparation.md) +- [ADR: valutazione prima dell'attivazione](adr/0003-evaluate-evidence-before-activation.md) +- [ADR: recupero ibrido deterministico](adr/0008-make-hybrid-evidence-retrieval-deterministic.md) diff --git a/mkdocs.yml b/mkdocs.yml index 19d1f697..3d87ec32 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -62,6 +62,8 @@ nav: - Collaudo PSD Progetto B: testing/psd-server-project-b-manual.md - ThothII (Documentazione Tecnica): - Panoramica Architettura: architecture/overview.md + - Componenti, moduli e flussi: architecture/components.md + - Evidence: evidence.md - Autenticazione: architecture/authentication.md - Installazione autenticazione locale: install/authentication-local.md - OIDC generico: install/authentication-oidc.md