Fogli, etti di pensieri sparsi

BugHunted Duranted

A(h)I A(h)I... Installazione / Set / Test / Report Bugs su #MATECLAW

Quattro specialità in un jolly. Un lavoro da Artistagiano: la tecnica non arriva dopo l’idea e l’arte non arriva dopo il lavoro. Si costruisce, si usa, si osserva; passando e ripassando il materiale si accantona, decanta, cambia funzione e diventa struttura.

Questa non nasce come recensione di MateClaw. Nasce mentre sto facendo altro.

Sto costruendo un Second Brain personale in Obsidian, Ologrammio. Voglio poterlo interrogare senza ridurlo a una cartella piena di file. Installo MateClaw, gli collego Ollama per gli embedding locali, gli do accesso in sola lettura al vault e costruisco un Employee dedicato. All’inizio si chiama Ologrammio Reader; poi capisco cosa deve fare davvero e lo rinomino Panoramio: non deve semplicemente leggere. Deve fare una panoramica sul materiale, attraversare nodi, documenti, rimandi, esperienze e fonti.

Nel frattempo, mentre il ponte prende forma, saltano fuori delle tegole storte.

Queste pagine sono i miei cartelli nel bosco: se qualcun altro passa di qui, magari evita di cozzarci o inciampare.


Accaduto, cosa stavo cercando di fare

La catena costruita è questa:

Obsidian / Ologrammio
        │
        │ filesystem source
        ▼
MateClaw Wiki KB (Lazy ingest)
        │
        │ embeddings locali
        ▼
Ollama / nomic-embed-text
        │
        │ semantic retrieval
        ▼
Panoramio — ReAct / Native Loop
        │
        │ OpenAI ChatGPT OAuth
        ▼
GPT-5.5

Obiettivo operativo:

materiale personale
→ indicizzazione
→ ricerca semantica
→ ricostruzione panoramica
→ fonti verificabili
→ nessuna scrittura autonoma nel vault

Governance voluta:

Panoramio cerca / legge / confronta / propone
        ↓
Scriba revisiona e corregge
        ↓
Josta approva
        ↓
solo dopo, eventualmente, si scrive

MateClaw non è autorizzato a creare, modificare o cancellare contenuti in Ologrammio.


Ambiente del laboratorio

Sorgente MateClaw ispezionato durante il bughunting: commit 6bbd3ac4dac0c04f00f6a95bde6689766f1c51e5.


Accadere, dal setup al Panoramio

1. MateClaw incontra Ologrammio

Il vault Obsidian viene configurato come source_directory della KB Ologrammio.

Con Lazy ingest MateClaw estrae, normalizza, chunkizza e indicizza i materiali senza dover generare preventivamente una pagina Wiki per ogni file. Questo è fondamentale: Panoramio deve poter interrogare il materiale indicizzato anche quando la Wiki compilata contiene solo poche pagine di sistema.

2. Ollama entra sotto il pavimento

Installazione locale di Ollama, API su:

http://127.0.0.1:11434

Modello embedding:

ollama pull nomic-embed-text

Test in MateClaw:

Passed · 768 dimensions

Da qui la ricerca semantica del vault non dipende da un embedding remoto.

3. Ologrammio Reader diventa Panoramio

Il nome precedente descriveva un’azione troppo piccola. Reader legge. Panoramio deve guardare il paesaggio.

Il suo compito operativo diventa:

Quando la regola panoramica entra in funzione, una singola domanda larga attiva una batteria di ricerche, Progress Ledger e raccolta di evidenze prima della risposta.

Evidenza E11, Panoramio apre il grandangolo: più Semantic Search KB, Progress Ledger e letture intermedie prima dell’output.


Qui il tempo al primo token cresce: non perché l’agente sia necessariamente bloccato, ma perché prima di parlare esegue più retrieval e organizza le prove.

Evidenza E14, Waiting for first token: latenza dopo retrieval multipli, prima dell’inizio dello streaming.


Cartello 1, il facendolo e il fatto compaiono insieme

Sintomo

Durante alcune risposte Wiki-grounded, la UI mostra:

  1. la risposta mentre viene streammata;

  2. la stessa risposta di nuovo dopo la finalizzazione.

In pratica il sistema espone contemporaneamente il facendolo e il fatto.

Non sono due database e non sono necessariamente due ricerche. È la stessa risposta che passa attraverso:

streaming
→ evidence/source normalization
→ finalization

Root cause isolata

In ReasoningNode.java:

