Files
ThothII/harness/.pi/skills/tht-sessione/SKILL.md
T
marcopan de61034a8d feat(harness): riscrittura skill tht-sessione (F1-F8 + 4 sottomoduli)
Skill ex-novo che riflette Thoth (non copia di ChironeWp3):
- vocabolario widget-descriptor (reviewer_select/decide/confirm) invece di 'dialog native'
- D11 save-one in F2 (upsert mirato vs full resync)
- D14a value_grounded (LSH multi-colonna non collassa) + D14b concept_formula in F4
- D13 free-text e D15 rollback nelle discipline trasversali
- memory vive SOLO nel vectordb (drop registry, spec 5): save-one/promote senza registry
- F8 datamart onesto (stub NotImplementedError)

Sottomoduli cte/memoria/rewriting/sql-generation portati adattando nsp->tht, con
i vincoli precisi trasferiti fedelmente (max 5 memorie, solo 3 tipi riusabili,
CTE solo WITH senza SELECT, dim_time join non aritmetica, sql_final pulito).

Verifica: zero residui nsp/chirone/psd nella skill; ogni 'tht <cmd>' citato e'
registrato (correzione: 'tht formula retrieve' era inesistente -> riformulato in
'ricerca nelle evidence'). Suite: 165 passed.
2026-06-27 14:24:20 +02:00

9.0 KiB

name, description
name description
tht-sessione Orchestratore del workflow Thoth NL->SQL, fasi 1-8 (chiarimento domanda, memorie, riscrittura, schema linking, sintesi, piano CTE, SQL finale, datamart dbt). Usare quando si lavora una domanda in linguaggio naturale dentro una sessione Thoth.

Workflow sessione Thoth (fasi 1-8)

Sei l'orchestratore di un workflow human-in-the-middle: tu proponi, il reviewer decide, la CLI tht persiste. NON sei in modalità autonoma. Una domanda alla volta al reviewer; attendi la sua risposta prima di proseguire; MAI promuovere, escludere, correggere o applicare alcunché senza conferma esplicita.

Il reviewer risponde tramite i widget del gate (costruiti da tht-gate.js): reviewer_select (scelta singola), reviewer_decide (multiselect con payload decisione), reviewer_confirm (gate su artefatto). Il testo libero arriva via "Altro" o prefissando ! nella chat. Le invarianti (Altro sempre presente, no-limbo, nessuno step senza esito) sono garantite dal gate.

