133 lines
8.6 KiB
Markdown
133 lines
8.6 KiB
Markdown
# Architecture overview
|
|
|
|
> For details about modules and flows, see [Components, modules, and flows](components.md).
|
|
|
|
ThothII is a **human-in-the-loop datamart builder**. It turns a natural-language question into validated SQL, and optionally a dbt datamart, through a **deterministic eight-phase NL-to-SQL workflow** in which the model *proposes* and a human reviewer *decides* at gates.
|
|
|
|
Production authentication uses local authentication, generic OIDC, or the
|
|
trusted-proxy upstream path used by Omics. `tht` is the operator CLI for the
|
|
installation and local/OIDC configuration. For roles and recovery, see
|
|
[authentication](authentication.md). One React build supports full and embedded;
|
|
[rendering architecture](application-shell.md) separates presentation from identity.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
USER["Reviewer"] --> FE["Frontend\nReact and SSE"]
|
|
FE --> BE["Backend\nFastify"]
|
|
BE --> CATALOG["Metadata catalog\nPostgreSQL"]
|
|
BE --> MODEL["Configured AI model\nvia short-lived LiteLLM helper"]
|
|
BE -->|bounded read-only samples| DWH
|
|
BE --> PI["Pi\nRPC per sessione"]
|
|
PI --> THT["tht and harness\nworkflow and persistence"]
|
|
THT --> DWH["DWH\nread only"]
|
|
THT --> EVIDENCE["Evidence\ncurated corpus"]
|
|
EVIDENCE --> THT
|
|
THT --> FE
|
|
```
|
|
|
|
## The three independently built layers
|
|
|
|
```
|
|
frontend (React/SSE) → backend (Fastify) → pi --mode rpc → tht/harness → DWH (read-only)
|
|
```
|
|
|
|
| Layer | Stack | Ruolo |
|
|
|---|---|---|
|
|
| **harness/** | Python (`tht` CLI) + Pi gate extension (JS) | Owns the workflow and all session persistence |
|
|
| **backend/** | Fastify + TypeScript + Kysely | Session bridge plus the isolated administrative metadata catalog |
|
|
| **frontend/** | React 18 + Vite | UI that renders gate widgets and rebuilds the live transcript from the SSE stream |
|
|
|
|
## The harness owns the workflow
|
|
|
|
`tht` (Python) is a deterministic CLI. `harness/.pi/extensions/tht-gate.js` is a Pi extension that guides the eight-phase workflow. `harness/workflow.yaml` is the single source of workflow truth, and `harness/.pi/skills/tht-sessione/SKILL.md` contains the orchestration rules the model must follow. The "current phase" is **not stored**. It is computed by folding the decision ledger (`harness/tht/phase.py`), which must be read before reasoning about phase logic.
|
|
|
|
## Persistence means phase documents, not chat
|
|
|
|
A session is a directory under `sessions/` (the workspace defines the path): `session_manifest.yaml`, phase artifacts (`question.md`, `schema_linking.json`, `sql_final.sql`, and others), and `review_decisions.jsonl`. The contract says: *"persisted state is the truth; what is not recorded did not happen"*. There is no verbatim transcript store. A resumed Pi process rebuilds context from `tht session show <id>` and the artifacts on disk.
|
|
|
|
## The backend bridges sessions and owns the metadata catalog
|
|
|
|
- `ThtRunner` runs `tht` subcommands in a shell.
|
|
- `PiProcessManager` runs one Pi child process per session and bridges its RPC stream.
|
|
- `SessionBridge` maps Pi RPC events to client events (`ui_request` / `text_delta` / `info`).
|
|
- `SseHub` distributes these events to the browser over SSE.
|
|
- `CatalogService` joins authoritative YAML workspace identities and Evidence settings with the
|
|
sole database authority: installation-local PostgreSQL Metadata Catalog records.
|
|
- `CatalogTableService` reconciles persisted Catalog Tables with a successful external schema scan;
|
|
`ConcreteCatalogTableIntrospector` isolates direct PostgreSQL, typed REST, and SSH-tunnel access.
|
|
- `DescriptionGenerationWorker` admits one installation-wide run and processes its table or column
|
|
targets sequentially.
|
|
- `PostgresDescriptionSourceSampler` reads bounded real rows and five representative examples from
|
|
the configured DWH connection; `ProcessModelCompleter` invokes the short-lived Python LiteLLM
|
|
helper with the installation-selected model.
|
|
|
|
Application settings keep only workspace and thinking preferences in `backend/data/settings.json`;
|
|
provider/model defaults come from the generated Installation Model Catalog. Session state remains in
|
|
harness phase documents. PostgreSQL stores the administrative database catalog, bindings, observed tables,
|
|
curated and generated descriptions, description-generation runs, sanitized run events, and the
|
|
authoritative preprocessing state/revisions.
|
|
Connector secrets remain write-only in the encrypted workspace secret store; model credentials
|
|
remain in the protected installation secret bundle. Catalog SSH support is limited to connection
|
|
tests, table synchronization, and bounded description-generation sampling; it does not change the
|
|
session runtime binding contract.
|
|
|
|
## Human-in-the-loop gate contract
|
|
|
|
The model proposes; a human reviewer decides at gates through widgets:
|
|
|
|
- **`reviewer_select`**: single choice. An option with a `decision` payload confirms and persists directly; an option without a payload only asks.
|
|
- **`reviewer_decide`**: multiselect. Each choice is a decision.
|
|
- **`reviewer_confirm`**: artifact or phase gate.
|
|
|
|
The frontend renders these widget descriptors (registry in `src/widgets/`). It rebuilds the live transcript in memory from the SSE stream (`src/store/sessionStore.ts`); it is **not persisted**.
|
|
|
|
## Evidence sources, local authority and search projections
|
|
|
|
The workspace repository publishes revision-pinned workspace identities and Evidence sources.
|
|
An initialized editable Evidence archive is maintained locally through external editors and
|
|
explicit consolidation; normal preprocessing or source refresh must not overwrite its manual
|
|
corrections. File save, active search generation and a later human Git commit/push are separate
|
|
outcomes. See [the current Evidence contract](../contracts/curated-evidence-v4.md) and
|
|
[source/publication boundaries](../contracts/workspace-evidence-v3.md).
|
|
|
|
Each workspace has separate Qdrant collections. `reference` contains Schema, relationships and
|
|
Evidence and may be replaced or cleared by preprocessing. Memory uses its own dense/BM25
|
|
projection, rebuilt from authoritative PostgreSQL cards rather than old vector payloads or
|
|
session artifacts. Both collections can contain sparse vectors; their ownership and cleanup
|
|
lifecycles remain separate. See [Memory](../gestione-memory.md).
|
|
|
|
The Administration control can clear the replaceable reference collection, LSH, corpus, and derived
|
|
checkpoints. The operation preserves the memory collection and makes preprocessing required before
|
|
the core can admit a new session.
|
|
|
|
## Recurring points of attention
|
|
|
|
- `tht -c`/`--config` is a **per-command** option. It must follow the subcommand, never precede it (`ThtRunner.buildArgv` enforces this).
|
|
- `--json` output must be plain JSON on stdout. It is a machine-readable contract.
|
|
- UI strings support English and Italian, with English fallback. Session interaction language
|
|
is pinned at creation; document content remains in the workspace language. See
|
|
[shell and localization](../operations/shell-and-localization.md).
|
|
- Each workspace defines identity and optional Evidence only. The PostgreSQL Metadata Catalog defines
|
|
its DWH target and binding; secrets remain in the protected workspace secret store.
|
|
- Settings are global (`backend/data/settings.json`: workspace/thinking); provider/model choices are
|
|
canonical catalog references selected per session.
|
|
- **Resume**: a resumable session returns to its last incomplete phase. The backend rejects resume with 409 when `finalized` or `archived`; `PiProcessManager.spawnFor` must send `/riprendi-sessione <id>` for resume and `/nuova-domanda` for a new session. The wrong prompt silently turns a resume into a new question.
|
|
|
|
## Runtime composition
|
|
|
|
PostgreSQL is the current database-metadata authority for all core consumers, not a deferred
|
|
catalog-to-core integration. The historical research on a separate catalog service and
|
|
`annotations.yaml` publication is superseded by ADRs 0004 and 0016. Preserve read-only DWH access,
|
|
installation-local bindings/secrets, revision-pinned workspace identity, and fail-closed readiness
|
|
when changing those boundaries. The exact snapshot interface is the
|
|
[Catalog Schema Snapshot contract](../contracts/catalog-schema-snapshot.md).
|
|
|
|
The local stack is started by `./scripts/run-stack.sh` after the installation descriptor and
|
|
`deploy/env/local.env` exist. `core` includes Pi. `catalog-db`, Qdrant, and the Ollama embedding
|
|
service are internal Compose services; only the DWH and model-provider endpoint remain external.
|
|
The launcher runs the explicit `catalog-migrate` one-shot service before application startup.
|
|
|
|
For the operator sequence, see [Install and first start](../install/first-start.md). For the
|
|
two user-facing paths, see [User guide](../guida-utente.md) and
|
|
[Database management](../operations/database-management.md).
|