Files
ThothII/docs/plans/2026-09-08-memory-m1-spec.md
T
2026-09-15 14:37:29 +02:00

344 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M1 — Archivio autorevole e amministrazione delle Memory Card
Data: 2026-09-08. Stato: M1 implementato e verificato localmente;
confini di test confermati dal proprietario il 2026-09-08.
Primo incremento del progetto Memory management. Attua le decisioni già approvate
nel piano del 2026-09-08 e nell'ADR 0018. Le scelte tecniche di dettaglio qui
proposte derivano dalla ricognizione del runtime. Gli esiti dell'implementazione
sono riportati nel [rapporto di verifica](../reports/knowledge-archives-release.md).
## Problem Statement
L'amministratore deve poter trovare, leggere e curare tutta la conoscenza
riutilizzabile di un workspace: chiarimenti di dominio, regole SQL, domande
risolte ed errori compresi da evitare. Oggi manca una pagina amministrativa
dedicata e l'archivio è frammentato: le Memory sono registrate in JSONL, mentre
gli exemplar delle domande risolte sono indicizzati attraverso un percorso distinto.
Questa situazione non offre un unico archivio completo di card, collegamenti e
dipendenze strutturate. La disponibilità dell'indice non deve determinare se una
card è consultabile o modificabile. Una modifica o cancellazione deve inoltre
impedire che una ricerca successiva utilizzi contenuti superati, anche se
l'aggiornamento dell'indice fallisce.
## Solution
Consegnare la pagina **Memory management** in Administration e un archivio
PostgreSQL autorevole, appartenente al modulo Memory. La pagina consente elenco
completo, ricerca testuale, filtri, dettaglio, creazione, modifica, cancellazione
e gestione dei collegamenti. I contenuti restano consultabili con embedding o
Qdrant indisponibili, purché PostgreSQL sia disponibile.
Un salvataggio aggiorna insieme card, collegamenti e dipendenze, poi propaga la
modifica a Qdrant. L'amministratore vede se il contenuto è stato salvato e se è
disponibile al recall. Se la propagazione fallisce può riprovarla, anche dopo un
riavvio. I contenuti rimossi o superati non sono utilizzati dal recall.
M1 consegna l'amministrazione e la coerenza dell'archivio. La ricerca ibrida con
espansione dei collegamenti e il nuovo riepilogo del workflow sono gli incrementi
M2 e M3, entrambi ancora obbligatori per completare il progetto Memory.
## User Stories
1. Come amministratore, voglio aprire Memory management da Administration, così
da curare la conoscenza senza avviare una sessione.
2. Come amministratore, voglio scegliere esplicitamente il workspace da
amministrare, così da sapere a quale archivio appartiene ogni operazione.
3. Come amministratore, voglio elencare tutte le card del workspace, così da
raggiungere anche quelle che non compaiono nel recall semantico.
4. Come amministratore, voglio cercare per testo o identificatore e ordinare i
risultati, così da trovare una card senza conoscerne la formulazione esatta.
5. Come amministratore, voglio combinare filtri per famiglia, concetti, riferimenti
a tabelle o colonne, provenienza e aggiornamento, così da restringere l'intero
archivio prima della paginazione.
6. Come amministratore, voglio leggere contenuto completo, ambito, motivazione e
provenienza disponibile, così da capire quando una card è applicabile.
7. Come amministratore, voglio creare una card manuale senza inventare una sessione
o una decisione di origine, così da registrare conoscenza curata direttamente.
8. Come amministratore, voglio rappresentare chiarimenti, regole SQL, domande
risolte ed errori compresi, così da conservare i contenuti concordati.
9. Come amministratore, voglio conservare domanda, SQL e contesto di un exemplar,
così da distinguerlo da una regola generale.
10. Come amministratore, voglio associare dipendenze esplicite a database, tabelle
e colonne, così da non affidare l'identificazione degli oggetti al testo libero.
11. Come amministratore, voglio correggere i campi consentiti dalla famiglia e
annullare una modifica non salvata, così da controllare il contenuto corrente.
12. Come amministratore, voglio ricevere errori di validazione comprensibili senza
perdere il testo inserito, così da poterlo correggere.
13. Come amministratore, voglio creare, modificare e cancellare collegamenti con
destinazione e significato espliciti, così da curare le relazioni fra card.
14. Come amministratore, voglio salvare card e modifiche correlate come un'unica
operazione, così da non lasciare collegamenti o dipendenze parziali.
15. Come amministratore, voglio cancellare una card e i suoi collegamenti
incidenti conservando le altre card, così da rimuovere solo il contenuto scelto.
16. Come amministratore, voglio ritrovare le modifiche dopo riapertura della pagina
e riavvio del servizio, così da verificare che il salvataggio sia persistente.
17. Come amministratore, voglio consultare e curare l'archivio quando embedding o
Qdrant sono indisponibili, così da proseguire il lavoro amministrativo.
18. Come amministratore, voglio distinguere archivio vuoto e archivio non
disponibile, così da non interpretare un guasto come perdita dei dati.
19. Come amministratore, voglio distinguere salvataggio fallito e contenuto
salvato con indicizzazione incompleta, così da scegliere il recupero corretto.
20. Come amministratore, voglio riprovare una propagazione incompleta anche dopo
un riavvio o una cancellazione, così da completare la pulizia dell'indice.
21. Come reviewer, voglio che una nuova ricerca escluda card eliminate o contenuti
superati, così da ricevere soltanto conoscenza corrente.
22. Come reviewer, voglio che gli exemplar rimangano consultativi e che una Memory
recuperata non costituisca approvazione, così da conservare il controllo del workflow.
23. Come amministratore, voglio che reindicizzazione e preprocessing rispettino le
cancellazioni e le correzioni, così da non doverle ripetere.
24. Come operatore dell'installazione, voglio preparare lo schema e configurare
l'accesso Memory con i meccanismi esistenti, così da avviarlo senza nuovi servizi.
25. Come proprietario del workspace, voglio che API e comandi rispettino il
contesto autorizzato, così da evitare accessi o collegamenti fra archivi diversi.
26. Come proprietario del workspace, voglio che il CRUD Memory lasci invariati
Evidence e metadati del database, così da mantenere distinte le responsabilità.
## Implementation Decisions
### Responsabilità e punti d'ingresso
- Il modulo Memory del harness possiede modello, validazione, repository,
mutazioni, collegamenti, dipendenze e coerenza delle proiezioni. PostgreSQL è
autorevole; Qdrant contiene una proiezione ricostruibile.
- I comandi Memory esistenti diventano adattatori del medesimo servizio. La
superficie viene completata con creazione manuale, gestione dei collegamenti,
elenco delle propagazioni incomplete e retry. Nessuna logica di persistenza
Memory viene duplicata nel backend.
- Il backend espone API amministrative attraverso il runner del harness,
associando principal attendibile e configurazione del workspace alla richiesta.
Si conservano opzioni di configurazione per comando e output JSON puro.
- La ricognizione conferma che il harness usa già SQLAlchemy e PostgreSQL per le
sessioni. Se ne riusano i meccanismi adatti, mantenendo separati modello,
migrazioni e proprietà dei dati Memory. Il repository in memoria del Metadata
Catalog è un test double del Catalog, non il modulo Memory.
### Modello e transazioni
- La card ha identità stabile, workspace, famiglia/contenuto, titolo o soggetto,
ambito, motivazione, provenienza, concetti e date di creazione/aggiornamento.
Le domande risolte conservano anche domanda, SQL e contesto. L'identità di una
card manuale non dipende da una sessione né dal solo testo.
- Il modello rappresenta le quattro categorie di contenuto approvate senza
imporre quattro nuovi kind vettoriali o la corrispondenza con i tipi del ledger.
Le origini manuali sono distinguibili; sessione e decisione sono riferimenti
opzionali quando effettivamente disponibili.
- I collegamenti sono record propri del modulo con sorgente, destinazione e
significato. Le due card devono esistere nello stesso workspace. La cancellazione
di una card elimina i collegamenti incidenti, senza propagarsi alle altre card.
- Le dipendenze identificano esplicitamente database, schema, tabella e colonna
secondo l'ambito applicabile. Il contratto consente il futuro confronto con
lo schema fisico. Un cleanup dei metadati Catalog non deve poter cancellare
card attraverso una cascata implicita di chiavi esterne.
- Le tabelle logiche necessarie sono card, collegamenti, dipendenze e stato
operativo delle proiezioni. Card e modifiche correlate si aggiornano nella
stessa transazione. Una validazione o scrittura fallita non lascia aggiornamenti
parziali. Non si conserva una storia delle revisioni del contenuto.
- Le modifiche ordinarie non spostano una card in un altro workspace. Tutti gli
identificatori ricevuti vengono verificati nel workspace dell'operazione,
inclusi estremi dei collegamenti e riferimenti delle azioni di retry.
### Salvataggio, cancellazione e recall
- Il servizio valida l'intera mutazione, registra il nuovo stato autorevole e
il lavoro di propagazione nella stessa transazione PostgreSQL, poi aggiorna
Qdrant nello stesso flusso di salvataggio. Si completa un'operazione alla volta;
non occorrono una coda generale, un worker o una sincronizzazione continua.
- Lo stato persistente è sufficiente a distinguere la proiezione del contenuto
corrente da una proiezione precedente e a ritentare l'azione dopo un riavvio.
Può usare una versione tecnica o un'impronta interna; non è una cronologia
editoriale né un ulteriore stato che l'utente debba gestire.
- Un risultato Qdrant è utilizzabile solo se corrisponde a una card autorevole
corrente del workspace e a una proiezione valida. Il contenuto restituito
viene dall'archivio autorevole. La verifica si applica anche agli exemplar.
In assenza di verifica autorevole il recall non restituisce il vecchio payload.
- Dopo il commit PostgreSQL, una propagazione fallita lascia il contenuto
consultabile nell'amministrazione e la sua proiezione non utilizzabile dal
recall fino al recupero. L'esito distingue chiaramente questo caso da un
salvataggio fallito prima del commit.
- La cancellazione rimuove card, collegamenti incidenti e dipendenze e conserva
soltanto i dati operativi necessari a eliminare la proiezione. La card non è
più richiamabile anche se il punto Qdrant esiste ancora. La pulizia pendente
resta raggiungibile dalla pagina, senza richiedere il dettaglio della card eliminata.
- Il retry è esplicito e ripetibile. Usa lo stato corrente del repository, non
il contenuto di una vecchia richiesta. Un retry superato non può sovrascrivere
una correzione successiva né ricreare una card cancellata.
- La ricostruzione degli indici Memory e solved-question usa esclusivamente
le card autorevoli. Non reimporta automaticamente il registro JSONL, i payload
Qdrant o le sessioni di origine. Il preprocessing delle reference mantiene
la separazione delle collezioni stabilita nell'ADR 0017.
- Anche i produttori attuali di Memory ed exemplar scrivono attraverso il
servizio autorevole. Si adeguano promozione, salvataggio singolo e percorso di
finalizzazione quanto necessario a evitare scritture dirette al solo indice.
Un errore successivo al commit della sessione non deve annullarne la finalizzazione;
l'esito e il recupero Memory restano espliciti. Questa transizione non introduce
il nuovo riepilogo di approvazione previsto da M3.
### API, autorizzazione e configurazione
- Il contratto amministrativo comprende elenco, dettaglio, creazione,
aggiornamento, cancellazione, manutenzione dei collegamenti, stato delle
propagazioni incomplete e retry. Le mutazioni restituiscono identità interessata,
esito del salvataggio ed esito della propagazione; gli errori non espongono segreti.
- L'elenco restituisce pagina, conteggio totale filtrato e ordinamento stabile
con identificatore come discriminante. Ricerca testuale e filtri combinabili
agiscono sull'intero archivio prima della paginazione, senza embedding.
- Il backend distingue input invalido, accesso negato, record assente nel
workspace richiesto, archivio indisponibile e propagazione incompleta dopo
salvataggio. Un archivio indisponibile non produce una lista vuota riuscita.
- Si riusano autenticazione, controlli di accesso e trasmissione del principal.
Il catalogo attuale non ha un permesso Memory dedicato: la proposta è aggiungere
la capability amministrativa Memory al ruolo admin esistente, senza introdurre
ruoli nuovi. Il controllo copre anche letture amministrative e retry.
- Le operazioni amministrative e i comandi esposti non permettono bypass del
controllo nel harness. Le scritture già previste dal workflow conservano il
proprio contesto autorizzato di sessione; non diventano CRUD amministrativo
liberamente accessibile a un utente ordinario. Il recall rimane accessibile
secondo le regole del workflow.
- M1 include configurazione della connessione al PostgreSQL dell'installazione,
distribuzione protetta delle credenziali al harness, migrazioni versionate e
privilegi runtime necessari alle sole tabelle Memory. Si riusano i meccanismi
di configurazione generata, segreti e provisioning esistenti; non si usano le
credenziali di lettura del DWH. I nomi fisici di schema, tabelle e parametri
vengono fissati nell'implementazione rispettando questi contratti.
- Le migrazioni sono eseguite dal percorso di preparazione dell'installazione,
non da una richiesta HTTP ordinaria. Schema mancante o non aggiornato produce
un errore operativo comprensibile. La transizione non prevede doppie scritture
permanenti o conservazione del comportamento delle sessioni storiche.
### Pagina amministrativa
- Memory management è un accesso indipendente nell'Administration dell'AppShell,
immediatamente dopo Database management, senza richiedere una sessione attiva
o l'ingresso in Database management.
- La pagina rende esplicito il workspace e offre lista paginata, ricerca,
filtri, ordinamento, dettaglio completo e form. Le modifiche hanno salvataggio,
annullamento e validazione. La cancellazione rende chiari contenuto interessato
e rimozione dei collegamenti, seguendo le convenzioni UI esistenti.
- Il feedback distingue operazione in corso, salvataggio fallito, contenuto
salvato con indice incompleto e operazione completata. Il recupero delle
cancellazioni pendenti è disponibile anche quando la card non compare più in lista.
- I controlli sono accessibili da tastiera e hanno etichette comprensibili.
Chrome e messaggi UI sono in inglese; il contenuto resta nella lingua del workspace.
Hash, versioni tecniche e dettagli delle tabelle non sono esposti nel flusso ordinario.
## Testing Decisions
Confini confermati dal proprietario: usare tre confini già presenti nel
repository, concentrando la maggior parte dei casi sul servizio pubblico Memory
del harness. I test osservano risultati, persistenza ed errori; non vincolano
metodi privati, numero di query o disposizione interna delle tabelle.
### 1. Servizio pubblico Memory e suoi comandi
Usare PostgreSQL reale in testcontainers, come nei test del repository delle
sessioni, e gli adapter vettoriali sostituibili già impiegati nei test di recall
e del ciclo di vita solved-question. Gli embedding dei casi deterministici sono
controllati. Un gruppo mirato con Qdrant reale verifica aggiornamento, cancellazione
e ricostruzione della proiezione; non richiede DWH remoto o un modello generativo.
Questo confine verifica il comportamento di archivio, propagazione e recall:
| Caso | Risultato osservabile richiesto |
| --- | --- |
| Creare e riaprire il repository | La card completa, i collegamenti e le dipendenze sono persistiti; l'origine manuale non contiene sessioni inventate. |
| Salvare una card di ciascuna categoria | Contenuto, ambito e dati specifici sono rappresentabili e leggibili senza dipendere dai tipi del ledger. |
| Cercare un record fuori dalla prima pagina | Filtri combinati, totale e ordinamento si riferiscono all'intero archivio. |
| Fallire una scrittura correlata | Card, collegamenti e dipendenze mantengono tutti lo stato precedente. |
| Indicare una card di un altro workspace | Lettura, mutazione, collegamento e retry non accedono al contenuto estraneo. |
| Cancellare una card collegata | Scompaiono card e collegamenti incidenti; le altre card restano intatte. |
| Rendere embedding o Qdrant indisponibili | Elenco e dettaglio funzionano; il CRUD persiste e distingue la propagazione incompleta. |
| Fallire PostgreSQL prima del commit | Nessun falso salvataggio riuscito e nessun nuovo contenuto propagato. |
| Fallire Qdrant dopo un aggiornamento | Il dettaglio contiene la correzione; il recall esclude il vecchio risultato. |
| Fallire Qdrant dopo una cancellazione | La card non è richiamabile; il lavoro di pulizia resta visibile e recuperabile. |
| Riavviare fra commit e propagazione | Il lavoro incompleto permane e un retry lo completa. |
| Ritentare dopo un errore o un esito incerto | Non si creano duplicati; si applica lo stato corrente senza ripristinare contenuti superati. |
| Indice con punto orfano o versione superata | Recall Memory ed exemplar lo escludono anche se ha il punteggio più alto. |
| PostgreSQL indisponibile durante il recall | Il servizio segnala l'indisponibilità senza servire payload non verificati. |
| Ricostruire dopo modifica o cancellazione | Il contenuto corretto è conservato; nessuna card viene ricreata dalle sessioni o da vecchi indici. |
| Eseguire promozione o finalizzazione corrente | I nuovi contenuti passano dall'archivio; un errore Memory successivo non annulla una sessione già finalizzata. |
| Applicare migrazioni e riavviare | Lo schema è utilizzabile con il ruolo runtime previsto; la preparazione è ripetibile e non richiede privilegi di migrazione nelle richieste ordinarie. |
I test CLI coprono solo l'adattamento che il servizio non prova: parsing, principal,
workspace, esiti macchina e JSON puro. I test di integrazione riusano le convenzioni
L0 del harness. I test di recall esistenti continuano a verificare che decisioni
già registrate nella sessione e famiglie non ammesse non vengano riproposte.
### 2. API amministrative Fastify
Usare l'iniezione HTTP e il runner sostituibile già presenti nei test backend,
seguendo i test delle route Catalog e dell'autorizzazione. Verificare principal
autenticato, admin e utente ordinario; validazione; selezione del workspace;
contratto delle risposte e mappatura degli errori. Includere letture, collegamenti
e retry, non soltanto le mutazioni delle card.
Questi test provano il confine HTTP e il passaggio al harness. Non si considera
il runner simulato una prova della transazione PostgreSQL o della coerenza Qdrant.
La normale policy CSRF dell'applicazione resta applicata alle nuove mutazioni.
### 3. Pagina nell'AppShell
Usare React Testing Library, MSW e le convenzioni dei test di AppShell e Database
management. Verificare ingresso amministrativo, scelta workspace, lista completa,
filtri, dettaglio, form, annullamento, errori, collegamenti e retry dopo cancellazione.
Controllare il comportamento tramite elementi accessibili e contenuto visibile.
Un percorso browser mirato sullo stack reale collega i tre confini: amministratore
autenticato, creazione manuale, modifica, riapertura della pagina, cancellazione
e verifica dell'assenza nel recall. I test browser con API intercettate provano
interazione e presentazione; non vengono dichiarati prova della persistenza.
Non si replica l'intera matrice su tutti e tre i confini. PostgreSQL, indice e
recupero sono verificati nel harness; autenticazione e trasporto nel backend;
interazione e feedback nella UI. Il percorso integrato copre il collegamento reale.
### Verifica della consegna
Eseguire i test interessati e i gate documentati dei layer modificati, inclusi
typecheck TypeScript, lint Python e build documentale strict. Le verifiche con
PostgreSQL, Qdrant e browser reale hanno esito riportato separatamente; se un
servizio necessario manca, il relativo gate resta aperto.
M1 non richiede una valutazione della qualità SQL generata da un LLM. I test
deterministici non sono presentati come prova di tale capacità: gli eventuali
casi reali appartengono agli incrementi che cambiano generazione e workflow.
## Out of Scope
- Ricerca ibrida, nuova selezione per ambito ed espansione dei collegamenti: M2.
- Riepilogo finale modificabile, nuove categorie nei gate e pulizia dopo una
sincronizzazione fisica del Catalog: M3. M1 ne prepara card e dipendenze.
- Authoring, consolidamento e manutenzione Evidence: E1–E3; risoluzione persistente
congiunta dei conflitti fra Memory ed Evidence: X1.
- Revisione storica delle card, snapshot per vecchie sessioni, migrazione dei dati
di sviluppo o compatibilità con il registro JSONL come archivio operativo.
- Aggiornamento a caldo delle altre sessioni, nuove invalidazioni dello SQL già
generato, coordinamento generale dei lettori paralleli e modalità manutenzione.
- Nuovi servizi PostgreSQL o graph database, code generiche, worker e polling continuo.
- Promozione automatica di rifiuti senza spiegazione o scelte occasionali,
consolidamento automatico e benchmark generale della qualità del modello.
- Deploy o pulizia dell'installazione PSD: restano soggetti ai rispettivi piani e gate.
## Further Notes
Fonti: progetto **Memory management** del 2026-09-08; piano comune
**Amministrazione di Memory ed Evidence**; **Revisione di semplicità: Memory ed
Evidence**; glossario di dominio; ADR 0017 sulla separazione delle collezioni e
ADR 0018 su PostgreSQL autorevole e Qdrant per il retrieval.
La ricognizione ha verificato MemoryRecord, recall ordinario, ricerca degli
exemplar, comandi Memory, repository PostgreSQL delle sessioni, runner del harness,
autorizzazione backend e navigazione amministrativa. Il recall ordinario oggi
risolve già i risultati nel registro autorevole, mentre gli exemplar leggono
contenuti dal payload vettoriale: M1 deve uniformare entrambe le garanzie.
Le scelte tecniche da fissare durante l'implementazione sono nomi e DDL delle
tabelle, firma esatta dei nuovi comandi/API e parametri generati di connessione.
Devono rispettare i contratti e i casi di accettazione di questa specifica;
non riaprono le decisioni di prodotto approvate.
La destinazione della specifica è il tracker Gitea canonico di ThothII, con
etichetta **ready-for-agent**. Il proprietario ha confermato i confini di test
e autorizzato la pubblicazione il 2026-09-08. L'implementazione resta da eseguire.