chore: preserve root worktree documents
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
# PRD — Modularizzazione a moduli incapsulati: disambiguazione, evidence, memory
|
||||
|
||||
**Status:** riflessione architetturale di plausibilità — nessuna decisione implementativa presa qui; il
|
||||
documento fissa confini, contratti condivisi e precondizioni da cui potranno nascere ticket e piani separati
|
||||
**Data:** 2026-08-21
|
||||
**Autore:** analisi del codice su main (`5f05754`), su richiesta del proprietario; incrocia e non sostituisce
|
||||
i documenti evidence-canonica già esistenti (sez. 9)
|
||||
**Uso:** riferimento per il programma di sviluppo parallelo dei tre sottosistemi (disambiguazione, gestione
|
||||
evidence, gestione memory); definisce cosa deve essere vero *prima* che i tre flussi possano girare in
|
||||
parallelo senza impatti incrociati
|
||||
|
||||
---
|
||||
|
||||
## 1. L'obiettivo del proprietario
|
||||
|
||||
Avviare uno sviluppo che cambi **in parallelo** tre aree del sistema:
|
||||
|
||||
1. **disambiguazione** (estratta e separata dal workflow);
|
||||
2. **gestione delle evidence** — nuovo componente che espone un'API verso il resto del workflow ma resta
|
||||
ben incapsulato al suo interno;
|
||||
3. **gestione della memory** — con lo stesso grado di forte incapsulamento.
|
||||
|
||||
Vincolo accettato: le modifiche fatte su un modulo **non devono impattare gli altri moduli** se non per
|
||||
eventuali ridefinizioni dei contratti (API) esposti.
|
||||
|
||||
## 2. Verdetto sintetico
|
||||
|
||||
**Plausibile, e il codebase è insolitamente ben predisposto per farlo.** Ma con tre precisazioni oneste:
|
||||
|
||||
1. i tre componenti sono oggi a **tre livelli di maturità diversi**: evidence è quasi un modulo, memory è
|
||||
già incapsulata meglio di quanto sembri, la disambiguazione **non è un componente di codice** e
|
||||
"estrarla" è un lavoro di natura diversa (sez. 4);
|
||||
2. esistono **due "quinti moduli" nascosti** — il ledger dei tipi di decisione con `workflow.yaml`, e il
|
||||
gate `tht-gate.js` con il vector store — che il piano a tre vie deve contemplare, altrimenti il
|
||||
parallelismo si rompe dove non si sta guardando (ledger e gate sono spiegati in sez. 3; le implicazioni
|
||||
in sez. 5);
|
||||
3. gli accoppiamenti reali **non sono negli import Python**: sono nei decision type del ledger, nelle
|
||||
proiezioni `search pack`/`search find`, nel modello di contenuto della memory e negli id evidence
|
||||
citabili. Sono quelli i contratti da definire e versionare **prima** del parallelismo (sez. 6–7).
|
||||
|
||||
## 3. Ledger e gate: i due elementi cardine del workflow
|
||||
|
||||
Il resto del documento usa di continuo due concetti che conviene fissare qui, perché sono
|
||||
i punti dove i tre moduli si incontrano davvero: il **ledger** (dove lo stato viene
|
||||
registrato) e il **gate** (chi decide e chi scrive).
|
||||
|
||||
### 3.1 Il ledger — il registro delle decisioni (`review_decisions.jsonl`)
|
||||
|
||||
Una sessione è una directory: manifest + artefatti per fase (`question.md`,
|
||||
`schema_linking.json`, `sql_final.sql`, …) + un file `review_decisions.jsonl`. Il ledger
|
||||
è **append-only**: una riga JSON per ogni decisione del reviewer, con numero progressivo
|
||||
`seq`, timestamp, `type`, `subject`, `detail`, `rationale` (più i campi di rollback
|
||||
`retracts`/`phase`). I `DecisionType` definiti in `tht/decisions.py` sono esattamente 30.
|
||||
|
||||
Esempio concreto: a F1 il reviewer sceglie "per 'ablazione' intendo la colonna
|
||||
`flag_ablazione` della fact delle procedure" → nel ledger viene accodata una riga come
|
||||
`{"seq": 3, "ts": "…", "type": "concept_clarified", "subject": "ablazione", "detail": "…",
|
||||
"rationale": "…"}`.
|
||||
|
||||
Due proprietà lo rendono cardine:
|
||||
|
||||
1. **la fase corrente non è memorizzata: è calcolata** rileggendo (fold) il ledger
|
||||
(`tht/phase.py`). Il ledger è la fonte di verità — "ciò che non è registrato non è
|
||||
accaduto". Il rollback non cancella nulla: aggiunge `decision_retracted`/
|
||||
`phase_reopened` e la vista *effettiva* (`effective_decisions`) esclude le righe
|
||||
ritirate e quelle rimaste stale oltre il punto di rollback;
|
||||
2. **è il canale di comunicazione tra i moduli**: la disambiguazione *scrive*
|
||||
`concept_clarified`/`ambiguity_open`/`value_grounded`; l'evidence *scrive*
|
||||
`evidence_accepted`/`evidence_rejected`/`concept_formula_approved|rejected`; la memory
|
||||
*legge* `concept_clarified` (per costruire le promozioni) e *scrive* `memory_promoted`/
|
||||
`memory_promotion_declined`. Per questo l'insieme dei decision type **è** un contratto:
|
||||
ridefinirlo (sez. 6.1) è l'equivalente di cambiare una API tra moduli.
|
||||
|
||||
### 3.2 Il gate — l'estensione che impone il human-in-the-loop (`tht-gate.js`)
|
||||
|
||||
ThothII non esegue il workflow con codice: lo esegue **un agente LLM (Pi)** che segue
|
||||
SKILL.md. Il modello propone, ma non decide e non persiste direttamente. Il gate è
|
||||
l'estensione JavaScript di Pi (~2000 righe, `harness/.pi/extensions/tht-gate.js`) che
|
||||
svolge tre lavori:
|
||||
|
||||
1. **traduce le proposte del modello in widget per l'umano**: il modello chiama un tool
|
||||
del gate — `reviewer_select` (scelta singola), `reviewer_decide` (multiselect),
|
||||
`reviewer_confirm` (gate su artefatto/fase) più i specializzati `rewrite_question`,
|
||||
`reviewer_schema_linking`, `reviewer_datamart`, `reviewer_memory_promote`,
|
||||
`write_schema_linking`, `write_cte_sql`, `write_final_sql`; il gate costruisce il
|
||||
descriptor del widget → RPC → backend → SSE → browser, dove il frontend lo renderizza
|
||||
dal registry `src/widgets/`;
|
||||
2. **persiste attraverso un unico canale**: alla risposta del reviewer, è il gate (non il
|
||||
modello) a invocare la CLI `tht` (es. `tht memory promote --preview --json`,
|
||||
`tht session sync-schema-linking`) e ad accodare la riga nel ledger;
|
||||
3. **fa rispettare le regole (enforcement)**: l'hook anti-bypass blocca `tht phase
|
||||
advance`, `tht decision add`, `tht memory promote|save-one` se il modello prova a
|
||||
eseguirli direttamente dalla shell; i payload vengono validati (TypeBox) e gli
|
||||
artefatti mostrati al reviewer sono ricostruiti in modo deterministico (es. il widget
|
||||
CTE mostra il SQL persistito via `tht cte info`, non il testo del modello); le
|
||||
chiusure di fase deterministiche sono automatiche.
|
||||
|
||||
Esempio concreto (F8): il modello chiama `reviewer_memory_promote`; il gate esegue
|
||||
`tht memory promote --preview --json`, costruisce la checklist pre-selezionata; il
|
||||
reviewer conferma; il gate salva le memory scelte (`memory save-one`), registra
|
||||
`memory_promoted`/`memory_promotion_declined` nel ledger e finalizza la sessione. Il
|
||||
modello non ha mai scritto nulla di propria mano.
|
||||
|
||||
Perché è cardine per la modularizzazione: il gate è **l'unico punto** in cui i tre moduli
|
||||
appaiono all'utente e in cui le loro regole vengono imposte — ogni cambiamento a
|
||||
disambiguazione/evidence/memory ha quasi sempre una controparte nel gate (sez. 5.2).
|
||||
|
||||
## 4. Stato attuale dei tre componenti
|
||||
|
||||
### 4.1 Evidence — il più vicino a essere un modulo
|
||||
|
||||
Fatti verificati nel codice:
|
||||
|
||||
- esiste già un **port vero** (`harness/tht/ports/evidence.py`: `discover`/`acquire`, credential-free,
|
||||
contratti Pydantic congelati) con **tre adapter** dietro il port (`adapters/evidence/{filesystem,http,s3}.py`);
|
||||
- la pipeline di canonizzazione/indicizzazione vive in `harness/tht/corpus/` (sorgente → normalize →
|
||||
chunk → embed → vector store, generazioni isolate stage→publish);
|
||||
- la **superficie di consumo del workflow è già quasi tutta incanalata in due comandi con JSON pulito**:
|
||||
`tht search pack` (sezione evidence: top 5, proiezione `{title, status, excerpt[:400]}`) e
|
||||
`tht search find [--kind evidence|formula]`. Quella proiezione è già di fatto un'API: evidence-canonica
|
||||
può rifare tutto dietro di essa (card, involucro tipizzato, retrieval duale) senza che F1 se ne accorga,
|
||||
finché il contratto di proiezione regge;
|
||||
- l'**inventario dei punti di consumo è già fatto**: `verifica-workflow.md` elenca i 12 touchpoint (T1–T12)
|
||||
con meccanismo e requisito. Quel documento **è** la bozza del contratto esterno del modulo.
|
||||
|
||||
Ciò che manca all'incapsulamento sono esattamente i tre GAP lì identificati:
|
||||
|
||||
- **GAP 1 — identità citabile**: il processo tratta l'id evidence come documento (F3 lo cita, F4 lo attacca
|
||||
ai candidati, il report di sessione lo risolve in file via `resolve_evidence_file`/`rglob`). La decisione
|
||||
già presa (id citabile `doc#card`) richiede l'estensione del resolver: è l'ultimo passo di contratto da
|
||||
chiudere;
|
||||
- **GAP 2 — formula store**: lettura cablata e funzionante, scrittura senza proprietario di produzione.
|
||||
La decisione già presa (le card famiglia 3 del corpus canonico sono fonte di verità; i `.sql.md` sono
|
||||
derivati della pipeline) assegna il proprietario senza toccare il contratto di lettura D14b;
|
||||
- **GAP 3 — conoscenza di dominio nei testi istruzionali**: dialetto, ricette temporali PSD, esempi clinici
|
||||
dentro SKILL.md e reference doc. È contenuto evidence sparso nel workflow: la migrazione verso il corpus
|
||||
canonico **è parte del lavoro di confine**, non un'attività cosmetica successiva.
|
||||
|
||||
Nota trasversale: il ciclo di vita evidence attraversa **due linguaggi** — materializzazione e ciclo di vita
|
||||
della collection stanno nel backend TypeScript (P4/P6), corpus e ricerca nello harness Python. L'API del
|
||||
modulo deve quindi essere il contratto CLI/JSON (che è già lo stile di casa: `--json` pristine), non
|
||||
un'interfaccia Python.
|
||||
|
||||
### 4.2 Memory — già incapsulata, con un accoppiamento semantico da esplicitare
|
||||
|
||||
Fatti verificati:
|
||||
|
||||
- il modulo vive in `harness/tht/memory.py` + `tht/solved.py` + `cli/memory_cmd.py`, con registro JSONL
|
||||
a scrittura atomica e dedup del contenuto reviewer-visibile;
|
||||
- i punti di contatto col workflow sono **esattamente tre**: F2 (ricerca + applicazione via gate), F8
|
||||
(gate di promozione), finalize (indicizzazione `solved_question`, best-effort);
|
||||
- il gate consuma la memory **solo tramite CLI**: `tht memory promote --preview --json` e
|
||||
`memory save-one`; la logica di calcolo dei candidati (dedup, decisioni storie post-rollback, seq
|
||||
rifiutate, esclusione delle già decise nella sessione) è tutta dentro memory.py. È incapsulamento vero,
|
||||
già operativo.
|
||||
|
||||
L'accoppiamento che conta non è di codice ma **semantico**: `REUSABLE_TYPES = {"concept_clarified"}` —
|
||||
il modello di contenuto della memory è definito dal tipo di output della disambiguazione. Se il ridisegno
|
||||
F1 cambia cosa sia un chiarimento (target group, tassonomia dell'ambiguità, caso unanswerable), cambia
|
||||
anche cosa la memory può promuovere e come. **Il contratto disambiguazione→memory va definito prima di
|
||||
far girare i due flussi in parallelo**, o si scontreranno esattamente lì.
|
||||
|
||||
### 4.3 Disambiguazione — non è un componente di codice
|
||||
|
||||
Il punto onesto: **non c'è niente da "estrarre" nel senso classico**. Oggi la disambiguazione è il
|
||||
comportamento dell'LLM in F1/F3/F4, governato da (ledger e gate: sez. 3):
|
||||
|
||||
- **prosa** (SKILL.md + `rewriting.md`): una sola ambiguità per volta, opzioni informate, "lascia aperta
|
||||
l'ambiguità" esplicita;
|
||||
- **retrieval**: pack iniettato (`retrieval_pack.md`), `tht search find`, `tht schema render`, LSH con
|
||||
`aggregate_lsh_multi` che espone *tutte* le colonne dove un valore appare (es. "ablazione" su flag
|
||||
booleano + campo patologia testuale);
|
||||
- **ledger**: `concept_clarified`, `ambiguity_open`, `value_grounded`, `question_rewritten`;
|
||||
- **gate**: i widget che presentano le interpretazioni candidate.
|
||||
|
||||
"Extractorla" significa quindi, in ordine:
|
||||
|
||||
1. **definire il suo contratto input/output** — in: domanda + contesto di retrieval; out: ambiguità con
|
||||
target group, opzioni candidate, segnale unanswerable distinto dall'ambiguo. È ciò che
|
||||
`impact-ridisegno-disambiguazione.md` §3 già elenca (retrieval duale lessicale+semantico, target group,
|
||||
unanswerable);
|
||||
2. **darle una superficie** che l'orchestratore consuma (sezione del pack, comando, sezione skill dedicata)
|
||||
invece di comportamento libero del modello;
|
||||
3. **spostare la conoscenza che usa** fuori da SKILL.md e dentro le evidence (GAP 3).
|
||||
|
||||
Rischio specifico e strutturale: l'LLM è colla che **può bypassare qualunque contratto su carta**. In
|
||||
questo codebase l'unico enforcement che funziona è a livello gate/CLI — il pattern è già dimostrato
|
||||
dall'hook anti-bypass che blocca `tht phase advance`/`decision add` da shell e `tht memory promote`/
|
||||
`save-one` fuori dal gate. Finché il contratto di disambiguazione non è enforcement (hook + CLI + skill
|
||||
come contratto completo), la proprietà "le modifiche non impattano altri moduli" è una speranza, non una
|
||||
proprietà verificabile.
|
||||
|
||||
## 5. I due quinti moduli nascosti
|
||||
|
||||
### 5.1 Il ledger + `workflow.yaml` — la colonna vertebrale condivisa
|
||||
|
||||
Tutti e tre i moduli leggono/scrivono il decision ledger (`review_decisions.jsonl`, sez. 3.1): la
|
||||
disambiguazione
|
||||
emette `concept_clarified`/`value_grounded`; l'evidence emette `evidence_accepted`/`evidence_rejected`/
|
||||
`concept_formula_approved|rejected`; la memory legge `concept_clarified` ed emette `memory_*`. Il campo
|
||||
`emits` di `workflow.yaml` accoppia fasi e decision type; `phase.py` piega il ledger per calcolare la
|
||||
fase corrente.
|
||||
|
||||
Questo è un **bene**: il ledger è già un contratto a eventi tra i moduli. Ma è superficie condivisa —
|
||||
tutti e tre i flussi vorranno toccarla. Va trattata come contratto a sé (quarto), con controllo dei
|
||||
cambiamenti, non come territorio libero.
|
||||
|
||||
### 5.2 Il gate (`tht-gate.js`) e il vector store — i punti caldi di merge
|
||||
|
||||
- **Il gate** (sez. 3; ~2000 righe + builders/enrich/artifact-contracts) renderizza candidati evidence, dedup
|
||||
opzioni memory, costruisce il widget schema-linking con id evidence, guida F2/F8 memory e fa enforcement
|
||||
anti-bypass. **Tutti e tre i flussi avranno bisogno di modifiche al gate**: se non viene spaccato lungo
|
||||
gli stessi confini dei moduli, diventa il punto caldo di merge del programma parallelo.
|
||||
- **Il vector store**: una collection Qdrant per workspace, kind-separata (`schema_table`, `schema_column`,
|
||||
`evidence`, `memory`, `solved_question`); il contratto di collection e payload-index è di proprietà del
|
||||
backend TS (P4), lettura/scrittura sono Python. I record schema/evidence sono revision-scoped (P3),
|
||||
memory/solved workspace-wide. Se evidence-canonica cambia la forma dei record/payload (il frontmatter
|
||||
già fluisce libero nei metadata), gli assunti di indicizzazione della memory ne risentono. Il vector
|
||||
store va designato come **infrastruttura condivisa con contratto proprio**, non come territorio
|
||||
implicito di uno dei tre.
|
||||
|
||||
## 6. I contratti che sono le vere API
|
||||
|
||||
Il parallelismo è protetto da quattro contratti, nessuno dei quali è un'interfaccia Python:
|
||||
|
||||
1. **Decision type del ledger** (`workflow.yaml` `emits` + `decisions.py`): l'interfaccia a eventi tra i
|
||||
tre moduli e il workflow. Ogni ridefinizione è una modifica di contratto, va versionata e comunicata;
|
||||
2. **Proiezioni di consumo evidence** (`search pack` / `search find --kind evidence|formula`): la forma di
|
||||
ciò che F1/F3/F4 vedono. È il cuore del ticket "Consumo per fase", che già porta i requisiti della F1
|
||||
ridisegnata e **non va congelato prima** che il disegno F1 abbia almeno uno schizzo;
|
||||
3. **Modello di contenuto memory** (`REUSABLE_TYPES` + campi del record + proiezione `promote --preview
|
||||
--json`): dipende semanticamente dal contratto di output della disambiguazione (sez. 4.2);
|
||||
4. **Id evidence citabile** (`doc#card` + estensione del resolver id→file): il contratto che tiene insieme
|
||||
F3 (citazioni), F4 (candidati), decisions (subject) e report di sessione.
|
||||
|
||||
## 7. Ordine di sviluppo consigliato
|
||||
|
||||
Coerente con quanto già deciso in `map.md` e nell'impact doc:
|
||||
|
||||
1. **schizzo del disegno F1** della disambiguazione (anche non finale): target group, retrieval duale,
|
||||
unanswerable — perché il contratto di consumo va progettato *contro la F1 ridisegnata*;
|
||||
2. **chiusura del contratto "Consumo per fase"** (cerniera tra evidence-canonica e F1): proiezioni,
|
||||
filtri, id citabili `doc#card` con resolver esteso;
|
||||
3. **definizione del contratto disambiguazione→memory** (cosa è riusabile, con quali campi);
|
||||
4. **solo allora** i tre flussi girano in parallelo, ciascuno nel suo worktree.
|
||||
|
||||
Strumento di protezione del parallelismo già disponibile in casa: il **pattern dei port-contract test**
|
||||
(`test_evidence_port_contract.py`, `test_vector_port_contract.py`, `test_dwh_port_contract.py`).
|
||||
Estenderlo ai nuovi confini (proiezioni evidence, contratto memory, enforcement di disambiguazione) è il
|
||||
modo più economico per rendere l'indipendenza dei moduli **verificabile** invece che sperata: un flusso
|
||||
rompe l'altro se e solo se rompe un test di contratto, non per effetti nascosti.
|
||||
|
||||
## 8. Rischi e mitigazioni
|
||||
|
||||
| Rischio | Natura | Mitigazione |
|
||||
|---|---|---|
|
||||
| L'LLM orchestratore bypassa il contratto di disambiguazione | strutturale (il workflow è LLM-driven) | enforcement gate/CLI sul modello dell'anti-bypass esistente; SKILL come contratto completo, non consiglio |
|
||||
| Collisione disambiguazione↔memory su `concept_clarified` | semantica | contratto esplicito (sez. 6.3) definito prima del parallelismo |
|
||||
| `tht-gate.js` punto caldo di merge | organizzativa | spaccare il gate lungo gli stessi confini dei moduli (builders per modulo) |
|
||||
| Deriva del contratto vector store tra TS e Python | infrastrutturale | contratto di collection/payload/kind di proprietà unica, test di contratto su entrambi i lati |
|
||||
| modifiche contagiose a `workflow.yaml`/ledger | processo | change control sul ledger come quarto contratto; `emits` data-driven già aiuta |
|
||||
| contratti congelati troppo presto (Consumo per fase) | sequenza | ordine sez. 7: prima schizzo F1, poi chiusura contratto |
|
||||
|
||||
## 9. Riferimenti
|
||||
|
||||
- `docs/wayfinder/evidence-canonica/map.md` — mappa del sottoprogetto evidence-canonica (destinazione,
|
||||
decisioni chiuse, nebbie);
|
||||
- `docs/wayfinder/evidence-canonica/prototypes/verifica-workflow.md` — i 12 touchpoint evidence (T1–T12) e
|
||||
i GAP 1–3: l'inventario dell'interfaccia esterna del futuro modulo evidence;
|
||||
- `docs/wayfinder/evidence-canonica/prototypes/impact-ridisegno-disambiguazione.md` — valutazione d'impatto
|
||||
del ridisegno F1 (requisiti: retrieval duale, target group, unanswerable; coordinamento dei due progetti);
|
||||
- `docs/wayfinder/evidence-canonica/prototypes/PROTOTIPO-formato-unita-canonica.md` e `tipologia-evidence.md`
|
||||
— formato card+involucro chiuso il 2026-08-21 e casistica a 7 famiglie;
|
||||
- `docs/disambiguazione-iniziale.md` — stato attuale della disambiguazione;
|
||||
- `docs/gestione-memory.md` — disegno della gestione memory;
|
||||
- `harness/workflow.yaml`, `harness/.pi/skills/tht-sessione/SKILL.md`, `harness/.pi/extensions/tht-gate.js`
|
||||
— le fonti di codice citate (fasi, discipline, gate);
|
||||
- `docs/prd/2026-08-09-workspace-preprocessing-prd.md` — il PRD da cui nasce l'attuale catena
|
||||
preprocessing/registry (contesto P2–P6 citato in sez. 4.1 e 5.2).
|
||||
@@ -0,0 +1,141 @@
|
||||
# Brief — Refactoring modulare conservativo del workflow
|
||||
|
||||
**Stato:** input autorevole per `grill-with-docs`; non è ancora una specifica
|
||||
implementativa.
|
||||
|
||||
## Obiettivo
|
||||
|
||||
Riorganizzare l’attuale applicazione ThothII per rendere locali e manutenibili le
|
||||
modifiche a Disambiguation, Evidence e Memory, preservando integralmente comportamento,
|
||||
frontend e flusso operativo esistenti.
|
||||
|
||||
La prima milestone è esclusivamente un refactoring. Non introduce nuove funzionalità e
|
||||
non generalizza ThothII come piattaforma di plugin.
|
||||
|
||||
## Vincoli già decisi
|
||||
|
||||
- Il progetto continuerà a essere sviluppato e mantenuto da un solo proprietario, in un
|
||||
unico repository e con un unico rilascio.
|
||||
- I moduli sono package interni secondo normali criteri di programmazione a oggetti.
|
||||
Non devono essere distribuibili indipendentemente, caricati dinamicamente o scritti da
|
||||
terze parti.
|
||||
- I moduli non devono condividere un contratto universale. Ogni modulo può presentare al
|
||||
workflow una piccola façade adatta alla propria responsabilità.
|
||||
- Moduli e fasi non coincidono necessariamente: un modulo può contribuire a più fasi e
|
||||
una fase può coordinare più moduli senza introdurre un protocollo generale.
|
||||
- Pi resta il runtime concreto per le elaborazioni assistite dal modello. Non viene
|
||||
introdotta un’astrazione `ModelRuntime`.
|
||||
- Il workflow resta ordinato e continua a usare `harness/workflow.yaml`, il ledger delle
|
||||
decisioni, i documenti di sessione e gli attuali gate human-in-the-loop.
|
||||
- Frontend, eventi SSE, widget, comandi `tht`, JSON, codici di uscita e formato delle
|
||||
sessioni devono rimanere compatibili.
|
||||
- Non sono previste migrazioni dei dati delle sessioni esistenti.
|
||||
- Il flusso SQL centrale, inclusi schema linking, sintesi, CTE e SQL finale, resta nel
|
||||
workflow core durante questa milestone.
|
||||
- Un altro componente futuro, estraneo al workflow e al core, non appartiene a questo
|
||||
refactoring.
|
||||
|
||||
## Moduli interni desiderati
|
||||
|
||||
### Admission
|
||||
|
||||
Occupa l’inizio logico del workflow. Nella prima milestone è un pass-through e ammette
|
||||
sempre la domanda, così il comportamento osservabile non cambia.
|
||||
|
||||
Per una fase futura è già stata scelta questa policy: una domanda non ammessa può essere
|
||||
riformulata nella stessa sessione; dopo il terzo tentativo fallito la sessione fallisce.
|
||||
La classificazione e l’esperienza utente non fanno parte del primo refactoring.
|
||||
|
||||
### Disambiguation
|
||||
|
||||
Raccoglie senza cambiarne il comportamento la logica attuale di chiarimento,
|
||||
interpretazione revisionata e riscrittura della domanda, comprese istruzioni Pi,
|
||||
validazioni e presentazione delle relative decisioni.
|
||||
|
||||
### Evidence
|
||||
|
||||
Consolida le superfici esistenti di acquisizione, canonizzazione, ricerca e citazione.
|
||||
Mantiene i seam già reali verso filesystem, HTTP e S3 e il contratto CLI/JSON necessario
|
||||
fra Python e TypeScript. Non introduce un contratto generale per gli altri moduli.
|
||||
|
||||
### Memory
|
||||
|
||||
Raccoglie senza variazioni funzionali ricerca, selezione, promozione e conoscenza delle
|
||||
domande già risolte, insieme alle istruzioni e ai gate specifici oggi dispersi.
|
||||
|
||||
### Datamart
|
||||
|
||||
Incapsula senza modificarla la parte di gestione del datamart oggi svolta nella fase F8.
|
||||
La fase F8 rimane visivamente e funzionalmente invariata, ma l’eventuale comportamento
|
||||
Memory che contiene appartiene al modulo Memory. La futura integrazione intelligente del
|
||||
SQL in un progetto dbt o in un flusso ETL è deliberatamente rinviata al momento in cui
|
||||
questo modulo verrà sviluppato.
|
||||
|
||||
## Responsabilità che restano condivise
|
||||
|
||||
Il workflow core conserva soltanto ciò che appartiene realmente all’intero flusso:
|
||||
|
||||
- ordine e avanzamento delle fasi;
|
||||
- ciclo di vita e resume delle sessioni;
|
||||
- ledger e documenti di sessione esistenti;
|
||||
- persistenza e locking comuni;
|
||||
- processo Pi e trasporto backend/frontend;
|
||||
- gate generici, sicurezza anti-bypass e finalizzazione;
|
||||
- coordinamento esplicito dei moduli tramite import statici.
|
||||
|
||||
I moduli non si scoprono tramite registry e non comunicano tramite event bus. Le
|
||||
dipendenze condivise vengono ricevute dal modulo oppure coordinate dal workflow core;
|
||||
un modulo non importa direttamente l’implementazione di un altro.
|
||||
|
||||
## Architettura esplicitamente rifiutata
|
||||
|
||||
Questa iniziativa non deve introdurre:
|
||||
|
||||
- Kernel separato dall’attuale harness;
|
||||
- manifest, registry, binding o composition resolver;
|
||||
- negoziazione e versionamento di un contratto universale;
|
||||
- adapter di esecuzione `in_process`, `process` o `job`;
|
||||
- `WorkflowDefinition`, `WorkflowCommit`, nuovo event store o upcaster;
|
||||
- artifact slot e revisioni universali;
|
||||
- Review Port, Interaction Request/Result o Instruction Bundle generici;
|
||||
- plugin dbt o automazioni ETL nella prima milestone.
|
||||
|
||||
## Fatti rilevanti sul codice attuale
|
||||
|
||||
- `harness/.pi/extensions/tht-gate.js` è il principale punto caldo condiviso, con circa
|
||||
2.000 righe e logica relativa a più domini.
|
||||
- `harness/.pi/skills/tht-sessione/SKILL.md` contiene circa 450 righe di istruzioni che
|
||||
attraversano tutte le fasi.
|
||||
- Evidence possiede già un port reale e tre adapter per filesystem, HTTP e S3.
|
||||
- Memory possiede già codice dedicato, ma responsabilità e integrazione sono distribuite
|
||||
tra modulo Python, CLI, gate e istruzioni Pi.
|
||||
- Disambiguation oggi è soprattutto comportamento distribuito fra istruzioni, decisioni
|
||||
e gate, non un package applicativo autonomo.
|
||||
- `harness/workflow.yaml` è già la fonte condivisa dell’ordine e dei requisiti delle
|
||||
fasi e deve rimanere tale.
|
||||
|
||||
L’analisi più ampia del problema corrente resta disponibile in
|
||||
[`2026-08-21-modularizzazione-disambiguazione-evidence-memory-prd.md`](2026-08-21-modularizzazione-disambiguazione-evidence-memory-prd.md).
|
||||
|
||||
## Criterio di riuscita
|
||||
|
||||
Dopo il refactoring, una modifica interna a Disambiguation, Evidence o Memory deve
|
||||
richiedere normalmente interventi nella directory e nei test del relativo modulo. Il
|
||||
workflow core cambia soltanto quando cambia davvero il flusso condiviso.
|
||||
|
||||
La suite esistente, i test di caratterizzazione e i test end-to-end devono dimostrare
|
||||
che il frontend e ogni comportamento osservabile sono rimasti invariati.
|
||||
|
||||
## Questioni da affidare a `grill-with-docs`
|
||||
|
||||
L’intervista deve concentrarsi soltanto sulle decisioni necessarie al refactoring:
|
||||
|
||||
1. ownership esatta dei file e delle responsabilità attuali;
|
||||
2. façade minima e specifica di ciascun modulo;
|
||||
3. collocazione delle istruzioni Pi e degli helper del gate relativi a ciascun dominio;
|
||||
4. dipendenze condivise che devono essere ricevute dai moduli;
|
||||
5. ordine di estrazione incrementale e test di caratterizzazione per ogni passaggio;
|
||||
6. criteri oggettivi che impediscano al refactoring di introdurre cambiamenti funzionali.
|
||||
|
||||
Le funzioni future di Admission e Datamart/dbt sono fuori dal frontier dell’intervista:
|
||||
vanno discusse soltanto dopo il completamento del refactoring conservativo.
|
||||
Reference in New Issue
Block a user