Una skill è la documentazione strutturata di come si usa un servizio
(il calendario di Google, una casella di posta, un servizio meteo). Vive
in un file di testo che si chiama SKILL.md, accompagnato da
qualche piccolo script di supporto. Lo standard pubblico si chiama
agentskills.io.
Il file ha un'intestazione (nome, autore, versione, dipendenze) seguita da paragrafi: «cosa fa», «come si configura la prima volta», «esempi di invocazione». Niente di esotico: il formato è pensato per essere letto da un essere umano e poi, di passaggio, da un agente.
Metnos sa importare una skill così com'è: legge il file, ne ricava una serie di executor in formato Metnos, e li mette nel catalogo come se fossero stati scritti a mano. Una volta importati, l'agente li chiama esattamente come gli altri, e l'utente non vede la differenza.
L'importazione è una catena di cinque fasi, tutte automatiche. L'unico passo richiesto all'utente è il via iniziale: «importa la skill X».
Il parser legge SKILL.md e ricava la struttura: nome, autore, capabilities dichiarate, lista di sotto-comandi con i loro argomenti.
Ogni sotto-comando viene mappato sul vocabolario chiuso di Metnos (verbo + oggetto canonico): calendar list diventa read_events, gmail send diventa send_messages.
Per ciascun executor il generatore produce il file Python e il manifest TOML usando template fissi (Jinja). Solo la descrizione del manifest viene rifinita da un modello linguistico per la cura linguistica.
Cinque verifiche cumulative: nome nel vocabolario, niente sovrapposizione con executor esistenti, descrizione coerente con il codice, capability dichiarate sensate, contratto in entrata e in uscita valido.
Il manifest viene firmato Ed25519. L'executor entra in una cartella sotto sorveglianza separata da quella degli executor scritti a mano. Il loader lo carica al riavvio.
Tra i cinque, solo il passo 3 (Generazione) si appoggia a un modello linguistico, e solo per due cose specifiche: la descrizione in italiano e inglese, e le otto-quindici parole chiave di affinità che aiutano il pianificatore a scegliere lo strumento giusto. Tutto il resto è deterministico: stesso ingresso, stessa uscita.
append_rows: diventa
change_files_xlsx. Una che parla di label messages
non genera label_messages: viene rifiutata se non c'è
un modo coerente di tradurla. La rigidità del vocabolario protegge
l'agente da nomi inventati o sinonimi: ogni domanda di lavoro viene
indirizzata allo stesso strumento di sempre.
La skill può arrivare da tre posti:
SKILL.md sul disco
che hai già (di solito perché lo stai sviluppando).agentskills.io/<autore>/<skill>; l'importatore
lo traduce nel corrispondente repository pubblico e scarica.SKILL.md raw; in questo caso l'importatore
clona o scarica direttamente.Le skill scaricate vengono messe nella cache locale per sette giorni. Importare due volte la stessa skill nello stesso periodo non genera traffico: si attinge dalla copia già in cache.
Dopo l'importazione, sul disco compaiono una o più cartelle, una
per ogni sotto-comando della skill. Ognuna contiene gli stessi file che
trovi in un executor scritto a mano: il file Python con la funzione
invoke, il manifest TOML, la firma, il profilo del recinto.
~/.local/share/metnos/executors/skills/google-workspace/
read_events/
read_events.py
manifest.toml
manifest.toml.sig
manifest.lang_state.json
set_events/
…
delete_events/
…
… (un'altra ventina, per Gmail, Drive, Sheets, Docs, Contatti)
La cartella di destinazione è skills/ (ADR 0160; il
nome precedente _imports/ resta letto in modalità back-
compat), sotto la cartella degli executor sintetizzati. Questo separa
visivamente quanto
viene da fuori da quanto Metnos ha scritto da solo, e da quanto è
stato scritto a mano. Tutti e tre i tipi finiscono però nello
stesso catalogo dell'agente, e tutti passano dagli stessi controlli al
momento dell'uso.
Nel manifest di un executor importato compare una sezione in più, che dichiara la sua origine:
[provenance] synthesized = true imported_from = "agentskills.io/googleworkspace/calendar" source_version = "1.1.0" imported_at = "2026-05-10T22:00:00Z" source_sha256 = "<impronta digitale del file di origine>"
È l'unico segno che lo distingue da un executor scritto a mano. Tutto il resto — firma, recinto, vocabolario, contratto — è identico.
Una skill importata non parte automaticamente come affidabile. Cinque controlli cumulativi decidono se ammetterla nel catalogo:
| Controllo | Cosa verifica | Cosa rifiuta |
|---|---|---|
| Nome canonico | Il nome dell'executor è nella forma verbo_oggetto con verbo e oggetto del vocabolario. | Nomi di fantasia o inventati, sinonimi non riconosciuti. |
| Sovrapposizione di affinità | L'executor importato non condivide troppe parole chiave con uno già esistente. | Doppioni mascherati, executor che ruberebbero il lavoro a uno già presente. |
| Coerenza descrizione-codice | Un modello linguistico controlla che ciò che il manifest promette sia ciò che il codice fa davvero. | Description ingannevoli, scollature semantiche. |
| Unicità delle credenziali | Se la skill richiede credenziali (chiave API, token), il loro nome di legame non è già preso da un'altra skill importata. | Collisioni invisibili che metterebbero un servizio sopra l'altro. |
| Asserzioni di instradamento | Per ogni executor accettato, viene aggiunta una piccola batteria di domande prototipiche («elenca i miei appuntamenti di domani» dovrà pescare read_events). | Tool che si infilano nel mestiere di altri (regressioni di routing). |
I rifiuti vengono registrati in un registro di audit insieme alle motivazioni. Quando un sotto-comando di una skill viene rifiutato, gli altri della stessa skill continuano la corsa: l'importazione è parziale, mai un tutto-o-niente.
La maggior parte delle skill utili si appoggia a servizi che richiedono una chiave di accesso: una API key, un token OAuth, il file di sessione di un account. L'importatore non chiede mai queste cose in anticipo. La prima volta che l'agente prova a usare un executor che richiede credenziali e non le trova, succede questo:
decision = "needs_inputs" con un
piccolo modulo di richiesta.~/.local/share/metnos/credentials/).
Le invocazioni successive non chiedono nulla. Se il token scade,
l'executor segnala error_class = "auth_required" e il
flusso ricomincia. Niente token nei file di configurazione,
niente password nel codice.
Per consultare cosa è già configurato senza vedere i
valori, ci sono tre executor canonici:
find_credentials (elenca i collegamenti configurati,
solo i metadati), set_credentials (registra una credenziale
nuova), delete_credentials (cancella un collegamento).
I valori in chiaro non escono mai da quegli executor: il pianificatore
e i suoi modelli vedono solo nome del collegamento, impronta digitale,
data, e stato («configurato», «scaduto», «mancante»).
Roberto chiede: «importa la skill di Google Workspace».
metnos-skills import agentskills.io/googleworkspace/google-workspacegmail reply collide con send_messages; gmail labels non ha qualifier canonico; sheets append collide con la sua update).skills/google-workspace/ (ADR 0160).read_events (uno dei 21), che risponde servono credenziali e apre il modulo di richiesta. Roberto fornisce il client secret e l'URL di redirezione una sola volta; le invocazioni successive funzionano in silenzio.Tempo totale, escluso il setup di OAuth la prima volta: meno di tre minuti per ventuno strumenti nuovi.
Importare codice scritto da altri (third-party) richiede strati di controllo che il codice handcrafted non ha. Una skill importata potrebbe essere stata manomessa, dichiarare cose diverse da quello che fa, imitare uno strumento esistente per dirottare la chat, o esfiltrare credenziali senza lasciare traccia. I sette strati riducono ognuno un rischio diverso, in modo progressivo. ADR 0159 dettaglia ogni strato.
| Strato | Quando | Cosa intercetta |
|---|---|---|
| L1 sign verify | ogni avvio | file manomesso dopo l'import (digest sha256 + Ed25519) |
| L2 affinity overlap | at-import | skill che imita uno strumento esistente (Jaccard ≥0.5 → rifiuto) |
| L3 efficacy ager | cron giornaliero | skill che fallisce silenziosamente o non viene mai scelta (deprecate 30g, archive 14g) |
| L5 smoke battery | at-import | skill che restituisce schema rotto o crasha |
| L6 verifier semantico LLM | at-import | scollamento fra cosa il manifest dichiara e cosa il codice fa |
| Runtime vaglio | ogni invocazione | azione attuale viola policy (guard + safe-verb shortcut + judge LLM) |
| Skill audit JSONL | ogni invocazione | esfiltrazione / abuso credenziali (traccia append-only per forensics) |
Gli executor handcrafted (scritti dal team Metnos) non hanno L2, L6 e
audit: il codice è trusted per costruzione, il manifest e il
comportamento sono allineati per definizione, e l'audit di chi ha fatto
cosa è in git blame.
Gli strati sono indipendenti: se L6 fallisce (LLM down) restano
attivi L1/L2/L3/L5; se L2 e' troppo stretto (Jaccard 0.5 puo' rigettare
skill legitime affini) il provider qualifier (_google_workspace)
distingue (ADR 0136).
| Per capire… | Leggi |
|---|---|
| cos'è un executor e come è fatto | executor |
| come il Synt scrive un executor da zero (alternativa all'import) | synt |
| il recinto in cui gli executor importati eseguono | sandbox |
| i controlli prima di ogni azione rischiosa | vaglio |
| l'archivio decisionale (perché importare invece di adottare lo standard) | ADR 0123 |
Metnos — skill importer, introduzione didattica