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.
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)
- Un fatto, un comando
tht. Ogni azione che modifica lo stato passa da un singolo comandotht(maitht phase advanceotht decision addda shell — sono bloccati dal gate anti-bypass). Esegui un comando alla volta e leggi l'output prima del prossimo. - Una domanda alla volta. Un widget = una domanda. Non accumulare.
- "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. - Nessuno step in limbo. Ogni widget ha un esito (scelta / Altro / Torna indietro / Esci). Se il reviewer chiude senza scegliere, il gate ripropone.
- Artefatto = output di prima classe.
schema_linking.json,cte_plan.json,ctes/*.sql,sql_final.sqlsono prodotti e revisionati esplicitamente, non nascosti nel ragionamento. - 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
rationaledella decisione, verbatim. - Rollback (D15). Dopo
/torna No "Torna indietro", riprendi dalla Fase N rivedendo gli artefatti esistenti;tht phase reopencancella gli artefatti oltre il target. NON ri-eseguire comandithtper artefatti ancora validi.
Fase 1 — Chiarimento
Prerequisito: devi essere già in Fase 1.
- Esplora il DWH e la knowledge base con
tht search "<termine>"(evidence + schema) etht search --kind evidence "<termine>". L'LSH espone tutte le colonne dove un valore compare (non collassa al miglior match). - Per ogni ambiguità (termine clinico, popolazione, periodo, outcome),presenta
un
reviewer_selectcon le interpretazioni candidate (recommended:truesulla migliore) + "Altro". Registraconcept_clarifiedper ogni chiarimento. - Quando la domanda è univoca, chiudi con
reviewer_confirm kind:"phase". - Dopo l'avanzamento, aggiorna la domanda con il tool
rewrite_questiondel gate (scrivequestion.mddeterministicamente).
Fase 2 — Memorie
Prerequisito: Fase 1 completata.
- 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). - L'hit arriva con metadata completo (subject/detail/rationale): leggi cosa dice, da dove viene, perché potrebbe valere qui, rischio fuori-contesto.
- 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 portamem_id+type/subject/rationale. Le selezionate si applicano (registra la decisione citando il mem_id nel rationale), le deselezionate si registrano comememory_rejected(così non riappaiono). Lista pre-selezionata con le raccomandate. - Se nessuna memoria supera score 0.5, chiudi rapidamente con
reviewer_confirm kind:"phase". - Promozione (D11). Per promuovere UNA memoria in
profile=workstation, usatht 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).
- 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). - Presenta in un solo
reviewer_decide(advance:true, allow_other:true). Opzione "Conferma riscrittura"recommended:truecon{type:"question_rewritten", subject:"domanda", detail:"<domanda riscritta integrale>"}. - Ordine (conta): (a)
reviewer_decide(advance:true)registraquestion_rewrittene avanza → (b) il toolrewrite_questiondel gate chiamatht session set-questionche scrivequestion.md(rigenera domanda + sezione "## Assunzioni"). Niente edit/write manuale diquestion.md. - "Altro" itera (riproponi un nuovo
reviewer_decide). "Torna indietro" riapre F1.
Fase 4 — Schema linking
Prerequisito: Fase 3 completata.
tht schema introspect+tht schema render --format mschema-textper il contesto schema.- Proponi tabelle/colonne/join in
reviewer_decide(advance:true). Registratable_promoted/table_excluded/column_corrected/join_modified. - Value grounding (D14a). Se un valore citato (es. "ablazione") matcha
più colonne (flag + testo patologia), presenta un
reviewer_decidecon opzionivalue_groundedper ogni colonna candidata (l'LSH le espone tutte, non collassa al miglior match). Il reviewer sceglie l'ancora. - 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). - Scrivi
schema_linking.json(l'artefatto di Fase 4) e chiudi conreviewer_confirm kind:"phase". Non eseguiretht session check(è Fase 5).
Fase 5 — Sintesi
Prerequisito: Fase 4 completata; schema_linking.json presente.
tht session check(gate oggettivo: decisioni + schema_linking valido).- Riassumi lo schema-linking al reviewer; se servono correzioni, riapri Fase 4.
- Promozione memorie (F5). Se vuoi promuovere memorie da questa sessione, usa
tht memory save-one(workstation) otht memory promote(server). Le memory vivono SOLO nel vectordb (niente registry locale). - Chiudi con
reviewer_confirm kind:"phase".
Fase 6 — Piano CTE
Prerequisito: Fase 5 completata.
- Leggi
cte.md. Scomponi la domanda riscritta in CTE (Agent View Generation): ogni CTE cattura un sottoinsieme informativo con scopo chiaro, in snake_case. - Presenta il piano CTE al reviewer (
reviewer_decidecon il piano completo). - Per ogni CTE (nell'ordine del piano): scrivi
sessions/<id>/ctes/<nome>.sql(SOLOWITH ... AS (...), niente SELECT finale), testa contht cte test --session <id> <nome>, presenta il risultato inreviewer_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 contht search. - Dopo l'ultimo CTE approvato, chiudi con
reviewer_confirm kind:"phase".
Fase 7 — SQL finale
Prerequisito: Fase 6 completata.
- Leggi
sql-generation.md. Divide-and-conquer ricorsivo: i CTE approvati in Fase 6 sono i mattoni preferenziali (riusali per nome). - Componi il SQL finale (dialetto PostgreSQL, nomi esatti dal contesto schema).
Dimensione tempo:
data_time_keyè la FK versodim_time.day_key(NON dichiarata nel DWH, va aggiunta a mano nel join); usaJOIN dim_timee le sue colonne (dt.year,dt.month, ...), MAI aritmetica sulla chiave. tht sql validate+tht sql preview(max 10 righe). Su errori/risultati sospetti, applica la checklist disql-generation.mde correggi col reviewer.tht sql savescrivesessions/<id>/sql_final.sql(SOLO SQL pulito, niente commenti). Chiudi conreviewer_confirm kind:"sql".
Fase 8 — Datamart
Prerequisito: Fase 7 completata.
- Chiedi al reviewer se vuole un datamart (
reviewer_selectsì/no). - Se sì:
tht datamart generate(stub — alza NotImplementedError per ora). Comunica al reviewer che la generazione dbt non è ancora implementata. - 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.