← Indice documentazione Fondamenti › Manuale di architettura
Manuale di architettura · luglio 2026

Metnos

Dal sistema nel suo insieme ai contratti dei componenti

Un solo tutorial, due livelli di dettaglio. Parti dalle idee, segui una richiesta reale, poi entra nei componenti che rendono eseguibile ogni promessa.

Stato: pre-1.0
Formato HTML self-contained — stampabile PDF

Pubblico: prima chi è curioso, poi chi deve implementare.
Linguaggio semplice, contratti precisi, diagrammi leggibili senza il codice.
5tappe didattiche
15+spiegazioni visuali
26approfondimenti tecnici
1architettura continua

Il tuo percorso nel sistema

OrientatiScopo, scommesse, vocabolario e confini. Segui un turnoDalle parole a un risultato misurato e onesto. Capisci l'azioneExecutor, autorità, placement e sintesi. Vedi cosa restaMemoria, sensi, canali, sicurezza e undo. Apri la macchinaMappa, contratti e guide implementative.
Indice completo dei capitoli
  1. Cos'è Metnos
  2. Le tre scommesse
  3. I concetti chiave
  4. L'architettura a strati
  5. Anatomia di un turno multitool
  6. Executor e autorità
  7. Synt: la fabbrica
  8. Modelli e routing deterministico
  9. Memoria
  10. Pipeline immagini
  11. Canali
  12. Sicurezza e reversibilità
  13. Atlante dei componenti
  14. Otto principi
  15. Cosa non è Metnos
  16. Dove andare dopo

Una sola architettura, tre livelli di ingrandimento

PerchéI principi e i limiti che rendono Metnos un assistente particolare.
Cosa succedeIl percorso completo di un turno, compresi diniego, recupero e undo.
Come è costruitoContratti canonici: schemi, chiamate, autorità e condizioni di errore.
Come usare il manuale. Leggilo una volta dall'inizio alla fine. Al secondo passaggio usa i link dei componenti come botole verso il dettaglio. La visione spiega la promessa; il contratto del componente definisce come mantenerla.
Parte I · Orientamento

Capisci cosa stai guardando

Prima lo scopo, poi le scelte di progetto, infine il piccolo vocabolario usato in tutto il manuale.

1. Cos'è Metnos

Metnos è un'architettura self-hosted per un agente governato. Il core non definisce un dominio applicativo: pianifica, applica policy, ricorda, sintetizza, isola e registra. È il set di executor ammessi a definire cosa può fare davvero una specifica istanza. Gli executor sono piccoli programmi firmati, generati o importati soltanto dentro un vocabolario chiuso e orchestrati da un planner LLM local-first. I modelli frontier sono consulti opzionali, non la sede del sistema.

Il nome viene da mētis (l'intelligenza astuta) + noûs (la mente). Vive su una macchina sotto il tuo controllo fisico e legale. L'istanza di riferimento si usa da Telegram e dal browser (porta 8770), e il suo catalogo corrente copre file, posta, foto, calendari, web, GitHub e operazioni sull'host. Sono usi di quel catalogo, non limiti di Metnos. Cambiando gli executor ammessi e le skill/backend attive cambia il dominio operativo, senza cambiare l'architettura che lo governa.

Regola di perimetro. Posta, foto e calendari non appartengono a Metnos: appartengono agli executor del catalogo di riferimento. Manutenere Metnos attraverso GitHub è già un uso diverso della stessa architettura.
Metnos in un colpo d'occhio la tua macchina — dati, logica e modelli restano qui Telefono Telegram, ovunque bottoni di conferma Browser chat + cruscotto admin HTTP :8770 long-poll in uscita il processo Metnos Canali daemon Telegram · server web :8770 La mente (cap. 5) intent → memoria dei piani → motore Mētis un piano intero in UNA chiamata LLM routing deterministico: stessa richiesta, stesso piano Le guardie (cap. 12) policy · vaglio (consenso) · sandbox Executor vettoriali (cap. 6) firmati nel catalogo + sintetizzati sotto controllo lista dentro → lista fuori backend & skill (a tua scelta) file & cartelle mail (IMAP/SMTP) foto & indici calendario web & ricerca GitHub agiscono qui backend LLM configurato endpoint risolti per fast · middle · wise locale o remoto, senza cambiare il planner pensa qui memoria persistente mnestoma · fast-path · cronologia undo · audit (SQLite) tier frontier (cloud, facoltativo) un consulto quando richiesto — mai il motore self-hosted: nessuna dipendenza obbligata da servizi di terzi; il cloud è una porta che apri tu, non una stanza in cui abiti.
Figura 1 — Metnos in un colpo d'occhio. Il processo vive su una macchina tua: i canali ricevono, la mente pianifica tramite i tier configurati, le guardie filtrano e gli executor agiscono sui backend attivati. Provider remoti e tier frontier sono scelte esplicite.

La carta d'identità

VoceStato reale
FormaProcesso Python ≥ 3.11, microarchitettura a executor; runtime ReAct con pianificazione one-shot (motore Mētis, cap. 5).
StrumentiExecutor firmati nel catalogo, più quelli sintetizzati al volo e quelli importati dietro gate (cap. 7). Tutti vettoriali: lista dentro, lista fuori. La reference dei domini offre la vista utente; nomi e conteggio correnti sono nel catalogo generato.
CervelloEndpoint LLM compatibili, locali o remoti; quattro tier astratti fast / middle / wise / frontier (cap. 8). Frontier = cloud facoltativo.
CanaliTelegram (long-poll in uscita, niente porte aperte) + web su porta 8770 (chat e cruscotto admin), cap. 11.
DispositiviUna parte controllata del catalogo può girare su PC registrati nella stessa rete tramite metnos-client: il server resta il punto di policy, scelta, firma e audit; il device esegue solo executor dichiarati compatibili. Dettaglio: executor remoti.
SensiPipeline immagini nel processo: semantica + volti + EXIF in un indice unificato (cap. 10).
Linguai18n per costruzione: ogni stringa e prompt è dato per-lingua. IT + EN validate; altre lingue = pacchetto di traduzione drop-in (non ancora testate).
Licenza / statoAGPL-3.0; pre-1.0. Repo pubblico: github.com/brunialti/metnos — subset deterministico dell'istanza in esercizio.
Pre-1.0, non un prodotto rifinito. Metnos è installabile e operativo, ma interfacce e default possono ancora cambiare. Contratti, sicurezza, test e fallimenti espliciti hanno priorità sulle promesse di stabilità.

2. Le tre scommesse

Tutto il progetto sta in tre scommesse architetturali. Sono scelte di campo, non ottimizzazioni: ciascuna rovescia un'abitudine diffusa dei framework agentici.

Tre scommesse, un sistema 1 · Vocabolario chiuso Gli strumenti non si importano a fiducia: si sintetizzano dentro una grammatica chiusa e auditata. «non fidarti del pacchetto: il pacchetto deve guadagnarsi il posto» cap. 3 · 6 · 7 2 · Locale prima Il pianificatore è un LLM sul tuo hardware. Niente giro in cloud per pensare o agire. il frontier è un consulto opzionale, non il motore cap. 8 3 · Determinismo Stessa richiesta → stesso piano, a ogni esecuzione: seed fissato, pareggi rotti da dato curato, grammar. auditabile e testabile come software, non come un prompt cap. 5 · 8 insieme: un agente riproducibile, verificabile, tuo
Figura 2 — Le tre scommesse. Ognuna rovescia un'abitudine dei framework agentici: skill importate a fiducia, prima il cloud, LLM come oracolo da rilanciare a ogni turno.

Il confronto, senza sconti

Framework agentico tipicoMetnos
StrumentiScritti a mano, importati o generati free-form, poi eseguiti così come sono, con i privilegi dell'assistenteSintetizzati anch'essi a runtime — ma da un vocabolario chiuso e auditato: firmati, invecchiati, smoke-testati e vagliati prima di poter girare
SicurezzaCi si fida dell'autore del pacchettoNon ci si fida del pacchetto: il pacchetto deve superare i controlli (gate a 7 livelli, cap. 7)
LLMSpesso prima il cloudLocale prima; frontier facoltativo
RoutingIl modello sceglie un tool a ogni turno — non riproducibileDeterministico per costruzione: inferenza locale a seed fissato, pareggi rotti da affinity curata (cap. 8)
OutputLibero, diverso per ogni toolUniforme: lista dentro / lista fuori, componibile fra step (cap. 6)
UndoRaro o best-effortDi prima classe: catalogo chiuso di pattern inversi, move = COPY-poi-DELETE, ok_count onesto (cap. 12)
LinguaInglese, stringhe nel codicei18n per costruzione: stringhe e prompt sono dati per-lingua
Perché il determinismo conviene. La maggior parte degli agenti tratta l'LLM come un oracolo da rilanciare: chiedi due volte, ottieni due piani diversi. Metnos fa la scommessa opposta: un pianificatore locale, vincolato a un vocabolario chiuso, può essere reso riproducibile. Così il routing si misura, si mette sotto test di regressione, si audita — come software ordinario. E si accumula: una richiesta già risolta una volta viene rieseguita da un percorso veloce senza alcuna chiamata LLM (cap. 9).

3. I concetti chiave, in sette carte

Sette parole reggono tutto il documento. Definirle adesso vi risparmia mezz'ora di confusione fra trenta righe; ognuna ha il suo contratto implementativo nell'atlante dei componenti.

executor — una capacità eseguibile: un piccolo programma che fa una cosa sola e bene (leggere file, mandare una mail, spostare messaggi, cercare foto). Accetta liste in ingresso e produce liste in uscita, ha un manifest che lo descrive, una firma Ed25519 che lo autentica e un profilo di sandbox che lo confina. È l'unica classe di cose che agiscono nel sistema.
vocabolario chiuso — ogni executor si chiama verbo_oggetto[_qualifier[_descriptor]], componendo insiemi governati di azioni e oggetti canonici più qualificatori in quattro famiglie. Non è una convenzione estetica: è il confine di ciò che il sistema può nominare — e quindi sintetizzare. Nuovi termini solo con governance esplicita (necessario · generale · comprensibile).
manifest — la carta d'identità TOML di un executor: descrizione in capitoli prescrittivi (SCOPO / PATTERN / NON / OUT), schema degli argomenti, parole di affinità, pattern di reversibilità, digest del codice. Non è documentazione per umani: è il prompt del tool, scritto perché un LLM medio lo usi bene (cap. 6).
synt — il processo che fa esistere ciò che il pool non sa ancora fare: una cascata di strategie a costo crescente che prima compone executor esistenti e solo come eccezione documentata genera codice nuovo, in cinque stadi più una verifica semantica (cap. 7). Propone; l'umano approva.
vaglio — il filtro che sta sempre prima dell'esecuzione: una guardia deterministica (percorsi vietati, comandi irrecuperabili) seguita da un giudice che pesa le operazioni in zona grigia e, sopra soglia, chiede conferma esplicita all'utente con bottoni sul canale (cap. 12).
mnest · mnestoma — il mnest è il filo che collega due executor attivati insieme: nasce dal contesto, si rinforza con l'uso, decade se non riusato. Il mnestoma è il grafo di tutti i mnest: la memoria associativa del sistema, su SQLite, curata da un processo notturno (l'ager). Dà al pianificatore l'intuizione di «quale executor di solito segue quale» (cap. 9).
skill ↔ backend — due assi ortogonali: la skill decide se un gruppo di capacità è attivo, fidato e configurato (dormiente finché manca il prerequisito); il backend decide come un'azione gira contro un servizio concreto (calendario = ICS locale oppure Google), scelto dalla configurazione — mai dall'LLM. Il pianificatore non vede mai il fornitore.