String answerWithSources = accessor.sourceEvidenceLedger()
        .appendWikiSourceTable(accumulatedContent);

poi:

.contentStreamed(
    !evidenceInsufficient
    && Objects.equals(answerWithSources, accumulatedContent)
)

Se appendWikiSourceTable(...) modifica il testo aggiungendo o normalizzando le fonti, answerWithSources != accumulatedContent e lo stato finisce per dire che il contenuto non è stato streammato, anche se il corpo è già apparso a video.

In FinalAnswerNode.java il finalizer applica nuovamente:

finalAnswer = accessor.sourceEvidenceLedger()
        .appendWikiSourceTable(finalAnswer);

Il risultato può essere il replay completo del corpo.

Evidenza

Evidenza E02, Punto di sutura fra il primo output streammato e il replay finalizzato.


Report tecnico completo:


Cartello 2, il replay non è solo brutto: può cambiare il significato delle citazioni

Questo è il punto che trasforma un difetto visivo in un problema di provenance.

La risposta originale può avere una mappa coerente:

[1] CV_Giuseppe_Seu_Remote_IT_AI_v4.pdf
[2] LLM Evaluation CV IT.docx
[4] Lavori Svolti.txt
[5] ShiduLab.md
[8] ComboCode.md
...

Il corpo usa quei numeri correttamente.

Poi il finalizer ricostruisce una nuova tabella con ordine diverso:

来源:
[1] Lavori Svolti.txt
[2] CV_Giuseppe_Seu_Remote_IT_AI_v4.pdf
[5] Ha senso parlare del copyright dei Prompter_ _ Connect.gt.pdf
...

Il corpo però conserva i vecchi [n].

Quindi un [5] che nel testo significava ShiduLab.md può diventare, nella tabella finale, un PDF sul copyright dei prompt.

Il corpo non è cambiato; è cambiato il dizionario che interpreta i numeri.

Invariante che dovrebbe valere:

Se [n] è già stato emesso nel corpo, la finalizzazione deve preservare l’identità della sorgente n, oppure deve riscrivere atomicamente sia i marker nel corpo sia la tabella finale.

Evidenza E12, Risposta originale: corpo e mappa numerica delle fonti ancora coerenti prima della rimappatura del finalizer.


Cartello 3, 来源: attraversa il backend e finisce in italiano

Il blocco fonti canonico espone la stringa cinese:

来源:

La UI italiana/inglese se la ritrova tale e quale.

È un piccolo indizio architetturale molto utile: ciò che avrebbe dovuto essere un dettaglio interno di canonicalizzazione è diventato contenuto utente.

Possibili soluzioni:


Cartello 4, la conversazione può sedersi sulla propria eco

Accaduto

Creo in Obsidian una nuova nota:

Competenze linguistiche.md

Eseguo Scan in MateClaw:

added 1
status: COMPLETED

Torno nella conversazione già aperta e rifaccio la domanda. Panoramio risponde usando il grounding precedente e non lancia una nuova Semantic Search KB.

Apro una chat nuova, stessa domanda: la ricerca semantica parte immediatamente e trova la nuova nota.

Evidenza E01, Fresh chat: dopo il rescan della KB, una nuova conversazione rilancia Semantic Search e trova subito la nuova nota.


Stato

Riprodotto. Root cause non ancora isolata.

Ipotesi da verificare: interazione tra conversation history, prior tool evidence e decisione ReAct di non richiamare il retrieval dopo un cambio della KB.

Non viene attribuito senza prova a un generico “buffer della context window”.

Report tecnico:


Cartello 5, TXT supportato, ma UTF-16 cade dal ponte

Durante lo scan:

Scanned 46 files, added 11, skipped 34
Failed to import: Lavori Svolti.txt (Input length = 1)

Il file si apriva normalmente in Windows. Era codificato UTF-16.

Nel sorgente attuale, WikiDirectoryScanService.java legge i file testuali così:

String content = Files.readString(realFile, StandardCharsets.UTF_8);

Quindi il .txt è nominalmente supportato, ma lo scan assume UTF-8.

Workaround verificato:

Blocco note
→ Salva con nome
→ Codifica: UTF-8
→ sostituisci file
→ Scan
→ import riuscito

Non lo classifico ancora come vulnerabilità né come root-cause bug complesso: è un pitfall riproducibile di ingest e un buon candidato a charset detection / fallback esplicito.

Vedi:


Cartello 6, cinque cucchiaiate non fanno una panoramica

Il tool wiki_semantic_search dichiara:

