chore: preserve root worktree documents
This commit is contained in:
@@ -86,3 +86,20 @@ frontend (React/SSE) → backend (Fastify) → pi --mode rpc → tht/harness →
|
|||||||
resume with 409 when `finalized` or `archived`, and `PiProcessManager.spawnFor` must send
|
resume with 409 when `finalized` or `archived`, and `PiProcessManager.spawnFor` must send
|
||||||
`/riprendi-sessione <id>` (resume mode) vs `/nuova-domanda` (new) — sending the wrong prompt
|
`/riprendi-sessione <id>` (resume mode) vs `/nuova-domanda` (new) — sending the wrong prompt
|
||||||
silently turns a resume into a new question.
|
silently turns a resume into a new question.
|
||||||
|
|
||||||
|
## Agent skills
|
||||||
|
|
||||||
|
### Issue tracker
|
||||||
|
|
||||||
|
Issues and specifications are tracked in GitHub Issues for `mptyl/ThothII`. See
|
||||||
|
`docs/agents/issue-tracker.md`.
|
||||||
|
|
||||||
|
### Triage labels
|
||||||
|
|
||||||
|
The repository uses the default canonical triage labels. See
|
||||||
|
`docs/agents/triage-labels.md`.
|
||||||
|
|
||||||
|
### Domain docs
|
||||||
|
|
||||||
|
The repository uses a single-context domain model rooted at `CONTEXT.md`, with
|
||||||
|
architectural decisions under `docs/adr/`. See `docs/agents/domain.md`.
|
||||||
|
|||||||
+31
-80
@@ -1,95 +1,42 @@
|
|||||||
# Contesto di dominio di ThothII
|
# Contesto di dominio di ThothII
|
||||||
|
|
||||||
## Architettura del workflow
|
## Workflow
|
||||||
|
|
||||||
**Workflow Kernel** — Il coordinatore deterministico che possiede lo stato del workflow,
|
**Workflow core** — La parte condivisa del workflow NL→SQL che governa la sequenza
|
||||||
le transizioni, il rollback, la finalizzazione e l'applicazione atomica degli esiti dei
|
delle fasi, il ciclo di vita delle sessioni, la revisione umana e la persistenza. Non è
|
||||||
moduli.
|
un processo distinto né un sistema estensibile di plugin.
|
||||||
|
|
||||||
**Workflow Module** — Una capacità incapsulata che espone un contratto versionato. Un
|
**Internal workflow module** — Un insieme coeso di comportamento e conoscenza di
|
||||||
modulo può partecipare a più stage e non modifica direttamente lo stato del workflow.
|
dominio sviluppato e rilasciato insieme a ThothII. È isolato per rendere locali le
|
||||||
|
modifiche, non per essere caricato dinamicamente o sostituito da implementazioni esterne.
|
||||||
|
|
||||||
**Stage** — Un punto del workflow, identificato semanticamente, nel quale viene invocato
|
**Pi** — Il runtime agentico concreto usato da ThothII per le elaborazioni che
|
||||||
un modulo. L'identità dello stage è indipendente dalla sua posizione visiva.
|
richiedono un modello. Segue le istruzioni del workflow e usa gli strumenti messi a
|
||||||
|
disposizione dai moduli interni.
|
||||||
|
|
||||||
**Display code** — L'etichetta di presentazione associata a uno stage, per esempio da
|
**Admission** — Il controllo che stabilisce se una domanda può entrare nel workflow
|
||||||
`F1` a `F8`. I display code alimentano gli indicatori di avanzamento nel frontend, ma non
|
NL→SQL oppure deve essere riformulata o rifiutata.
|
||||||
sono usati come identità del workflow o chiavi di dipendenza.
|
|
||||||
|
|
||||||
**Module outcome** — Il risultato proposto da un modulo: eventi tipizzati, modifiche agli
|
**Disambiguation** — La responsabilità di rendere esplicita e sottoporre a revisione
|
||||||
artifact, un'eventuale richiesta di revisione umana e uno stato di esecuzione. Il
|
l’interpretazione di una domanda ambigua prima della generazione SQL.
|
||||||
Workflow Kernel valida e applica l'esito.
|
|
||||||
|
|
||||||
**Revision request** — La proposta tipizzata con cui un modulo segnala che lo stage
|
**Evidence** — La conoscenza di dominio curata e citabile usata per fondare
|
||||||
corrente non può concludersi validamente senza rieseguire lo stesso stage o uno stage
|
l’interpretazione della domanda e le scelte effettuate durante il workflow.
|
||||||
precedente. Non produce direttamente una transizione: il Workflow Kernel valida la
|
|
||||||
richiesta, sospende l'avanzamento e, per riaprire uno stage già completato, attende una
|
|
||||||
decisione umana tipizzata. Il Kernel, non il modulo, determina gli eventi e gli artifact
|
|
||||||
causalmente da rendere stale.
|
|
||||||
|
|
||||||
**Question Admission** — Il controllo preliminare eseguito prima delle fasi da `F1` a
|
**Memory** — La conoscenza riutilizzabile derivata da decisioni o sessioni precedenti e
|
||||||
`F8`. Nella prima release distingue una domanda utilizzabile da input garbage e verifica
|
resa disponibile alle elaborazioni successive.
|
||||||
che la domanda appartenga allo scope dichiarato dal workspace. Il suo stato è mostrato
|
|
||||||
separatamente dagli otto indicatori di fase.
|
|
||||||
|
|
||||||
**Workspace scope** — La dichiarazione gestita e versionata di ciò che il database di un
|
**Datamart** — L’attività finale già esistente che gestisce l’eventuale produzione del
|
||||||
workspace rappresenta e delle domande alle quali è destinato a rispondere. Question
|
datamart dopo la generazione del SQL.
|
||||||
Admission la usa come riferimento per valutare la pertinenza di una domanda.
|
|
||||||
|
|
||||||
**Datamart Plugin** — Il modulo sostituibile che implementa lo stage semantico
|
**Paused session** — Una sessione interrotta intenzionalmente ma resumibile. L’azione
|
||||||
`datamart`, presentato con display code `F8`. La promozione della memory e la
|
|
||||||
finalizzazione della sessione non appartengono al Datamart Plugin.
|
|
||||||
|
|
||||||
**Ordered workflow** — La pipeline deterministica composta dal preflight Admission,
|
|
||||||
dagli otto stage principali ordinati da `F1` a `F8` e dalla finalizzazione. L'ordine
|
|
||||||
degli stage è esplicito; il workflow non è un DAG generale.
|
|
||||||
|
|
||||||
**Extension point** — Una posizione semantica nel lifecycle dell'Ordered workflow alla
|
|
||||||
quale possono contribuire uno o più moduli senza diventare nuovi stage visibili. Un
|
|
||||||
extension point non possiede un display code.
|
|
||||||
|
|
||||||
**Stage state** — La proiezione deterministica degli eventi del workflow che descrive
|
|
||||||
uno stage come `pending`, `ready`, `running`, `awaiting_human`, `completed`, `skipped` o
|
|
||||||
`failed`. Non è un valore corrente memorizzato separatamente dal ledger.
|
|
||||||
|
|
||||||
**Required contribution** — Il contributo di un modulo a un extension point che deve
|
|
||||||
concludersi o essere esplicitamente saltato secondo policy prima che il workflow possa
|
|
||||||
avanzare.
|
|
||||||
|
|
||||||
**Best-effort contribution** — Il contributo di un modulo il cui fallimento viene
|
|
||||||
registrato e mostrato come warning, ma non impedisce al workflow di avanzare.
|
|
||||||
|
|
||||||
**Blocked workflow** — La proiezione complessiva di un workflow che non può avanzare a
|
|
||||||
causa di uno stage o di un contributo required fallito o non disponibile. `Blocked` non
|
|
||||||
è uno Stage state autonomo.
|
|
||||||
|
|
||||||
**Module invocation** — Una singola richiesta del Workflow Kernel a un modulo in uno
|
|
||||||
stage o extension point. Conserva la stessa identità attraverso eventuali retry, che
|
|
||||||
sono tentativi distinti della medesima invocation.
|
|
||||||
|
|
||||||
**Stage skip** — La conclusione esplicita di uno stage senza eseguirne il comportamento.
|
|
||||||
È ammessa soltanto dalla policy dello stage e registra motivo e attore; un fallimento non
|
|
||||||
equivale mai implicitamente a uno skip.
|
|
||||||
|
|
||||||
**Stage reopen** — La riapertura di uno stage non finalizzato che rende stale gli esiti
|
|
||||||
causalmente successivi. Gli effetti esterni già prodotti richiedono una marcatura o una
|
|
||||||
compensazione esplicita e non sono presentati come automaticamente annullati. Può essere
|
|
||||||
applicata dal Workflow Kernel in seguito all'approvazione di una Revision request, ma
|
|
||||||
non può essere eseguita direttamente da Pi o da un Workflow Module.
|
|
||||||
|
|
||||||
**Completion policy** — La regola con cui uno stage si conclude: `automatic` quando il
|
|
||||||
kernel può verificarne deterministicamente l'esito, oppure `review_required` quando è
|
|
||||||
necessaria un'approvazione umana tipizzata.
|
|
||||||
|
|
||||||
**Paused session** — Una sessione interrotta intenzionalmente ma resumibile. L'azione
|
|
||||||
“Stop and save” mette la sessione in pausa; non la completa e non la marca come fallita.
|
“Stop and save” mette la sessione in pausa; non la completa e non la marca come fallita.
|
||||||
|
|
||||||
**Finalized session** — Una sessione completata con esito canonico e immutabile. Una
|
**Finalized session** — Una sessione completata che non accetta ulteriori modifiche al
|
||||||
correzione successiva crea una nuova sessione derivata, collegata a quella precedente.
|
proprio risultato.
|
||||||
|
|
||||||
**After-finalize hook** — Una notifica o attività best-effort eseguita tramite outbox
|
**Workspace scope** — La dichiarazione di ciò che il database di un workspace
|
||||||
dopo la finalizzazione. Non può modificare il ledger, gli artifact canonici o lo stato
|
rappresenta e delle domande alle quali è destinato a rispondere.
|
||||||
terminale della sessione.
|
|
||||||
|
|
||||||
## Catalogo dei metadati
|
## Catalogo dei metadati
|
||||||
|
|
||||||
@@ -103,8 +50,12 @@ Workspace Database. Non definisce quali elementi partecipano al workflow SQL.
|
|||||||
**Database Profile** — L'insieme curato di scope, descrizioni e metadati semantici
|
**Database Profile** — L'insieme curato di scope, descrizioni e metadati semantici
|
||||||
associato a un Workspace Database.
|
associato a un Workspace Database.
|
||||||
|
|
||||||
**AI Proposal** — Un contenuto generato con l'ausilio dell'AI che non è ancora stato
|
**Generated comment** — Il testo descrittivo prodotto dall'AI per una tabella o una
|
||||||
approvato come contenuto canonico.
|
colonna. Rimane distinto dalla descrizione finché l'utente non ne richiede la copia.
|
||||||
|
|
||||||
|
**Core Schema Selection** — Il sottoinsieme di tabelle, colonne e relazioni di un
|
||||||
|
Workspace Database reso disponibile al processo core di ThothII. È distinto dal
|
||||||
|
Workspace scope, che descrive il dominio e le domande ammesse.
|
||||||
|
|
||||||
**Publication** — Una versione approvata e immutabile dei contenuti del Metadata
|
**Publication** — Una versione approvata e immutabile dei contenuti del Metadata
|
||||||
Catalog resa disponibile ai suoi consumatori.
|
Catalog resa disponibile ai suoi consumatori.
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# Domain documentation
|
||||||
|
|
||||||
|
ThothII uses a single domain context.
|
||||||
|
|
||||||
|
## Before exploring
|
||||||
|
|
||||||
|
Read:
|
||||||
|
|
||||||
|
- `CONTEXT.md` for the canonical domain vocabulary;
|
||||||
|
- relevant ADRs under `docs/adr/`, when present.
|
||||||
|
|
||||||
|
Missing documents are not an error. Domain terms and ADRs are created only when an
|
||||||
|
actual decision makes them necessary.
|
||||||
|
|
||||||
|
## Vocabulary
|
||||||
|
|
||||||
|
Use the canonical terms defined in `CONTEXT.md`. Avoid introducing synonyms for
|
||||||
|
concepts already defined there.
|
||||||
|
|
||||||
|
When a required concept is absent, use `domain-modeling` to clarify and record it.
|
||||||
|
|
||||||
|
## Architectural decisions
|
||||||
|
|
||||||
|
If proposed work contradicts an existing ADR, surface the conflict explicitly rather
|
||||||
|
than overriding the decision silently.
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Issue tracker: GitHub
|
||||||
|
|
||||||
|
Issues and specifications for this repository live in GitHub Issues. Use the `gh` CLI
|
||||||
|
for all operations.
|
||||||
|
|
||||||
|
## Repository
|
||||||
|
|
||||||
|
- Repository: `mptyl/ThothII`
|
||||||
|
- URL: https://github.com/mptyl/ThothII
|
||||||
|
- Pull requests as a triage surface: no
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Create issues with `gh issue create`.
|
||||||
|
- Read issues and comments with `gh issue view`.
|
||||||
|
- Apply labels with `gh issue edit`.
|
||||||
|
- Record resolutions in a comment before closing an issue.
|
||||||
|
- Refer to issues by their linked title in user-facing documentation, not only by
|
||||||
|
number.
|
||||||
|
|
||||||
|
## Wayfinding operations
|
||||||
|
|
||||||
|
- A Wayfinder map is an issue labelled `wayfinder:map`.
|
||||||
|
- Decision tickets are child issues labelled `wayfinder:research`,
|
||||||
|
`wayfinder:prototype`, `wayfinder:grilling` or `wayfinder:task`.
|
||||||
|
- Use native GitHub sub-issues and issue dependencies when available.
|
||||||
|
- If native sub-issues are unavailable, use a task list in the map and add
|
||||||
|
`Part of #<map>` to each ticket.
|
||||||
|
- If native dependencies are unavailable, add `Blocked by: #<issue>` to the ticket.
|
||||||
|
- An open, unassigned and unblocked child issue belongs to the frontier.
|
||||||
|
- Claim a ticket by assigning it before beginning work.
|
||||||
|
- Resolve a ticket by recording the decision in a comment, closing it and adding a
|
||||||
|
linked one-line summary to the map.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Triage labels
|
||||||
|
|
||||||
|
| Canonical role | GitHub label | Meaning |
|
||||||
|
| ----------------- | ----------------- | --------------------------------------------- |
|
||||||
|
| `needs-triage` | `needs-triage` | The issue still needs evaluation |
|
||||||
|
| `needs-info` | `needs-info` | More information is required |
|
||||||
|
| `ready-for-agent` | `ready-for-agent` | Ready for autonomous agent work |
|
||||||
|
| `ready-for-human` | `ready-for-human` | Requires human intervention or implementation |
|
||||||
|
| `wontfix` | `wontfix` | Will not be actioned |
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
# Refactoring modulare conservativo del workflow — Design
|
||||||
|
|
||||||
|
**Data:** 2026-08-23
|
||||||
|
|
||||||
|
**Stato:** approvato dal proprietario
|
||||||
|
|
||||||
|
**Ambito:** modularizzazione interna di Disambiguation, Evidence e Memory senza cambiamenti
|
||||||
|
funzionali
|
||||||
|
|
||||||
|
**Baseline del codice:** `b5db0cd3c12a4184a91933f6cf9d4ee13241ba65`
|
||||||
|
|
||||||
|
**Input autorevole:**
|
||||||
|
[`docs/prd/2026-08-23-refactoring-modulare-conservativo-brief.md`](../../prd/2026-08-23-refactoring-modulare-conservativo-brief.md)
|
||||||
|
|
||||||
|
## 1. Scopo
|
||||||
|
|
||||||
|
Questa milestone riorganizza il workflow ThothII in tre moduli interni profondi:
|
||||||
|
Disambiguation, Evidence e Memory. Una modifica alla semantica interna di uno di questi domini deve
|
||||||
|
richiedere normalmente interventi nella directory e nei test del modulo relativo. Il workflow core
|
||||||
|
cambia soltanto quando cambia una responsabilità realmente condivisa.
|
||||||
|
|
||||||
|
La milestone è un refactoring conservativo. Non aggiunge funzionalità, non cambia il flusso
|
||||||
|
operativo e non trasforma ThothII in una piattaforma di plugin. Pi resta il runtime concreto del
|
||||||
|
workflow assistito dal modello. Il repository, il rilascio e la proprietà del prodotto restano
|
||||||
|
unici.
|
||||||
|
|
||||||
|
## 2. Perimetro deciso
|
||||||
|
|
||||||
|
Sono inclusi:
|
||||||
|
|
||||||
|
- estrazione delle responsabilità Disambiguation oggi distribuite fra istruzioni Pi, gate,
|
||||||
|
decisioni e rendering della domanda;
|
||||||
|
- consolidamento di Memory, compresi recall F2, promozione F8 e indicizzazione delle domande
|
||||||
|
risolte;
|
||||||
|
- consolidamento di Evidence attraverso Python e TypeScript, dall'acquisizione alla citazione;
|
||||||
|
- separazione del gate monolitico fra meccanismi condivisi e use case specifici dei moduli;
|
||||||
|
- modularizzazione delle istruzioni Pi senza modificare il prompt effettivo;
|
||||||
|
- test di caratterizzazione e contract test che dimostrino equivalenza osservabile;
|
||||||
|
- un E2E live finale sull'intero workflow.
|
||||||
|
|
||||||
|
Sono esclusi:
|
||||||
|
|
||||||
|
- un modulo Admission, anche come pass-through;
|
||||||
|
- l'estrazione di Datamart o nuove funzioni dbt/ETL;
|
||||||
|
- il futuro ridisegno di F1, inclusi target group, classificazione unanswerable o nuovo retrieval;
|
||||||
|
- nuove funzionalità Evidence o Memory;
|
||||||
|
- un kernel separato, plugin, registry, manifest o resolver di composizione;
|
||||||
|
- un contratto universale fra moduli;
|
||||||
|
- `ModelRuntime`, event bus, nuovo event store, upcaster o artifact universali;
|
||||||
|
- modifiche al frontend o all'esperienza del reviewer;
|
||||||
|
- migrazioni dei dati o delle sessioni esistenti;
|
||||||
|
- correzioni opportunistiche di failure semantics, atomicità o altri comportamenti correnti;
|
||||||
|
- un piano esecutivo dettagliato, che sarà un documento successivo.
|
||||||
|
|
||||||
|
Admission e Datamart potranno essere progettati soltanto dopo il completamento e l'accettazione di
|
||||||
|
questa milestone.
|
||||||
|
|
||||||
|
## 3. Invarianti di compatibilità
|
||||||
|
|
||||||
|
Durante la milestone sono congelati:
|
||||||
|
|
||||||
|
- `harness/workflow.yaml`, ordine delle fasi e meccanismi di avanzamento;
|
||||||
|
- tassonomia, forma e significato delle decisioni del ledger;
|
||||||
|
- nomi, parametri, schemi TypeBox e risultati dei tool Pi;
|
||||||
|
- comandi `tht`, grammatica, JSON, stdout, stderr e codici di uscita;
|
||||||
|
- nomi, formato e contenuto deterministico dei documenti di sessione;
|
||||||
|
- widget descriptor, eventi SSE e loro ordine;
|
||||||
|
- prompt Pi effettivo e comportamento di caricamento delle reference;
|
||||||
|
- lifecycle e resume delle sessioni;
|
||||||
|
- lifecycle delle collection Qdrant e relativi payload condivisi;
|
||||||
|
- sequenza delle mutazioni e comportamento degli errori parziali;
|
||||||
|
- numero e ordine dei gate, dei turni Pi e delle operazioni esterne per fixture deterministiche.
|
||||||
|
|
||||||
|
Gli import Python, JavaScript e TypeScript usati soltanto dentro il repository non sono contratti
|
||||||
|
pubblici e possono cambiare. Qualunque modifica sostanziale a un elemento congelato interrompe il
|
||||||
|
refactoring: deve essere isolata, progettata e autorizzata come lavoro funzionale separato.
|
||||||
|
|
||||||
|
Non è sufficiente aggiornare un golden perché un test torni verde. Ogni differenza deve prima essere
|
||||||
|
trattata come possibile regressione.
|
||||||
|
|
||||||
|
## 4. Principi di modularità
|
||||||
|
|
||||||
|
### 4.1 Ownership
|
||||||
|
|
||||||
|
L'ownership indica dove vive una regola e quale modulo deve cambiare quando la regola cambia. Non
|
||||||
|
indica chi possiede il repository né quale implementazione scrive fisicamente un file.
|
||||||
|
|
||||||
|
Il modulo possiede:
|
||||||
|
|
||||||
|
- la semantica del proprio dominio;
|
||||||
|
- le validazioni specifiche;
|
||||||
|
- la presentazione specifica al reviewer;
|
||||||
|
- l'ordine delle mutazioni del proprio use case;
|
||||||
|
- le istruzioni Pi specifiche;
|
||||||
|
- i test attraverso la propria façade.
|
||||||
|
|
||||||
|
Il core possiede:
|
||||||
|
|
||||||
|
- ordine e avanzamento delle fasi;
|
||||||
|
- lifecycle, resume e finalizzazione delle sessioni;
|
||||||
|
- schema e persistenza del ledger;
|
||||||
|
- documenti e repository di sessione;
|
||||||
|
- locking e scritture atomiche condivise;
|
||||||
|
- processo Pi e trasporto backend/frontend;
|
||||||
|
- tool reviewer generici e widget transport;
|
||||||
|
- enforcement anti-bypass e protezione dei file;
|
||||||
|
- registry dei workspace e infrastruttura vector-store condivisa;
|
||||||
|
- composizione statica dei moduli.
|
||||||
|
|
||||||
|
Il modulo decide **cosa** mutare, **quando** e in quale ordine. Il core fornisce il meccanismo con cui
|
||||||
|
la mutazione viene eseguita.
|
||||||
|
|
||||||
|
### 4.2 Moduli profondi e asimmetrici
|
||||||
|
|
||||||
|
I moduli non devono avere la stessa forma né implementare una base comune. Ciascuno espone la più
|
||||||
|
piccola façade adatta ai propri use case. Un modulo esiste soltanto nei runtime in cui possiede
|
||||||
|
comportamento reale:
|
||||||
|
|
||||||
|
- Disambiguation è prevalentemente JavaScript e Pi;
|
||||||
|
- Memory attraversa Python, JavaScript e Pi;
|
||||||
|
- Evidence attraversa Python e TypeScript e fornisce dati al workflow Pi;
|
||||||
|
- non vengono creati package vuoti per ottenere simmetria visiva.
|
||||||
|
|
||||||
|
Non si introducono classi `*Facade`, DTO paralleli o un metodo universale `execute()`. Le interfacce
|
||||||
|
esterne già consumate dal workflow restano la façade pubblica; gli entrypoint di installazione sono
|
||||||
|
soltanto seam interni di composizione.
|
||||||
|
|
||||||
|
## 5. Architettura risultante
|
||||||
|
|
||||||
|
```text
|
||||||
|
workflow core
|
||||||
|
phase order · session · ledger · gate core
|
||||||
|
/ | \
|
||||||
|
/ | \
|
||||||
|
Disambiguation Memory Evidence
|
||||||
|
F1/F3 policy F2/F8 + solved acquire→cite
|
||||||
|
\ | /
|
||||||
|
\------ existing contracts ---/
|
||||||
|
ledger · artifacts · CLI/JSON
|
||||||
|
```
|
||||||
|
|
||||||
|
La composizione avviene tramite import statici. Non esistono discovery, registry o binding runtime.
|
||||||
|
Un modulo non importa l'implementazione di un altro modulo.
|
||||||
|
|
||||||
|
Le sole comunicazioni semantiche fra domini sono i contratti già esistenti:
|
||||||
|
|
||||||
|
- Disambiguation → Memory: record del ledger, in particolare `concept_clarified`;
|
||||||
|
- Evidence → Disambiguation/workflow: proiezioni di `tht search pack` e
|
||||||
|
`tht search find`;
|
||||||
|
- moduli → workflow: decisioni, artefatti e risultati CLI già definiti.
|
||||||
|
|
||||||
|
`DecisionType`, `workflow.yaml` e i repository restano di proprietà del core. Ogni collegamento fra
|
||||||
|
domini è protetto da un contract test e non da una chiamata diretta.
|
||||||
|
|
||||||
|
## 6. Modulo Disambiguation
|
||||||
|
|
||||||
|
Disambiguation possiede:
|
||||||
|
|
||||||
|
- istruzioni Pi di F1 e F3 e la tecnica descritta da `rewriting.md`;
|
||||||
|
- semantica di `concept_clarified`, `ambiguity_open`, `value_grounded` e
|
||||||
|
`question_rewritten`, senza possedere il registro globale dei tipi;
|
||||||
|
- validazione e normalizzazione dei payload Disambiguation inviati ai tool reviewer generici;
|
||||||
|
- presentazione delle interpretazioni e dei chiarimenti;
|
||||||
|
- tool specializzato `rewrite_question`;
|
||||||
|
- sequenza corrente `session set-question` → `question_rewritten` → chiusura F3;
|
||||||
|
- rendering del contenuto di `question.md`, incluse le assunzioni.
|
||||||
|
|
||||||
|
Il repository condiviso continua a effettuare la scrittura di `question.md`. Il core continua a
|
||||||
|
registrare `reviewer_select` e `reviewer_decide`; quando il payload appartiene a Disambiguation,
|
||||||
|
delega staticamente policy e normalizzazione al modulo.
|
||||||
|
|
||||||
|
Non viene introdotto un motore deterministico di disambiguazione, un nuovo comando CLI o un nuovo
|
||||||
|
tool Pi. Il modello continua a proporre le opzioni secondo le istruzioni correnti.
|
||||||
|
|
||||||
|
La façade interna del gate comprende soltanto:
|
||||||
|
|
||||||
|
- installazione di `rewrite_question` tramite un entrypoint come
|
||||||
|
`installDisambiguationGate(deps)`;
|
||||||
|
- policy richiamate staticamente dai tool reviewer generici.
|
||||||
|
|
||||||
|
## 7. Modulo Memory
|
||||||
|
|
||||||
|
Memory possiede:
|
||||||
|
|
||||||
|
- ricerca, selezione, dedup e applicazione delle memory in F2;
|
||||||
|
- definizione locale dei tipi riusabili, attualmente `concept_clarified`;
|
||||||
|
- calcolo deterministico dei candidati di promozione;
|
||||||
|
- presentazione, selezione e promozione in F8;
|
||||||
|
- tool `reviewer_memory_promote` e relativi builder/normalizer;
|
||||||
|
- salvataggio mirato nel vector store e decisioni `memory_promoted` /
|
||||||
|
`memory_promotion_declined`;
|
||||||
|
- indicizzazione best-effort delle domande risolte durante finalize;
|
||||||
|
- comportamento e istruzioni Pi Memory.
|
||||||
|
|
||||||
|
La CLI `tht memory ...` conserva integralmente la propria interfaccia e diventa un adapter sottile
|
||||||
|
verso il modulo. Il core continua a possedere repository, ledger, fase, finalizzazione e vector-store
|
||||||
|
generico.
|
||||||
|
|
||||||
|
La façade esterna resta composta dai comandi `tht memory ...`, dal tool
|
||||||
|
`reviewer_memory_promote` e dall'hook solved invocato durante finalize. L'entrypoint JavaScript
|
||||||
|
interno è del tipo `installMemoryGate(deps)`; non costituisce un protocollo condiviso con gli altri
|
||||||
|
moduli.
|
||||||
|
|
||||||
|
## 8. Modulo Evidence
|
||||||
|
|
||||||
|
Evidence possiede:
|
||||||
|
|
||||||
|
- port e adapter filesystem, HTTP e S3;
|
||||||
|
- acquisizione e materializzazione;
|
||||||
|
- modelli canonici, normalizzazione, chunking, staging e publication del corpus;
|
||||||
|
- ricerca Evidence e formula store;
|
||||||
|
- contratti Evidence-specific dei comandi preprocessing e search;
|
||||||
|
- risoluzione degli ID citabili;
|
||||||
|
- proiezione `{id, file, esito, decision_seq}` usata nei documenti di sessione;
|
||||||
|
- orchestrazione TypeScript specifica di Evidence oggi dispersa nel sottosistema workspace.
|
||||||
|
|
||||||
|
Il core passa decisioni e schema linking al projector Evidence e scrive il risultato tramite il
|
||||||
|
repository di sessione. Schema linking, sintesi e relativi widget restano nel workflow core.
|
||||||
|
|
||||||
|
Restano condivisi:
|
||||||
|
|
||||||
|
- registry e configurazione dei workspace;
|
||||||
|
- orchestrazione generale del preprocessing;
|
||||||
|
- lifecycle e indici obbligatori della collection Qdrant;
|
||||||
|
- vector store, embedder e configurazione infrastrutturale;
|
||||||
|
- persistenza delle sessioni.
|
||||||
|
|
||||||
|
La façade inter-language resta il contratto CLI/JSON esistente. Non viene introdotta una nuova
|
||||||
|
interfaccia generale Python/TypeScript.
|
||||||
|
|
||||||
|
## 9. Mappa fisica
|
||||||
|
|
||||||
|
La struttura obiettivo è:
|
||||||
|
|
||||||
|
```text
|
||||||
|
harness/.pi/extensions/gate/
|
||||||
|
core/ # hook, enforcement e meccanismi generici
|
||||||
|
disambiguation/ # policy F1/F3, rewrite tool, test
|
||||||
|
memory/ # F2/F8, promotion tool, test
|
||||||
|
|
||||||
|
harness/.pi/skills/tht-sessione/modules/
|
||||||
|
disambiguation/
|
||||||
|
memory/
|
||||||
|
|
||||||
|
harness/tht/
|
||||||
|
memory/ # assorbe memory.py e solved.py
|
||||||
|
evidence/ # assorbe port, adapter, corpus e search/evidence
|
||||||
|
|
||||||
|
harness/tests/
|
||||||
|
disambiguation/
|
||||||
|
memory/
|
||||||
|
evidence/
|
||||||
|
|
||||||
|
backend/src/workspaces/evidence/
|
||||||
|
materialization.ts
|
||||||
|
preprocessing.ts
|
||||||
|
|
||||||
|
backend/test/workspaces/evidence/
|
||||||
|
```
|
||||||
|
|
||||||
|
`harness/.pi/extensions/tht-gate.js`, `harness/.pi/skills/tht-sessione/SKILL.md`, le CLI e
|
||||||
|
`backend/src/workspaces/preprocessing-service.ts` restano entrypoint stabili. Delegano ai moduli
|
||||||
|
tramite import espliciti.
|
||||||
|
|
||||||
|
Più precisamente:
|
||||||
|
|
||||||
|
- `harness/tht/memory.py` e `harness/tht/solved.py` confluiscono nel package
|
||||||
|
`harness/tht/memory/`;
|
||||||
|
- `harness/tht/corpus/`, `harness/tht/search/evidence.py`, il port Evidence e gli adapter
|
||||||
|
Evidence confluiscono sotto `harness/tht/evidence/`;
|
||||||
|
- le funzionalità non Evidence di `harness/tht/search/` restano condivise;
|
||||||
|
- `backend/src/workspaces/evidence-materialization.ts` confluisce nel modulo Evidence;
|
||||||
|
- da `preprocessing-service.ts` viene estratta soltanto l'orchestrazione specifica Evidence;
|
||||||
|
- `qdrant-collection.ts`, registry, stato e coordinamento generale restano nel package workspace;
|
||||||
|
- i test di dominio seguono il modulo; il comando pubblico `npm test` del harness continua a
|
||||||
|
eseguire l'intera suite JavaScript anche dopo l'aggiornamento della discovery interna.
|
||||||
|
|
||||||
|
Non viene creata una directory Evidence nel gate finché non esiste comportamento JavaScript
|
||||||
|
specifico da collocarvi.
|
||||||
|
|
||||||
|
## 10. Istruzioni Pi
|
||||||
|
|
||||||
|
Le istruzioni dei moduli diventano frammenti sorgente sotto
|
||||||
|
`harness/.pi/skills/tht-sessione/modules/`. `SKILL.md` rimane nel percorso attuale come proiezione
|
||||||
|
generata, deterministica e committata.
|
||||||
|
|
||||||
|
Il generatore:
|
||||||
|
|
||||||
|
- usa una lista statica e ordinata di frammenti;
|
||||||
|
- non effettua discovery;
|
||||||
|
- produce output ripetibile;
|
||||||
|
- viene verificato da un test che fallisce se `SKILL.md` non coincide con i frammenti;
|
||||||
|
- nella prima estrazione deve riprodurre byte per byte il `SKILL.md` della baseline.
|
||||||
|
|
||||||
|
Il gate continua a leggere e iniettare `SKILL.md` come oggi. I reference document che il modello
|
||||||
|
legge durante le fasi, inclusi `rewriting.md`, `cte.md` e `sql-generation.md`, mantengono in questa
|
||||||
|
milestone percorso e comportamento correnti. Non viene introdotta composizione dinamica al runtime.
|
||||||
|
|
||||||
|
## 11. Capability e sicurezza
|
||||||
|
|
||||||
|
Ogni modulo riceve un oggetto di capability specifico, costruito dal core. Non esiste
|
||||||
|
`ModuleContext` universale.
|
||||||
|
|
||||||
|
Le capability JavaScript ammissibili, assegnate nel sottoinsieme minimo necessario, sono:
|
||||||
|
|
||||||
|
- esecuzione controllata della CLI;
|
||||||
|
- emissione e attesa di una UI request;
|
||||||
|
- registrazione di una decisione;
|
||||||
|
- lettura della fase corrente;
|
||||||
|
- avanzamento o chiusura della fase;
|
||||||
|
- notifica al reviewer.
|
||||||
|
|
||||||
|
Le dipendenze Python ammissibili sono repository di sessione, port Evidence, vector store,
|
||||||
|
embedder e clock, soltanto per i moduli che li usano. Le dipendenze TypeScript Evidence comprendono
|
||||||
|
accesso controllato a filesystem, process runner e stato del preprocessing.
|
||||||
|
|
||||||
|
Un modulo non crea direttamente factory globali, non legge configurazione globale e non accede
|
||||||
|
all'implementazione di un altro modulo. Somiglianze fra due oggetti di capability non giustificano
|
||||||
|
la loro unificazione.
|
||||||
|
|
||||||
|
Restano esclusivamente nel gate core:
|
||||||
|
|
||||||
|
- hook anti-bypass;
|
||||||
|
- input lock e steering del testo libero;
|
||||||
|
- kickoff di nuova sessione e resume;
|
||||||
|
- protezione dei file e del codice del gate;
|
||||||
|
- `agent_end` safety;
|
||||||
|
- tool reviewer generici;
|
||||||
|
- enforcement dei codici di uscita e delle regole condivise.
|
||||||
|
|
||||||
|
I moduli non registrano hook globali e non ricevono accesso diretto a filesystem o ledger. Tutte le
|
||||||
|
mutazioni passano dalle capability controllate.
|
||||||
|
|
||||||
|
## 12. Failure semantics
|
||||||
|
|
||||||
|
Il refactoring conserva anche gli stati intermedi oggi osservabili, non soltanto gli happy path.
|
||||||
|
|
||||||
|
Esempi vincolanti:
|
||||||
|
|
||||||
|
- Memory continua a salvare nel vector store prima di registrare `memory_promoted`; se la seconda
|
||||||
|
operazione fallisce, conserva le attuali istruzioni di recupero;
|
||||||
|
- `rewrite_question` continua a scrivere la domanda, poi il ledger e infine ad avanzare F3;
|
||||||
|
- codici di uscita 5 e 6 conservano il significato corrente per il gate;
|
||||||
|
- retry, resume e finalizzazione continuano a reagire agli errori nello stesso modo;
|
||||||
|
- materializzazione Evidence e checkpoint del preprocessing conservano gli attuali stati di
|
||||||
|
successo, attesa e fallimento.
|
||||||
|
|
||||||
|
Migliorare atomicità, retry o messaggi richiede un ticket funzionale successivo.
|
||||||
|
|
||||||
|
## 13. Sequenza di estrazione
|
||||||
|
|
||||||
|
L'ordine obbligatorio delle slice è:
|
||||||
|
|
||||||
|
1. aggiungere i test di caratterizzazione mancanti senza spostare codice;
|
||||||
|
2. estrarre Memory e introdurre il pattern di capability specifiche;
|
||||||
|
3. estrarre Disambiguation e la composizione deterministica delle istruzioni;
|
||||||
|
4. consolidare Evidence lato Python;
|
||||||
|
5. consolidare Evidence lato TypeScript;
|
||||||
|
6. ripulire il core, rimuovere shim e verificare l'assenza di duplicazioni.
|
||||||
|
|
||||||
|
Ogni slice deve essere un commit verificabile e revertibile. Gli shim di re-export sono ammessi fra
|
||||||
|
due commit per mantenere il repository verde, ma devono sparire entro la milestone, salvo che
|
||||||
|
proteggano un import dimostrabilmente consumato fuori dal repository.
|
||||||
|
|
||||||
|
Non si eseguono le tre estrazioni in parallelo: Memory stabilisce il pattern, Disambiguation lo
|
||||||
|
applica al gate e alle istruzioni, Evidence chiude il lavoro più ampio e cross-runtime.
|
||||||
|
|
||||||
|
## 14. Strategia di caratterizzazione
|
||||||
|
|
||||||
|
### 14.1 Catalogo dei contratti
|
||||||
|
|
||||||
|
Prima della prima estrazione viene committato un catalogo leggibile dei contratti congelati. Ogni
|
||||||
|
voce collega:
|
||||||
|
|
||||||
|
- comportamento protetto;
|
||||||
|
- owner corrente e owner risultante;
|
||||||
|
- fixture o golden;
|
||||||
|
- test che lo verifica;
|
||||||
|
- tipo di uguaglianza richiesto.
|
||||||
|
|
||||||
|
Si usano fixture e golden leggibili per payload strutturati. Gli hash sono riservati a contenuti
|
||||||
|
testuali grandi, come il prompt Pi. Non viene introdotto un unico manifest opaco di hash.
|
||||||
|
|
||||||
|
### 14.2 Matrice minima delle sessioni
|
||||||
|
|
||||||
|
La matrice di caratterizzazione comprende:
|
||||||
|
|
||||||
|
- F1 con chiarimento approvato;
|
||||||
|
- F1 con ambiguità lasciata aperta;
|
||||||
|
- F2 con memory applicata;
|
||||||
|
- F2 con memory rifiutata;
|
||||||
|
- F2 senza memory;
|
||||||
|
- F3 con domanda riscritta e assunzioni;
|
||||||
|
- Evidence usata nello schema linking;
|
||||||
|
- Evidence esplicitamente accettata e scartata;
|
||||||
|
- sessione legacy senza corpus canonico;
|
||||||
|
- F8 con candidati promossi;
|
||||||
|
- F8 con candidati rifiutati;
|
||||||
|
- F8 senza candidati;
|
||||||
|
- resume nelle fasi interessate;
|
||||||
|
- repository filesystem e PostgreSQL dove la semantica differisce;
|
||||||
|
- failure path e recuperi elencati nella sezione 12.
|
||||||
|
|
||||||
|
Per ogni fixture devono restare uguali documenti, ledger, stato, tool, payload, sequenza CLI ed
|
||||||
|
eventi osservabili.
|
||||||
|
|
||||||
|
### 14.3 Gate per ogni slice
|
||||||
|
|
||||||
|
Ogni estrazione richiede:
|
||||||
|
|
||||||
|
- uguaglianza esatta dei payload deterministici;
|
||||||
|
- stessi tool registrati e stessi schemi TypeBox;
|
||||||
|
- stessa sequenza CLI e stesso comportamento d'errore;
|
||||||
|
- stessi artefatti e ledger per fixture equivalenti;
|
||||||
|
- test della façade con capability fake;
|
||||||
|
- suite completa del layer interessato;
|
||||||
|
- nessun aggiornamento non spiegato dei golden;
|
||||||
|
- nessun nuovo gate, turno Pi o I/O esterno.
|
||||||
|
|
||||||
|
I vecchi test di helper possono essere eliminati soltanto quando la stessa proprietà è coperta
|
||||||
|
attraverso la nuova façade. I test non devono restare permanentemente duplicati su entrambi i lati
|
||||||
|
del seam.
|
||||||
|
|
||||||
|
### 14.4 Gate finale
|
||||||
|
|
||||||
|
La milestone richiede:
|
||||||
|
|
||||||
|
- suite completa Python del harness;
|
||||||
|
- suite JavaScript completa del gate;
|
||||||
|
- suite, typecheck e build di backend e frontend;
|
||||||
|
- test di caratterizzazione e contract test completi;
|
||||||
|
- verifica delle sessioni legacy;
|
||||||
|
- `git diff --check`;
|
||||||
|
- un E2E live completo dalla nuova domanda alla finalizzazione;
|
||||||
|
- nel live E2E, almeno un percorso Evidence, un percorso Memory e una ripresa di sessione.
|
||||||
|
|
||||||
|
Il live E2E è eseguito una volta alla fine, non dopo ogni slice. Se ambiente, DWH o credenziali non
|
||||||
|
sono disponibili, l'automazione può risultare verde ma la milestone resta con gate manuale
|
||||||
|
pendente e non è dichiarata completa.
|
||||||
|
|
||||||
|
## 15. Budget operativo
|
||||||
|
|
||||||
|
Per una fixture deterministica, prima e dopo il refactoring devono coincidere:
|
||||||
|
|
||||||
|
- numero e ordine dei widget reviewer;
|
||||||
|
- numero e ordine dei comandi `tht`;
|
||||||
|
- numero di turni Pi necessari;
|
||||||
|
- query a DWH, Qdrant ed Evidence;
|
||||||
|
- avanzamenti di fase;
|
||||||
|
- retry e percorso di resume.
|
||||||
|
|
||||||
|
Sono ammesse soltanto differenze trascurabili di import e startup locale. Non è ammesso nuovo I/O
|
||||||
|
esterno. Il fake runtime deve registrare comandi e interazioni in modo che il budget sia verificato
|
||||||
|
automaticamente.
|
||||||
|
|
||||||
|
## 16. Criteri di accettazione
|
||||||
|
|
||||||
|
Il refactoring è accettato soltanto quando:
|
||||||
|
|
||||||
|
1. esistono moduli profondi Disambiguation, Memory ed Evidence secondo questa ownership;
|
||||||
|
2. non esistono moduli Admission o Datamart introdotti dalla milestone;
|
||||||
|
3. `tht-gate.js` contiene solo composizione e responsabilità realmente condivise;
|
||||||
|
4. una modifica interna tipica richiede interventi nel modulo e nei suoi test, non nel core;
|
||||||
|
5. nessun modulo importa l'implementazione di un altro;
|
||||||
|
6. non esiste un contratto universale, registry o discovery di moduli;
|
||||||
|
7. `SKILL.md` è generato dai frammenti e inizialmente byte-identico alla baseline;
|
||||||
|
8. tutti i contratti congelati e il budget operativo risultano invariati;
|
||||||
|
9. sessioni esistenti, legacy e riprese producono gli stessi risultati;
|
||||||
|
10. failure semantics e recuperi correnti sono preservati;
|
||||||
|
11. tutti i gate automatizzati e il gate live finale sono verdi;
|
||||||
|
12. non restano shim temporanei, codice duplicato, cartelle vuote o fonti istruzionali divergenti;
|
||||||
|
13. frontend, SSE, widget, CLI e formati persistiti non hanno richiesto modifiche funzionali.
|
||||||
|
|
||||||
|
## 17. Lavoro successivo
|
||||||
|
|
||||||
|
Dopo l'accettazione potranno essere progettati separatamente:
|
||||||
|
|
||||||
|
- Admission e la policy dei tre tentativi;
|
||||||
|
- evoluzione funzionale di Disambiguation;
|
||||||
|
- nuovo contratto di consumo Evidence per una F1 ridisegnata;
|
||||||
|
- evoluzione del contratto Disambiguation → Memory;
|
||||||
|
- Datamart intelligente, dbt o automazioni ETL;
|
||||||
|
- miglioramenti di atomicità e recovery emersi durante la caratterizzazione.
|
||||||
|
|
||||||
|
Nessuno di questi elementi può essere anticipato nel refactoring sotto forma di scaffold,
|
||||||
|
astrazione o comportamento dormiente.
|
||||||
Reference in New Issue
Block a user