L'anatomia di un nome

Il vocabolario chiuso è l'idea più fertile del progetto: rende i nomi componibili (il pianificatore può prevedere come si chiama una capacità che non ha mai visto), filtrabili (il prefilter ragiona su verbo e oggetto) e sintetizzabili (synt non può nominare nulla fuori dalla grammatica).

Anatomia di un nome: verbo_oggetto[_qualifier[_descriptor]] find _ images _ indices _ dry-run azione insieme canonico governato read, write, move, find, get, list, filter, send, … oggetto insieme canonico governato files, messages, events, images, urls, entries, … qualifier (opz.) 4 famiglie formato · modalità safety · provider descriptor (opz.) kebab-case, max 30 variante comportamentale a parità di argomenti i 5 verbi-produttori, ortogonali find = pattern / query get = id noti o snapshot read = id → contenuto list = enumera il contenitore filter = predicato su lista l'asse è l'input primario, mai un sinonimo read_messages move_files get_urls classify_entries write_files_doc find_issues_github Il vocabolario è CHIUSO: un termine nuovo entra solo se necessario, generale e comprensibile a un LLM medio. Sinonimi prima dell'estensione; escalation umana per ogni parola nuova. La grammatica decide cosa è nominabile.
Figura 3 — L'anatomia di un nome. Quattro livelli posizionali, di cui gli ultimi due opzionali; i cinque verbi-produttori si distinguono per l'input primario, così il pianificatore non deve mai scegliere fra sinonimi.
Parte II · Una richiesta in movimento

Segui un turno dalle parole agli effetti

Gli strati diventano più chiari quando osservi dati, decisioni e autorità attraversarli.

4. L'architettura a strati

Metnos è una cipolla: l'esterno parla col mondo, l'interno esegue. Ogni strato si fida solo di quello più interno e i privilegi calano scendendo verso il centro. Una richiesta — venga da un utente o da un task schedulato — li attraversa tutti, nell'ordine.

