chore: commit remaining worktree changes

This commit is contained in:
2026-08-26 08:10:37 +02:00
parent ec061c42d4
commit f48196a57f
234 changed files with 146 additions and 61044 deletions
@@ -1,171 +0,0 @@
# Audit critico dei comandi `tht`
Data: 2026-08-15
## Scopo
Questo audit valuta tutti i comandi terminali registrati dall'attuale CLI Python `tht` prima di
unificare la CLI di ThothII sotto un solo eseguibile pubblico. La valutazione incrocia:
- il contratto del workflow Pi in `harness/.pi/skills/tht-sessione/SKILL.md`;
- le invocazioni reali del gate in `harness/.pi/extensions/tht-gate.js`;
- le invocazioni del backend in `backend/src/tht/tht-runner.ts`;
- i job operatore in `backend/src/workspaces/preprocessing-service.ts`;
- il migratore in `docker/session-migrate.sh`;
- test e documentazione esistenti.
L'inventario autorevole contiene 76 comandi Typer più il comando callback `doctor`: 77 comandi
terminali complessivi.
## Legenda
- **WF — intoccabile workflow**: chiamato da Pi, dal gate o dal contratto delle otto fasi. Va
conservato con semantica, output JSON ed exit code compatibili. Non deve necessariamente apparire
nell'help ordinario dell'utente.
- **PL — intoccabile piattaforma**: chiamato dal backend, dai job workspace o dal deployment. Anche
questo è un contratto interno, non necessariamente un comando da mostrare all'utente.
- **ADV — mantenere avanzato**: non è nel flusso automatico, ma offre una capacità amministrativa o
di recupero che sarebbe imprudente perdere. Va nascosto dall'help base.
- **ACCORPA**: la capacità serve, ma non merita un comando autonomo.
- **RIMUOVI**: il comando non ha chiamanti reali ed è duplicato, superato, pericoloso o incompleto.
L'eventuale logica riutilizzata da altri flussi resta una libreria interna.
## Risultato sintetico
| Esito | Numero | Conseguenza |
|---|---:|---|
| WF o PL, intoccabili | 55 | Conservare il contratto; nascondere i primitivi tecnici dall'help base |
| ADV o ACCORPA | 8 | Conservare la capacità riducendo la superficie UX |
| RIMUOVI | 14 | Eliminare il comando dalla nuova CLI |
| **Totale** | **77** | Una sola CLI pubblica molto più semplice, senza riscrivere il workflow vivo |
## Matrice completa
### Diagnostica, configurazione e dipendenze
| Comando | Valutazione |
|---|---|
| `config check` | **ACCORPA** in `tht doctor`: la validazione della configurazione serve, ma due preflight distinti confondono l'utente. |
| `doctor` | **ACCORPA/MANTIENI pubblico** come unico `tht doctor`, includendo controlli host, Compose, storage e configurazione runtime. |
| `db ping` | **PL**: il backend lo usa per rifiutare correttamente una nuova sessione quando il DWH non è raggiungibile o non è read-only. Interno. |
| `db fetch-ca` | **ACCORPA** in `tht setup` o nella configurazione workspace: utile per TLS, ma non giustifica un comando isolato. |
| `ollama ensure` | **PL**: preflight automatico dell'embedder usato dal backend. Interno. |
### Fasi e decision ledger
| Comando | Valutazione |
|---|---|
| `phase advance` | **WF**: il gate lo usa per avanzare solo dopo la decisione umana. Primitivo anti-bypass, quindi interno. |
| `phase meta` | **WF**: fornisce al gate la definizione data-driven delle fasi e dei tipi di decisione. Interno. |
| `phase reopen` | **WF**: è il percorso canonico per tornare a una fase precedente e invalidare deterministicamente gli artefatti successivi. |
| `phase show` | **WF**: il gate lo usa per calcolare la fase corrente. Interno. |
| `decision add` | **WF**: persistenza fondamentale delle decisioni del reviewer. Solo gate, non shell utente. |
| `decision add-batch` | **WF**: scrittura atomica delle decisioni multiple. Evita ledger parziali. |
| `decision add-join-set` | **WF**: sostituzione atomica dell'intero insieme di join. |
| `decision list` | **RIMUOVI**: nessun chiamante; `session show --json` contiene già il ledger necessario. |
| `decision retract` | **RIMUOVI** dalla CLI: nessun flusso vivo lo invoca e `phase reopen` è il percorso di correzione supportato. La semantica tombstone può restare nel dominio finché utile. |
### Sessioni
| Comando | Valutazione |
|---|---|
| `session archive` | **PL**: usato dalla gestione sessioni del backend. |
| `session check` | **WF**: gate oggettivo della fase 5; verifica decisioni e schema linking. |
| `session close` | **PL**: usato dal backend. |
| `session delete` | **PL**: usato dal backend con i relativi controlli applicativi. |
| `session documents` | **WF/PL**: ricostruisce il contesto persistito e alimenta sia Pi sia la GUI. |
| `session fail` | **PL**: usato dal backend per rappresentare il fallimento terminale. |
| `session finalize` | **WF**: chiusura deterministica della fase finale e indicizzazione della domanda risolta. |
| `session list` | **PL**: alimenta la lista sessioni della GUI. |
| `session migrate` | **PL**: eseguito dal servizio one-shot di migrazione server; resta interno dietro `tht sessions migrate`. |
| `session new` | **WF/PL**: crea la persistenza iniziale della domanda; il backend dipende dal JSON restituito. |
| `session preferences get` | **PL**: lettura delle preferenze applicative. Interno. |
| `session preferences set` | **PL**: scrittura delle preferenze applicative. Interno. |
| `session reopen` | **PL**: riapertura dello stato terminale esposta dalla gestione sessioni. |
| `session retrieval-pack` | **WF**: legge il retrieval pack già persistito per il kickoff di Pi. Distinto da `search pack`, che lo costruisce. |
| `session set-group` | **PL**: rinomina il raggruppamento dalla GUI. |
| `session set-name` | **PL**: rinomina la sessione dalla GUI. |
| `session set-question` | **WF**: persiste deterministicamente domanda riscritta e assunzioni. Solo gate. |
| `session set-schema-linking` | **WF**: valida e scrive `schema_linking.json`. Solo gate. |
| `session show` | **WF/PL**: fonte compatta dello stato persistito per resume, gate e backend. |
| `session sync-schema-linking` | **WF**: riproietta deterministicamente il ledger nello schema linking. |
| `session unarchive` | **PL**: usato dalla gestione sessioni del backend. |
### Schema e retrieval
| Comando | Valutazione |
|---|---|
| `schema check` | **PL**: validazione delle annotazioni curate nel workflow workspace. |
| `schema columns` | **WF**: il gate usa il catalogo colonne per validare e correggere il linking. |
| `schema introspect` | **WF**: fallback previsto dal contratto quando manca lo schema fisico; la modalità refresh resta manutenzione. |
| `schema render` | **WF**: produce il contesto mschema usato dal modello. |
| `schema suggest-fks` | **PL**: comando del flusso operatore per le annotazioni FK curate. |
| `search find` | **WF**: ricerca mirata di evidence, valori e formule durante le fasi. |
| `search pack` | **WF/PL**: costruisce e persiste il contesto iniziale F1; usato anche dal backend. |
### CTE, SQL e datamart
| Comando | Valutazione |
|---|---|
| `cte info` | **WF**: restituisce SQL persistito, posizione nel piano e ultimo test. |
| `cte list` | **RIMUOVI**: nessun chiamante o test; `cte plan`, `cte info` e `session documents` coprono il bisogno. |
| `cte next` | **WF**: il gate determina il prossimo CTE da revisionare. |
| `cte plan` | **WF**: persiste l'ordine completo dei CTE. |
| `cte save` | **WF**: tool deterministico di scrittura usato dal gate. |
| `cte test` | **WF**: verifica read-only dei CTE prevista esplicitamente dal contratto. |
| `sql validate` | **WF**: validazione strutturale e read-only prima dell'esecuzione. |
| `sql preview` | **WF/PL**: preview controllata usata dal modello e dalla GUI. |
| `sql set-final` | **WF**: unica scrittura canonica di `sql_final.sql` attraverso il repository di sessione. |
| `sql export` | **PL**: esportazione richiesta dalla GUI. |
| `sql explain` | **RIMUOVI**: nessun chiamante, test o requisito nel workflow corrente. Si reintroduce solo con un vero passo di analisi del piano. |
| `sql save` | **RIMUOVI**: duplica `set-final` ed `export` e permette un percorso di scrittura non usato. |
| `datamart generate` | **WF**: fase 8 del workflow. |
### Memory
| Comando | Valutazione |
|---|---|
| `memory promote` | **WF**: preview dei candidati di promozione usata dal gate. |
| `memory save-one` | **WF**: persistenza atomica della singola memory approvata. |
| `memory search` | **WF**: recupero delle memory riutilizzabili nella fase 2. |
| `memory solved-index` | **WF**: recupero manuale previsto se l'indicizzazione al finalize fallisce. |
| `memory solved-search` | **WF**: recupero di domande risolte simili nelle fasi successive. |
| `memory list` | **ADV**: mantenere per amministrare record errati, ma fuori dall'help base. |
| `memory show` | **ADV**: mantenere insieme a `list` per ispezione puntuale. |
| `memory update` | **ADV**: mantenere per correggere il merito di una memory senza alterarne la provenienza. |
| `memory delete` | **ADV**: mantenere come rimedio selettivo; richiede conferma esplicita nella nuova CLI. |
| `memory index` | **ADV**: utile come riparazione/full-resync, ma va presentato come manutenzione e non come uso normale. |
| `memory clear` | **RIMUOVI**: distruzione globale non usata; confligge con una UX sicura di backup/ripristino. |
| `memory migrate` | **RIMUOVI**: migrazione legacy una tantum senza dati di produzione da preservare. |
### Preprocessing, evidence e indici
| Comando | Valutazione |
|---|---|
| `preprocess dwh` | **PL**: pipeline canonica usata da `tht workspace preprocess dwh/run`. |
| `preprocess evidence` | **PL**: pipeline canonica usata da `tht workspace preprocess evidence/run`. |
| `vector index-schema` | **PL**: indicizzazione schema usata dal workflow workspace. |
| `evidence extract` | **RIMUOVI**: primitivo superato dalla pipeline versionata `preprocess evidence`. Conservare soltanto la logica riusata. |
| `evidence index` | **RIMUOVI**: primitivo superato dalla stessa pipeline versionata. |
| `lsh build` | **RIMUOVI** come comando: è già uno step di `preprocess dwh`; il builder resta interno. |
| `lsh query` | **RIMUOVI**: probe visuale senza chiamanti, test o documentazione operativa. La ricerca applicativa passa da `search find`. |
| `vector init` | **RIMUOVI**: il controllo di Qdrant/embedder è ormai coperto dal reconciler di collezione, da `ollama ensure` e dal nuovo `tht doctor`. |
### Formule di concetto
| Comando | Valutazione |
|---|---|
| `formula save` | **RIMUOVI** dalla CLI corrente: nessun chiamante, test o flusso di approvazione lo usa. Conservare il formato/store e la lettura tramite `search find --kind formula`. |
| `formula list` | **RIMUOVI**: stesso sottosistema incompleto. Un futuro flusso di curation dovrà progettare insieme creazione, approvazione, elenco e modifica. |
## Conseguenza per la nuova CLI unica
La semplificazione migliore non consiste nel rinominare tutti i 55 contratti vivi o nel mostrarli
all'utente. Consiste nel mantenere un unico eseguibile `tht` con due livelli di visibilità:
1. l'help ordinario mostra soltanto setup, lifecycle, backup/restore, Pi e workspace;
2. i contratti WF/PL restano invocabili dallo stesso eseguibile, ma sono interni/nascosti e usati da
backend, gate e job one-shot.
In questo modo l'utente vede una CLI piccola, mentre il workflow non subisce una riscrittura inutile
e rischiosa. Non serve un secondo eseguibile né un alias `thothctl`.
@@ -1,148 +0,0 @@
# Proposta maintain-erase-enhance per i comandi `tht`
Data: 2026-08-15
## Criterio
- **MAINTAIN**: il comando resta disponibile senza modifiche sostanziali. Come richiesto, non viene
aggiunta una motivazione.
- **ERASE**: il comando viene eliminato dalla nuova CLI; la motivazione indica la duplicazione, il
superamento o l'assenza di un utilizzo reale.
- **ENHANCE**: la capacità viene mantenuta, ma il comando viene migliorato, accorpato o reso più
sicuro. La proposta indica l'intervento.
La proposta copre tutti i 77 comandi terminali dell'attuale CLI Python.
## Sintesi
| Proposta | Numero |
|---|---:|
| MAINTAIN | 55 |
| ENHANCE | 8 |
| ERASE | 14 |
| **Totale** | **77** |
## Lista completa
### Diagnostica, configurazione e dipendenze
| Comando | Proposta |
|---|---|
| `config check` | **ENHANCE** — incorporare la validazione nel comando pubblico `tht doctor`, mantenendo una funzione interna riutilizzabile e l'output strutturato. Evita due preflight sovrapposti. |
| `doctor` | **ENHANCE** — farne l'unica diagnostica multilivello: installazione, descriptor, Compose, storage, configurazione runtime, DWH, Pi, Qdrant ed embedder. Deve offrire output umano e `--json`, senza mutare lo stato. |
| `db ping` | **MAINTAIN** |
| `db fetch-ca` | **ENHANCE** — integrarlo nel setup guidato del workspace, mostrando endpoint e fingerprint prima della conferma. Può restare disponibile come operazione TLS avanzata, ma non come passaggio manuale obbligatorio. |
| `ollama ensure` | **MAINTAIN** |
### Fasi e decision ledger
| Comando | Proposta |
|---|---|
| `phase advance` | **MAINTAIN** |
| `phase meta` | **MAINTAIN** |
| `phase reopen` | **MAINTAIN** |
| `phase show` | **MAINTAIN** |
| `decision add` | **MAINTAIN** |
| `decision add-batch` | **MAINTAIN** |
| `decision add-join-set` | **MAINTAIN** |
| `decision list` | **ERASE** — non ha chiamanti reali e duplica il ledger già restituito da `session show --json`. |
| `decision retract` | **ERASE** — non è invocato dal workflow corrente; `phase reopen` è il percorso supportato per correggere e invalidare deterministicamente le decisioni. La semantica tombstone può restare nel dominio. |
### Sessioni
| Comando | Proposta |
|---|---|
| `session archive` | **MAINTAIN** |
| `session check` | **MAINTAIN** |
| `session close` | **MAINTAIN** |
| `session delete` | **MAINTAIN** |
| `session documents` | **MAINTAIN** |
| `session fail` | **MAINTAIN** |
| `session finalize` | **MAINTAIN** |
| `session list` | **MAINTAIN** |
| `session migrate` | **MAINTAIN** |
| `session new` | **MAINTAIN** |
| `session preferences get` | **MAINTAIN** |
| `session preferences set` | **MAINTAIN** |
| `session reopen` | **MAINTAIN** |
| `session retrieval-pack` | **MAINTAIN** |
| `session set-group` | **MAINTAIN** |
| `session set-name` | **MAINTAIN** |
| `session set-question` | **MAINTAIN** |
| `session set-schema-linking` | **MAINTAIN** |
| `session show` | **MAINTAIN** |
| `session sync-schema-linking` | **MAINTAIN** |
| `session unarchive` | **MAINTAIN** |
### Schema e retrieval
| Comando | Proposta |
|---|---|
| `schema check` | **MAINTAIN** |
| `schema columns` | **MAINTAIN** |
| `schema introspect` | **MAINTAIN** |
| `schema render` | **MAINTAIN** |
| `schema suggest-fks` | **MAINTAIN** |
| `search find` | **MAINTAIN** |
| `search pack` | **MAINTAIN** |
### CTE, SQL e datamart
| Comando | Proposta |
|---|---|
| `cte info` | **MAINTAIN** |
| `cte list` | **ERASE** — non ha chiamanti o test e sovrappone informazioni già disponibili con `cte plan`, `cte info` e `session documents`. |
| `cte next` | **MAINTAIN** |
| `cte plan` | **MAINTAIN** |
| `cte save` | **MAINTAIN** |
| `cte test` | **MAINTAIN** |
| `sql validate` | **MAINTAIN** |
| `sql preview` | **MAINTAIN** |
| `sql set-final` | **MAINTAIN** |
| `sql export` | **MAINTAIN** |
| `sql explain` | **ERASE** — non è usato né testato dal workflow attuale. Va reintrodotto soltanto se l'analisi del piano diventa un passo esplicito del processo. |
| `sql save` | **ERASE** — duplica `sql set-final` e `sql export` e introduce un percorso di scrittura non utilizzato. |
| `datamart generate` | **MAINTAIN** |
### Memory
| Comando | Proposta |
|---|---|
| `memory promote` | **MAINTAIN** |
| `memory save-one` | **MAINTAIN** |
| `memory search` | **MAINTAIN** |
| `memory solved-index` | **MAINTAIN** |
| `memory solved-search` | **MAINTAIN** |
| `memory list` | **ENHANCE** — trasformarlo in una vista amministrativa paginata, con filtri, provenienza, stato e output `--json`; non mostrarlo nell'help base. |
| `memory show` | **ENHANCE** — mostrare provenienza immutabile, decisione sorgente, stato dell'indice e riferimenti necessari a una correzione consapevole. |
| `memory update` | **ENHANCE** — limitare l'aggiornamento ai campi modificabili, mostrare un diff prima della conferma e impedire modifiche alla provenienza. |
| `memory delete` | **ENHANCE** — richiedere identificatore esatto e conferma esplicita, mostrare l'impatto e verificare la rimozione coerente da registro e indice. |
| `memory index` | **ENHANCE** — riposizionarlo come comando di repair: prima rileva il drift, poi ricostruisce soltanto con conferma e verifica finale. Non deve sembrare un'operazione ordinaria. |
| `memory clear` | **ERASE** — cancellazione globale non usata e troppo facile da eseguire per errore; backup/ripristino e cancellazione selettiva sono percorsi più sicuri. |
| `memory migrate` | **ERASE** — migrazione legacy una tantum; non esistono dati di produzione da preservare e la nuova architettura può partire direttamente dal formato corrente. |
### Preprocessing, evidence e indici
| Comando | Proposta |
|---|---|
| `preprocess dwh` | **MAINTAIN** |
| `preprocess evidence` | **MAINTAIN** |
| `vector index-schema` | **MAINTAIN** |
| `evidence extract` | **ERASE** — è un primitivo superato dalla pipeline versionata `preprocess evidence`; l'eventuale logica condivisa resta interna. |
| `evidence index` | **ERASE** — è un secondo primitivo superato dalla stessa pipeline, che già gestisce materializzazione, indicizzazione, versionamento e resume. |
| `lsh build` | **ERASE** — la costruzione LSH è già uno step di `preprocess dwh`; mantenere due ingressi permette esecuzioni parziali incoerenti. |
| `lsh query` | **ERASE** — probe visuale senza chiamanti, test o documentazione operativa; il workflow usa `search find`. |
| `vector init` | **ERASE** — il controllo di Qdrant ed embedder è già coperto dal reconciler della collezione, da `ollama ensure` e dal nuovo `tht doctor`. |
### Formule di concetto
| Comando | Proposta |
|---|---|
| `formula save` | **ERASE** — non ha chiamanti, test o un flusso di approvazione completo. Il formato e lo store possono restare disponibili alla ricerca finché non viene progettata una vera curation. |
| `formula list` | **ERASE** — appartiene allo stesso sottosistema incompleto; un futuro flusso deve progettare insieme creazione, approvazione, elenco, modifica e cancellazione. |
## Impatto sulla UX
I 55 comandi `MAINTAIN` comprendono molti contratti macchina intoccabili. Mantenerli non implica
mostrarli tutti nell'help principale. La futura CLI unica può conservare gli stessi percorsi per
backend, gate e job, mostrando all'utente soltanto i gruppi operativi di primo livello.
-126
View File
@@ -1,126 +0,0 @@
# L2 Run Report — 2026-06-27 (sessione cardioversione + ablazione)
> Esito della prima sessione L2 end-to-end dopo il porting CLI+skill (Onda -1→4 +
> Skill + 0b). Sessione non-deterministica, esito informativo non bloccante per il
> "done" del porting codice (come da piano L2.1, riga 1187).
## Setup al momento del run
- Pi: `@earendil-works/pi-coding-agent`, provider `zai`, model `glm-5.2` (default).
- Harness: Onda -1→4 + Skill committate; Onda 0b (workspace cliente `tht-workspace-psd`,
indice LSH 75737 valori, evidence 35).
- `.env` popolato, VPN OK, DWH REST 200, Ollama UP.
- Pre-run fix applicati in questa sessione: `_YamlModel.to_yaml` (bloccava `session new`),
`config/tht.yaml` symlink al workspace cliente (il gate chiama `tht` senza `-c`).
## Come è partita la sessione
Lancio `pi --mode rpc` + `/nuova-domanda "<cardioversione + ablazione same-year>"`.
**Nota critica su `--mode rpc`:** la TUI interattiva di Pi (`pi` senza `--mode`) **non
renderizza** i widget `extension_ui_request` del gate (gestiti solo in `modes/rpc/`).
La modalità RPC emette i widget come JSONL su stdio per un client esterno — che non
esiste ancora in ThothII. Il run è stato possibile solo perché il modello, non vedendo
UI, ha operato via shell/tool fino al blocco fatale (vedi bug #4).
## Cosa ha fatto il modello (transcript: 117 eventi, 365KB)
Sessione Pi: `~/.pi/agent/sessions/--Users-mp-projects-ThothII-harness--/2026-06-27T13-44-51...jsonl`.
Sessione tht: `tht-workspace-psd/sessions/2026-06-27-134553-crea-una-lista...` (status: open, F1).
Il modello ha lavorato molto e correttamente nel dominio:
- Ha creato la sessione, caricato la skill, iniziato F1.
- Ha eseguito ricerche semantiche (evidence + LSH), individuato le tabelle centrali
(`fact_cardioversione_elettrica`, `fact_see_ablazione`, `dim_patient`).
- Ha letto evidence molto pertinenti (esempio NLQ, glossario coorti/universi), costruendo
un quadro dominio corretto e verificato sulle tabelle reali.
Il workflow **non è avanzato oltre F1**: nessuna decisione registrata
(`review_decisions.jsonl` assente). Il modello si è arenato su bug di porting (sotto).
## Bug di porting emersi (4, di cui 1 fatale)
### #1 — `tht` non nel PATH del processo Pi [basso]
Il gate chiama `execFileSync("tht", args, {cwd: ctx.cwd})`. L'eseguibile nel venv non è nel
PATH di Pi. Il modello ha creato un wrapper in `~/.local/bin` (workaround).
**Fix root-cause:** installare `tht` in una dir nel PATH (pip install -e . con entry point
globale, o symlink `/usr/local/bin/tht -> harness/.venv/bin/tht`).
### #2 — `phase show` non passava il config [medio, FIXATO]
`phase_cmd._cfg()` non passava il config a `_load_config_or_exit()`, quindi falliva con
"File non trovato config/tht.yaml" quando non c'era `THT_WORKSPACE` env.
**Fix applicato (dal modello in sessione, validato e pulito):** `_cfg()` ora risolve
`THT_WORKSPACE`/`THT_CONFIG` env, poi fallback a `config/tht.yaml` (stessa convenzione di
`CONFIG_OPT`). Testato: `phase show` funziona. Suite 165 passed.
### #3 — `session check` signature inconsistente [basso, da verificare]
Il modello ha notato che `session check` prende la sessione come argomento posizionale,
non `--session` come gli altri cmd. Da verificare e allineare.
### #4 — `ctx.sendRaw is not a function` [FATALE, blocca tutti i widget]
Il gate `tht-gate.js:164` emette i widget con `ctx.sendRaw({type:"extension_ui_request"...})`.
Il runtime Pi installato **non espone `ctx.sendRaw`** sul context delle extensions. Il
modello l'ha verificato leggendo le type definitions (`ExtensionContext` espone `ui`,
`mode`, `hasUI`, `cwd`, `abort` — ma non `sendRaw`). **Nessun widget può essere emesso in
nessuna modalità.** Questo ha fermato il workflow a F1.
## Analisi del bug #4 (mismatch architetturale, non un typo)
Il commento nel gate stesso (righe 2-6) dice: *"REWRITE of the reference implementation...
replaces ctx.ui.* blocking primitives"*. Il porting ha **sostituito** i dialog nativi di Pi
con `ctx.sendRaw`, presumendo un'API widget-descriptor diretta che **questa versione di Pi
non espone alle extensions**. Verifiche sul runtime installato:
- `ctx.sendRaw`: **non esiste** (0 refs in `core/extensions/`).
- `extension_ui_request`: emesso **solo dal runtime** (`modes/rpc/rpc-mode.js`), come
traduzione dei dialog nativi (`ctx.ui.select` → `{method:"select"}`), non come API per
le extensions.
- Canali disponibili in RPC mode per ricevere una decisione umana (enum chiuso):
`ctx.ui.select` / `confirm` / `input` / `editor` (+ `notify` one-way). I `method` di
`extension_ui_request` sono: select/confirm/input/editor/notify/setWidget/setStatus/
set_editor_text. **Nessun method custom** per widget-descriptor.
- `ctx.ui.custom` (usato da ChironeWp3 per il multiselect TUI): in RPC mode è un **no-op**
(`return undefined`, commento: "Custom UI not supported in RPC mode").
### Conseguenza per i 6 widget della spec §4
- `select` (scelta singola) → ✅ `ctx.ui.select`
- `confirm` (approvazione) → ✅ `ctx.ui.confirm`
- `input` (testo libero / Altro) → ✅ `ctx.ui.input`
- `multiselect` (scelta multipla — **critico per F4 schema-linking**) → ❌ nessun canale
in RPC. Solo `ctx.ui.custom` lo faceva (TUI only).
Il multiselect è il vero ostacolo. F4 richiede di promuovere/escludere **più** tabelle/
colonne in una volta.
## Opzioni per il design del gate (decisione architetturale APERTA)
Il design del gate influenza tutta la relazione harness↔backend↔FE. Non è un fix da
inserire in coda a una sessione di porting; merita brainstorming dedicato. Opzioni:
- **A — Torna a `ctx.ui.*` nativi.** Il gate riscrive `emitAndWait` su `ctx.ui.select`/
`confirm`/`input` (come ChironeWp3 originale). Multiselect F4 emulato (serie di select, o
un input). Funziona con il Pi installato ora. Perde i widget-descriptor ricchi spec §4;
il FE riceve method nativi, la mappatura kind→method va nel backend/FE.
- **B — Versione di Pi con API widget custom.** Verificare se un Pi più recente/preview
espone `ctx.sendRaw` o un method custom. Se sì, il gate attuale funziona. Rischio:
inseguire un'API magari non pubblica; aggiornare Pi può rompere provider/auth.
- **C — Wrapper ibrido (valutato, NON realizzabile).** Registrare un handler che intercetti
gli `extension_ui_request` nativi e li arricchisca nel formato widget-descriptor spec §4
prima di mandarli al client RPC. **Scartato:** non c'è canale per widget-descriptor custom
in RPC (method è enum chiuso, `ctx.ui.custom` è no-op in RPC).
## Artefatti prodotti
- `tht-workspace-psd/sessions/2026-06-27-134553-.../` (manifest + question.md, F1, open).
- Sessione Pi transcript (vedi sopra) — fonte primaria per il debug.
- Fix codice: `_cfg()` in `phase_cmd.py` (bug #2), applicato pulito.
## Conclusione
**La sessione L2 ha colto bug di porting reali — ha fatto il suo lavoro.** Il loop
skill→LLM→gate funziona nel dominio (ricerche, evidence, quadro corretto) ma si blocca a
F1 sul bug fatale #4. Tre dei quattro bug sono risolvibili a basso costo (#1, #2 fixato,
#3); il #4 è una decisione di design del gate che richiede brainstorming prima del codice.
**Stato del porting codice (Onda -1→4 + Skill + 0b):** completo e verificato a livello L0/L1
(165 passed) + L2 value-grounding (PASS). I bug L2 emersi sono incrementi di qualità, non
regressioni del porting — L2 coglie ciò che L0/L1 per design non possono.