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

22 KiB
Raw Blame History

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.

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.