docs: defer DWH client cutover before Project B

This commit is contained in:
User
2026-08-21 14:35:37 +02:00
parent 7118950416
commit 9974fb4bc0
12 changed files with 244 additions and 86 deletions
+8 -4
View File
@@ -1,6 +1,6 @@
# PSD — rollout controllato DWH REST
Questo runbook rispecchia i Task 9–10 del [piano](../superpowers/plans/2026-08-20-dwh-rest-per-installation-auth.md). È descrittivo: non autorizza mutazioni ora. Activity 1 PSD resta `IN_DISCUSSION` fino a due consensi espliciti separati.
Questo runbook rispecchia i Task 9–10 del [piano](../superpowers/plans/2026-08-20-dwh-rest-per-installation-auth.md). Gate A e la parte dual-key di Gate B sono stati eseguiti con autorizzazioni separate. L'emendamento del proprietario del 2026-08-21 rinvia collaudo Mac, osservazione e revoca a prima di Project B; non autorizza ulteriori mutazioni.
## Invarianti
@@ -29,11 +29,15 @@ Serve un secondo consenso: presentare file, backup, canale consegna Mac, osserva
2. Aggiungere solo `/etc/nginx/conf.d/dwh-auth-rate-limit.conf` e route DWH; preservare upstream `http://127.0.0.1:3001/`, mantenere byte-identiche le location vector e rimuovere la chiave prima di PostgREST.
3. Eseguire checker strutturale, scansione segreti con solo `PASS/FAIL` e metadati, installare candidati e `sudo nginx -t`. No raw diff: non eseguire o conservare raw diff, `nginx -T` o dump: il file legacy può contenere la chiave. Se uno fallisce, ripristinare backup prima di reload e registrare FAIL sanitizzato.
4. Dopo consenso fare reload, poi HTTPS `.it` con CA e file header curl protetti 0600: v1=2xx, legacy=2xx, casuale=401, assente=401 su `/dwh/rpc/ping`; guasto autenticatore=503, mai accesso permissivo.
5. Consegnare al Mac chiave e CA separatamente, verificare fingerprint fuori banda, configurare vault GUI o `API_KEY_FILE`, poi **Validate workspace source** e **Test workspace connections**.
6. Dopo osservazione revocare `legacy-shared` con ragione `shared-credential-rotation`; v1=2xx post-revoca, legacy=401 post-revoca e journal limitato senza chiavi/digest.
5. **Deferred pre-Project-B:** consegnare al Mac chiave e CA separatamente, verificare fingerprint fuori banda, configurare vault GUI o `API_KEY_FILE`, poi **Validate workspace source** e **Test workspace connections**.
6. **Deferred pre-Project-B:** completare 48 ore di osservazione comprendenti due cicli ETL delle 03:00, quindi revocare `legacy-shared` con ragione `shared-credential-rotation`; v1=2xx post-revoca, legacy=401 post-revoca e journal limitato senza chiavi/digest.
## Rollback e chiusura
Durante dual-key il rollback ripristina solo route/servizio revisionati, verifica `nginx -t` e fa reload autorizzato. Non ripristina chiavi revocate, PostgreSQL, dati legacy o stack. Scatta per TLS, risposte inattese, salute degradata o assenza di consenso.
Activity 1 diventa `PASS` solo con v1=2xx post-revoca, legacy=401 post-revoca, servizio/Nginx validi, log sanitizzati, rollback leggibile e accettazione owner; poi avanza a Activity 2, con programma ancora `SURVEY_NO_GO`. Compilare [evidenza](../testing/evidence/psd-dwh-auth-rollout-report-template.md) e [collaudo](../testing/dwh-auth-manual-acceptance.md).
Activity 1 resta `DEFERRED_PRE_PROJECT_B`: dual-key è attivo, ma PASS richiede ancora v1=2xx
post-revoca, legacy=401 post-revoca, servizio/Nginx validi, log sanitizzati, rollback leggibile e
accettazione owner. Il rinvio non blocca il survey e Project A privato; blocca Project B. Compilare
[evidenza](../testing/evidence/psd-dwh-auth-rollout-report-template.md) e
[collaudo](../testing/dwh-auth-manual-acceptance.md).
@@ -22,16 +22,17 @@ Authentik, Aritmolab o repository esterni.
- Survey report: `/var/tmp/thothii-psd-survey.fJh7DS/survey-report.md`
- Survey report SHA-256: `36461b6c7d1e44d055f24d6919e892b7017352ac9eb99ac67b9ae62f0614f8e7`
- Legacy stack: deve restare acceso e invariato durante la discussione di questa lista
- Project A remains forbidden fino a un nuovo `SURVEY_GO` e all'approvazione esplicita del proprietario
- La preparazione statica di Project A privato è autorizzata; stop del legacy e start del nuovo
restano vietati fino a `SURVEY_GO_PROJECT_A_PRIVATE` e a un consenso di mutazione separato
- Project B remains forbidden fino ai PASS automatico, umano e del proprietario per Project A
## Current activity and resume point
- Current activity: `1`
- Title: Rotate or revoke the exposed DWH credential safely
- Resume from: Activity 1, review the approved implementation plan and choose its execution mode
- Current activity: `2`
- Title: Identify accountable owners for the private Project A scope
- Resume from: Activity 2, assign owner/authority for legacy rollback, direct DWH, workspace and Pi/LLM
- Discussion rule: una sola attività può essere `IN_DISCUSSION`
- Allowed states: `PENDING`, `IN_DISCUSSION`, `BLOCKED`, `PASS`
- Allowed states: `PENDING`, `IN_DISCUSSION`, `DEFERRED_PRE_PROJECT_B`, `BLOCKED`, `PASS`
## How to use this checklist
@@ -51,20 +52,20 @@ Authentik, Aritmolab o repository esterni.
| ID | Attività | Stato | Responsabile | Prossimo gate |
|---|---|---|---|---|
| 1 | Rotazione controllata della credenziale DWH esposta | `IN_DISCUSSION` | Proprietario del progetto | Revisionare il piano eseguibile e scegliere l’esecuzione |
| 2 | Assegnazione dei responsabili dei componenti condivisi | `PENDING` | Unassigned | Elenco owner confermato |
| 3 | Risoluzione del dominio pubblico `.it` oppure `.com` | `PENDING` | Unassigned | Origine autorevole documentata |
| 4 | Topologia e responsabilità del load balancer | `PENDING` | Unassigned | Route, health, TLS, rollback e allowlist verificati |
| 5 | Accesso read-only protetto ad Authentik | `PENDING` | Unassigned | Inventario API autorizzato e redatto |
| 6 | Accesso catalog-only protetto a PostgreSQL | `PENDING` | Unassigned | Catalogo, grant e PostgREST verificati |
| 7 | Backup e rollback del vecchio ThothII | `PENDING` | Unassigned | Backup verificabile e restart recipe completa |
| 8 | Accesso Git read-only al workspace PSD | `PENDING` | Unassigned | SHA, descriptor e deploy key verificati |
| 9 | Metadati Pi e LLM verificabili | `PENDING` | Unassigned | Versione, policy e reachability redatte |
| 1 | Rotazione controllata della credenziale DWH esposta | `DEFERRED_PRE_PROJECT_B` | Proprietario del progetto | Chiusura obbligatoria prima di Project B |
| 2 | Assegnazione dei responsabili dei componenti condivisi | `IN_DISCUSSION` | Proprietario del progetto | Owner privati A e shared B distinti |
| 3 | Risoluzione del dominio pubblico `.it` oppure `.com` | `BLOCKED` | Unassigned | Necessario per Project B, non per A privato |
| 4 | Topologia e responsabilità del load balancer | `BLOCKED` | Unassigned | Necessario per Project B/route opzionale |
| 5 | Accesso read-only protetto ad Authentik | `BLOCKED` | Unassigned | Necessario per Project B, non per A privato |
| 6 | Accesso catalog-only protetto a PostgreSQL | `BLOCKED` | Unassigned | DWH direct read-only ancora da provare |
| 7 | Backup e rollback del vecchio ThothII | `BLOCKED` | Proprietario del progetto | Procedura e destinazione da approvare |
| 8 | Accesso Git read-only al workspace PSD | `BLOCKED` | Curator da confermare | Checkout/deploy key server mancanti |
| 9 | Metadati Pi e LLM verificabili | `BLOCKED` | Unassigned | Policy e reachability redatte mancanti |
| 10 | Conservazione evidenze e nuovo survey bounded | `PENDING` | Unassigned | Nuovo report e decisione proprietario |
## Activity 1: Rotate or revoke the exposed DWH credential safely
- Status: `IN_DISCUSSION`
- Status: `DEFERRED_PRE_PROJECT_B`
- Accountable owner: Proprietario del progetto (confermato dall'utente)
- Objective: sostituire o revocare in modo controllato la credenziale DWH comparsa nell'output
interno del survey, senza interrompere consumer legittimi e senza esporne nuovamente il valore.
@@ -161,16 +162,17 @@ Authentik, Aritmolab o repository esterni.
trasporto. Il proprietario del progetto è accountable per coordinare la rotazione. Il meccanismo
target è il servizio server-only `dwh-auth`, indipendente dallo stack ThothII, con registro a file
e una chiave revocabile per installazione.
- Blockers: il piano eseguibile attende la revisione del proprietario; mancano ancora la
sorgente protetta per importare la chiave legacy, la procedura realizzata di aggiornamento e
verifica del Mac, la documentazione TLS implementata, l'autorizzazione ai due gate di mutazione
e la revoca provata della vecchia chiave.
- Next step: revisionare il piano eseguibile e scegliere tra esecuzione subagent-driven o inline.
Le Task 1–8 non mutano il server; le Task 9–10 richiedono due autorizzazioni esplicite separate.
- Owner amendment 2026-08-21: Gate A e dual-key Gate B sono eseguiti; il Mac live test, le 48 ore
comprendenti due cicli ETL delle 03:00 e la revoca di `legacy-shared` sono rinviati al gate
obbligatorio prima di Project B. Il rinvio non equivale a PASS.
- Blockers: per chiudere Activity 1 restano il collaudo Mac, l'osservazione completa, la revoca,
v1 positivo post-revoca e legacy `401`.
- Next step: continuare Activity 2–10 per lo scope Project A privato; riaprire Activity 1 prima di
congelare il candidato Project B.
## Activity 2: Identify accountable owners for shared components
- Status: `PENDING`
- Status: `IN_DISCUSSION`
- Accountable owner: Unassigned
- Objective: associare ogni componente condiviso a una persona o a un team con autorità di lettura,
modifica, approvazione e rollback.
@@ -185,11 +187,12 @@ Authentik, Aritmolab o repository esterni.
- Discussion notes: Not discussed
- Decision: No decision recorded
- Blockers: nessun owner condiviso è stato ancora formalmente confermato.
- Next step: compilare la matrice owner/componente dopo la chiusura dell'Activity 1.
- Next step: compilare ora la matrice distinguendo componenti necessari a Project A privato e
componenti shared/pubblici rinviabili a Project B.
## Activity 3: Resolve the authoritative public origin
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: scegliere sulla base di evidenze l'unica origine pubblica finale tra il dominio `.it`
osservato e il dominio `.com` riportato nel piano.
@@ -209,7 +212,7 @@ Authentik, Aritmolab o repository esterni.
## Activity 4: Establish the load-balancer contract
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: documentare il confine effettivo del load balancer e la procedura reversibile per le
route temporanea e finale.
@@ -230,7 +233,7 @@ Authentik, Aritmolab o repository esterni.
## Activity 5: Provide protected read-only Authentik survey access
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: permettere un inventario Authentik bounded e read-only della versione installata.
- Why this is required: applicazioni, provider, flow, mapping, gruppi, service account, permessi API
@@ -250,7 +253,7 @@ Authentik, Aritmolab o repository esterni.
## Activity 6: Provide protected catalog-only PostgreSQL survey access
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: verificare database, schemi, ruoli, grant, migrazioni e PostgREST con sole query di
catalogo.
@@ -265,14 +268,22 @@ Authentik, Aritmolab o repository esterni.
6. registrare TLS/CA, backup e convenzioni per ruoli migrator/runtime.
- Required redacted evidence: risultati catalogici bounded, nomi dei ruoli, attributi e grant,
schemi PostgREST, riferimento a backup e TLS; nessuna stringa di connessione.
- Discussion notes: Not discussed
- Decision: No decision recorded
- Blockers: non esiste ancora un meccanismo psql approvato post-rotazione.
- Next step: far predisporre dal DBA l'accesso catalog-only.
- Discussion notes: il wrapper ETL `ConnectionFactory` ha aperto una sessione dichiarata
read-only e ha eseguito sole query aggregate a `pg_catalog`. Il database è PostgreSQL 15.8;
l'identità disponibile è `postgres`, owner dello schema `datawarehouse`, con `USAGE` e
`CREATE`. Su tutte le 163 relazioni catalogate possiede SELECT e anche tutti i privilegi di
scrittura/DDL tabellari verificati. Nessun nome tabella o dato clinico è stato raccolto.
- Decision: il meccanismo esistente è valido per il survey catalogico, ma è vietato come identità
runtime del nuovo core perché non è least-privilege né read-only.
- Blockers: il DBA deve fornire un ruolo dedicato con soli USAGE/SELECT e una route diretta
certificabile dal nuovo core. Il PostgREST DWH è loopback host su 127.0.0.1:3001 e non prova il
percorso PostgreSQL diretto richiesto da Project A.
- Next step: definire con il DBA ruolo, secret-file protetto, TLS/rete e query di grant da ripetere;
non creare il ruolo durante il survey.
## Activity 7: Prove legacy backup and rollback
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: dimostrare che il vecchio ThothII possa essere preservato e ripristinato prima di
qualsiasi stop.
@@ -287,14 +298,26 @@ Authentik, Aritmolab o repository esterni.
6. eseguire il backup soltanto nella successiva fase autorizzata, prima dello stop.
- Required redacted evidence: inventario, percorso backup, checksum, owner, restart recipe e
rollback route; nessun contenuto di secret.
- Discussion notes: il legacy stack è ancora attivo e invariato.
- Decision: No decision recorded
- Blockers: lifecycle supportato, backup owner e comandi esatti non stabiliti.
- Next step: approvare la procedura senza eseguirla durante la discussione.
- Discussion notes: il legacy stack è ancora attivo e invariato. Compose project `thothii` usa
`/home/chirone/ThothII/compose.yaml`; i servizi sono `core` e `frontend`, senza named volume.
Il solo bind applicativo RW è `/home/chirone/thothii-data` (con i bind Pi annidati); Evidence è
un bind RO esterno. Una lettura tar verso `/dev/null` di source e data ha dato
`legacy_backup_readability=PASS`. Il source è circa 1.05 GB e il data bind circa 1.9 MB.
I dry-run Compose passano solo fornendo il path non segreto
`PI_AUTH_FILE=/home/chirone/thothii-data/pi-config/agent/auth.json` insieme a
`--env-file deploy/thothii.env -p thothii -f compose.yaml`; stop individua entrambi i container
e start è sintatticamente valido (non trova container arrestati mentre lo stack è ancora attivo).
- Decision: il controller e le radici da archiviare sono identificati; nessun backup o stop è stato
eseguito. Per un rollback normale i container restano esistenti e il controller usa `start`.
- Blockers: scegliere/approvare la destinazione protetta, creare il backup con manifest/checksum,
verificare la leggibilità dell'archivio, definire la gestione della route durante lo stop e
ottenere il consenso separato prima di eseguire stop/start.
- Next step: approvare manifest, destinazione e comandi; eseguire backup e checksum soltanto nel
successivo gate di mutazione.
## Activity 8: Provide read-only PSD workspace Git access
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: verificare il repository remoto condiviso e il suo stato corrente dal server senza
capacità di push.
@@ -315,7 +338,7 @@ Authentik, Aritmolab o repository esterni.
## Activity 9: Make Pi and LLM metadata verifiable
- Status: `PENDING`
- Status: `BLOCKED`
- Accountable owner: Unassigned
- Objective: verificare versione Pi, provider, modello, thinking level, riferimento credenziale e
reachability LLM senza esporre il secret.
@@ -330,10 +353,51 @@ Authentik, Aritmolab o repository esterni.
- Required redacted evidence: versione, provider, model ID, thinking level, endpoint sanitizzato,
percorso/mode della credenziale e risultato di reachability.
- Discussion notes: host `x86_64`; due GPU NVIDIA osservate, ma `nvidia-smi` non è utilizzabile per
mismatch driver/libreria NVML. Il deployment CPU resta da valutare con le immagini pinned.
- Decision: No decision recorded
- Blockers: configurazione Pi protetta non leggibile e nessun endpoint LLM credential-free noto.
- Next step: ottenere un controllo assistito o permessi read-only mirati.
mismatch driver/libreria NVML. Una lettura whitelist di `settings.json` ha rilevato Pi 0.80.3,
provider `deepseek`, modello `deepseek-v4-pro` e thinking `high`, senza leggere
`auth.json`. Un singolo probe senza tool, contesto o sessione ha prodotto solo
`pi_reachability=FAIL`. Il catalogo custom dichiara inoltre il solo provider `local-qwen`.
- Decision: i metadati sono verificati, ma reachability e coerenza default/catalogo non passano.
- Blockers: diagnosticare il FAIL senza esporre la credenziale e confermare il provider/modello
approvato per Project A; il mismatch NVML/GPU resta rischio separato, non un motivo per assumere
che il percorso CPU funzioni.
- Next step: eseguire un controllo assistito e sanitizzato della configurazione provider, quindi
ripetere una sola reachability probe bounded.
## Read-only resume — 2026-08-21
- Host/source: Linux x86_64, Docker 29.1.1, Compose 2.40.3, application worktree clean at
`7118950416b3008a8182825de027c7f8b235de57`; Qdrant/Ollama images are local, while the required
embedding image/model is not yet proved local.
- Capacity: approximately 1.1 TB free on `/home` and 36 GB on `/`; several loopback candidate
ports are currently free. These facts do not reserve a path or port.
- Legacy: project `thothii` is still running and unchanged. Source is
`/home/chirone/ThothII` at `6ca4275`; the only RW application bind is
`/home/chirone/thothii-data`, plus the nested Pi binds. The source is about 1.05 GB and the data
bind about 1.9 MB. No backup was created.
- Recovery evidence: existing containers can be inventoried for a stopped-container restart, but
backup destination, checksum/restore procedure and route ordering are not yet approved.
- Identity collision: legacy data and protected subtrees are numerically owned by UID/GID 10001.
The example in `docs/install/server.md` and the Project A Pi preparation use UID 10001 for the
new service. Do not create that host
identity or grant it access until a reviewed isolation/ownership strategy is approved.
- Candidate paths: documented examples `/srv/thothii` and `/srv/thothii-backups` are absent and
therefore only candidates; they have not been created. `127.0.0.1:18080` è il candidato
frontend e risultava libero al momento del survey, ma non è riservato e va ricontrollato prima
dello start. Existing `/home/chirone/thothii-data` must not be reused.
- Workspace: the canonical private remote is documented as
`git@github.com:mptyl/tht-workspace-psd.git`; a non-interactive read-only remote query resolved
`main` at `bfbabf9f2defcf861a3225296eaff8c6d44c0ac9`. No server checkout or dedicated deploy-key
reference is present at the documented local paths, and the credential's inability to push is
not yet proved.
- Pi/LLM: legacy Pi version `0.80.3` is visible, but provider/model/thinking/credential reference
and bounded reachability remain unknown.
- Shared scope: `.it` resolves locally and `.com` does not, Nginx is valid/active, Authentik
2026.2.1 and Supabase components are running. Owner, LB contract, Authentik inventory and
PostgreSQL catalog grants remain unproved and are not inferred.
- Decision: `SURVEY_NO_GO` for Project A private remains. The bounded work authorized now is
limited to planning/static preparation; no source clone, protected tree, backup, stop or start
has been performed.
## Activity 10: Retain evidence and run the missing bounded survey checks
@@ -357,20 +421,28 @@ Authentik, Aritmolab o repository esterni.
- Blockers: dipende dalla chiusura delle Activity 1–9 e dall'approvazione del retention root.
- Next step: avviare soltanto dopo la chiusura dei blocker precedenti.
## Fresh survey and owner gate
## Fresh survey and owner gates
Un nuovo `SURVEY_GO` richiede contemporaneamente:
Un nuovo `SURVEY_GO_PROJECT_A_PRIVATE` richiede:
- credenziale DWH precedente revocata e rotazione verificata;
- owner e autorità di modifica/rollback identificati;
- origine pubblica unica e load-balancer contract provati;
- accessi read-only Authentik, PostgreSQL, workspace Git e Pi/LLM verificati;
- owner e autorità di backup/stop/start/rollback identificati per il legacy e Project A;
- accessi read-only PostgreSQL, workspace Git e Pi/LLM verificati;
- identità DWH dimostrata read-only;
- backup e restart recipe legacy verificabili;
- risorse e percorsi della nuova installazione approvati;
- report redatto, secret-scan valido e checksum verificato;
- approvazione esplicita del proprietario.
`SURVEY_GO_PROJECT_B` richiede inoltre:
- collaudo Mac `rest_api` con chiave per installazione;
- 48 ore di osservazione comprendenti due cicli ETL delle 03:00;
- credenziale `legacy-shared` revocata, v1 positiva e legacy `401`;
- owner e autorità di modifica/rollback per tutti i componenti shared;
- origine pubblica unica e load-balancer contract provati;
- accesso read-only Authentik e inventario della release installata;
- ogni altro blocker pubblico/shared delle Activity 2–9 chiuso.
Il PASS tecnico del survey non autorizza automaticamente Project A. L'autorizzazione deve essere
registrata separatamente.
@@ -379,3 +451,4 @@ registrata separatamente.
| Data | Attività | Modifica | Autore |
|---|---|---|---|
| 2026-08-20 | Initial | Creata checklist; Activity 1 aperta, Activity 2–10 pending | Sol |
| 2026-08-21 | Sequencing amendment | Activity 1 deferred pre-B; survey ripreso read-only; Project A private resta NO-GO | Owner/Sol |