@ToolParam(description = "Max results (default 5)", required = false) Integer topK

ed esegue:

int k = (topK != null && topK > 0) ? Math.min(topK, 20) : 5;

Per domande molto larghe, topK=5 può restituire pochi chunk e anche più chunk dello stesso documento. Il risultato sembra “intelligente”, ma può essere magro, parziale e sbilanciato.

La correzione lato Employee non richiede patch:

Il comportamento cambia radicalmente: invece del mestolino parte il grandangolo.


Cartello 7, Obsidian non è il magazzino: è l’Ologrammio

Non serve duplicare tutto il materiale creativo dentro Obsidian solo per renderlo interrogabile. MateClaw usa un filesystem source: una KB può puntare a una cartella normale.

La separazione che voglio mantenere è:

Ologrammio
→ nodi, mappe, relazioni, sintesi curate

Archivio creativo / professionale
→ documenti, testi, PDF, DOCX, materiale grezzo

Panoramio può essere legato a più KB e fare da sguardo trasversale.

Dentro Ologrammio metto invece ciò che deve diventare nodo: curriculum, competenze, Second Brain, FilosoVia, progetti, connessioni.

Evidenza E13, Curriculum e Competenze diventa un nodo-hub nel grafo Obsidian.


E quando il grafo cresce, quello che nei fumetti sembrava fantascienza diventa interfaccia domestica del pensiero:

Evidenza E10, Panoramio di Ologrammio: il grafo come mappa operativa di nodi e relazioni.

Una cosa che non è un bug, ma cambia il lavoro

La latenza al primo token va letta assieme al workflow.

Una query puntuale può fare una sola ricerca e rispondere presto. Una query panoramica può fare molte Semantic Search, aggiornare il Progress Ledger, leggere risultati intermedi e solo dopo iniziare a generare testo.

Quindi:

TTFT alto != automaticamente blocco

Va osservato insieme a:


Cose viste ma non ancora isolate

Raw Wiki-link HTML leakage

In una risposta semantica è comparso HTML interno del wikilink, ad esempio una forma tipo:

<a class="wiki-link" ...>VocabolAndiam</a>

Da separare dal bug del replay finché non viene dimostrato un percorso comune.

Conversation-state ↔ duplicate replay

Il replay non avviene su ogni singola query. In una fresh chat, dopo l’aggiunta di una nuova nota, una risposta è comparsa una sola volta. Lo stato conversazionale sembra avere un ruolo, ma la relazione causale va ancora dimostrata.


Il metodo Artistagiano

Il percorso reale non è stato:

leggere manuale
→ configurare tutto perfettamente
→ usare

È stato:

INSTALLARE
    ↓
SETTARE
    ↓
USARE
    ↓
OSSERVARE
    ↓
ROMPERE / FAR EMERGERE
    ↓
LEGGERE IL SORGENTE
    ↓
RIPRODURRE
    ↓
ISOLARE
    ↓
SCRIVERE IL CARTELLO
    ↓
TORNARE A COSTRUIRE

Installazione / Set / Test / Report Bugs non sono quattro reparti separati. Nel lavoro reale possono stare nella stessa persona e nella stessa ora.

Solo costruendo il ponte su cui si cammina, col materiale già usato. Passando e ripassando, accantonando e decantando.

Questo è il senso di BUGHUNTED DURANTED: non vado a caccia di bug come attività separata. Li incontro mentre sto facendo altro, li fermo, li guardo, li segno e continuo.

Un cartello non è il bosco.

Serve a chi ci passerà dopo.


Accadrà?

Le prove successive utili sono già implicite nei problemi trovati:

  1. test A/B maxIterations=6 vs 10 sullo stesso scenario, senza cambiare altro;

  2. test automatico stream → normalize → finalize che garantisca un solo corpo visibile;

  3. test atomico della mappa [n] → source dopo più wiki_semantic_search;

  4. invalidazione/versionamento del grounding conversazionale dopo KB rescan;

  5. charset detection o messaggio esplicito per .txt non UTF-8;

  6. test i18n del source-table header;

  7. test dedicato al leakage di raw Wiki-link HTML;

  8. misura TTFT correlata a numero di tool call e dimensione del retrieval.

Non è una sentenza sul progetto. È una fotografia del sistema mentre accade.

E per questo, più che una review, è una vivovedocronaca.

JostaDev 👀 #MateClaw

(Parte 2, il giorno dopo :D
Metriche alla mano…)
https://shidulab.github.io/BUGHUNTED-Duranted/


Articolo originale su Substack