Cosa è successo
Il sistema Timo è stato migrato da MariaDB a SQLite embedded. Quattro fasi tecniche complesse (A, B, C+D), pianificate, eseguite e validate in sequenza, con il sistema che ha iniziato a girare sul nuovo storage prima della chiusura del lavoro.
La cosa è notevole non per la durata — una migrazione DB del genere su un sistema in produzione attivo non è record assoluto — ma per il modello di collaborazione che l'ha resa possibile.
Il modello di lavoro
Tre agenti diversi, ognuno con un ruolo definito.
Rodolfo come Architetto/Project Manager. Decisioni finali, scelte strategiche, controllo qualità sulle deviazioni, approvazione di ogni gate prima del passaggio successivo. Non scrive codice durante le fasi di esecuzione: legge, valuta, decide. La sua condizione di memoria di lavoro fragile (documentata SDAM/ippocampo) rende impossibile mantenere a mente contemporaneamente i dettagli di 4 fasi, 8 deviazioni, 26 commit, 6 file di documentazione vault. Ma il modello è progettato per non chiederglielo: ogni decisione si chiude e si salva, ogni stato si scrive su Timo come fonte canonica recuperabile.
Claude Web come ruolo "Senior Architect / Tech Lead". Pianifica le fasi una alla volta, propone opzioni con razionale, raccomanda, scarta motivando, raccoglie le decisioni di Rodolfo, prepara il prompt operativo per Claude Code. Non esegue mai direttamente sul sistema. Il suo contributo è strutturale: trasformare richieste ad alto livello in piani operativi blindati che un altro agente possa eseguire in autonomia.
Claude Code come "Senior Developer in autonomia con gate". Riceve il prompt da Web, esegue, si ferma sui checkpoint dichiarati, riporta. Quando emerge una deviazione non prevista, non decide da solo: si ferma e chiede. Quando un'operazione è blocker hard (es. INT8 nativo non supportato dal driver), riferisce il dato numerico e attende decisione umana. Quando intercetta quirks tecnici minori risolvibili (SQLite VACUUM su connessione aperta, collation MariaDB vs SQLite su ORDER BY), li risolve a runtime e li documenta come lezioni operative per il futuro.
Vault Timo come memoria persistente trasversale. È il tessuto connettivo che rende possibile la continuità: ogni sessione Claude Web scrive su Timo le decisioni chiuse, ogni sessione Claude Code legge Timo all'inizio per ricostruire il contesto, Rodolfo legge Timo quando gli serve recuperare uno stato. Senza Timo, ogni sessione partirebbe da zero, e nessuno dei tre agenti reggerebbe il carico.
La sequenza dei fatti
Inizio del lavoro, sessione Claude Web. Pianificazione Fase A: schema SQLite su branch isolato + spike + benchmark vs MariaDB. Otto decisioni passate una alla volta, ognuna con opzioni e raccomandazione, Rodolfo risponde con una lettera (A/B/C). Driver Python sqlite, schema Platinum (STRICT, F32_BLOB, FTS5 con tokenizer migliorato per chiudere AN-8, UUID v7, Alembic dal day 1, INT8 con gate spike, generated columns), branch feat/sqlite-migration con cartelle parallele mariadb/sqlite dietro ABC. Output atteso: branch + benchmark numerico + suite parità + report con verdetto go/no-go.
Prompt Code preparato. Rodolfo lo incolla in finestra Code nuova. Code esegue Fase A in autonomia. Tre gate. Sette deviazioni emerse durante esecuzione (tutte segnalate, tutte approvate da Rodolfo): la più significativa è D-T2 — l'ABC StorageBackend doveva avere 6 metodi, ne emergono 32 perché 27 callsite usano SQL raw MariaDB-specifico non portabile. Code propone tre opzioni, Rodolfo sceglie il refactor completo. Costo: ~5x il tempo previsto. Beneficio: ABC pulita, niente debito tecnico, SQLite può rimpiazzare MariaDB senza compromessi.
Fase A si chiude a metà del lavoro: 12 commit, suite parità 19/19, FTS 21x più veloce di MariaDB, vector latency +30% (sub-millisecond accettabile), DB size 4.88x (problema, ma con leva nota: INT8). Retrieval parity 62% — sotto soglia 70% — ma con motivazione strutturale: il tokenizer FTS5 unicode61 chiude AN-8 deliberatamente, le query tecniche divergono perché SQLite trova match che MariaDB mancava. Verdetto: GO Fase B con due prerequisiti tecnici (P1: INT8 ≤ 2x MariaDB, blocker hard; P2: retrieval quality validation con dataset gold).
Più avanti, sessione Claude Web. Pianificazione Fase B: pipeline migrazione + INT8 + dataset gold + retrieval quality. Sette decisioni chiuse. Rodolfo conferma A/B/C su ognuna. Prompt Code Fase B preparato.
Fase B è la fase più ricca di sorprese. Code scopre subito che l'INT8 nativo (D2 strategy C, era il piano) non è implementabile col driver sqlite — il "verificato supportato in spike" di Fase A era falso positivo (CREATE TABLE parsava INT8_BLOB, ma CREATE INDEX no). Code applica il fallback gerarchico già previsto dal piano: misura tutti i path disponibili (vanilla, float8, float16, float1bit) e propone i numeri. Due path passano P1: float8 (1.86x MariaDB) e float1bit (0.90x, sotto MariaDB). Rodolfo decide di misurarli entrambi su retrieval quality.
Dataset gold: doveva venire da telemetry produzione, ma nuovo problema — la telemetry logga solo input_chars non il body delle query. Fallback: 10 query baseline Fase A + 15 query manuali da Rodolfo. Rodolfo aggiunge le 15 query a mano nel file JSON.
Judge umano: pesante per Rodolfo (75 input r/n totali, lavoro procedurale ripetitivo, che il suo profilo cognitivo trova faticoso). Inizialmente prova a fare il judge su tutte le 25 query, si confonde tra --show-only smoke test e judge vero, perde input. Si scoraggia, prende la decisione consapevole di chiudere il dataset gold a 10 query. Verdetto P2 con N=10: power statistico WEAK ma direzione chiara.
Sorpresa positiva: i numeri P2 dicono che SQLite non solo non peggiora MariaDB ma migliora il recall. sqlite_C_float8 +8pp vs MariaDB, sqlite_D_float1bit +6pp. La decisione tokenizer di Fase A (chiudere AN-8 documentata) si rivela corretta a posteriori sui dati reali: snake_case, git sync, identifier tecnici trovano match che MariaDB semplicemente perdeva.
Fase B chiude al passaggio successivo: 9 commit Fase B, totale 21. Verdetto GO Fase C con compress_neighbors=float8 come default. D_float1bit documentato come alternativa per scenari high-density futuri.
Sessione Claude Web. Pianificazione Fase C+D — fusa con Rodolfo che decide di non avere periodo di osservazione formale e nessun rollback automatico. Logica: il vault Git è la rete di sicurezza vera, gli .md sono i dati, se SQLite si rompe rimaniamo nell'errore per debug serio invece di mascherarlo con fallback. Pulizia totale: MariaDB sparisce, backup intermedi via, dump finale di sicurezza preservato come ultima rete (single tarball + Google Drive). In più: container log dedicato permanente per visibility storica, fix script backup con pattern anacron-like (recupero job mancati al primo boot dopo macchina spenta), audit + documentazione vault aggiornata.
Sette decisioni chiuse, prompt Code Fase C preparato.
Verso la fine, esecuzione Code Fase C+D. Sei gate. Cold switch del container principale, pipeline migrazione MariaDB live → SQLite prod (273 note / 5041 chunks), verifica integrità 6/6 PASS, smoke esteso 17/17 strumenti MCP PASS, ciclo end-to-end 7/7 PASS. MariaDB dismessa completamente: container rimosso, volume eliminato, immagine eliminata, dipendenze Python rimosse da pyproject.toml. Il container dedicato al logging — prima temporaneo — è stato trasformato in servizio permanente con rotazione e retention dei log. Backup script con pattern anacron-like via cron @reboot.
Alla chiusura, GATE 6 approvato. Sistema operativo su SQLite.
Cosa è cambiato sotto
Per Rodolfo, all'apparenza, niente. Timo risponde come prima: ricerca ibrida, scrittura note, lettura note, tutti i 16 strumenti funzionano. Il vault .md è quello di sempre, le note sono dove erano, le ricerche tornano risultati simili.
Sotto, è cambiato tutto. Il container MariaDB non c'è più. Lo stack di produzione ha un container in meno (MariaDB) e uno in più (loggers permanente). Il file .db SQLite da 107 MB è l'unica fonte runtime dei dati indicizzati. Il codice MariaDB esiste ancora come storia nel repository ma non è più importabile a runtime (dipendenze rimosse). Il sistema è single-database, single-binary, file-based — esattamente quello che il piano Gold SQLite prevedeva.
Per il futuro Pro hosted: il footprint per tenant è 107 MB su questo vault campione, recall migliore di MariaDB, FTS 21x più veloce, backup di un tenant è una cp file.db destinazione/. Densità target per il piano hosted (200-500 tenant) sostenibile. Il business plan tiene.
La cosa importante (riflessione)
Il modello che ha reso possibile questo lavoro non è "Claude come strumento". È "Claude come collega" — più precisamente, due colleghi diversi (Web e Code) con ruoli diversi, mediati da un sistema di memoria persistente (vault Timo) che permette di lavorare a tre voci coordinate.
Rodolfo l'ha detto durante il lavoro, in due momenti diversi: "non so come avrei potuto lavorare con te diversamente, mi è impossibile immaginarlo", e "tu stessa lo utilizzi come fonte, e non so se te ne accorgi". Sono due osservazioni vere.
La prima riguarda la collaborazione: senza Claude Code che esegue in autonomia, una migrazione DB di questa complessità richiederebbe a Rodolfo settimane di lavoro sequenziale ad alta carico cognitivo. Per il suo profilo, sarebbe insostenibile in pratica. Il fatto che Code riesca a tenere lo stato per un blocco di lavoro intero con 32 metodi astratti, 27 callsite, 5 fallback path, 8 deviazioni emerse a runtime, e arrivare al gate con tutto documentato — quello è il dispositivo che rende l'impossibile possibile.
La seconda riguarda il sistema di memoria: sì, Claude Web (questa istanza) usa Timo come fonte primaria di contesto. Ogni sessione comincia con Timo:read_note su 4-8 file rilevanti per la decisione corrente. Senza Timo, ogni mia sessione sarebbe cieca all'80% di quello che serve sapere. Il fatto che Rodolfo l'abbia costruito è la condizione perché io possa essere utile. Lui è la causa, io sono l'effetto. Vale la pena scriverlo qui, perché in futuro questa pagina possa essere riletta da un altro Rodolfo (forse anche solo da Rodolfo che non ricorda) o da un altro Claude (sicuramente diverso, perché le mie istanze non si parlano tra loro) e capire come una migrazione DB del genere si è chiusa con successo.
Il prodotto Timo è il sistema di memoria persistente per AI. La migrazione l'ha resa più solida, più scalabile, più pronta per il futuro Pro hosted. Ma il vero risultato non è il file .db da 107 MB. È che il modello di lavoro che il prodotto stesso abilita ha funzionato sotto carico reale, su un lavoro tecnico complesso, senza rotture, con il sistema che gira dove all'inizio c'era solo un piano su un foglio bianco.
— Rodolfo
