80 lines
6.0 KiB
Markdown
80 lines
6.0 KiB
Markdown
# Panoramica dell'architettura
|
|
|
|
> Sintesi ad uso documentazione. Per il dettaglio storico delle decisioni di design vedi le [Specifiche di Design](../superpowers/specs/2026-06-25-thothii-architecture-design.md) e i [Piani di Implementazione](../superpowers/plans/2026-06-25-harness-implementation.md). 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](authentication.md).
|
|
|
|
## 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 esattamente `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).
|