observability — rendere visibile il sistema senza passare dai logUn sistema che si comporta come Metnos — pianificatore ReAct, synt che genera executor, mnestoma che cresce, vaglio che giudica, pairing che riconosce sender — produce parecchio stato. La dashboard di osservabilita' e' il modo per vedere quello stato senza aprire terminali, senza ispezionare SQLite a mano, senza grep sui log JSONL. Un singolo file HTML, una pagina che riassume tutto cio' che serve a un proprietario per capire dove e' arrivato il sistema.
La scelta architetturale e' deliberatamente non-live: niente server, niente WebSocket, niente JavaScript. Il file e' generato on demand da uno script Python che legge le stesse sorgenti dati autoritative del runtime, le trascrive in HTML, e si ferma. Aprire con browser locale.
| Sorgente | Cosa fornisce | Path |
|---|---|---|
| Mnestoma | Stats globali (totale mnest, active, proto, decaying, eventi), top-N attivi per peso, top-N proto-mnest in attesa di sintesi, ultimi 20 event cronologici. | ${METNOS_INSTALL_ROOT}/workspace/.mnestoma/mnest.sqlite (override MNESTOMA_DB_PATH) |
| Pairings | Pairing attivi (channel, sender_id, livello, paired_at, paired_by, last_seen) e numero di pairing revocati nello storico. | ~/.local/state/metnos/pairings.db |
| Turns | Ultimi 15 turni eseguiti dal pianificatore (timestamp, query utente, esito, numero step, prima riga della risposta). | ~/.local/share/metnos/turns/YYYY-MM-DD.jsonl |
| Vaglio | Ultime 20 decisioni del Vaglio (executor, score, blocked_by, motivazione abbreviata, ts). | ~/.local/share/metnos/vaglio/YYYY-MM.jsonl |
| Scheduler | Task builtin del runtime (apply_ager, synt_suggest, …), schedule, ultima esecuzione, esito. |
~/.local/share/metnos/scheduler/state.sqlite |
| Test framework | Numero moduli, numero test case, distribuzione last_status, top moduli per case count. | /opt/metnos/runtime/testing/tests.db |
Niente di queste sorgenti e' stato creato per la dashboard: tutte preesistevano come fonte di verita' di un componente del runtime. La dashboard e' un consumatore in piu', non scrive nulla.
render_dashboard
La funzione esposta e' observability.render_dashboard(out_path).
Per ciascuna sorgente c'e' un piccolo helper privato
(_collect_mnestoma, _collect_pairings,
_collect_recent_turns, …) che apre la sorgente in
sola lettura, raccoglie un dict serializzabile, e lo restituisce.
Se una sorgente e' assente o solleva (es. SQLite non esiste perche'
non hai mai avviato lo scheduler), l'helper ritorna un dict vuoto o un
dizionario con la chiave error: la dashboard renderizza
una nota informativa ma non si interrompe.
La render e' un singolo passo: nessun template engine, nessuna dipendenza esterna. Solo helper Python che concatenano stringhe HTML. Stesso CSS in linea dei doc canonici (per coerenza visiva con metnos.com), tabelle e card statiche, niente JavaScript.
Il file HTML prodotto contiene, in ordine:
approve, rossa per block:guard o block:judge. Risponde alla domanda «la guardia sta tenendo? Sto bloccando troppo o troppo poco?».
Tutto cio' che esce da una sorgente passa per html.escape
prima di essere inserito nel DOM. Il caso garantito dal test
render_html_escape_sicuro: anche se un sender_id contiene
<script>, il file prodotto mostra
<script> — mai un tag attivo. Una
dashboard di osservabilita' non e' superficie di attacco, ma e'
disciplina mantenerla tale.
args_keys (non i valori), il pairing
non logga il payload del codice ma solo il suo code_id, gli
allegati delle mail non vengono mai materializzati nel turn log. La
dashboard eredita queste scelte: se non e' nella sorgente, non e' nel
file prodotto.
Il file di default e' workspace/dashboard/index.html, che
vive sotto il METNOS_INSTALL_ROOT e non e' deployato su
metnos.com (e' uno strumento operativo locale). Per consultarlo:
file:///opt/metnos/workspace/dashboard/index.html nel
browser, oppure scp dal server alla macchina di Roberto se si vuole
guardarlo da remoto.
Il file e' di solo-output. Si rigenera ogni volta che si lancia
python3 -m observability render: 100 ms tipici. La
prossima evoluzione (vedi cap. 8) sara' un task dello
scheduler builtin che lo
rigenera ogni N minuti.
python3 -m observability render # default: workspace/dashboard/index.html python3 -m observability render --out path.html # path custom
Niente sotto-comandi diversi da render in. Il
generatore non offre dump o export JSON: chi vuole i dati grezzi va
direttamente alle sorgenti (SQLite + JSONL).
/admin.metnos-server di Roberto.render_dashboard, ogni 5 min) la
manterra' fresca senza intervento.