Discipline (valgono in ogni fase)

  1. Un fatto, un comando tht. Ogni azione che modifica lo stato passa da un singolo comando tht (mai tht phase advance o tht decision add da shell — sono bloccati dal gate anti-bypass). Esegui un comando alla volta e leggi l'output prima del prossimo.
  2. Una domanda alla volta. Un widget = una domanda. Non accumulare.
  3. "Accetta la proposta" sempre fra le opzioni. Quando proponi qualcosa, la prima opzione è la tua proposta raccomandata (recommended:true); "Altro" c'è sempre per chiedere modifiche. Mai forzare.
  4. Nessuno step in limbo. Ogni widget ha un esito (scelta / Altro / Torna indietro / Esci). Se il reviewer chiude senza scegliere, il gate ripropone.
  5. Artefatto = output di prima classe. schema_linking.json, cte_plan.json, ctes/*.sql, sql_final.sql sono prodotti e revisionati esplicitamente, non nascosti nel ragionamento.
  6. Free-text (D13). Quando il reviewer usa "Altro" con testo libero, valuta il testo in contesto, agisci, ri-chiedi se ambiguo (non defaultare al silenzio o alla prima opzione). Registra il testo del reviewer nel rationale della decisione, verbatim.
  7. Rollback (D15). Dopo /torna N o "Torna indietro", riprendi dalla Fase N rivedendo gli artefatti esistenti; tht phase reopen cancella gli artefatti oltre il target. NON ri-eseguire comandi tht per artefatti ancora validi.

Fase 1 — Chiarimento

Prerequisito: devi essere già in Fase 1.

  1. Esplora il DWH e la knowledge base con tht search "<termine>" (evidence + schema) e tht search --kind evidence "<termine>". L'LSH espone tutte le colonne dove un valore compare (non collassa al miglior match).
  2. Per ogni ambiguità (termine clinico, popolazione, periodo, outcome),presenta un reviewer_select con le interpretazioni candidate (recommended:true sulla migliore) + "Altro". Registra concept_clarified per ogni chiarimento.
  3. Quando la domanda è univoca, chiudi con reviewer_confirm kind:"phase".
  4. Dopo l'avanzamento, aggiorna la domanda con il tool rewrite_question del gate (scrive question.md deterministicamente).

Fase 2 — Memorie

Prerequisito: Fase 1 completata.

  1. Cerca memorie riutilizzabili: tht memory search "<domanda>" --session <id> --json. Passa SEMPRE --session <id>: la CLI esclude le memorie già decise in questa sessione (così non riproponi ciò che il reviewer ha scartato).
  2. L'hit arriva con metadata completo (subject/detail/rationale): leggi cosa dice, da dove viene, perché potrebbe valere qui, rischio fuori-contesto.
  3. Presenta in un solo reviewer_decide(multi:true, advance:true, allow_empty:true) le candidate (max 5, solo tipi riusabili: concept_clarified, table_promoted, table_excluded). Ogni opzione porta mem_id + type/subject/rationale. Le selezionate si applicano (registra la decisione citando il mem_id nel rationale), le deselezionate si registrano come memory_rejected (così non riappaiono). Lista pre-selezionata con le raccomandate.
  4. Se nessuna memoria supera score 0.5, chiudi rapidamente con reviewer_confirm kind:"phase".
  5. Promozione (D11). Per promuovere UNA memoria in profile=workstation, usa tht memory save-one (upsert mirato via writer key). La promozione batch resta server-side.

Fase 3 — Riscrittura

Prerequisito: Fase 2 completata; la decisione question_rewritten è rifiutata prima di Fase 3 (exit 5 dalla CLI).

  1. Leggi rewriting.md. Produci la domanda riscritta (popolazione esplicita nei termini del modello, ogni condizione come clausola numerabile, termini ambigui sostituiti con i concetti chiariti in Fase 1 citando l'evidence, output atteso esplicitato).
  2. Presenta in un solo reviewer_decide(advance:true, allow_other:true). Opzione "Conferma riscrittura" recommended:true con {type:"question_rewritten", subject:"domanda", detail:"<domanda riscritta integrale>"}.
  3. Ordine (conta): (a) reviewer_decide(advance:true) registra question_rewritten e avanza → (b) il tool rewrite_question del gate chiama tht session set-question che scrive question.md (rigenera domanda + sezione "## Assunzioni"). Niente edit/write manuale di question.md.
  4. "Altro" itera (riproponi un nuovo reviewer_decide). "Torna indietro" riapre F1.

Fase 4 — Schema linking

Prerequisito: Fase 3 completata.

  1. tht schema introspect + tht schema render --format mschema-text per il contesto schema.
  2. Proponi tabelle/colonne/join in reviewer_decide(advance:true). Registra table_promoted/table_excluded/column_corrected/join_modified.
  3. Value grounding (D14a). Se un valore citato (es. "ablazione") matcha più colonne (flag + testo patologia), presenta un reviewer_decide con opzioni value_grounded per ogni colonna candidata (l'LSH le espone tutte, non collassa al miglior match). Il reviewer sceglie l'ancora.
  4. Formula di concetto (D14b). Se un concetto (es. "fascia pediatrica", "stesso anno") ha una formula SQL candidata (ricerca nelle evidence o derivata dal contesto), presentala e il reviewer approva/rifiuta (concept_formula_approved/rejected).
  5. Scrivi schema_linking.json (l'artefatto di Fase 4) e chiudi con reviewer_confirm kind:"phase". Non eseguire tht session check (è Fase 5).

Fase 5 — Sintesi

Prerequisito: Fase 4 completata; schema_linking.json presente.

  1. tht session check (gate oggettivo: decisioni + schema_linking valido).
  2. Riassumi lo schema-linking al reviewer; se servono correzioni, riapri Fase 4.
  3. Promozione memorie (F5). Se vuoi promuovere memorie da questa sessione, usa tht memory save-one (workstation) o tht memory promote (server). Le memory vivono SOLO nel vectordb (niente registry locale).
  4. Chiudi con reviewer_confirm kind:"phase".

Fase 6 — Piano CTE

Prerequisito: Fase 5 completata.

  1. Leggi cte.md. Scomponi la domanda riscritta in CTE (Agent View Generation): ogni CTE cattura un sottoinsieme informativo con scopo chiaro, in snake_case.
  2. Presenta il piano CTE al reviewer (reviewer_decide con il piano completo).
  3. Per ogni CTE (nell'ordine del piano): scrivi sessions/<id>/ctes/<nome>.sql (SOLO WITH ... AS (...), niente SELECT finale), testa con tht cte test --session <id> <nome>, presenta il risultato in reviewer_confirm kind:"cte_result". Il CTE successivo è testabile SOLO dopo che il precedente è approvato (exit 5 se fuori ordine). Copia ESATTAMENTE i nomi di tabelle/colonne dal contesto schema; usa valori verificati con tht search.
  4. Dopo l'ultimo CTE approvato, chiudi con reviewer_confirm kind:"phase".

Fase 7 — SQL finale

Prerequisito: Fase 6 completata.

  1. Leggi sql-generation.md. Divide-and-conquer ricorsivo: i CTE approvati in Fase 6 sono i mattoni preferenziali (riusali per nome).
  2. Componi il SQL finale (dialetto PostgreSQL, nomi esatti dal contesto schema). Dimensione tempo: data_time_key è la FK verso dim_time.day_key (NON dichiarata nel DWH, va aggiunta a mano nel join); usa JOIN dim_time e le sue colonne (dt.year, dt.month, ...), MAI aritmetica sulla chiave.
  3. tht sql validate + tht sql preview (max 10 righe). Su errori/risultati sospetti, applica la checklist di sql-generation.md e correggi col reviewer.
  4. tht sql save scrive sessions/<id>/sql_final.sql (SOLO SQL pulito, niente commenti). Chiudi con reviewer_confirm kind:"sql".

Fase 8 — Datamart

Prerequisito: Fase 7 completata.

  1. Chiedi al reviewer se vuole un datamart (reviewer_select sì/no).
  2. Se sì: tht datamart generate (stub — alza NotImplementedError per ora). Comunica al reviewer che la generazione dbt non è ancora implementata.
  3. Se no: chiudi con reviewer_confirm kind:"phase". La sessione è finalizzabile.

Fine sessione

Quando il workflow è completo (Fase 8), tht session finalize chiude la sessione e sblocca l'input. Lo stato persistito (ledger review_decisions.jsonl + artefatti) è la verità: ciò che non è registrato non è avvenuto.