This commit is contained in:
+6
-1
@@ -1,12 +1,17 @@
|
||||
# ThothII — Project State
|
||||
|
||||
Last updated: 2026-09-02.
|
||||
Last updated: 2026-09-04.
|
||||
|
||||
This file is the short operational snapshot. Stable commands and the architecture mental model
|
||||
live in `AGENTS.md`; current design and runtime contracts live under `docs/architecture/`,
|
||||
`docs/contracts/`, `docs/adr/`, and `docs/evidence.md`. Superseded plans and reports are
|
||||
available from Git history rather than duplicated in the working tree.
|
||||
|
||||
The guarded server migration from a legacy checkout to the schema-v2 installation, Gitea source,
|
||||
Authentik, internal catalog/embedding services, and the PSD workspace repository is documented in
|
||||
`docs/operations/server-upgrade-gitea-workspace-v2.md`. Treat its operator gates and rollback
|
||||
requirements as mandatory; do not replace the running server stack in place.
|
||||
|
||||
## Current product shape
|
||||
|
||||
ThothII is a human-in-the-loop datamart builder with three independently built layers:
|
||||
|
||||
@@ -0,0 +1,705 @@
|
||||
# Upgrade del server alla configurazione ThothII v2
|
||||
|
||||
Questo runbook è il passaggio di consegne per il Codex che opererà sul server remoto. Porta una
|
||||
installazione precedente alla configurazione corrente di ThothII senza modificare Authentik o il
|
||||
DWH esterno e senza cancellare lo stack precedente durante il primo cutover.
|
||||
|
||||
La procedura si applica a `main` quando contiene almeno il commit
|
||||
`eba6148511675fc6a187aabb69a975adc5e3c542`. Deve essere presente anche questo file. Il commit
|
||||
minimo è un controllo di sicurezza, non un invito a fermarsi a quella revisione: installare sempre
|
||||
la `origin/main` approvata dall'operatore.
|
||||
|
||||
## Regole non negoziabili
|
||||
|
||||
- Eseguire prima l'intero inventario in sola lettura e consegnarlo all'operatore.
|
||||
- Non stampare mai password, token, chiavi private, cookie, file `.env` o contenuti dei Docker
|
||||
secret. Nei report sono ammessi solo percorsi, nomi delle variabili e valori non segreti.
|
||||
- Non usare `set -x`, credenziali dentro URL Git, `http.sslVerify=false`, `docker compose down -v`,
|
||||
`docker volume rm`, `git reset --hard` o pulizie ricorsive.
|
||||
- Non inventare l'indirizzo IP di `git.tylconsulting.it` e non aggiungerlo a `/etc/hosts` senza un
|
||||
valore e un fingerprint TLS forniti dall'amministratore.
|
||||
- Non sovrascrivere la vecchia configurazione. Creare una nuova installation ID e mantenere
|
||||
configurazione, immagini, container e volumi precedenti fino all'accettazione scritta.
|
||||
- Fermarsi a ogni **Gate operatore**. Il Codex prepara evidenze e comandi esatti; l'operatore
|
||||
autorizza backup con segreti, fermo dello stack, cambio del reverse proxy e rimozioni.
|
||||
- Il DWH resta read-only e diretto. Nessuna migrazione o DDL deve essere eseguita sul DWH.
|
||||
|
||||
## Cosa contiene la nuova release
|
||||
|
||||
Il confine informale “da auth in poi” non coincide con un singolo commit Git. OIDC/Authentik e il
|
||||
CLI host `tht` fanno parte del contratto che il nuovo server deve rispettare, ma la tranche promossa
|
||||
da `f5861526` a `eba61485` riguarda soprattutto:
|
||||
|
||||
- Database Management e il catalogo metadati isolato nel PostgreSQL interno `catalog-db`;
|
||||
- sincronizzazione di tabelle, colonne e relazioni, generazione descrizioni e flag di sensibilità;
|
||||
- Installation Model Catalog schema v2 come unica sorgente authored per modelli e provider;
|
||||
- workspace schema v4 e proiezioni runtime generate;
|
||||
- Qdrant per gli indici del workspace e Ollama per il solo modello di embedding;
|
||||
- analisi locale deterministica delle colonne sensibili, con NER CPU opzionale;
|
||||
- hardening delle proiezioni e stabilizzazione dei gate di test pre-deploy.
|
||||
|
||||
La topologia base attesa è:
|
||||
|
||||
| Servizio | Funzione | Persistenza |
|
||||
| --- | --- | --- |
|
||||
| `frontend` | UI React | nessuna persistenza propria |
|
||||
| `core` | Fastify, Pi RPC e catalog API | volumi settings, Pi, registry, secrets e sessioni |
|
||||
| `catalog-db` | PostgreSQL del catalogo metadati | volume `catalog-data` |
|
||||
| `catalog-migrate` | migrazioni esplicite del catalogo | job one-shot, deve terminare con exit 0 |
|
||||
| `qdrant` | indice vettoriale workspace | volume `qdrant-data` |
|
||||
| `embedding` | Ollama interno per embedding | volume `embedding-models` |
|
||||
| `embedding-model-init` | scarica/verifica il modello | job one-shot, deve terminare con exit 0 |
|
||||
|
||||
`catalog-db` non è il DWH. Non pubblica porte sull'host e usa credenziali runtime e migrator
|
||||
separate. Ollama non controlla le password utente: l'autenticazione resta OIDC tramite Authentik.
|
||||
|
||||
Il PostgreSQL per le **sessioni** è un'altra funzione ancora. L'overlay
|
||||
`deploy/compose.session-server.yaml.example` è esplicitamente opt-in: non abilitarlo durante questo
|
||||
upgrade salvo decisione separata dell'operatore e presenza di un database sessioni già
|
||||
provisionato. L'introduzione richiesta qui è soltanto `catalog-db`.
|
||||
|
||||
## Stato finale desiderato
|
||||
|
||||
Sono due repository distinti e non devono essere confusi:
|
||||
|
||||
| Uso | Remote atteso | Branch | Trasporto |
|
||||
| --- | --- | --- | --- |
|
||||
| codice applicativo ThothII, remote `origin` | `https://git.tylconsulting.it/mptyl/ThothII.git` | `main` | HTTPS |
|
||||
| workspace PSD, `workspaceRepository` | `git@github.com:mptyl/tht-workspace-psd.git` | `main` | SSH |
|
||||
|
||||
Il riferimento locale approvato usa il workspace precedente e questi default di modello:
|
||||
|
||||
- sessione: `zai/glm-5.3`;
|
||||
- generazione metadati: `zai/glm-5.3`;
|
||||
- embedding: `ollama/qwen3-embedding:0.6b`, 1024 dimensioni.
|
||||
|
||||
Non copiare i file generati locali. La sorgente authored è il nuovo
|
||||
`thothii-installation.yaml`; i file Pi, settings, catalogo runtime e Compose derivati vengono
|
||||
rigenerati da `tht`.
|
||||
|
||||
## 0. Preparare le variabili di lavoro
|
||||
|
||||
Usare percorsi assoluti reali. I valori seguenti sono esempi e vanno sostituiti dopo l'inventario:
|
||||
|
||||
```bash
|
||||
THTII_REPO=/absolute/path/to/ThothII
|
||||
THTII_GITEA_URL=https://git.tylconsulting.it/mptyl/ThothII.git
|
||||
THTII_MIN_COMMIT=eba6148511675fc6a187aabb69a975adc5e3c542
|
||||
THTII_NEW_ID=psd-server-v2
|
||||
THTII_WORKSPACE_REMOTE=git@github.com:mptyl/tht-workspace-psd.git
|
||||
THTII_WORKSPACE_BRANCH=main
|
||||
THTII_OLD_INSTALLATION=/absolute/path/to/legacy/thothii-installation.yaml
|
||||
THTII_NEW_INSTALLATION=/absolute/path/to/ThothII/deploy/psd-server-v2/thothii-installation.yaml
|
||||
THTII_NEW_ENV=/absolute/path/to/ThothII/deploy/psd-server-v2/operator.env
|
||||
THTII_BACKUP_ARCHIVE=/protected/backups/thothii-pre-v2-YYYYMMDD.zip
|
||||
THTII_SECRETS_FILE=/protected/thothii-v2/thothii.secrets
|
||||
THTII_PI_AUTH_FILE=/protected/thothii-v2/pi-auth.json
|
||||
THTII_CATALOG_RUNTIME_PASSWORD=/protected/thothii-v2/catalog-runtime-password
|
||||
THTII_CATALOG_MIGRATOR_PASSWORD=/protected/thothii-v2/catalog-migrator-password
|
||||
THTII_WORKSPACE_SSH_KEY=/protected/thothii-v2/workspace-deploy-key
|
||||
THTII_WORKSPACE_KNOWN_HOSTS=/protected/thothii-v2/workspace-known-hosts
|
||||
THTII_PUBLIC_URL=https://thothii.example.invalid
|
||||
THTII_AUTH_ISSUER=https://authentik.example.invalid/application/o/thothii/
|
||||
THTII_AUTH_CLIENT_ID=replace-with-approved-client-id
|
||||
THTII_AUTHENTIK_URL=https://authentik.example.invalid
|
||||
```
|
||||
|
||||
Definire inoltre, senza pubblicarne il contenuto:
|
||||
|
||||
- percorso del descriptor e comando di avvio della vecchia installazione;
|
||||
- installation ID, Compose project, porte e reverse-proxy route correnti;
|
||||
- percorsi protetti per secret bundle, Pi auth, chiave SSH GitHub e `known_hosts`;
|
||||
- Public URL, issuer, client ID, URL Authentik e nomi dei gruppi;
|
||||
- host, porta, database, utente e CA del binding diretto DWH;
|
||||
- directory persistenti e directory backup della nuova installazione.
|
||||
|
||||
**Esito richiesto:** tutte le variabili indicano target esistenti o percorsi nuovi approvati; nessun
|
||||
valore segreto compare nel terminale condiviso.
|
||||
|
||||
## 1. Inventario in sola lettura del server
|
||||
|
||||
Non fare ancora fetch, checkout, stop o modifica di remote. Dal checkout esistente raccogliere:
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
git status --short --branch
|
||||
git branch --show-current
|
||||
git rev-parse HEAD
|
||||
git remote -v
|
||||
git tag --points-at HEAD
|
||||
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
|
||||
docker volume ls
|
||||
df -h
|
||||
tht version --json
|
||||
```
|
||||
|
||||
Se `tht` non esiste ancora, registrarlo come assente senza installarlo in questo passo. Individuare
|
||||
anche i container realmente appartenenti al vecchio stack, i loro image ID, i volumi montati e il
|
||||
comando esatto che oggi li avvia. Non assumere nomi dai file della nuova release.
|
||||
|
||||
Raccogliere in forma redatta:
|
||||
|
||||
1. configurazione Authentik attuale: Public URL, issuer, client ID, callback, claim gruppi e gruppi
|
||||
ruolo; non leggere in output client secret o API token;
|
||||
2. binding DWH diretto: tipo `postgres_direct`, endpoint, database e utente; non stampare password;
|
||||
3. remote, branch e revisione del vecchio workspace;
|
||||
4. stato delle sessioni e directory dati che devono essere conservate;
|
||||
5. spazio disponibile per immagini, volume Ollama, Qdrant, catalogo e backup.
|
||||
|
||||
Se il worktree è sporco o contiene configurazioni non committate, fermarsi: descrivere file e
|
||||
proprietario delle modifiche, senza fare stash, reset o checkout.
|
||||
|
||||
**Esito richiesto:** un report redatto identifica vecchio stack, dati, immagini, rete, Authentik,
|
||||
DWH e workspace; il worktree è pulito oppure l'operatore ha risolto esplicitamente le differenze.
|
||||
|
||||
## 2. Rendere Gitea raggiungibile e assegnarlo a `origin`
|
||||
|
||||
“Impostare Gitea come origin” e “risolvere il dominio Gitea” sono due operazioni diverse. Verificare
|
||||
prima DNS e TLS:
|
||||
|
||||
```bash
|
||||
getent hosts git.tylconsulting.it
|
||||
curl --fail --silent --show-error --head https://git.tylconsulting.it/
|
||||
```
|
||||
|
||||
Se `getent` non è disponibile, usare il resolver diagnostico già installato, per esempio
|
||||
`dig +short git.tylconsulting.it`. Se il nome non risolve, fermarsi e chiedere la correzione DNS o
|
||||
la mappatura IP ufficiale. Se TLS fallisce per una CA interna, installare la CA fornita
|
||||
dall'amministratore nel trust store; non disabilitare la verifica.
|
||||
|
||||
Quando rete e TLS sono validi, registrare l'URL corrente di `origin` nel report e configurare Gitea:
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
git remote get-url origin
|
||||
git remote set-url origin "$THTII_GITEA_URL"
|
||||
git remote -v
|
||||
git ls-remote --exit-code origin refs/heads/main
|
||||
```
|
||||
|
||||
Se `origin` non esiste, usare `git remote add origin "$THTII_GITEA_URL"` al posto di
|
||||
`set-url`. Se serve autenticazione HTTPS, configurare il credential helper o il token nel secret
|
||||
store del server; non inserire il token nell'URL o nella shell history.
|
||||
|
||||
**Esito richiesto:** `origin` mostra l'URL Gitea esatto per fetch e push e `ls-remote` restituisce
|
||||
`refs/heads/main`. Non eseguire push dal server.
|
||||
|
||||
## 3. Fare fetch e aggiornare `main` senza perdere il rollback
|
||||
|
||||
Con worktree pulito:
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
git fetch --prune origin
|
||||
git branch rollback/server-pre-v2-YYYYMMDD HEAD
|
||||
git switch main
|
||||
git merge --ff-only origin/main
|
||||
git merge-base --is-ancestor "$THTII_MIN_COMMIT" HEAD
|
||||
test -f docs/operations/server-upgrade-gitea-workspace-v2.md
|
||||
git status --short --branch
|
||||
git rev-parse HEAD
|
||||
```
|
||||
|
||||
Sostituire `YYYYMMDD` con la data reale e registrare hash precedente, rollback branch e nuovo hash.
|
||||
Un merge non fast-forward, un file mancante o il fallimento di `merge-base` sono condizioni di stop.
|
||||
Non risolvere divergenze con reset o rebase sul server.
|
||||
|
||||
**Esito richiesto:** `main` coincide con la `origin/main` approvata, contiene il commit minimo e il
|
||||
runbook, e il rollback branch punta ancora al vecchio HEAD.
|
||||
|
||||
## 4. Salvare vecchia installazione, dati e immagini
|
||||
|
||||
### Gate operatore A — custodia del backup
|
||||
|
||||
Prima di leggere o archiviare secret, presentare l'elenco esatto dei file e volumi da salvare e
|
||||
ottenere l'autorizzazione. Il backup deve stare fuori dal repository, su storage protetto, con
|
||||
permessi restrittivi e checksum registrato separatamente.
|
||||
|
||||
Se il vecchio CLI espone `backup` e accetta il suo descriptor, usare il percorso esplicito:
|
||||
|
||||
```bash
|
||||
umask 077
|
||||
tht --installation "$THTII_OLD_INSTALLATION" backup \
|
||||
--output "$THTII_BACKUP_ARCHIVE" --include-secrets --yes --drain
|
||||
sha256sum "$THTII_BACKUP_ARCHIVE"
|
||||
```
|
||||
|
||||
Se il vecchio formato non è accettato, usare la procedura di backup già approvata sul server. Non
|
||||
improvvisare un archivio ricorsivo di `/srv` o della root. Il backup deve includere almeno:
|
||||
|
||||
- descriptor, env non segreto, configurazione auth canonica, secret bundle, Pi auth e certificati;
|
||||
- repository/configurazione workspace precedente e sessioni persistite;
|
||||
- inventario di container, reti, volumi, mount, image name e image ID;
|
||||
- configurazione del reverse proxy necessaria a ripristinare il servizio.
|
||||
|
||||
Conservare anche le immagini effettivamente in uso: assegnare tag di rollback agli image ID
|
||||
espliciti identificati al passo 1 oppure salvarli in un archivio Docker protetto. Non selezionare
|
||||
immagini tramite glob. Il nuovo build può riutilizzare gli stessi tag mentre i container vecchi
|
||||
continuano a funzionare.
|
||||
|
||||
Il backup integrato va considerato sufficiente per un volume solo se il suo manifest lo elenca e la
|
||||
procedura di restore è stata verificata. In questa migrazione il nuovo `catalog-data` nasce vuoto;
|
||||
non esiste quindi un vecchio catalogo da importare. Per upgrade successivi, il catalogo PostgreSQL
|
||||
dovrà avere un dump consistente esplicito se il backup corrente non lo comprende.
|
||||
|
||||
**Esito richiesto:** archivio, checksum, immagini di rollback e comando di ripristino sono
|
||||
verificati; nessun vecchio container o volume è stato eliminato.
|
||||
|
||||
## 5. Installare il CLI corrente e creare una installation v2 affiancata
|
||||
|
||||
Dal nuovo checkout:
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
./scripts/install-tht.sh
|
||||
tht version --json
|
||||
```
|
||||
|
||||
Preparare fuori dal repository file protetti distinti per:
|
||||
|
||||
- secret bundle applicativo;
|
||||
- Pi auth;
|
||||
- password runtime e migrator di `catalog-db`;
|
||||
- chiave privata e `known_hosts` del repository workspace GitHub.
|
||||
|
||||
Le due password del catalogo devono essere casuali, non vuote e diverse. I file devono essere
|
||||
leggibili solo dall'operatore autorizzato. Nel secret bundle servono i riferimenti approvati per i
|
||||
provider (`ZAI_API_KEY` e, se mantenuto, `DEEPSEEK_API_KEY`) e per Authentik
|
||||
(`THT_OIDC_CLIENT_SECRET`, `THT_AUTHENTIK_API_TOKEN`), mai i valori nel descriptor YAML.
|
||||
|
||||
Verificare l'accesso SSH al workspace con la chiave e il file `known_hosts` approvati. Non costruire
|
||||
`known_hosts` accettando alla cieca il primo fingerprint restituito dalla rete:
|
||||
|
||||
```bash
|
||||
ssh-keygen -F github.com -f "$THTII_WORKSPACE_KNOWN_HOSTS"
|
||||
GIT_SSH_COMMAND="ssh -i $THTII_WORKSPACE_SSH_KEY -o IdentitiesOnly=yes -o UserKnownHostsFile=$THTII_WORKSPACE_KNOWN_HOSTS" \
|
||||
git ls-remote --exit-code "$THTII_WORKSPACE_REMOTE" refs/heads/main
|
||||
```
|
||||
|
||||
Creare la configurazione server in modalità `configure-only`; il profilo server richiede root per
|
||||
creare la proiezione auth con UID/GID del container. La versione corrente di `setup` non scrive
|
||||
ancora i due path catalogo nell'env generato: passarli all'ambiente del comando per validare
|
||||
Compose, quindi aggiungerli subito a `operator.env` nel passo successivo.
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
sudo env \
|
||||
THT_CATALOG_RUNTIME_PASSWORD_SOURCE="$THTII_CATALOG_RUNTIME_PASSWORD" \
|
||||
THT_CATALOG_MIGRATOR_PASSWORD_SOURCE="$THTII_CATALOG_MIGRATOR_PASSWORD" \
|
||||
tht setup --configure-only \
|
||||
--installation-id "$THTII_NEW_ID" \
|
||||
--profile server \
|
||||
--workspace-remote "$THTII_WORKSPACE_REMOTE" \
|
||||
--workspace-branch "$THTII_WORKSPACE_BRANCH" \
|
||||
--workspace-access ssh \
|
||||
--secrets-file "$THTII_SECRETS_FILE" \
|
||||
--pi-auth-file "$THTII_PI_AUTH_FILE" \
|
||||
--git-ssh-key-file "$THTII_WORKSPACE_SSH_KEY" \
|
||||
--git-known-hosts-file "$THTII_WORKSPACE_KNOWN_HOSTS" \
|
||||
--auth-mode oidc \
|
||||
--auth-public-url "$THTII_PUBLIC_URL" \
|
||||
--auth-issuer "$THTII_AUTH_ISSUER" \
|
||||
--auth-client-id "$THTII_AUTH_CLIENT_ID" \
|
||||
--auth-authentik-base-url "$THTII_AUTHENTIK_URL" \
|
||||
--auth-user-group 'TOT Users' \
|
||||
--auth-admin-group 'TOT Admin'
|
||||
```
|
||||
|
||||
Se sul server i gruppi hanno nomi diversi, usare i nomi verificati al passo 1. Non indovinarli.
|
||||
Registrare il descriptor prodotto, normalmente
|
||||
`deploy/<installation-id>/thothii-installation.yaml`, e usarlo esplicitamente in ogni comando
|
||||
successivo. Aggiungere all'`operator.env` generato, usando un editor che non stampi i valori:
|
||||
|
||||
```dotenv
|
||||
THT_CATALOG_RUNTIME_PASSWORD_SOURCE=/protected/thothii-v2/catalog-runtime-password
|
||||
THT_CATALOG_MIGRATOR_PASSWORD_SOURCE=/protected/thothii-v2/catalog-migrator-password
|
||||
THT_CATALOG_SYNC_TIMEOUT_MS=600000
|
||||
```
|
||||
|
||||
I valori a destra devono essere i percorsi assoluti reali preparati sopra. Verificare che
|
||||
`THTII_NEW_INSTALLATION` e `THTII_NEW_ENV` corrispondano ai file appena creati.
|
||||
|
||||
**Esito richiesto:** esistono descriptor schema v2, env operatore e directory auth canonica/runtime
|
||||
della nuova installation; lo stack precedente è ancora in esecuzione.
|
||||
|
||||
## 6. Allineare il descriptor alla configurazione locale approvata
|
||||
|
||||
Il `setup` genera un catalogo modelli valido ma generico. Sostituire il suo blocco `modelCatalog`
|
||||
con questo riferimento corrente, soltanto dopo aver verificato che il server raggiunga gli endpoint
|
||||
necessari:
|
||||
|
||||
```yaml
|
||||
modelCatalog:
|
||||
defaults:
|
||||
session: zai/glm-5.3
|
||||
metadataGeneration: zai/glm-5.3
|
||||
embedding:
|
||||
id: ollama/qwen3-embedding:0.6b
|
||||
dimensions: 1024
|
||||
providers:
|
||||
deepseek:
|
||||
authentication:
|
||||
mode: pi_auth
|
||||
session:
|
||||
mode: pi_builtin
|
||||
models:
|
||||
deepseek-v4-pro:
|
||||
session: {}
|
||||
deepseek-v4-flash:
|
||||
session: {}
|
||||
deepseek-metadata:
|
||||
authentication:
|
||||
mode: secret_env
|
||||
apiKeyEnv: DEEPSEEK_API_KEY
|
||||
metadataGeneration:
|
||||
litellmProvider: deepseek
|
||||
models:
|
||||
deepseek-v4-pro:
|
||||
label: DeepSeek V4 Pro
|
||||
metadataGeneration: {}
|
||||
deepseek-v4-flash:
|
||||
label: DeepSeek V4 Flash
|
||||
metadataGeneration: {}
|
||||
zai:
|
||||
endpoint:
|
||||
baseUrl: https://api.z.ai/api/coding/paas/v4
|
||||
authentication:
|
||||
mode: secret_env
|
||||
apiKeyEnv: ZAI_API_KEY
|
||||
session:
|
||||
mode: openai_compatible
|
||||
metadataGeneration:
|
||||
litellmProvider: openai
|
||||
models:
|
||||
glm-5.3:
|
||||
label: GLM 5.3
|
||||
session:
|
||||
reasoning: true
|
||||
contextWindow: 200000
|
||||
maxTokens: 131072
|
||||
metadataGeneration: {}
|
||||
local-qwen:
|
||||
endpoint:
|
||||
baseUrl: https://ml-aritmolab.policlinicosandonato.it/v1
|
||||
authentication:
|
||||
mode: none
|
||||
session:
|
||||
mode: openai_compatible
|
||||
metadataGeneration:
|
||||
litellmProvider: openai
|
||||
models:
|
||||
qwen3.6-35b-a3b:
|
||||
label: AritmoLab Qwen 3.6 35B A3B
|
||||
session:
|
||||
reasoning: false
|
||||
input: [text]
|
||||
cost: {input: 0, output: 0, cacheRead: 0, cacheWrite: 0}
|
||||
contextWindow: 131072
|
||||
maxTokens: 16384
|
||||
compatibility:
|
||||
supportsDeveloperRole: false
|
||||
supportsReasoningEffort: false
|
||||
supportsStore: false
|
||||
maxTokensField: max_tokens
|
||||
metadataGeneration:
|
||||
disableThinking: true
|
||||
```
|
||||
|
||||
Controllare inoltre:
|
||||
|
||||
- `profile: server` e `projectDirectory` uguale al checkout reale;
|
||||
- `workspaceRepository` uguale alla riga PSD della tabella iniziale;
|
||||
- `authentication.configDirectory` nella nuova directory canonica;
|
||||
- `authentication.runtimeProjection` in una directory separata, con `uid: 10001` e `gid: 10001`;
|
||||
- un solo override Git SSH;
|
||||
- nessun riferimento a vecchi `deploy/pi/models.json`, `deploy/pi/settings.json` o model metadata
|
||||
nel workspace;
|
||||
- nessun overlay session PostgreSQL salvo approvazione separata.
|
||||
|
||||
La proiezione Compose dell'auth runtime è automatica: non aggiungere manualmente
|
||||
`deploy/compose.auth-runtime-projection.yaml` agli override. Se un endpoint di modello non è
|
||||
raggiungibile dal server, fermarsi e chiedere quale provider mantenere; non cambiare silenziosamente
|
||||
i default.
|
||||
|
||||
Aggiornare l'env operatore usando `deploy/env/server.env.example` come checklist. Devono essere
|
||||
valorizzati almeno i percorsi `THT_CATALOG_RUNTIME_PASSWORD_SOURCE`,
|
||||
`THT_CATALOG_MIGRATOR_PASSWORD_SOURCE`, `THT_DATA_ROOT`, `THT_PI_STATE_ROOT`,
|
||||
`THT_WORKSPACE_REGISTRY_ROOT`, `THT_BACKUP_ROOT`, le sorgenti auth/Git e le porte. Le directory
|
||||
persistenti della nuova installation non devono coincidere accidentalmente con quelle legacy.
|
||||
|
||||
**Esito richiesto:** descriptor e env contengono soltanto configurazione non segreta, puntano ai
|
||||
secret file protetti e descrivono esattamente workspace, auth e modelli approvati.
|
||||
|
||||
## 7. Verificare Authentik senza ricrearlo
|
||||
|
||||
Se Public URL resta invariato, non creare una seconda applicazione/provider in Authentik. Il
|
||||
provider esistente deve avere:
|
||||
|
||||
- callback esatta `<PUBLIC_URL>/api/auth/oidc/callback`;
|
||||
- scope `openid profile email`;
|
||||
- claim `groups` non vuoto come array JSON;
|
||||
- gruppi applicativi attesi, normalmente `TOT Users` e `TOT Admin`;
|
||||
- token del service account con sola lettura dei gruppi.
|
||||
|
||||
Configurare o rigenerare soltanto la configurazione canonica della nuova installation:
|
||||
|
||||
```bash
|
||||
sudo tht --installation "$THTII_NEW_INSTALLATION" auth configure \
|
||||
--mode oidc \
|
||||
--public-url "$THTII_PUBLIC_URL" \
|
||||
--issuer "$THTII_AUTH_ISSUER" \
|
||||
--client-id "$THTII_AUTH_CLIENT_ID" \
|
||||
--authentik-base-url "$THTII_AUTHENTIK_URL" \
|
||||
--user-group 'TOT Users' \
|
||||
--admin-group 'TOT Admin'
|
||||
tht --installation "$THTII_NEW_INSTALLATION" auth status --json
|
||||
```
|
||||
|
||||
Il comando non riceve secret come argomenti: li risolve dai riferimenti nel secret bundle. La nuova
|
||||
directory `auth-state` può partire vuota. Le vecchie sessioni browser non devono essere migrate e
|
||||
gli utenti dovranno autenticarsi di nuovo dopo il cutover.
|
||||
|
||||
**Esito richiesto:** lo status redatto indica `mode: oidc`, URL e gruppi corretti; nessun secret è
|
||||
presente in YAML, argomenti, log o report.
|
||||
|
||||
## 8. Preflight e preparazione dei servizi interni
|
||||
|
||||
`tht start` rigenera le proiezioni e avvia i servizi, ma non esegue il job esplicito
|
||||
`catalog-migrate`. Preparare quindi immagini e servizi interni con la stessa identità Compose della
|
||||
nuova installation mentre il vecchio frontend/core sono ancora attivi.
|
||||
|
||||
Per prima cosa validare il descriptor e il render Compose:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" update --check-only
|
||||
```
|
||||
|
||||
Questo comando carica e valida il descriptor; dopo la modifica del `modelCatalog`, la proiezione
|
||||
generata da `setup` resta intenzionalmente precedente fino a `tht start`. Non usare `doctor` come
|
||||
gate in questo momento: i servizi sono fermi e il suo controllo di drift deve ancora fallire. Il
|
||||
gate completo viene eseguito al passo 10, dopo che `start` ha rigenerato la proiezione.
|
||||
|
||||
Calcolare il Compose project name con la stessa regola del CLI e costruire l'array dei file. Questo
|
||||
blocco è esatto per il descriptor atteso, che ha il solo override Git SSH. Se nel descriptor ci sono
|
||||
altri override approvati, inserirli nello stesso ordine subito dopo `compose.git-ssh.yaml`; non
|
||||
ometterli e non aggiungere l'overlay sessioni per comodità.
|
||||
|
||||
```bash
|
||||
THTII_NEW_INSTALLATION=$(realpath "$THTII_NEW_INSTALLATION")
|
||||
THTII_INSTALL_DIR=$(dirname "$THTII_NEW_INSTALLATION")
|
||||
THTII_COMPOSE_PROJECT="thothii-$(printf '%s' "$THTII_NEW_INSTALLATION" | sha256sum | cut -c1-12)"
|
||||
THTII_COMPOSE=(
|
||||
docker compose
|
||||
--project-name "$THTII_COMPOSE_PROJECT"
|
||||
--project-directory "$THTII_REPO"
|
||||
--env-file "$THTII_NEW_ENV"
|
||||
-f "$THTII_REPO/compose.yaml"
|
||||
-f "$THTII_REPO/deploy/compose.server.yaml"
|
||||
-f "$THTII_REPO/deploy/compose.git-ssh.yaml"
|
||||
-f "$THTII_INSTALL_DIR/generated/compose.models.yaml"
|
||||
-f "$THTII_REPO/deploy/compose.auth-runtime-projection.yaml"
|
||||
)
|
||||
"${THTII_COMPOSE[@]}" config --quiet
|
||||
```
|
||||
|
||||
Non stampare il render completo. Costruire le immagini e avviare soltanto i servizi interni privi
|
||||
di porte host:
|
||||
|
||||
```bash
|
||||
"${THTII_COMPOSE[@]}" build core frontend
|
||||
"${THTII_COMPOSE[@]}" up --detach catalog-db qdrant embedding
|
||||
"${THTII_COMPOSE[@]}" run --rm catalog-migrate
|
||||
"${THTII_COMPOSE[@]}" run --rm embedding-model-init
|
||||
"${THTII_COMPOSE[@]}" ps --all
|
||||
```
|
||||
|
||||
Il comando `catalog-migrate` deve terminare con exit 0 prima che `core` venga avviato. Anche
|
||||
`embedding-model-init` deve terminare con exit 0 e lasciare il modello nel volume della nuova
|
||||
installation. Questi comandi non pubblicano la nuova applicazione e non toccano i volumi legacy.
|
||||
|
||||
Confermare inoltre che il server abbia accesso in uscita necessario al primo pull del modello
|
||||
Ollama e spazio sufficiente per `embedding-models`. Qdrant e `catalog-db` devono restare sulla rete
|
||||
Compose privata, senza porte host pubblicate.
|
||||
|
||||
L'overlay NER `deploy/compose.sensitivity-ner.yaml` non è richiesto per il primo avvio. La policy
|
||||
deterministica funziona senza NER. Abilitare il modello CPU soltanto con la procedura e i gate in
|
||||
[Analisi locale della sensibilità](sensitivity-analysis.md).
|
||||
|
||||
**Esito richiesto:** render Compose valido, immagini costruite, `catalog-db` healthy, migrazione exit
|
||||
0, Qdrant/Ollama healthy e modello embedding inizializzato; `core` e `frontend` nuovi sono ancora
|
||||
fermi.
|
||||
|
||||
## 9. Cutover controllato
|
||||
|
||||
### Gate operatore B — finestra di manutenzione
|
||||
|
||||
Presentare prima:
|
||||
|
||||
- hash release, descriptor nuovo e risultato del preflight;
|
||||
- comando esatto per fermare e riavviare il vecchio stack;
|
||||
- comando di rollback, image ID conservati e durata stimata;
|
||||
- porte e route del reverse proxy che resteranno invariate o verranno cambiate.
|
||||
|
||||
Dopo approvazione, bloccare nuove attività applicative e fermare solo lo stack legacy con il comando
|
||||
registrato al passo 1. Non rimuoverne container o volumi. Avviare quindi la nuova installation:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" start
|
||||
```
|
||||
|
||||
Il primo avvio deve:
|
||||
|
||||
1. rigenerare le proiezioni del model catalog aggiornato;
|
||||
2. riutilizzare le immagini costruite e il catalogo già migrato al passo 8;
|
||||
3. confermare healthy `catalog-db` e Qdrant;
|
||||
4. avviare Ollama ed eseguire/verificare `embedding-model-init` per
|
||||
`qwen3-embedding:0.6b`;
|
||||
5. avviare `core` soltanto dopo le dipendenze richieste;
|
||||
6. avviare `frontend` sulla bind address prevista per il reverse proxy.
|
||||
|
||||
Non interrompere il primo pull perché è lento se log e avanzamento restano regolari. In caso di
|
||||
errore, raccogliere soltanto i log sanitizzati:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" status
|
||||
tht --installation "$THTII_NEW_INSTALLATION" logs
|
||||
```
|
||||
|
||||
`embedding-model-init` è one-shot: `exited (0)` è lo stato corretto, non un guasto. Il job
|
||||
`catalog-migrate` è stato eseguito con `run --rm`, quindi fa fede l'exit 0 registrato al passo 8.
|
||||
Qualsiasi exit diverso da zero blocca il cutover.
|
||||
|
||||
**Esito richiesto:** servizi persistenti healthy/running, job one-shot terminati con exit 0 e
|
||||
reverse proxy diretto alla nuova UI; i volumi legacy esistono ancora.
|
||||
|
||||
## 10. Verificare autenticazione e runtime
|
||||
|
||||
Eseguire:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" status
|
||||
tht --installation "$THTII_NEW_INSTALLATION" doctor --json
|
||||
tht --installation "$THTII_NEW_INSTALLATION" auth status --json
|
||||
tht --installation "$THTII_NEW_INSTALLATION" auth check
|
||||
tht --installation "$THTII_NEW_INSTALLATION" pi test
|
||||
```
|
||||
|
||||
Dal browser verificare:
|
||||
|
||||
1. redirect ad Authentik e ritorno alla callback corretta;
|
||||
2. login di un membro `TOT Users`;
|
||||
3. accesso amministrativo soltanto a un membro `TOT Admin`;
|
||||
4. logout e nuova autenticazione;
|
||||
5. assenza di loop OIDC, cookie error o `502` del reverse proxy.
|
||||
|
||||
È previsto che le sessioni browser precedenti non siano più valide. Non è previsto modificare
|
||||
issuer, client o gruppi per aggirare un errore: diagnosticare prima callback, claim e secret refs.
|
||||
|
||||
**Esito richiesto:** `doctor`, `auth check` e `pi test` passano e i due ruoli Authentik sono mappati
|
||||
correttamente.
|
||||
|
||||
## 11. Ripuntare e materializzare il workspace PSD
|
||||
|
||||
Il vecchio workspace runtime non è una sorgente da copiare. La nuova installation deve clonare e
|
||||
validare il repository Git approvato:
|
||||
|
||||
```text
|
||||
git@github.com:mptyl/tht-workspace-psd.git, branch main, access ssh
|
||||
```
|
||||
|
||||
Nella UI amministrativa, nell'ordine:
|
||||
|
||||
1. usare **Update workspace repository** per fetch/clone e validazione;
|
||||
2. selezionare il workspace PSD; l'ID atteso è `psd-clinical`, ma confermarlo dal catalogo
|
||||
`thoth-workspaces.yaml` anziché forzarlo;
|
||||
3. usare **Validate workspace source**;
|
||||
4. aprire **Database Management** e creare/aggiornare il database del workspace;
|
||||
5. configurare il binding `postgres_direct` con gli stessi endpoint, ruolo read-only e CA già
|
||||
approvati sul server; reinserire la password nel secret store write-only, non nel repository;
|
||||
6. eseguire **Test workspace connections**;
|
||||
7. eseguire una sincronizzazione completa dello schema nel nuovo catalogo;
|
||||
8. selezionare quel workspace come workspace globale dell'installation.
|
||||
|
||||
Poi verificare e materializzare con il CLI:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" workspace inspect \
|
||||
--workspace psd-clinical --json
|
||||
tht --installation "$THTII_NEW_INSTALLATION" workspace preprocess run \
|
||||
--workspace psd-clinical --json
|
||||
```
|
||||
|
||||
Se il preprocess restituisce un run ID interrotto, usare il suo `--resume RUN` soltanto dopo aver
|
||||
diagnosticato la causa. Non lanciare run paralleli. Il preprocess DWH materializza gli artifact
|
||||
runtime; il preprocess Evidence ricostruisce l'indice Qdrant con l'embedding fisso. Le nuove sessioni
|
||||
pinzano la revisione Git attiva del workspace.
|
||||
|
||||
Non copiare nel nuovo descriptor i legacy `harness/workspaces/*.yaml` come catalogo authored e non
|
||||
trasferire vecchi indici vettoriali incompatibili. Il repository workspace schema v4 definisce
|
||||
database ed Evidence; binding, segreti e selezione attiva restano locali all'installation.
|
||||
|
||||
**Esito richiesto:** `workspace inspect` mostra repository, branch e revisione PSD corretti; test
|
||||
DWH diretto, schema sync e preprocess completo terminano con successo; Qdrant contiene la nuova
|
||||
generazione Evidence.
|
||||
|
||||
## 12. Accettazione finale
|
||||
|
||||
Prima di dichiarare concluso l'upgrade, consegnare una checklist con evidenze redatte:
|
||||
|
||||
- `git rev-parse HEAD` uguale alla release approvata e worktree pulito;
|
||||
- `origin` uguale al Gitea ThothII e workspace remote uguale al GitHub PSD;
|
||||
- `tht doctor --json`, `auth check` e `pi test` senza errori;
|
||||
- `catalog-db`, Qdrant, Ollama, core e frontend healthy;
|
||||
- `catalog-migrate` ed `embedding-model-init` terminati con exit 0;
|
||||
- login Authentik utente/admin verificato;
|
||||
- binding DWH diretto read-only verificato;
|
||||
- catalogo sincronizzato e preprocess workspace completato;
|
||||
- una nuova sessione di prova crea artifact e usa la revisione workspace attiva;
|
||||
- backup, checksum, rollback branch e immagini legacy ancora disponibili;
|
||||
- nessun secret aggiunto al repository o ai log condivisi.
|
||||
|
||||
### Gate operatore C — fine osservazione
|
||||
|
||||
Non rimuovere ancora stack, immagini, volumi o backup legacy. La loro eliminazione è un'attività
|
||||
successiva e distruttiva, autorizzata soltanto dopo un periodo di osservazione e un backup completo
|
||||
della nuova installazione che includa esplicitamente anche il catalogo PostgreSQL.
|
||||
|
||||
## Rollback
|
||||
|
||||
Eseguire il rollback se il nuovo stack non diventa healthy, Authentik non completa il login, il DWH
|
||||
diretto non passa il test o il workspace non si materializza entro la finestra approvata.
|
||||
|
||||
1. Raccogliere `status` e log sanitizzati della nuova installation.
|
||||
2. Fermarla senza volumi:
|
||||
|
||||
```bash
|
||||
tht --installation "$THTII_NEW_INSTALLATION" stop
|
||||
```
|
||||
|
||||
3. Ripristinare i tag immagine legacy dagli image ID/tag conservati se il nuovo build li ha
|
||||
sostituiti.
|
||||
4. Riportare il checkout al rollback branch soltanto se il comando legacy legge file dal checkout:
|
||||
|
||||
```bash
|
||||
cd "$THTII_REPO"
|
||||
git switch rollback/server-pre-v2-YYYYMMDD
|
||||
```
|
||||
|
||||
5. Riavviare il vecchio stack con il comando esatto registrato al passo 1.
|
||||
6. Ripristinare la route reverse proxy precedente se era cambiata.
|
||||
7. Verificare vecchia UI, Authentik e DWH; non montare i nuovi volumi nel vecchio stack.
|
||||
8. Lasciare intatti i volumi della nuova installation per l'analisi post-mortem.
|
||||
|
||||
**Esito richiesto:** il servizio precedente è nuovamente disponibile con i suoi dati originali e
|
||||
la nuova installazione è ferma ma ispezionabile.
|
||||
|
||||
## Riferimenti operativi
|
||||
|
||||
- [Installazione e primo avvio](../install/first-start.md)
|
||||
- [Authentik](../install/authentik.md)
|
||||
- [OIDC generico](../install/authentication-oidc.md)
|
||||
- [Operazioni workspace](workspaces.md)
|
||||
- [Configurazione dei modelli Pi](../general/pi-configuration.md)
|
||||
- [Contesti Docker](../installazione-docker-4-contesti.md)
|
||||
- [Database Management](database-management.md)
|
||||
- [Analisi locale della sensibilità](sensitivity-analysis.md)
|
||||
@@ -46,6 +46,7 @@ nav:
|
||||
- Home: index.md
|
||||
- Install and operate:
|
||||
- Install and first start: install/first-start.md
|
||||
- Server upgrade from legacy release: operations/server-upgrade-gitea-workspace-v2.md
|
||||
- Local authentication: install/authentication-local.md
|
||||
- Generic OIDC: install/authentication-oidc.md
|
||||
- Authentik: install/authentik.md
|
||||
|
||||
Reference in New Issue
Block a user