Files
ThothII/docs/architecture/overview.md
T

6.0 KiB

Panoramica dell'architettura

Sintesi ad uso documentazione. Per il dettaglio storico delle decisioni di design vedi le Specifiche di Design e i Piani di Implementazione. Per lo stato corrente del progetto (gate manuali pendenti, layout workspace/secret) vedi PROJECT_STATE.md nella radice del repo.

ThothII è un datamart builder human-in-the-loop: trasforma una domanda in linguaggio naturale in SQL validato (ed eventualmente un datamart dbt) attraverso un workflow deterministico a 8 fasi NL→SQL, in cui il modello propone e un revisore umano decide ai gate.

L'autenticazione di produzione usa local oppure OIDC generico; il solo CLI operatore è tht. Per sessioni, ruoli, gruppi, diagnostica e ripristino vedere la documentazione autenticazione.

I tre progetti indipendenti

frontend (React/SSE) → backend (Fastify) → pi --mode rpc → tht/harness → DWH (sola lettura)
Layer Stack Ruolo
harness/ Python (tht CLI) + Pi gate extension (JS) Possiede il workflow e tutta la persistenza
backend/ Fastify + TypeScript Ponte sottile senza database proprio
frontend/ React 18 + Vite UI che renderizza i widget di gate e ricostruisce il transcript live dallo stream SSE

L'harness possiede il workflow

tht (Python) è una CLI deterministica; harness/.pi/extensions/tht-gate.js è un'estensione Pi che guida il workflow a 8 fasi. La fonte di verità unica del workflow è harness/workflow.yaml; le regole di orchestrazione che il modello deve seguire sono in harness/.pi/skills/tht-sessione/SKILL.md. La "fase corrente" non è memorizzata: viene calcolata piegando il decision ledger (harness/tht/phase.py) — va letta prima di ragionare sulla logica di fase.

Persistenza = documenti di fase, non chat

Una sessione è una directory sotto sessions/ (path definito dal workspace): session_manifest.yaml + artefatti per fase (question.md, schema_linking.json, sql_final.sql, …) + review_decisions.jsonl. Il contratto (SKILL.md): "lo stato persistito è la verità — ciò che non è registrato non è accaduto". Non esiste uno store di transcript verbatim. Un processo Pi ripreso ricostruisce il contesto da tht session show <id> + gli artefatti su disco.

Il backend è un ponte sottile senza database

  • ThtRunner esegue subcommand tht in shell
  • PiProcessManager esegue un processo Pi figlio per sessione e fa da bridge al suo stream RPC
  • SessionBridge mappa eventi RPC di Pi → eventi client (ui_request / text_delta / info)
  • SseHub distribuisce questi eventi via SSE al browser

Le impostazioni applicative vivono in un file JSON (backend/data/settings.json), non in un database.

Contratto del gate human-in-the-loop

Il modello propone; un revisore umano decide ai gate tramite widget:

  • reviewer_select — scelta singola: un'opzione con decision payload auto-conferma/persiste direttamente; un'opzione senza payload chiede soltanto
  • reviewer_decide — multiselect: ogni scelta È una decisione
  • reviewer_confirm — gate su artefatto/fase

Il frontend renderizza questi widget-descriptor (registro in src/widgets/); il transcript live viene ricostruito in memoria dallo stream SSE (src/store/sessionStore.ts) — non è persistito.

Evidence curata e immutabile

Il repository del workspace è il confine di pubblicazione: il curatore prepara evidence/source/, revisa le unità in evidence/curated/, valida e fa merge. Per evidence.schema_version: 2 il runtime materializza l'intero albero evidence/ dal commit Git esatto, ma il renderer consegna al preprocessing soltanto curated/**/*.md dalla root immutabile della revisione. Sorgenti, manifest ed evaluation restano disponibili solo per tracciabilità. Il runtime non modifica, stagea, committa o pubblica il repository di authoring.

Prima dell'indicizzazione, il corpus curato della revisione pinnata viene validato. La collezione Qdrant condivisa conserva il vettore dense senza nome di Schema e Memory; il preprocessing Evidence può aggiungere soltanto in modo additivo il vettore sparse bm25 con idf, senza eliminare, rinominare o ricreare la collezione. workspace preprocess evidence e la parte Evidence di workspace preprocess run sono le sole operazioni pubbliche che effettuano questo upgrade.

Punti di attenzione ricorrenti

  • tht -c/--config è un'opzione per-comando: deve seguire il subcommand, mai precederlo (ThtRunner.buildArgv lo impone).
  • L'output --json deve essere JSON puro su stdout — è un contratto machine-readable.
  • Le stringhe UI sono in inglese; il contenuto dei documenti resta nella lingua del workspace (italiano per psd), perché è il dato reale — solo chrome/label sono in inglese.
  • I workspace (harness/workspaces/*.yaml) impostano il target DB e i path assoluti paths.sessions/artifacts/indexes — per psd puntano a un repo separato e non versionato (tht-workspace-psd/). I segreti vivono solo in harness/.env (gitignored).
  • Le impostazioni sono globali (backend/data/settings.json: workspace/provider/modello/thinking); il form di nuova sessione richiede solo la domanda.
  • Resume: una sessione riprendibile rientra all'ultima fase incompleta. Il backend rifiuta il resume con 409 se finalized o archived; PiProcessManager.spawnFor deve inviare /riprendi-sessione <id> (resume) vs /nuova-domanda (nuova) — il prompt sbagliato trasforma silenziosamente un resume in una nuova domanda.

Come si lancia lo stack

Lo stack locale si avvia con ./scripts/run-stack.sh, dopo aver creato deploy/env/local.env da deploy/env/local.env.example. Il core Compose include Pi; DWH, vector DB, embedding e LLM sono endpoint esterni configurati nel file locale.

Comandi per singolo layer, test, lint: vedi il file CLAUDE.md nella radice del repo (guida operativa per Claude Code, tenuta sincronizzata con questa pagina).