Gli strati, dall'esterno verso il centro 1 · Canali adattatori verso il mondo: daemon Telegram (pairing, bottoni) · server web :8770 (chat, admin, SSE) runtime/channels/ · metnos_http_server 2 · Runtime del turno normalizza la richiesta · scorciatoie letterali · estrazione dell'intent (verbo + oggetto + parole chiave) agent_runtime · intent_extractor 3 · Motore cognitivo — Mētis memoria dei piani (fastpath ★ · autopath) → prefilter → proposer (1 chiamata, GBNF) → validator → esecuzione recovery mirata sugli errori · terminator onesto sui vicoli ciechi — cap. 5 runtime/engine/* 4 · Guardie policy (tre livelli di autonomia) · vaglio = guardia + giudice + consenso · sandbox bubblewrap per ogni invoke policy · vaglio · sandbox 5 · Executor firmati, sintetizzati o importati dietro gate — tutti vettoriali, tutti col loro manifest executors/ · ~/.local/…/executors/ 6 · Backend & skill il fornitore concreto (file locali, IMAP, Google Workspace, GitHub, web…) scelto dalla configurazione, mai dall'LLM backends/ · skills 7 · Tessuti persistenti mnestoma · archivi fast-path/autopath · cronologia + blob di undo · audit append-only (tutto SQLite + filesystem) ~/.local/share/metnos/ una richiesta li attraversa in ordine privilegi e fiducia calano scendendo
Figura 4 — I sette strati reali, con i moduli che li implementano. Il motore cognitivo (strato 3) è il cuore del capitolo 5; le guardie (strato 4) stanno sempre fra il piano e l'effetto.

5. Anatomia di un turno multitool

Questo è il capitolo da leggere se ne leggete uno solo. Seguiamo una richiesta vera — «cerca le mail spam e mettile nel cestino» — dall'ingresso alla risposta: quattro strumenti concatenati, una sola chiamata al modello, ogni passaggio misurato e annotato.

5.1 La cascata, passo per passo

La regola di fondo: il modello è l'ultima risorsa, non la prima. Prima si tenta la memoria (zero LLM, millisecondi); se la richiesta è nuova, il modello viene interrogato una volta sola e gli si chiede l'intero piano; l'esecuzione che segue è pura meccanica deterministica.

Un turno, dall'ingresso alla risposta «cerca le mail spam e mettile nel cestino» scorciatoie letterali tabella chiusa: «che ora è», «dove sono», «annulla»… microsecondi ✗ nessun match → si prosegue intent_extractor — LLM tier fast, ragionamento spento verb = move object = messages kw = spam… ~0,4 s richieste composte → lista ordinata di clausole motore Mētis — un solo punto d'ingresso, ogni strato annota se ha risposto Fastpath ★ — scorciatoie approvate dall'utente impronta esatta <5 ms · somiglianza semantica <150 ms 0 LLM ✗ miss Autopath — piani appresi dai turni riusciti cerca per significato della richiesta, poi per intent esatto 0 LLM ✗ miss: richiesta nuova prefilter → il pool della clausola find_messages classify_entries filter_entries move_messages rango: verbo+oggetto » qualifier » affinity (cap +3) 0 LLM deterministico: stessa query → stesso pool, stesso ordine Proposer Mētis — tier wise, UNA chiamata propone l'intero piano: steps + collegamenti + messaggio finale N candidati adattivi, ognuno vincolato dalla grammatica GBNF verb-filter sul pool · early-stop se il primo convince · rango teleologico 1× LLM il modello sceglie DENTRO il binario: niente prosa, niente args inventati (cap. 8) Validator — controllo deterministico del piano i tool esistono? gli args sono ben formati? i riferimenti puntano a step reali? 0 LLM errore banale → 1 riproposta, mai eseguire Esecuzione deterministica — passo per passo, niente dadi 1 find_messages → 42 entries 2 classify spam / non spam 3 filter → 12 entries 4 move_messages ⚙ vaglio: consenso → ok_count=12 per ogni step: risolvi from_step e segnaposti → vaglio → invoke in sandbox → observation cap di sicurezza: max 12 step per turno · stesso executor max 3 volte di fila render del messaggio finale "Spostate ${step4.ok_count} mail nel cestino." → valori reali Autopath registra il piano riuscito la prossima volta: stessa risposta, 0 LLM (cap. 9) uno step fallisce? Recovery mirata classifica: tool sbagliato · args · input mancante ripropone escludendo il tool fallito, riesegue Terminator — vicolo cieco onesto «Non posso risolvere: X. Per procedere: Y.» registra la lacuna — mai una risposta inventata «Spostate 12 mail nel cestino.» il log annota quale strato ha risposto e i ms di ogni fase telemetria per sotto-fase: intent_ms · prefilter_ms · vaglio_ms · exec_ms — ogni turno è misurabile e confrontabile
Figura 5 — L'anatomia di un turno multitool. Le scorciatoie (0 LLM) si tentano prima; se la richiesta è nuova, il Proposer chiede al modello l'intero piano in una sola chiamata vincolata; l'esecuzione è deterministica, con il vaglio davanti all'unico passo che modifica stato. A destra, i due percorsi d'errore: recovery mirata e vicolo cieco onesto.
  1. Scorciatoie letterali. Una tabella chiusa riconosce le frasi notissime («che ora è») in microsecondi. Qui: nessun match.
  2. Intent. Una chiamata al tier fast (ragionamento spento, ~0,4 s) estrae verbo canonico, oggetto e parole chiave. Le richieste composte diventano una lista ordinata di clausole, ognuna col suo pool.
  3. Memoria dei piani. Fastpath (scorciatoie che hai approvato col bottone ★) e Autopath (piani imparati da soli) rispondono senza modello se riconoscono la richiesta. Qui: miss, è la prima volta.
  4. Prefilter. Il catalogo si riduce al pool pertinente per la clausola: match su verbo+oggetto, bonus per qualifier, e — per rompere i pareggi fra fratelli — il bonus di affinity curata (cap +3). Tutto deterministico: stessa query, stesso pool, stesso ordine.
  5. Proposer Mētis. UNA chiamata al tier wise produce l'intero piano: steps, collegamenti, messaggio finale. Genera fino a N candidati (adattivo, con early-stop), ognuno fisicamente vincolato dalla grammatica GBNF del pool; un rango teleologico sceglie il migliore.
  6. Validator. Typecheck del piano prima di eseguire: tool esistenti, args ben formati, riferimenti reali. Un errore banale costa una riproposta, non un'esecuzione sbagliata.
  7. Esecuzione. Meccanica pura: per ogni step il runtime risolve i segnaposti, passa dal vaglio, invoca in sandbox, accumula l'osservazione. Cap: 12 step per turno, stesso executor max 3 volte di fila.
  8. Chiusura. Il messaggio finale è un template riempito dai risultati veri. Se il turno riesce, Autopath lo registra: la prossima volta si salta direttamente al punto 3.

5.2 Il piano: cosa propone davvero il modello

Il Proposer non produce prosa: produce un oggetto strutturato — steps, slot da riempire (fillers), messaggio finale. Questo è il piano reale della nostra richiesta:

{
  "steps": [
    {"tool": "find_messages",
     "args": {"folder": "INBOX", "query": "is:unread"}},
    {"tool": "classify_entries",
     "args": {"from_step": 1, "dimension": "spam"}},
    {"tool": "filter_entries",
     "args": {"from_step": 2, "where_field": "spam", "where_value": "spam"}},
    {"tool": "move_messages",
     "args": {"from_step": 3, "dst_folder": "${FILLER:cestino_folder}"}}
  ],
  "fillers": {
    "cestino_folder": {
      "prompt": "Come si chiama la cartella cestino per questo account?",
      "default": "Trash",
      "tier": "fast"
    }
  },
  "final_message": "Spostate ${step4.ok_count} mail nel cestino."
}

Da notare: il modello non conosce il nome della cartella cestino dell'account — e non lo inventa. Dichiara uno slot (${FILLER:cestino_folder}) che il runtime riempirà al momento giusto con una micro-chiamata economica (con cache) o col default.

5.3 Il data piping: come i passi si parlano

SegnapostoCosa fa
from_step: NPrendi le entries prodotte dallo step N (numerazione da 1) e passale intere a questo step. Le liste viaggiano solo così: mai re-incollate nel prompt.
${stepN.field}Estrai un campo scalare dal risultato dello step N (percorsi annidati supportati). Usato soprattutto nel messaggio finale.
${FILLER:nome}Slot riempito al volo da una micro-chiamata al tier fast (con cache) o dal default dichiarato.
${RUNTIME:chiave}Contesto del turno, risolto dal runtime: actor (chi parla), lang, channel.
Il data piping: liste fra gli step, scalari nei segnaposti step 1 · find_messages folder="INBOX" query="is:unread" → entries (42 mail) step 2 · classify_entries from_step: 1 dimension="spam" → entries + campo spam step 3 · filter_entries from_step: 2 where spam == "spam" → entries (12 mail) step 4 · move_messages from_step: 3 dst=${FILLER:cestino_folder} → results, ok_count=12 entries entries entries ${FILLER:cestino_folder} slot dichiarato dal piano, riempito dal runtime: micro-chiamata tier fast (con cache) oppure default → «Trash» ${RUNTIME:actor · lang · channel} contesto del turno, iniettato dal runtime: chi sta parlando, in che lingua, da quale canale final_message — il template della risposta "Spostate ${step4.ok_count} mail nel cestino." riempito a esecuzione finita con i valori reali → «Spostate 12 mail nel cestino.» ${step4.ok_count} scalare, non lista legenda dei collegamenti from_step — liste intere fra step ${stepN.field} — un campo scalare ${FILLER:nome} — slot riempito al volo ${RUNTIME:chiave} — contesto del turno
Figura 6 — Il piano della Figura 5 visto come flusso di dati. Le liste scorrono fra gli step via from_step; gli scalari, gli slot e il contesto passano per segnaposti tipizzati che l'esecutore risolve in modo deterministico.
Quando un cap si fa sentire, lo vedi. Se un limite tronca un risultato (entries, byte, step), l'executor lo dichiara nei campi (truncated: true, used, available_total) e il runtime lo dice nella risposta — con l'offerta di allargare solo se tecnicamente possibile, e mai allargando da solo. Un parziale presentato come completo è considerato un bug, non un'ottimizzazione.
Parte III · Agire

Piccoli programmi, autorità esplicita

Gli executor fanno il lavoro. I manifest lo limitano. Policy e placement decidono dove può avvenire.

6. Executor: vettoriali per costruzione

Ogni executor accetta una lista e ritorna una lista — anche quando la lista ha zero o un elemento. Non esiste nessun *_batch: la versione batch è l'executor. È la decisione che rende i piani corti e i risultati componibili.

Un solo contratto per N = 0, 1, mille paths = [] paths = ["/tmp/x.txt"] paths = [… ×1000] lista degenere o enorme: stesso ingresso, nessun caso speciale move_files iterazione, paginazione e finestre temporali vivono DENTRO; la diramazione torna al pianificatore cap espliciti: max_total, max_results, max_bytes sempre una lista, più la verità results = […] ok_count = 12 (reali, non sperati) truncated = true used = 200, available_total = 312 cap_field = "max_total" move_files_batch  non esiste — e non esisterà: la forma vettoriale è l'unica forma.
Figura 7 — Il contratto vettoriale. Zero, uno o mille elementi attraversano lo stesso codice; i cap sono argomenti espliciti e il troncamento è dichiarato nei campi, mai nascosto.

Dal contratto discendono tre convenzioni che vedrete ovunque:

Il manifest: il prompt del tool

Ogni executor porta con sé un manifest TOML. Non è documentazione di cortesia: è ciò che il pianificatore legge quando decide se e come usare lo strumento — scritto su misura per un LLM medio locale, non per un modello frontier. Frasi corte, esempi letterali, default in chiaro; la descrizione segue quattro capitoli prescrittivi:

Lo stesso manifest dichiara anche dove l'executor puo' girare. I campi platforms e [placement] impediscono di mandare a Windows un tool scritto solo per Linux, o di eseguire su un PC un executor non auditato per il device. Quando la chat nomina un PC appaiato, il runtime usa queste dichiarazioni per decidere se eseguire sul server o sul dispositivo; se il bersaglio non e' raggiungibile, l'esito e' onesto, non un fallback silenzioso.

[description]
it = "SCOPO: cerca file per pattern in directory.
      PATTERN: find_files(base_path=\"/\", patterns=[\"*.jpg\"]).
      NON: list_dirs+filter_entries; get_files (lookup ID).
      OUT: entries=[{path,name,type,mime,kind,size,mtime}]."
Il manifest alimenta quattro meccanismi diversi executors/find_files/manifest.toml name = "find_files" affinity = ["trova","cerca","search", "file","glob","pattern",…] [description] SCOPO: … PATTERN: find_files(…) NON: … OUT: entries=[{…}] per lingua (IT+EN), con tracking dello stato [args] — JSON Schema base_path (req) · patterns · recursive max_total … tipi, default, esempi reverse_pattern + capabilities es. "swap_src_dst" · fs:read · provider:access [code] digest sha256 + firma files = ["find_files.py"] prefilter (cap. 5) l'affinity curata rompe i pareggi fra fratelli pool del Proposer (cap. 5) il modello copia la FORMA dal PATTERN, non inventa grammatica GBNF (cap. 8) lo schema args diventa il binario del decode undo (cap. 12) il pattern inverso viene da un catalogo chiuso il digest firma il codice: se il file cambia senza ri-firma, il loader scarta l'executor — niente codice alla deriva
Figura 8 — Un solo manifest, quattro consumatori: prefilter, pool del pianificatore, grammatica e undo leggono campi diversi dello stesso TOML. Il digest lega il manifest al codice firmato.

Una sola politica di esecuzione

Ogni chiamata a un executor, locale o remota, attraversa lo stesso motore di esecuzione. In un punto solo il runtime applica metriche, retropressione, limiti per risorsa e un tetto derivato dall'hardware. Il comportamento predefinito resta intenzionalmente seriale e il pool trasversale e' spento: adottare l'infrastruttura non cambia l'ordine, gli input, gli output o le capacita' degli executor esistenti.

[execution]
effect = "unknown"
parallelism_class = 0
resource_class = "default"
concurrency_key = "none"
equivalence_gate = "unverified"
ClasseBudget richiestoAmmissione
0Nessun thread trasversale.Predefinita per tutti gli executor esistenti e generati.
1Concorrenza moderata.Solo dopo equivalenza verificata; sempre entro i limiti del motore e dell'hardware.
2Concorrenza alta.
3Massimo controllato.

La classe misura soltanto un budget: non concede autorita' e non significa sola lettura. Un futuro executor che crea o modifica oggetti puo' essere concorrente, ma deve dichiarare una chiave d'isolamento, fornire l'identita' della risorsa e superare prove di equivalenza, collisione, idempotenza e postcondizione. Se manca una di queste evidenze, il loader lo riporta alla classe 0.

Anche i tre percorsi che generano executor — proposta Synt, sintesi reattiva e generazione da skill — consumano un unico contratto centrale. Il modello locale puo' progettare un'implementazione ricca, ma non puo' riscrivere identita', ciclo di vita, I/O o politica iniziale. Se parallelizza elementi indipendenti, il numero di worker arriva dal motore e i risultati devono tornare nell'ordine di ingresso.

Regola di conservazione. Un executor resta seriale finche' non dichiara esplicitamente di essere parallelizzabile e non supera la prova di equivalenza. Cambiare la politica centrale propaga limiti e osservabilita' a tutti; non promuove implicitamente nessun executor.

Autorità remota: dichiarata una volta, consumata tre volte

Il nome di un provider dentro un argomento è un dato, non un permesso. Per un executor conforme, l'accesso remoto esiste solo quando il manifest dichiara una capability provider:access effettiva. Una condizione when chiusa può attivarla soltanto per il backend selezionato. Condizioni invalide o non corrispondenti non concedono nulla.

Regola di autorità. Lo stesso binding effettivo governa credenziali, rete e placement. Nomi, suffissi e argomenti arbitrari non sono percorsi di permesso indipendenti per gli executor conformi. L'inferenza legacy resta soltanto come ponte temporaneo di migrazione.

Esecuzione sul server o su un PC registrato

La forma normale resta semplice: il piano sceglie un executor, il runtime lo passa attraverso policy e vaglio, poi lo invoca nella sandbox del server. Gli executor remoti aggiungono una sola deviazione controllata: per alcuni executor dichiarati portabili, il punto di esecuzione puo' essere un PC registrato nella stessa rete o overlay.

Non e' un nuovo canale e non e' un backend qualunque. Il canale resta Telegram o web; il backend resta file, posta, calendario o altro servizio. Il remote executor e' il luogo in cui gira il piccolo programma firmato. Metnos mantiene sul server la scelta dell'executor, il controllo di policy, il registro dei device, la firma del payload, il timeout e l'audit.

chat "sul PC ufficio" server Metnos planner + policy + vaglio manifest: platforms + placement coda firmata, deadline, audit metnos-client poll in uscita + verifica firma PC registrato executor compatibile Job Object / bwrap result firmato result firmato: stesso shape di un executor locale
Figura 8b — Il remote executor non sposta il cervello: sposta solo l'esecuzione di un executor ammesso. Il server resta l'autorita' che decide, firma, attende e registra.

La scelta non dipende dall'indirizzo IP del browser. In una UI web la macchina che apre la pagina puo' coincidere col server, con un altro PC della rete, o essere dietro un proxy; da Telegram non c'e' proprio un browser locale. Per questo Metnos usa il nome del device appaiato e lo ancora al linguaggio della richiesta: «sul portatile» e' un target, «il portatile» da solo non lo e'.

Il client remoto non riceve liberta' generale. Fa polling verso il server, non espone porte; verifica la firma del server prima di eseguire; scarica solo executor firmati e compatibili; scrive il result nello spool locale prima di consegnarlo. Se il server non risponde, ritenta la consegna senza rieseguire il lavoro gia' fatto.

Il client remoto e' contenuto per costruzione: su Windows il Job Object limita durata, memoria e albero dei processi; su Linux la sandbox usa bwrap quando presente. Su questa base i remote executor non sono piu' solo read-only: da C7 (ADR 0183) girano sul dispositivo anche i mutanti — scrittura, spostamento e cancellazione file — resi sicuri dalla policy che a lungo avevano richiesto: idempotenza, audit e reversibilita' device-aware (reverse pattern deterministici e backup blob accodati allo stesso dispositivo per l'annullamento; con il gap noto che il restore-da-blob non e' remotabile). Gli executor le cui dipendenze non sono risolvibili sul dispositivo restano server-only.

Il dettaglio operativo — pairing del PC, installazione dalla UI, heartbeat, coda firmata, sandbox per sistema operativo e limiti attuali — sta nel contratto executor remoti.

7. Synt: la fabbrica degli strumenti

Quando il pool non sa fare una cosa, il pianificatore non improvvisa codice nel mezzo del turno: passa la mano a synt, il processo che fa esistere ciò che manca. Prima prova a comporre executor esistenti; solo come eccezione documentata genera un executor nuovo — in cinque stadi, ognuno col suo contratto.

La catena di montaggio: cinque stadi + verifica ogni stadio vede solo la fetta minima di contesto; il vocabolario chiuso entra SOLO allo stadio 1 1 · NAMING nome conforme al vocabolario chiuso + revertible, critical tier middle 2 · SIGNATURE schema degli args, capabilities richieste, pattern di reversibilità tier middle 3 · TESTS 4-6 test di nascita: caso felice, lista vuota, args invalidi, edge tier middle 4 · DESCRIPTION descrizione a capitoli (SCOPO/PATTERN/NON/OUT) + parole di affinity tier middle 5 · CODE il file Python con def invoke() (+ reverse se serve) tier wise stadio 6 · verifica semantica (fail-safe) un LLM separato confronta descrizione e codice: dicono la stessa cosa? nel dubbio rifiuta: meglio perdere un buon synth che ammetterne uno fasullo firma Ed25519 + digest manifest e codice legati insieme test di nascita in sandbox i 4-6 test dello stadio 3, eseguiti davvero nel pool, accanto ai fratelli stesso contratto vettoriale, stesso manifest, stessa sandbox degli executor scritti a mano La sintesi è locale: nessun provider esterno scrive codice che girerà sulla tua macchina. E un bug in un executor sintetizzato si corregge iterando il prompt dello stadio, mai riscrivendo a mano il file generato.
Figura 9 — La pipeline di sintesi: quattro stadi procedurali sul tier medio, il codice sul tier alto, poi verifica semantica indipendente, firma e test di nascita. Il multistadio convalida dove il prompt singolo falliva.

Due inneschi, una cascata

ModoInnescoTempo
ReattivoDurante un turno: il pianificatore non trova nessun executor che soddisfi la richiesta.Sincrono — l'utente sta aspettando; prima si tenta la composizione di executor esistenti.
IntrovertivoDi notte: l'ager scorre il mnestoma e trova ricorrenze, tracce sovrapposte, famiglie con la stessa forma.Asincrono, in omeostasi: propone fusioni, generalizzazioni, specializzazioni.

In entrambi i casi vale la stessa regola: synt propone, l'umano approva. Nessuna auto-modifica senza filtro; ogni proposta arriva con motivazione, ed è reversibile.

Il gate a 7 livelli

Lo stesso imbuto vale per il codice sintetizzato e per le skill importate da fuori: nessun pacchetto si esegue sulla fiducia.

Il gate d'ammissione: sette livelli, nessuna eccezione pacchetto / synth nuovo non fidato 1 firma Ed25519+digest 2 vocabolario nome + affinity 3 aging quarantena d'uso 4 sandbox profilo dal manifest 5 smoke test esecuzione provata 6 verifier LLM descrizione vs codice 7 audit append-only executor fidato nel pool «non fidarti del pacchetto — il pacchetto deve guadagnarsi il posto» i formati di skill drop-in eseguono codice di terzi con i privilegi dell'assistente: per un agente che tocca file, mail e shell è esecuzione remota di codice per design. Metnos sceglie la sicurezza per costruzione. roadmap: mappare l'ecosistema skill pubblico DENTRO questo modello, non eseguirlo crudo
Figura 10 — Il gate a 7 livelli, identico per executor sintetizzati e importati: firma, vocabolario, quarantena d'uso, sandbox, smoke test, verifica semantica, audit. Solo in fondo all'imbuto un pacchetto diventa un executor fidato.

8. Quattro tier, un routing deterministico

I tier sono ruoli astratti, non modelli inchiodati: fast / middle / wise sono incarichi che leghi a qualunque endpoint tu abbia, frontier è il cloud facoltativo. Più tier possono condividere un endpoint oppure essere separati: il planner vede sempre il ruolo.

TierRuoloVincolo
fastEstrazioni brevi e strutturate: intent, filler, classificazioni. Ragionamento spento.Endpoint configurato; risposta corta. Obbligatorio.
middleLavoro procedurale: stadi 1-4 della sintesi, descrizioni, giudizi.Endpoint e parametri configurati per il ruolo.
wiseIl pianificatore: propone il piano intero; scrive il codice dello stadio 5.Obbligatorio: non degrada mai a fast.
frontierUn consulto esterno quando richiesto esplicitamente (es. analisi di un issue).API cloud, facoltativo, con ripiego gestito se la chiave non c'è.
Tier ≠ modello. Nessuna GPU o NPU è richiesta per costruzione: un endpoint su CPU, un modello che già servi, o il ripiego frontier sono percorsi di prima classe. Un modello locale più debole significa pianificazione più debole, non un'installazione rotta.

Le tre serrature del determinismo

Un LLM a temperatura zero non basta a rendere il routing riproducibile: il server locale resta non-deterministico per via della decodifica speculativa col seed casuale. Metnos chiude la porta con tre serrature, una per ogni fonte di rumore:

Tier astratti a sinistra, determinismo a destra fast intent · filler · classify middle synt 1-4 · descrizioni wise piani · codice synth endpoint configurati condivisi o distinti per ruolo cambiano modello e parametri: think · num_predict frontier consulto cloud, facoltativo solo se richiesto, mai il motore Serratura 1 — seed fissato a temperatura 0 il server resta non-deterministico (decodifica speculativa a seed casuale): il seed va inchiodato per env. METNOS_LLM_SEED=42 (default; -1 = casuale esplicito) Serratura 2 — pareggi rotti da dato curato fra fratelli con stesso oggetto decide l'affinity distintiva del manifest (verbi generici esclusi), mai un lancio di moneta. prefilter: bonus = min(|query ∩ affinity|, 3) Serratura 3 — grammatica come binario dal pool dello step si genera una GBNF (unione discriminata): il modello non PUÒ emettere un tool_call malformato, né mischiare il nome di un tool con gli args di un altro. stessa richiesta → stesso pool → stesso piano, a ogni esecuzione il routing si mette sotto bench e test di regressione come software ordinario soft constraint = «per favore guida a destra» · grammar = il guard-rail il primo si può ignorare, il secondo no: ogni token candidato viene filtrato contro la grammatica prima della scelta + verb-filter: il pool si restringe ai verbi compatibili con l'intent della clausola
Figura 11 — A sinistra i tier come ruoli legati agli endpoint configurati; a destra le serrature che rendono il routing riproducibile: seed fissato, affinità curate per i pareggi e grammatica GBNF sul decode.
Niente parser fragili. Il tool-use è nativo: il modello emette tool_calls strutturati, e la grammatica garantisce la forma a monte. Non c'è nessun parsing di JSON pescato dentro prosa — il punto debole classico degli agenti fai-da-te.
Parte IV · Ciò che circonda l'azione

Memoria, sensi, canali e protezioni

Questi tessuti rendono il sistema utile nel tempo, visibile all'utente e abbastanza sicuro da operare.

9. La memoria che accelera

Metnos non addestra modelli: niente fine-tuning, niente RLHF. Tutto ciò che impara è dato ispezionabile — piani, tracce, scorciatoie — e ogni cosa imparata si può leggere, correggere, cancellare. L'effetto pratico: più lo usi, meno chiama il modello.

Il circolo: usare → ricordare → non chiedere più turno riuscito il piano ha funzionato davvero Autopath registra piano indicizzato per significato della richiesta (embedding) richiesta simile, domani piano già pronto: riesecuzione in millisecondi, 0 LLM ★ promozione esplicita un bottone sotto la risposta promuove il piano a scorciatoia Fastpath garantita mnestoma — il grafo dei mnest (SQLite) due executor attivati insieme → un filo che si rinforza con l'uso e decade se non riusato; le lacune restano come aspirazioni l'orologio è il tempo dell'uso, non il calendario: un sistema che dorme non invecchia di notte: l'ager + le proposte di synt le sequenze multi-step molto usate (>50 volte) diventano candidate a executor sintetici; tracce sovrapposte propongono fusioni e generalizzazioni — sempre col filtro umano proposte loggate, mai auto-applicate (cap. 7) ogni turno lascia tracce imparare = accumulare dati verificabili, mai ritoccare pesi
Figura 12 — Il circolo dell'apprendimento senza addestramento: i piani riusciti diventano scorciatoie (Autopath, Fastpath ★), le co-attivazioni diventano mnest, le ricorrenze notturne diventano proposte di sintesi. Tutto è dato leggibile e reversibile.

10. I sensi: la pipeline immagini

Per cercare nelle foto, Metnos non spedisce nulla a nessuno: tre estrattori nel processo trasformano ogni immagine in tre segnali — cosa si vede, chi c'è, dove e quando — fusi in un indice unificato interrogabile dal vocabolario normale.

Tre segnali da ogni foto, un indice solo una foto dell'archivio semantica — SigLIP l'immagine diventa un vettore: «tramonto al mare», «torta di compleanno», «sentiero in montagna» volti — RetinaFace + ArcFace trova i volti, li trasforma in impronte d'identità; le persone si registrano con nome solo se lo chiedi tu contesto — EXIF coordinate GPS, data e ora, fotocamera: il dove e il quando senza nessun modello indice unificato un record per foto: scena + persone + luogo + tempo costruito una volta, interrogato sempre «le foto in montagna dell'estate scorsa» find_images_indices stesso vocabolario di tutto il resto tutto nel processo, sulla tua macchina: l'archivio fotografico non lascia mai casa
Figura 13 — La pipeline immagini: SigLIP per la scena, RetinaFace+ArcFace per le identità, EXIF per luogo e tempo. I tre segnali confluiscono in un indice unificato che si interroga con un executor normale del vocabolario.

La ricerca arriva dal canale come qualunque altra richiesta: il pianificatore compone find_images_indices con i criteri estratti dalla frase, e il canale mostra le anteprime inline. La costruzione dell'indice è un lavoro di fondo, incrementale e riavviabile, che si lancia con una frase («indicizza le foto in…»).

11. I canali: Telegram e web

Un canale è un adattatore: converte un'interfaccia esterna in messaggi e risposte, più una capacità opzionale — rendere bottoni per conferme e scelte. Due canali nascono con l'installazione; aggiungerne altri non tocca il nucleo.

Due porte d'ingresso, zero porte aperte verso Internet la macchina di Metnos server web — porta 8770 chat (streaming SSE) + cruscotto admin daemon Telegram long-poll IN USCITA verso l'API del bot browser in LAN (o via overlay VPN tuo) chiave admin al primo accesso proposte · executor · esecuzioni safety · turni · grafici HTTP :8770 API Telegram il daemon CHIEDE lui: niente porte aperte, niente IP pubblico telefono ovunque c'è rete, parli col tuo bot bottoni inline chi può parlare? solo chi è accoppiato: codici firmati Ed25519 con scadenza, livello di autorizzazione per persona un mittente sconosciuto viene scartato senza eco; le conferme del vaglio e le scelte (get_inputs) arrivano come bottoni sul canale
Figura 14 — I due canali. Il browser parla direttamente col server sulla 8770 (chat con streaming + cruscotto); Telegram funziona per long-poll in uscita, quindi nessuna porta aperta né IP pubblico. In basso, il pairing che decide chi può parlare.
CanaleCosa offre
Web :8770Chat nel browser con risposta in streaming (SSE), anteprime immagini, badge di feedback; cruscotto admin per proposte, executor, esecuzioni, safety e turni. La stessa API risponde JSON o HTML a seconda dell'Accept. Chiave admin auto-creata al primo avvio, file con permessi 0600.
TelegramIl tuo bot personale: messaggi, foto, bottoni inline per le conferme del vaglio e per le scelte a opzioni. Accoppiamento col comando /pair e un codice firmato con scadenza.

Il Tutor: spiegare senza eseguire

Le domande esplicite su come usare Metnos vengono intercettate allo stesso confine HTTP/Telegram, prima del pianificatore e senza consumare un dialogo pendente. Un rilevatore prudente riconosce soltanto la classe di richiesta; la scheda pertinente non è scelta da sinonimi o frasi exact, ma da embedding BGE-M3 locali confrontati con vettori conservati nel catalogo SQLite firmato.

Dopo il recupero, il principal autenticato filtra il contenuto. Le procedure amministrative restano deterministiche; per le guide informative il modello locale formula la risposta usando soltanto la scheda recuperata e l'inventario ammesso dell'istanza. Non riceve strumenti e attraversa lo slot centrale llm in classe seriale: può spiegare, non agire. Catalogo non valido, match debole o contesto insufficiente producono un esito dichiarato, mai una capacità inventata.

Separazione essenziale. Il codice deterministico governa rilevamento, identità, audience, integrità e procedure di sicurezza; embedding e LLM locale servono dove la varietà del linguaggio rende fragile una tabella di frasi.

12. Sicurezza e reversibilità

La sicurezza non è un modulo: è una catena di guardie indipendenti, e un'azione deve passarle tutte. E siccome anche la guardia migliore sbaglia, l'ultima difesa è poter tornare indietro: undo onesto, per costruzione.

La catena delle guardie — e l'undo come ultima difesa pairing chi sei? codice firmato, ruolo per persona sconosciuto = scartato policy tre livelli di autonomia: ReadOnly · Supervised · Full capability per categoria vaglio guardia: vietati e irrecuperabili; giudice + consenso coi bottoni sempre PRIMA di eseguire sandbox bubblewrap con profilo dal manifest: rete, utente, IPC isolati mai subprocess nudi firma + audit codice legato al manifest via digest; ogni azione in un registro append-only deriva = scarto silenzioso l'ultima difesa: undo di prima classe ● catalogo chiuso di pattern inversi (5): scambia src/dst · elimina i creati · ripristina dal blob · cancella per id ● ogni move è COPY → verifica → DELETE: mai una cancellazione senza copia confermata ● i contenuti sovrascritti finiscono in blob con hash sha256 nella cronologia del turno: «annulla» li rimette al loro posto ok_count onesto anche nell'undo: se dice che ha annullato 3 cose, ha annullato 3 cose le skill restano dormienti finché manca il prerequisito; disattivarne una toglie di mezzo l'intera superficie la skill di sistema (shell, sudo, pacchetti, mount) esiste — ed è per questo che ogni azione privilegiata richiede consenso esplicito, e l'intera skill si può spegnere con una frase
Figura 15 — Cinque guardie in serie (pairing, policy, vaglio, sandbox, firma+audit) e, sotto, la rete di protezione: un undo con catalogo chiuso di pattern inversi, copie verificate prima di ogni cancellazione e conteggi onesti.
Il potere c'è, ed è per questo che è imbrigliato. Con il relativo set di executor, un'istanza Metnos può davvero amministrare una macchina (shell, sudo, pacchetti, mount). Questo la rende un'architettura operativa e non un chatbot. Ma ogni azione privilegiata passa dal vaglio con conferma esplicita, gira in sandbox, finisce nell'audit; e l'intera skill di sistema si può disattivare, chiudendo Metnos fuori dal sistema operativo.
Parte V · Apri la macchina

Dalle promesse ai contratti dei componenti

Qui la visione e il modello implementativo si incontrano: una mappa, una richiesta guidata e un catalogo di contratti di dettaglio.

13. Atlante dei componenti

L'architettura vista fin qui dice cosa promette il sistema. Questo atlante mostra quale componente possiede ogni promessa e dove vive il suo contratto esatto.

13.1 Dalla visione ai contratti dei componenti

L’architettura di Metnos ha due livelli di ingrandimento. Il livello alto descrive il sistema nel suo insieme: strati, organi, leggi e fini. È il percorso che avete appena seguito dal capitolo 1.

Il livello basso è l'insieme degli approfondimenti collegati qui sotto: un documento HTML per ogni componente, con il dettaglio sufficiente a scriverne il codice senza inventare nulla. Le scelte qui non sono opinioni — sono contratti: schema dei dati, firme delle funzioni, flag di sandbox, condizioni di errore. Quando il codice e il documento divergono, vince il documento e il codice si adegua, oppure il documento viene corretto subito (mai «dopo»).

La regola di vita è semplice: nessun componente viene implementato prima che il suo HTML esista, sia approvato e parli la stessa lingua del codice già in casa.

Verifica. Prima di proseguire, dovete aver chiari due punti: (a) il Livello 1 spiega cosa, il Livello 2 spiega come; (b) i documenti del Livello 2 sono contratti, non bozze. Se uno di questi due punti non è ovvio, rileggete il paragrafo precedente prima di andare avanti.

13.2 Quattro nomi, ora come contratti implementativi

Tutto Metnos gira intorno a quattro nomi. Definirli adesso vi risparmia mezz’ora di confusione fra trenta righe.

executor
Una capacità eseguibile: un piccolo programma che fa una cosa sola e bene (leggere file, mandare una mail, calcolare un hash, tradurre un OCR, scoprire URL nuovi su un sito). Ogni executor accetta liste in ingresso e produce liste in uscita; ha un manifest che lo descrive, una firma Ed25519 che lo autentica e un profilo di sandbox che lo confina. Gli appartenenza al prodotto, origine e trasporto restano assi distinti. Gli executor GitHub mantenuti da Metnos sono builtin di origine handcrafted, non importati; il catalogo generato è la fonte unica per la suddivisione del tree sorgente.
mnest
Il filo che collega due executor quando sono stati attivati insieme dal pianificatore. Non è un puntatore di codice, è una traccia: nasce dal contesto, si rinforza con la ripetizione, decade se non viene riusato.
mnestoma
Il grafo emergente di tutti i mnest. È la memoria associativa del sistema: vive su SQLite, viene curata da un processo notturno (ager) e fornisce al pianificatore l’intuizione di «quale executor di solito segue quale». La controparte inglese del termine è mnestome.
agent runtime
Il motore che orchestra il tutto: riceve la richiesta dell’utente, la spezza in passi, sceglie gli executor, li lancia in sandbox, raccoglie le osservazioni, decide il passo dopo. Implementa il loop ReAct con tool-use nativo (LLM locale, tier wise) e si appoggia agli altri componenti per le decisioni difficili (Vaglio per la sicurezza, Synt per le capacità mancanti, Telos per i fini).
Verifica. Provate a completare a voce le frasi: «Un’email viene mandata da un…», «Quando due executor lavorano insieme spesso, fra loro nasce un…», «Tutti questi fili insieme formano il…», «Chi decide la sequenza dei passi è l’…». Se rispondete executor, mnest, mnestoma, agent runtime, potete proseguire.

13.3 La mappa dei componenti

I componenti documentati sono organizzati per ruolo. Lo schema sotto raggruppa i nodi principali per ruolo: il bordo nero spesso è il motore centrale, le forme verdi i «servizi» che il motore consulta, le forme azzurre i «tessuti» che memorizzano lo stato, le forme color bronzo gli organi periferici verso l’utente e verso l’ambiente. Le frecce indicano chi chiama chi.

telos — fini ultimi channel (Telegram) pairing approval_ux agent runtime loop ReAct · pianificatore tool-use nativo vaglio policy sandbox synt executor (pool) contratti firmati + sintesi controllata scratchpad stato del turno mnest tracce di co-attivazione mnestoma grafo + ager obs. dashboard orienta
Mappa dei componenti documentati. Tratto continuo: chiamata diretta. Tratto tratteggiato: orientamento o lettura.

Tre osservazioni utili per leggere lo schema.

  1. Il telos sta sopra a tutto: non è un servizio che si chiama, è un’orientazione. Il runtime pesa le alternative anche in funzione dei fini dichiarati nell’omonimo file del workspace.
  2. Il vaglio è sempre prima dell’esecuzione, mai dopo. Una volta che un executor è partito non si torna indietro in modo gratuito: l’undo esiste, ma costa storia e blob di backup.
  3. Il pool di executor è aperto: il synt può comporne di nuovi mettendo in fila quelli esistenti, oppure (se non basta) generandone uno ex novo, con firma e installazione automatica.

13.4 Una seconda richiesta guidata

Per fissare la mappa, seguiamo una richiesta semplice dall’ingresso fino alla risposta: «sposta in ~/Archivio/2026 i PDF di fatture arrivati questa settimana».

  1. Channel. Telegram riceve il messaggio dell’utente. Il daemon controlla che il mittente sia stato pairato con un livello d’autorizzazione sufficiente; in caso contrario il messaggio viene scartato senza eco. Pairing significa «canale + sender ID riconosciuto»: si ottiene rispondendo a un codice Ed25519 firmato con TTL.
  2. Agent runtime — pianificazione. Il runtime estrae l’intent (verbo canonico: move; oggetto: files; criterio: PDF allegati a fatture in finestra «ultima settimana»), interroga il prefilter per ridurre il catalogo agli executor pertinenti e prepara il primo passo del loop ReAct.
  3. Vaglio — guardia + giudice. Prima di lanciare l’executor il Vaglio controlla due cose: che il percorso non sia vietato (forbidden paths), che il comando shell non sia irrecuperabile (rm -rf e simili). Per le operazioni che cadono in zona grigia, il giudice rule-based assegna un punteggio e, se sopra soglia, chiede una conferma all’utente tramite carta a 3 righe (cosa/dove/perché).
  4. Sandbox + executor. Il runtime invoca read_messages dentro bwrap con i flag derivati dal manifest. L’output torna come lista di entries; ogni entry è un dizionario con il path del PDF e i metadati.
  5. Pipe. Il passo successivo è move_files; riceve la lista del passo precedente con from_step: N. La verità sui dati vive nello scratchpad: il pianificatore non vede l’intera lista, ne vede una vista sintetica che gli basta per decidere.
  6. Mnest + mnestoma. La coppia read_messages → move_files rinforza una traccia esistente nel grafo. Se non esiste, viene creata. L’ager notturno farà manutenzione: decadimento, fusioni, scarti.
  7. Risposta. Il runtime restituisce all’utente, via Telegram, il numero di file spostati e il primo motivo di scarto se qualcosa è stato escluso. La final_answer include il marker di troncamento se la lista di partenza era stata limitata da un cap.
Verifica. Provate a rispondere senza guardare i passi: chi parla con l’utente? chi decide la sequenza? chi lancia gli executor? chi controlla che l’operazione sia lecita? chi memorizza che le due capacità sono andate a braccetto? Se le risposte sono channel, agent runtime, agent runtime, vaglio, mnestoma, allora la mappa è vostra.

13.5 Gli approfondimenti canonici

Sotto, i documenti sono raggruppati per ruolo. Tutti hanno la controparte inglese in /en/architecture/.

Motore centrale
ComponenteCosa copre
Motore cognitivo Il motore a quattro strati che pianifica ed esegue (sostituisce il pianificatore passo-passo iterativo): Fastpath serve le scorciatoie approvate dall'utente (hash + coseno BGE-M3), Autopath riconosce e riusa le skill apprese dal feedback (sqlite, match semantico + intent), Validator controlla il piano prima di eseguirlo, e il blocco Engine propone l'intero piano in una sola chiamata LLM locale (Proposer), lo esegue deterministico (Executor), recupera classificando l'errore in 4 classi (Recovery) e, se non c'è via d'uscita, spiega onestamente cosa manca (Terminator). Una sola proposta invece di sei chiamate: più veloce, costo zero, e accelera ancora man mano che impara.
agent_runtime Loop ReAct, mode router, data piping fra step (from_step: int per liste, {{stepN.field}} per scalari), scratchpad, hook su mnestoma. È il motore che chiama tutti gli altri.
scratchpad Archivio temporaneo del turno: tiene le observation grandi senza occupare il contesto del pianificatore. Builtin scratchpad_read con head/tail/range.
grammar Constrained generation via GBNF per il tool_call del PLANNER. Discriminated union nome+args, schema recursive, pool filter contestuale, validator post-decode. Risolve thinking-loop, mix-match args, escape-hatch arbitrari. Bench convergenza 50% → 100%.
fastpath e autopath Due livelli di memoizzazione prima del pianificatore. L0 — fastpath: la scorciatoia della stessa richiesta, riconosciuta per impronta (hash) o per vicinanza semantica (coseno BGE-M3) e riservita con il piano già pronto, argomenti concreti compresi. L1 — autopath: il piano generalizzato di un cluster di richieste affini (lo scheletro senza argomenti), promosso dai riscontri positivi ripetuti e custodito in autopath.sqlite (tabelle autopaths/anti_autopaths). Estrattore di argomenti ibrido (regola + memoria + LLM opzionale).
Tutor Guida locale pre-planner: compila manifest ammessi, documentazione pubblica allowlist e procedure curate in un catalogo BGE-M3 firmato. Risponde senza strumenti, filtra l'audience prima del modello, distingue spiegazioni da azioni e dichiara le lacune. Include architettura F2 e roadmap F3/F4.
account mail Configurazione di mailbox IMAP/SMTP, anche non Google: binding cifrati, account multipli, compatibilità con i file env e confine con le funzioni specifiche di Gmail.
lifecycle Lifecycle unificato dei cambiamenti al sistema: un solo oggetto change_intent, una sola macchina a stati (proposed→accepted→applied→observed→finalized, più staged/rejected/failed/rolled_back), una sola UI /admin/changes. Convoglia le sorgenti di proposta (telos, introvertiva, synt, fast-path, feedback) in un’unica coda. Pipeline notturna: materializzazione (dedup fra sorgenti via fingerprint), applicazione per tipo, osservazione con periodo di grazia e rollback fisico.
virtualizzazione dei modelli Come Metnos sceglie e sostituisce i suoi modelli: tre facciate (get_llm, get_embedder, get_vlm) che chiedono un ruolo, non un modello, e traducono il ruolo leggendo i file {llm,embedding,vlm}_tiers.toml. Cambiare modello = editare un TOML, mai il codice. Segregazione (nessun consumatore importa più l’embedder concreto), autonomia dell’embedding (BGE-M3 e SigLIP girano ONNX in-process), endpoint remoto via provider="http". Sottoinsieme leggero del pattern supranet: Protocol + factory, niente registry/DI.
Capacità eseguibili e loro nascita
ComponenteCosa copre
executor Introduzione didattica: cos'è un executor, anatomia in cinque file, manifesto firmato, recinto di esecuzione, ciclo di vita, tre origini (a mano / generato / di sistema). Tre esempi concreti. Il conteggio corrente vive nel catalogo generato, non in questo testo.
catalogo executor Censimento generato dai manifest firmati: tutti gli executor first-party raggruppati per dominio canonico, con scopo, criticità, piattaforme e posizione nel sorgente.
remote_executors Come una parte controllata del catalogo executor può girare su dispositivi registrati: metnos-client, appaiamento del device, placement da manifest, sandbox per sistema operativo, installazione dalla UI e limiti espliciti su Windows/Linux.
executor intelligenti Agenti a mandato ristretto dietro un normale contratto executor: ciclo adattivo bounded, resolver deterministici prima del modello, autorità invariata e postcondizioni verificabili. login_sites è il primo esempio.
synt Come nascono nuovi executor: pipeline a cinque stadi (naming, signature, tests, description, code), cascata reattiva (compose → generate) e introvertiva (dedupe, generalize, specialize).
skill_importer Importa skill di terzi da agentskills.io e ne ricava executor Metnos: pipeline a cinque stadi (fetch, parse, map, wrap, register), tabella di mapping verbi skill_vocab_map.json, helper di wrapping con confine del verbo e CLI metnos-skills import|list|uninstall|status|evaluate.
skills & backends Perché skill e backend sono due assi ortogonali: il backend dice COME esegui un verbo_oggetto (configurazione, backend_resolver, invisibile all'LLM), la skill dice SE/QUALI capacità sono sbloccate (attivazione, dormienza, recinto). Tre tier (core / first_party / imported), architettura multi-provider trasparente al planner, promozione con frontier una-tantum.
Memoria associativa
ComponenteCosa copre
mnest La traccia di co-attivazione fra due executor: anatomia, lifecycle, decadimento, persistenza, proto-mnest.
mnestoma Il grafo emergente di tutti i mnest: schema dati SQLite, operazioni atomiche, ager notturno, snapshot. In EN il termine è mnestome.
Sicurezza, regole, sandbox
ComponenteCosa copre
vaglio Guardia binaria (forbidden paths, comandi shell quasi-irrecuperabili) e giudice graduato rule-based con soglia configurabile. Giudice LLM probabilistico rinviato.
policy Capability registry chiuso, tabella autonomy × capability (ReadOnly / Supervised / Full), grants per_target persistenti, effective_outcome combinato.
sandbox Profilo bwrap derivato dal manifest: read-only del codice, isolamento di rete se nessuna capability lo richiede, fallback graceful se bwrap manca. Landlock rinviato.
Canale verso l’utente
ComponenteCosa copre
channel Adattatore canale (Protocol con send / poll) e prima implementazione concreta: TelegramChannel con long-poll, persistenza last_update_id, daemon e systemd user unit. Multi-user: send_to(chat_id, OutboundMessage) + /start <token> per pairing guest.
http_api Secondo server HTTP (porta 8770): canale agent uniforme su POST /agent/turn (SSE + JSON), dashboard /admin in htmx + Jinja2 + uPlot, gestione utenti, proposte introvertiva, scheduler runs. Auth via admin key (cookie 7g) o Bearer device.
pairing Due percorsi: /pair con codici Ed25519 firmati per device tecnici e /start <token> a vita breve per familiari/guest (multi-utente). Registro users.db con host + guest, user_channels, resolve_recipients. Bootstrap automatico del host al primo avvio.
approval_ux Carta a 3 righe per le richieste di conferma: render_approval_card, ApprovalRequest, modulazione full / medium / short per ricorrenza, dispatcher Telegram approve:<tok> / reject:<tok>.
Multilinguismo
ComponenteCosa copre
multilang Tre layer multilingua: prompt LLM (runtime/prompts/<lang>/<role>.j2), description executor (manifest TOML + companion JSON), messaggi user-facing (i18n.sqlite). Source-of-truth latest-wins: nessuna lingua canonica per costruzione, vince chi viene editato per ultimo. Comando admin metnos-prompts add-language <code>. Tier frontier opt-in per qualità superiore.
Visibilità e fini
ComponenteCosa copre
observability Dashboard statica HTML che aggrega le sorgenti dati di Metnos (mnestoma, pairing, turni, decisioni del Vaglio, scheduler). Generata su richiesta: nessun server live, niente JavaScript.
telos Fini ultimi dell’utente, funzione di allineamento, bother budget con quote di scheduler, telos di non-rinuncia (t.coltivazione_strumenti) e clausola di stop. Il file TELOS.md vive nel workspace.

13.6 Vocabolario e primitive

Il vocabolario chiuso conta 26 azioni (read, write, move, delete, create, find, list, filter, sort, group, classify, get, set, send, describe, render, extract, compress, compute, compare, change, order, share, open, login, act) e 26 oggetti (files, dirs, packages, messages, events, contacts, places, processes, urls, numbers, images, signatures, texts, proposals, persons, tasks, inputs, approval, credentials, issues, pulls, calendars, entries, lists, skills, sites). I qualifier sono divisi in quattro famiglie: formato (codifica del dato), modalità (come agisce l’executor), criterio di sicurezza, provider (per indicare un backend diverso da quello predefinito, ad esempio _google_workspace). Tutto centralizzato in runtime/vocab.py.

Le liste di entries che il turno produce passo per passo si manipolano con nove consumer planner-visible. I cinque operatori strutturali o numerici sono filter_entries, filter_lists, sort_entries, group_entries e compute_entries. I quattro helper semantici in-process sono classify_entries, compare_entries, extract_entries e describe_entries. Il primo gruppo filtra una lista, combina due liste, ordina, unisce/deduplica o calcola un aggregato; il secondo classifica, confronta semanticamente, estrae record strutturati o sintetizza. L'elenco è verificato contro il registro del runtime e i manifest firmati. Esempio reale: la domanda «c’è un appuntamento HLT che si sovrappone a uno MNM nei prossimi tre mesi?» viene risolta in sei passi: read_events → due filter_entries (uno per HLT, uno per MNM) → filter_lists(op=overlap) → risposta finale.

L'inventario live verificato comprende 115 executor standard e firmati: 82 handcrafted nel tree principale, 16 builtin GitHub di origine handcrafted e 17 builtin runtime con trasporto in-process. Il Composer usa lo stesso contratto per tutti e non sceglie in base al trasporto. I verbi produttori ortogonali sono cinque (find per pattern, get per id/stato, read per blob da sorgente, list per container, filter per riduzione).

13.7 Convenzioni dei contratti

Ogni file di contratto di un componente segue lo stesso template della visione architetturale di questo manuale:

14. I principi, in otto carte

Se di questo documento doveste ricordare solo otto frasi, sono queste. Tutto il resto — codice, prompt, convenzioni — discende da qui.

1Vettoriale per costruzione. Ogni executor accetta una lista e ritorna una lista, anche degenere. La versione batch è l'executor: *_batch non esiste.
2Vocabolario chiuso, governato. Tutto ciò che agisce ha un nome componibile dentro una grammatica chiusa. Un termine nuovo entra solo se necessario, generale e comprensibile.
3Nessun fallimento silenzioso. I conteggi riflettono ciò che è successo davvero; il troncamento si dichiara, non si nasconde; un parziale presentato come completo è un bug.
4Deterministico > LLM. Dove un automa o una tabella bastano, il modello non si usa. L'LLM entra dove un parser equipotente sarebbe davvero troppo complesso — e ci entra vincolato.
5Mai una cancellazione implicita. Ogni spostamento è copia → verifica → cancellazione; mai DELETE senza COPY confermata.
6Reversibilità con motivazione. Ogni atto evolutivo (sintesi, fusione, archiviazione) è reversibile e motivato. Dire sì costa meno quando si può tornare indietro.
7i18n per costruzione. Ogni stringa e prompt rivolto all'utente è dato per-lingua: una lingua nuova è un pacchetto di traduzione, non un fork del codice.
8Comprensibilità come dovere. Se l'utente non capisce il sistema, il sistema non serve. La semplicità non è estetica: è il criterio che ha selezionato tutto il resto.

15. Cosa NON è Metnos

Metà del design sta nei no. Ogni tentazione di aggiungere un elemento di questa lista va respinta.

16. Dove andare dopo

Ora avete entrambi i livelli: il sistema dall'alto e la mappa dei contratti dei componenti. Usate l'atlante per il dettaglio implementativo, oppure proseguite con il tour, il glossario e i dialoghi di progetto.

riferimento
Contratti dei componenti
Torna all'atlante e apri il contratto implementativo esatto che ti serve.
reference operativa
Domini ed esempi
Che cosa puoi chiedere a Metnos, dominio per dominio, con frasi naturali pronte da adattare.
guida introduttiva
L'interfaccia
I due canali, le sezioni di Settings e la mappa delle pagine con il loro percorso.
tour · 10 min
Quick Tour
Il giro veloce con le schermate: cosa si prova a usarlo, prima di studiarlo.
riferimento
Glossario
Ogni termine del progetto, definito una volta e linkato ovunque.
dialogo · 40 min
Dialogo sui fini e sui limiti
Le origini galileiane: teleologia, le 4 Leggi, il vaglio. Perché un agente proattivo ha bisogno di un freno.
dialogo · 45 min
Dialogo sugli executor
La fondazione tecnica: executor, mnest, mnestoma, tracce, ager, i sei principi originari.
contratto del componente
Executor remoti
Come Metnos sposta alcuni executor dal server a un PC registrato, mantenendo policy, audit e limiti espliciti.
codice
Il repository
AGPL-3.0, pre-1.0: il subset pubblico dell'istanza in esercizio, installer compreso.

Metnos — Manuale di architettura (luglio 2026).
mētis + noûs: l'intelligenza astuta al servizio della mente — su hardware tuo.
Documentazione bilingue IT+EN su metnos.com; codice su github.com/brunialti/metnos.