Sistec · audit skill · marketplace interno · 2026-07
Da marzo 2025 a oggi, nell'ambiente src/ di Sistec si sono accumulati
20 file — comandi, script, framework. Alcuni sono skill preziose e riusabili;
altri sono nati per esigenze contingenti e oggi sono rumore. Questo documento è l'esito della
validazione: 6 skill integrate nel marketplace, 14 scartate
con la motivazione scritta per ciascuna, e il filtro a tre domande che ha
deciso ogni caso.
Il marketplace delle skill è un repository git interno, branch main protetto, accesso via PR.
A differenza di un marketplace pubblico, la specificità di dominio Sistec (lo schema
language_spv per le traduzioni HMI, le convenzioni Sistec.Core, i pattern di
sviluppo delle soluzioni .NET per automazione industriale) non squalifica un file —
anzi, è il motivo per cui una skill esiste: incapsula conoscenza di dominio che un LLM generico non ha.
Nota importante: i command sono deprecati in Claude Code a favore delle skill. La forma
corretta per un'operazione che un umano invoca esplicitamente è una skill con
disable-model-invocation: true. Tutti i file src/ in formato command sono
stati giudicati come potenziali skill, non come command.
Il cuore dell'audit è un filtro a tre domande. Un file merita di diventare una skill nel marketplace solo se passa tutte e tre. Se anche una sola risposta è «no» o «forse», il file viene scartato.
Git, linter, analyzer, docker compose, uno script PowerShell. Se per quel compito esiste
già un tool deterministico che dà risposte certe, un'approssimazione LLM ha valore
negativo: aggiunge non-determinismo, consuma contesto, e azzera il vantaggio di uno strumento
che invece produce lo stesso risultato ogni volta. La risposta «sì» squalifica immediatamente.
Claude Code ha funzionalità native: la plan mode per analizzare senza scrivere, /clear per resettare il contesto, i tool di default (Read, Grep, Glob). Se un file cerca di insegnare a Claude ciò che Claude sa già fare, è ridondante — e peggio, rischia di peggiorare il comportamento nativo con istruzioni approssimative.
La domanda decisiva. La skill deve portare giudizio semantico — qualcosa che solo un LLM può fare: interpretare un output ambiguo, tradurre un intento in codice, applicare conoscenza di dominio a un contesto specifico. Se togli la skill e Claude se la cava comunque (magari con un prompt un po' più lungo), la skill non merita il marketplace.
Il filtro nasce da un'osservazione pratica: nei mesi di utilizzo di Claude Code in Sistec, molti comandi e script sono stati scritti per compensare presunti limiti dell'LLM, ma in realtà cercavano di risolvere con un prompt ciò che un altro tool faceva già in modo certo. Il filtro rovescia la prospettiva: invece di partire da «cosa posso insegnare a Claude?», si parte da «cosa solo Claude può fare qui?».
Dall'audit emergono due pattern ricorrenti che superano il filtro:
1. Bundla + interpreta. Uno script deterministico raccoglie dati grezzi (es. sonda la configurazione DPI delle form, o scandisce le NIC di rete); l'LLM interpreta il risultato e decide l'azione migliore. Il valore LLM è nel giudizio, non nella raccolta.
2. Puro semantico. Un lavoro che nessun tool deterministico sa fare: tradurre testo HMI da IT a EN rispettando le chiavi esatte del database, manutenere un .docx preservando commenti e revisioni, portare l'intento di una feature tra due codebase divergenti.
Il punto comune: l'LLM non sostituisce un tool — fa ciò che il tool non può fare.
Sei file di src/ sono diventati skill nel marketplace. Cinque sono skill nuove; una è il
risultato di una fusione tra due file, dove solo una parte del secondo è stata recuperata.
Ognuna è stata de-coupled dal workspace privato di chi l'ha scritta: i path assoluti
(C:\Users\Sistec 23\…) sono diventati relativi o referenziano
$env:CLAUDE_PLUGIN_ROOT, le direttive proprietarie sono state riscritte in regole chiare,
e gli engine deterministici (.ps1) sono stati bundlati come assets/ del plugin.
File src/ originale | Skill nel marketplace |
|---|---|
dpiRepair | hmi-developer/dpi-anchor-fix |
networkProbe | device-spy/network-probe |
manualize | technical-writer/maintain-manual |
translate | hmi-developer/translate |
gitReconcile | hmi-developer/reconcile-solutions |
commentize (parziale) | hmi-developer/add-doc fuso |
hmi-developer/dpi-anchor-fix
Il problema. Le form .NET 8 di Sistec soffrono di un bug noto di DPI e ancoraggio: su schermi ad alta risoluzione, i controlli si spostano o si ridimensionano male perché l'ancoraggio non è calcolato correttamente al cambio di DPI. È un problema deterministico — uno script può analizzare il file .resx o il designer e identificare le form a rischio.
La soluzione. Uno script PowerShell bundlato scandisce le form aperte e produce un
report: quali controlli hanno ancoraggio incompleto, quali form hanno il flag DPI assente, quali
property sono potenzialmente errate. L'LLM interpreta il report e, per ogni
segnalazione, decide quale configurazione applicare — perché la correzione dipende dal contesto:
a volte basta aggiungere AutoScaleMode = Dpi, a volte va rivisto l'ancoraggio dei
controlli figli, a volte è un falso positivo.
Perché passa il filtro. Lo script fa la parte deterministica; l'LLM fa ciò che lo script non può fare: decidere, caso per caso, quale rimedio è sicuro sotto le condizioni del progetto. Pattern «bundla + interpreta».
device-spy/network-probe
Il problema. Quando un dispositivo industriale (PLC, pannello HMI, IPC) non risponde in rete, le cause possono essere molteplici: cavo scollegato, conflitto IP, driver corrotto, link-flap sul switch, scheda di rete disabilitata. Un tecnico in sede deve diagnosticare rapidamente, ma la diagnostica manuale è lenta.
La soluzione. La skill lancia uno script che sonda la macchina: interroga le NIC
via Get-NetAdapter, controlla l'assegnazione IP (Get-NetIPAddress),
verifica la connettività con ping e tracert, raccoglie lo stato dei driver. L'LLM analizza
l'output e diagnostica: «link-flap sulla porta 3 dello switch» vs «conflitto IP con 192.168.1.45»
vs «driver Intel PRO/1000 fermo al codice 43».
Perché passa il filtro. Stesso pattern: lo script raccoglie dati deterministici,
l'LLM li interpreta con conoscenza di dominio che un tool da solo non ha. Un ingegnere esperto
riconoscerebbe link-flap dall'output di Get-NetAdapterStatistics; la skill incapsula
quella conoscenza.
technical-writer/maintain-manual
Il problema. I manuali tecnici di Sistec sono file .docx (non markdown) con commenti, revisioni tracciate, immagini incorporate. «Aggiungi un paragrafo sulla procedura di calibrazione» non è un'operazione banale: bisogna aprire il file con python-docx, navigare la struttura XML nascosta, inserire il contenuto nel punto giusto senza rompere i canali di commenti e tracked changes, aggiornare il conteggio delle immagini, e salvare preservando il formato.
La soluzione. La skill incapsula tutto il know-how python-docx necessario: l'apertura corretta del file, la navigazione dei paragrafi, l'inserimento di testo con formattazione, la preservazione dei commenti esistenti, l'aggiornamento del conteggio immagini. L'operatore dice «aggiungi questa sezione dopo il paragrafo X» e la skill gestisce il resto.
Perché passa il filtro. Puro valore LLM riusabile. Nessun tool deterministico sa gestire i canali nascosti di commenti e revisioni di un .docx — servono conoscenza del formato XML di Office Open XML e dell'API python-docx. La skill è il know-how stesso, non un'istruzione su come usare un tool esterno.
hmi-developer/translate
Il problema. Le HMI di Sistec hanno stringhe in italiano da tradurre in inglese
(e viceversa). Le traduzioni vivono in un database con schema language_spv, dove
ogni stringa ha una chiave esatta che deve corrispondere al call-site
(# = esatta, niente approssimazioni). Il file MissingTranslations.csv
elenca le chiavi mancanti.
La soluzione. La skill legge il CSV, per ogni chiave mancante inferisce il
significato dal contesto di chiamata (legge il file .xaml o .cs che usa quella chiave), e
produce gli INSERT corretti per il database. La regola «chiave esatta» è critica:
l'LLM non deve inventare variazioni — deve generare la traduzione giusta per quel contesto preciso.
Perché passa il filtro. La traduzione HMI non è tradurre parole: è capire
dove quella stringa appare nell'interfaccia e tradurla coerentemente con le
convenzioni Sistec (es. «Avvia ciclo» → «Start cycle» e non «Start the cycle»). Solo un LLM
può farlo — un dizionario deterministico non basta. La skill è stata semplificata
rispetto all'originale: ora usa connessione DB diretta, rileva automaticamente la versione
(5.7 ≡ 8), e supporta --apply e --rescan.
hmi-developer/reconcile-solutions
Il problema. In Sistec coesistono prodotti distinti che condividono heritage — ad esempio, due soluzioni .NET partite dallo stesso codice base ma divergenti da anni. Portare una feature da una all'altra non è un semplice merge: i nomi sono cambiati, le architetture si sono differenziate, le API pubbliche non coincidono più.
La soluzione. La skill non applica diff: riapplica l'intento della feature. Dove il codice condiviso esiste ancora, fa cherry-pick o merge. Dove i due prodotti sono divergenti, l'LLM capisce cosa faceva la feature nell'originale e la reimplementa nel nuovo contesto, adattandola alle convenzioni e all'architettura del destinatario.
Perché passa il filtro. Raro ma legittimo. Il documento SKILL-AUDIT.md
spiega il caveat: per feature tra branch dello stesso repo, il workflow
giusto è un branch. Ma quando i prodotti sono davvero distinti (non branch dello stesso
storico git), l'LLM è l'unico strumento che può riapplicare l'intento. reconcile-solutions
è stato tenuto esplicitamente con questa consapevolezza — non è la soluzione di default, ma
esiste per il caso eccezionale.
hmi-developer/add-doc fusa da commentize
Il problema. Documentare il codice è un problema eterno. Due file di
src/ cercavano di risolverlo: commentize e un altro frammento
di disciplina commenti. Entrambi avevano parti valide e parti scartabili.
La soluzione. Dalla fusione è nata add-doc, una skill singola
e generale che applica una disciplina di commenti solo sul changed-set —
non sull'intera codebase. Da commentize è stato recuperato solo lo scoping
sul changed-set; sono stati scartati /simplify (un altro comando assente),
la regola S9 «documenta i privati» (eccessiva), e il gitize-cache (caching non necessario).
Il risultato è una skill corta, generale, con zero leakage di workspace privato.
Perché passa il filtro. È il perfetto esempio di cosa sia una skill ben fatta: non dice «scrivi commenti», ma disciplina dove scriverli (solo ciò che è cambiato) e come (convenzioni Sistec). L'LLM interpreta il diff e decide cosa merita un commento — è giudizio semantico, non un copia-incolla.
Ogni skill ha subito lo stesso trattamento di de-coupling: gli path assoluti
(C:\Users\Sistec 23\…) sono diventati $env:CLAUDE_PLUGIN_ROOT o percorsi
relativi; le label proprietarie (P0–P15, convenzioni S-series) sono state trasformate in regole
in chiaro o in rimandi a assets/rules/; i memory-anchor ([[…]]) e i
ledger di progetto attivo sono stati rimossi; le description sono state riscritte
orientate al trigger (cosa fa scattare la skill), e per le operazioni deliberate o rischiose è
stato impostato disable-model-invocation: true; gli engine deterministici
(.ps1) sono stati bundlati come assets/ del plugin, non referenziati da path locali.
La barra di qualità usata è add-doc: corta, generale, zero leakage di workspace
privato, description che dice chiaramente cosa fa e quando si usa.
Quattordici file non hanno superato il filtro. Le motivazioni si dividono in tre categorie nette, più un caso a sé stante (port-solution) che è stato scartato per un cambio di paradigma nel flusso di lavoro.
Il gruppo più numeroso (7 file). Sono comandi che avvolgono operazioni che un tool deterministico esegue già in modo perfetto: git puro, docker compose, comandi di copia file, scan di dead code. In tutti questi casi, un LLM non solo non aggiunge valore — lo sottrae, perché introduce non-determinismo, consuma contesto, e rischia di sbagliare ciò che un tool farebbe sempre giusto.
| File | Cosa faceva | Perché scartato |
|---|---|---|
fetch |
Eseguiva operazioni git di sincronizzazione: fetch, rev-list,
status --porcelain, merge --ff-only, più predicati per decidere
se un branch è aggiornato o divergente. |
Git puro. Un loop in PowerShell o bash fa esattamente le stesse operazioni in modo deterministico, senza consumare contesto LLM, senza rischio di allucinazioni, e con exit code certi. Le condizioni booleane («è aggiornato?») non richiedono giudizio semantico: sono predicati su diff di SHA. |
gitAlign |
Allineava branch locali ai remoti, con guard condition su merge in corso. | Git puro + predicati. L'unico pezzo con un briciolo di logica (la guard «non fare
--split se c'è un merge in corso») non merita una skill: è una condizione da mettere
nello script gitize o in un alias git. Il resto sono comandi git sequenziali. |
gitWipe |
Puliva branch locali già mergiati: for-each-ref, branch --merged,
branch -d/-D. |
Operazione distruttiva e deterministica. Cancellare branch è un'operazione a rischio: va eseguita da uno script deterministico con safety net (dry-run prima, conferma dopo), non da un LLM che potrebbe sbagliare branch da cancellare. Git stesso è la safety net (reflog), ma l'esecuzione deve essere certa. |
merge |
Eseguiva git merge --no-ff in loop per più branch. L'unico contributo
LLM era comporre il messaggio di merge. |
«Non basta git merge?» 240 righe per eseguire un comando git in serie.
L'unico valore LLM — il messaggio di merge — è già una capacità nativa di Claude
(la usa in gitize). Il resto è un for-loop. |
codesys |
Wrapper su docker compose per avviare/fermare/riavviare i container CODESYS. | docker compose up -d, docker compose down,
docker compose restart. I comandi sono un mapping 1:1 con docker compose.
Una skill di 100 righe per avvolgere tre comandi docker — il modo nativo è usare
docker compose direttamente, o al massimo uno script .bat/.ps1. |
deploy |
Rilasciava il progetto in produzione: copia UNC di file binari + creazione shortcut sul desktop del cliente. | 240 righe per un copia-incolla. Operazione rischiosa (produzione), irreversibile,
deterministica. Un LLM non deve gestire deploy in produzione — è il caso d'uso perfetto
per uno script PowerShell deterministico (robocopy + WScript.Shell
per lo shortcut) con log e rollback. La skill è stata scartata con la motivazione più
netta dell'intero audit: un'operazione in produzione non può dipendere da un LLM
non-deterministico. |
deadcode |
Scansionava l'intera codebase per trovare dead code (metodi non chiamati, classi inutilizzate, variabili morte). | Scan LLM dell'intera codebase = consumo proibitivo di contesto + risultato non-deterministico. Il dead code si trova in modo deterministico e completo con l'analyzer Roslyn (IDE0051 per metodi privati non usati, CS0169 per campi mai referenziati) o con ReSharper. Nessun giudizio semantico richiesto. |
Quattro file cercavano di insegnare a Claude ciò che Claude Code sa già fare in modo nativo. Sono ridondanti per definizione: la domanda 2 del filtro li coglie subito.
| File | Cosa faceva | Perché scartato |
|---|---|---|
proj |
Framework di sessione: cambiava directory, caricava _config e
MEMORY.md, gestiva anchor e work-dir stale. |
L'infrastruttura di sessione è nativa in Claude Code: la cwd è
il progetto, la memoria automatica (MEMORY.md) è già caricata, i comandi
/clear e /compact gestiscono il
contesto. Il framework privato (_config, anchor, ledger) era legato al
workspace personale dell'autore e non riusabile. |
feedback |
Analizzava il codice senza modificarlo e dava un parere. | È esattamente la plan mode di Claude Code: modalità sola lettura che raccoglie contesto, analizza e produce un parere senza scrivere nulla. La versione della skill era una copia striminzita e meno capace. |
issue |
Issue tracker su file: creava, elencava, aggiornava issue in una tabella markdown. | Tre problemi: (1) un umano apre issue su GitHub, non in una tabella markdown locale; (2) l'analisi di un problema è nativa («analizza questo bug»); (3) i verbi CRUD sono manipolazione deterministica di una tabella markdown — non serve un LLM per aggiungere una riga a un file. La persistenza tramite spec-driven o «salva un md» è già coperta da pattern esistenti. |
port-solution |
Rimodellava un tipo (classe, interfaccia) da una solution all'altra, adattandolo alle convenzioni della destinazione. | Vedi §3.4 per l'analisi completa. In sintesi: è nato dall'abitudine di tenere copie parallele di solution, ma il workflow giusto è un branch. Senza il framing «port tra due solution distinte», è un refactor nativo. |
Tre file sono stati scritti per creare, gestire o registrare skill e comandi. Oggi nel marketplace esiste già skill-creator — uno strumento dedicato che fa tutto ciò in modo strutturato. Questi file sono obsoleti per definizione.
| File | Cosa faceva | Perché scartato |
|---|---|---|
command |
Framework per creare, listare, abilitare, disabilitare comandi. Spawner, ledger, catalog, profili, autorizzazioni. | Il modo nativo di creare un comando è scrivere un file .md in
.claude/commands/. Per le skill, il marketplace ha skill-creator
che fa tutto in modo più pulito (distillazione, audit, port). Lo spawner, il ledger
e il catalog erano bespoke e legati al workspace privato dell'autore. |
skillify |
«Registrava» una skill osservando il comportamento di Claude e trasformandolo in una skill. | Il recording era solo comportamentale — osservava cosa faceva Claude e cercava di
ricostruire una skill. Ma Claude Code non ha hook on-disk per catturare il comportamento
in modo affidabile, quindi il risultato era fragile e incompleto. Coperto da
skill-creator che fa distillazione strutturata. |
skilliDo |
Partner di skillify: produceva la skill una volta registrata. |
Stesso motivo. Se skillify è fragile, skilliDo non ha
senso di esistere. L'intero ecosistema di registrazione è stato sostituito da
skill-creator. |
port-solution merita un discorso a parte perché tocca un'abitudine radicata
in Sistec: tenere copie parallele di soluzione (es. 5309 e
5315) e portare pezzi da una all'altra.
Il file port-solution prendeva un tipo da una solution e lo adattava per
l'altra: rinominava namespace, cambiava convenzioni, adattava costruttori. Il problema è
che il workflow giusto non è portare tra due solution — il workflow giusto
è un branch: su un singolo repo, con una feature branch, Claude ha contesto
ampio, git gestisce il merge, e c'è meno rischio di rompere API pubbliche rispetto a copie
parallele che divergono.
Per questo port-solution è stato scartato: nel caso comune (stessa famiglia
di prodotti, branch-milestone diversi) si riduce a un refactor nativo, che Claude fa senza
skill. Il caso raro (prodotti davvero distinti) è coperto da reconcile-solutions,
che è stato tenuto esplicitamente.
reconcile-solutions e port-solution nascono dallo stesso problema
ma hanno avuto esiti opposti. La differenza? reconcile-solutions porta
l'intento di una feature — giudizio semantico puro. port-solution
rimodella un tipo — operazione che con i branch diventa un merge o un
refactor nativo. La lezione per il futuro: prima di scrivere una skill «cross-solution»,
chiedersi «posso invece usare un branch?». Se la risposta è sì, la skill probabilmente
non serve.
L'audit dei 20 file non è solo un esercizio di classificazione: ha fatto emergere tre pattern ricorrenti che spiegheremo per evitare di riscriverli in futuro.
Quattro file scartati (fetch, gitAlign, gitWipe,
merge) sono wrapper su git. Il pattern è sempre lo stesso: «insegno a Claude
come usare git». Ma Claude Code usa già git in modo nativo — fa commit, push, branch, diff,
restore, merge. Insegnargli comandi git in una skill è come insegnargli a leggere un file:
è un tool nativo, non un giudizio semantico.
Criterio per il futuro: se una skill si limita a chiamare comandi git in sequenza, anche con predicati booleani, non supera la domanda 1 del filtro. L'unica eccezione è quando l'LLM deve decidere cosa fare in base al risultato di git (es. «il merge ha conflitti in questi file, risolvili semanticamente»). Ma in quel caso, la decisione è il valore — la chiamata git è solo il presupposto.
port-solution è l'esempio perfetto. La skill nasce perché esisteva un'abitudine
(copie parallele di solution) che è essa stessa problematica. La skill non risolveva il
problema di fondo — lo aggirava automatizzando un workflow sbagliato.
Il filtro l'ha colta: se il workflow giusto è un branch, la skill che automatizza il workflow
sbagliato non va pubblicata nel marketplace, va sostituita da un cambiamento di processo.
Criterio per il futuro: prima di scrivere una skill, chiedersi «il problema che risolve esisterebbe se il nostro processo fosse diverso?». Se la risposta è sì, la skill potrebbe essere una stampella per un processo subottimale.
command e proj sono framework che l'autore aveva costruito per
organizzare il proprio workspace. Funzionavano per lui, ma erano legati al suo ambiente:
path assoluti, convenzioni personali, ledger di progetto attivo, memory-anchor. Quando
de-couplati dal workspace privato, restava poco o nulla di riusabile. La domanda 3 del
filtro («Claude farebbe peggio senza?») li ha bocciati: ciò che facevano era o nativo
(sessione, memoria) o coperto da skill-creator.
Criterio per il futuro: una skill non è un framework personale. Se per usarla servono file di configurazione, ledger, anchor, o path specifici della macchina dell'autore, probabilmente non è una skill — è un setup personale che va tenuto fuori dal marketplace.
| Categoria | Conteggio | % su 20 |
|---|---|---|
| Skill integrate | 6 | 30% |
| Skill rifiutate | 14 | 70% |
| Totale file src/ auditati | 20 | 100% |
Le 14 skill rifiutate per motivo:
| Motivo | Conteggio | File |
|---|---|---|
| Operazione deterministica (tool/script meglio) | 7 | fetch, gitAlign, gitWipe, merge, codesys, deploy, deadcode |
| Comportamento nativo di Claude Code | 4 | proj, feedback, issue, port-solution |
| Meta-tooling coperto da skill-creator | 3 | command, skillify, skilliDo |
Il dato più significativo: il 70% dei file di src/ non ha superato
il filtro. Non perché fossero scritti male — al contrario, molti erano ben fatti per il loro
scopo contingente. Ma non erano skill nel senso del marketplace: non portavano
giudizio semantico che solo un LLM poteva dare. La maggior parte era automazione deterministica
vestita da skill. Il filtro ha separato i due mondi.
main protetto,
accesso via PR, maintainer che applica il filtro a tre domande