<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gioxx.org</title>
	<atom:link href="https://gioxx.org/feed/" rel="self" type="application/rss+xml" />
	<link>https://gioxx.org</link>
	<description>Life is short. Live your dream and share your passion</description>
	<lastBuildDate>Tue, 01 Sep 2026 15:18:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>

<image>
	<url>https://gioxx.org/wp-content/uploads/2018/02/cropped-ICON_path231-32x32.png</url>
	<title>Gioxx.org</title>
	<link>https://gioxx.org</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Tikka Masala: metti al sicuro i tuoi tunnel Cloudflare</title>
		<link>https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/</link>
					<comments>https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 07:30:52 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Cloudflare]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[In Evidenza]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Ricerca e Sviluppo]]></category>
		<category><![CDATA[Self-Hosted]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tikka Masala]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125880</guid>

					<description><![CDATA[<p>Era marzo di quest&#8217;anno. Uno di quei tentativi da dopocena, con i bambini messi a nanna e la possibilità di svaccarsi (termine tecnico eh, mica pizza e fichi) sul divano a guardare qualcosa di decente in TV con mia moglie, quando mi sono messo in testa di provare DockFlare. Me ... <a title="Tikka Masala: metti al sicuro i tuoi tunnel Cloudflare" class="read-more" href="https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/" aria-label="Read more about Tikka Masala: metti al sicuro i tuoi tunnel Cloudflare">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/">Tikka Masala: metti al sicuro i tuoi tunnel Cloudflare</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Era marzo di quest&#8217;anno. Uno di quei tentativi da dopocena, con i bambini messi a nanna e la possibilità di <em>svaccarsi</em> (termine tecnico eh, mica pizza e fichi) sul divano a guardare qualcosa di decente in TV con mia moglie, quando mi sono messo in testa di provare <a href="https://dockflare.app/" rel="noopener">DockFlare</a>. Me lo aveva consigliato qualcuno (non ricordo più se su Reddit o nel solito gruppo di compari e nerd con cui chiacchiero ogni giorno) e l&#8217;idea di gestire i <a href="https://gioxx.org/2024/07/16/cloudflare-tunnel-cose-e-come-usarlo-con-docker/">tunnel di Cloudflare</a> direttamente a partire dai container Docker mi solleticava parecchio. Ormai sono passati tre anni e più da quando ho iniziato a tenere diverse cose in self-hosting tra le mura di casa (e su qualche servizio sparso online), quindi provo sempre cose nuove per migliorare l&#8217;esperienza d&#8217;uso dei prodotti sui quali mi appoggio nel quotidiano.</p>
<p>Sarà stata la stanchezza, sarà che quella sera ero semplicemente poco lucido, fatto sta che ho tirato in piedi un tunnel di test con cui giocare e rompere cose in santa pace.<br />
Peccato che poi, volendo sperimentare sul serio, ho dato a DockFlare la conferma per prendere <em>possesso</em> del tunnel principale, quello che tiene in piedi buona parte dei servizi di casa. Quello che non avevo capito è che nell&#8217;intervallo di tempo tra il mio clic e l&#8217;esecuzione dell&#8217;operazione avrei perso tutte le configurazioni, dalla prima all&#8217;ultima, nessuna route sopravvissuta, vuoto pneumatico.</p>
<p>Sia chiaro: non è colpa di DockFlare, la conferma l&#8217;ho data io e la distrazione era tutta mia. Però intanto ho buttato giù il monitor del Mac, ho imprecato quanto serviva e ho rimandato tutto al giorno dopo. Ricostruire era fattibile, ma significava buttare via un mucchio di tempo. Quando l&#8217;ho fatto, ho anche provato a salvarmi la configurazione da qualche parte, un export da poter reimportare velocemente in caso di nuovo disastro, e non ho trovato niente che facesse al caso mio.</p>
<h1>Il nome</h1>
<p>In quella chat che alimentiamo a pane, cazzate e lamentele ogni giorno si stava parlando di India, di supporto, di call center e di non ricordo neanche più cos&#8217;altro. E a me era pure venuta fame senza apparente motivo. È in quel contesto, mentre con l&#8217;aiuto di Claude Code mettevo in piedi le prime righe di questo progetto, che ho scelto un nome provvisorio: <strong>Tikka Masala</strong>. Mi fa sorridere ancora oggi, il provvisorio è diventato definitivo, e il software esiste per rimediare a una mia disattenzione: ne ho avuto bisogno in prima persona e l&#8217;ho reso pubblico nella speranza che eviti ad altri la stessa situazione (o per lo meno l&#8217;idea è quella di provarci, stile raccomandazione della nonna su cosa devi fare per <em>non prendere freddo</em>).</p>
<h1>Cosa fa</h1>
<p>Il sottotitolo che ho scelto per il progetto è <em>&#8220;backup and restore Cloudflare Tunnels, without the spreadsheet&#8221;</em>, e riassume abbastanza bene le intenzioni.</p>
<p>Gli dai un <strong>API token di Cloudflare</strong>, lui verifica che sia valido, ti elenca i tunnel che vede sull&#8217;account e ti permette di salvarne uno <strong>snapshot</strong>: un file JSON con la configurazione del tunnel così come la restituiscono gli endpoint di configurazione dei Cloudflare Tunnel (regole di ingress, hostname pubblici), più i metadati che servono a ritrovarla (data dell&#8217;export, account, ID e nome del tunnel, eventuali note). I metadati e lo storico stanno in un piccolo database SQLite, gli snapshot veri e propri sono file su disco.</p>
<p>Il perimetro è quello e solo quello: la configurazione dei tunnel. Non tocca le impostazioni Cloudflare a livello di account, e non salva &#8211; al momento &#8211; Access (Applications e Policies), per cui trovi solo delle scorciatoie che ti portano dritto alla sezione giusta della dashboard. Quando serve, gli chiedi di <strong>ripristinare</strong>: prende lo snapshot e sovrascrive la configurazione remota del tunnel con quella salvata. Puoi rimetterla sul tunnel di origine, su un altro tunnel o su un altro account, e ogni ripristino resta tracciato nello storico (quando, su quale account, su quale tunnel).</p>
<p>I backup li fai partire a mano oppure li lasci a uno scheduler interno (con <code>cron</code> e possibilità di scegliere il fuso orario). Qui la parte che uso di più: per ogni tunnel scegli una frequenza, a ogni esecuzione, una volta a settimana o una volta al mese, e decidi se coprirli tutti o solo un sottoinsieme. Nel mio caso i tunnel che tocco spesso girano a ogni ciclo, quelli fermi da mesi si accontentano del giro mensile. C&#8217;è una retention (<code>BACKUP_RETENTION_DAYS</code>, io la tengo a 90 giorni) che dopo ogni nuovo backup fa piazza pulita di quelli più vecchi della soglia, snapshot e relativo storico compresi.</p>
<p>Occhio a una cosa sui permessi del token: per far girare anche i ripristini, Tikka Masala avrà necessità del permesso <em>Cloudflare Tunnel</em> in scrittura (più <em>DNS</em> sulla zona), ma se ti interessa solo il backup puoi tenerlo al guinzaglio e sola lettura. Il token viene cifrato, non resta in chiaro sul disco.</p>
<p>Sotto il cofano è un&#8217;applicazione <strong>FastAPI</strong> in Python, niente di esotico, con un sistema di notifiche via webhook o Telegram per farti sapere quando un backup o un ripristino va storto. L&#8217;ho rilasciato pronto per <strong>Docker</strong> (immagine <code>gfsolone/tikkamasala</code> su Docker Hub o in alternativa <code>ghcr.io/gioxx/tikkamasala</code> via GitHub, con un <code>docker-compose</code> di esempio <a href="https://github.com/gioxx/TikkaMasala/blob/main/docker-compose.yml" rel="noopener">disponibile sul repository</a>): lo metti in piedi accanto agli altri servizi di casa, lo configuri la prima volta e te ne dimentichi (sempre però rispettando la regola che uno strumento di backup è definibile funzionante solo quando sei in grado di ripristinare senza il minimo errore, quindi provalo prima di metterti comodo sul tuo cuscino).</p>
<h1>I numeri, i miei</h1>
<p>Lo uso da marzo, senza interruzioni, e nel frattempo siamo arrivati alla versione 1.3.8.<br />
A oggi che scrivo queste righe la mia installazione personale mi restituisce questa situazione:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">Unique tunnels     5
Routes archived    5095
Restores           12
Scheduled runs     170
Oldest backup      2026-05-31T03:00:04+00:00
Latest backup      2026-08-29T03:00:04+00:00

Archive retention  90 day(s)
Backups kept       127
Backup storage     1.1 MB
Database size      112.0 KB</pre>
<p>Cinque tunnel sotto controllo, 170 cicli di backup programmati, poco più di un mega di spazio occupato per mesi di storico e un database che sta in 112 KB. Il campo dei ripristini segna dodici ma si tratta dei miei test che ogni tanto lancio a tradimento, per fortuna non ho più dovuto usarlo <em>per davvero</em> (anche se i test hanno comunque sovrascritto tunnel di produzione), è il motivo per cui oggi mi fido a lasciarlo lì a lavorare da solo.</p>
<p>Dovrei prevedere anche delle conservazioni più a lungo termine (mensili, annuali), ma è una caratteristica che non è ancora disponibile, mi sono già promesso di tornarci sopra e lavorarci.</p>
<h1>In conclusione</h1>
<p>È un software piccolo e per certi versi banale, ma per come lavoro io è ormai fondamentale.<br />
Non fa niente di spettacolare: è un&#8217;assicurazione contro la tua stessa distrazione.</p>
<p>Trovi tutto su <a href="https://tikkamasala.gioxx.org">tikkamasala.gioxx.org</a> e sul repo <a href="https://github.com/gioxx/TikkaMasala" rel="noopener">github.com/gioxx/TikkaMasala</a>. Se lo provi, se ci trovi un bug o se hai idee per migliorarlo, le Issue su GitHub sono il canale più rapido per arrivare a me. Per tutto il resto, l&#8217;area commenti qui sotto è a tua disposizione, come sempre.</p>
<p><strong>#KeepItSimple</strong></p>
<hr />
<h6>Immagine di copertina: mia, prodotta con l&#8217;aiuto dell&#8217;intelligenza artificiale che ha lavorato allo sfondo che c&#8217;è alle spalle del logo ufficiale di Cloudflare.</h6>
<p><a rel="nofollow" href="https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/">Tikka Masala: metti al sicuro i tuoi tunnel Cloudflare</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/09/03/tikka-masala-backup-cloudflare-tunnel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>YOURLS: il plugin antispam che cancellava i miei short URL</title>
		<link>https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/</link>
					<comments>https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/#comments</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Mon, 31 Aug 2026 07:30:47 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[DNS]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Serverplan]]></category>
		<category><![CDATA[Sicurezza]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Spam]]></category>
		<category><![CDATA[Test Hw/Sw]]></category>
		<category><![CDATA[YOURLS]]></category>
		<category><![CDATA[YOURLS Plugins]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125868</guid>

					<description><![CDATA[<p>Venerdì sera mi arriva una mail: [YOURLS] Short URL deleted: .... Ero in viaggio, in autostrada, in mezzo al traffico e ai campioni dello slalom tra corsie a velocità che porca miseria levati perché altrimenti ti prendo a schiaffi, non avevo sicuramente modo di accorgermene né tanto meno di capire ... <a title="YOURLS: il plugin antispam che cancellava i miei short URL" class="read-more" href="https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/" aria-label="Read more about YOURLS: il plugin antispam che cancellava i miei short URL">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/">YOURLS: il plugin antispam che cancellava i miei short URL</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Venerdì sera mi arriva una mail: <code>[YOURLS] Short URL deleted: ...</code>.<br />
Ero in viaggio, in autostrada, in mezzo al traffico e ai <em>campioni dello slalom tra corsie a velocità che porca miseria levati perché altrimenti ti prendo a schiaffi</em>, non avevo sicuramente modo di accorgermene né tanto meno di capire perché mai il mio YOURLS avesse effettuato una cancellazione senza passare per una mia azione. Poco dopo un&#8217;altra, e un&#8217;altra, e poi un&#8217;altra ancora. Short URL che uso da anni, con decine di migliaia di clic alle spalle, che sparivano uno dopo l&#8217;altro dalla mia istanza di YOURLS. Il primo pensiero è stato quello che avresti fatto anche tu: qualcuno mi ha bucato lo shortener.</p>
<p>Spoiler: <strong>nessun attacco</strong>.<br />
Ma per arrivarci mi è servita un&#8217;oretta di log, e la spiegazione è abbastanza istruttiva da meritare un post, soprattutto se anche tu tieni attivo, come me, un plugin che avevi installato e dimenticato lì.</p>
<h2>La caccia all&#8217;intruso che non c&#8217;era</h2>
<p>Prima cosa, accesso SSH all&#8217;hosting e giù dentro i log di Apache.<br />
Cosa cercavo: richieste alla API di YOURLS (<code>yourls-api.php</code>), POST all&#8217;area <code>admin/</code>, qualunque cosa somigliasse a una cancellazione pilotata da fuori.</p>
<p><strong>Niente</strong>. Zero chiamate alla API in tutto il log. Un solo POST all&#8217;admin nella giornata: il mio, fatto <em>dopo</em> aver ricevuto l&#8217;allarme per andare a controllare. Il filesystem era pulito: nessuna webshell, nessun file PHP modificato di recente, <code>~/.ssh/authorized_keys</code> vuoto, nessun utente aggiunto all&#8217;array degli amministratori in <code>config.php</code>. Eppure i link sparivano davvero: me lo confermava il database, le righe non c&#8217;erano più, le notifiche ricevute dal mio <a href="https://yourls.gioxx.org/plugins/change-notifier">Change Notifier</a> erano la conferma ultima a mezzo posta elettronica (maledettamente comodo, <strong>diversamente non me ne sarei accorto per tempo</strong> e chissà quanti altri link avrei <em>lasciato per la strada</em>).</p>
<p>Un&#8217;azione che tocca il database di YOURLS ma non lascia traccia nei log web è il tipo di contraddizione che di solito significa che stai guardando nel posto sbagliato.</p>
<h2>L&#8217;indizio era nella mia stessa mail</h2>
<p>Come ti dicevo poco sopra, quelle notifiche me le manda un plugin che ho scritto io, <a href="https://github.com/gioxx/YOURLS-ChangeNotifier" rel="noopener">YOURLS-ChangeNotifier</a>: invia una mail a ogni creazione, modifica o cancellazione di uno short URL. Dando un&#8217;occhiata più approfondita al corpo del messaggio di uno dei messaggi di cancellazione, saltava fuori questo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">Event:   DELETE
When:    2026-08-29T08:26:27+00:00
By:      user: (authenticated)
IP:      34.10.46.191</pre>
<p>Due dettagli che prima avevo letto di sfuggita. Il campo <code>By:</code> diceva <code>user: (authenticated)</code> <strong>senza nome utente</strong>: è l&#8217;ultima spiaggia del mio plugin, quello che scrive quando <code>yourls_is_valid_user()</code> dice &#8220;sì&#8221; ma non riesce a tirare fuori né un login, né un cookie di sessione, né un header di autenticazione. Tradotto: nessun accesso vero all&#8217;area riservata.</p>
<p>E l&#8217;<code>IP:</code> cambiava a ogni mail. In un caso era quello di un monitor esterno che mi passa a controllare i redirect ogni mattina alla stessa ora.<br />
Non un attaccante: solo chi, per caso, stava visitando quel link nel momento esatto della cancellazione.</p>
<p>Il che restringeva parecchio il campo: qualcosa <strong>dentro</strong> YOURLS cancellava i link <em>quando venivano visitati</em>.</p>
<h2>Il colpevole: un plugin antispam del 2012</h2>
<p><code>user/plugins/antispam/</code>. Il plugin <strong>Anti spam</strong> di Ozh, uno dei più vecchi dell&#8217;ecosistema YOURLS. Attivo da anni sulla mia istanza, mai toccato, completamente uscito dai radar. Fa due cose. Alla creazione di uno short URL controlla la destinazione contro alcune DNS blacklist e rifiuta se è elencata: legittimo. Ma poi c&#8217;è la seconda parte, agganciata all&#8217;evento <code>redirect_shorturl</code>, cioè eseguita <strong>a ogni click</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">// Has the remote link become compromised lately? Check on redirection
yourls_add_action( 'redirect_shorturl', 'ozh_yourls_antispam_check_redirect' );
function ozh_yourls_antispam_check_redirect( $url, $keyword = false ) {
    // ...
    if( $chances == mt_rand( 1, $chances ) ) {
        if( ozh_yourls_antispam_is_blacklisted( $url ) != false ) {
            // Delete link &amp; die
            yourls_delete_link_by_keyword( $keyword );
            yourls_die( 'This domain has been blacklisted. This short URL has been deleted from our record.', 'Domain blacklisted', '403' );
        }
    }
}</pre>
<p>Con probabilità 1 su 5 (link creato da meno di tre giorni) o 1 su 15, a ogni visita interroga la URL di destinazione contro cinque blacklist:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">'zen.spamhaus.org',
'multi.surbl.org',
'bl.spamcop.net',
'combined.abuse.ch',
'dnsbl.sorbs.net',</pre>
<p>Se <strong>una sola</strong> risponde positivo, il link non viene sospeso, non finisce in quarantena, non ti manda un avviso: <code>yourls_delete_link_by_keyword()</code>. <strong>Cancellato</strong>.<br />
E l&#8217;utente si becca un 403, quella pagina da 866 byte che nel frattempo avevo visto passare decine di volte nei log senza dargli peso.</p>
<h2>Perché proprio adesso</h2>
<p>Perché quelle blacklist, nel 2026, sono in buona parte inaffidabili se non le usi nel modo giusto:</p>
<ul>
<li><strong>SORBS</strong> (<code>dnsbl.sorbs.net</code>) è stata <strong>spenta a giugno 2024</strong>. La zona DNS non è garantito che risponda in modo sensato.</li>
<li><strong>SpamCop</strong> e <strong>SURBL</strong> <em>degradano di proposito</em> le risposte quando le query arrivano da resolver pubblici o ad alto volume, cioè esattamente lo scenario di un hosting condiviso, dove il resolver è in comune con centinaia di altri account.</li>
</ul>
<p>Il risultato è falsi positivi a raffica. Il readme del plugin, va detto, non nasconde niente:</p>
<blockquote><p>Checking against DNS blacklists may or may not work for you [&#8230;] It may even result in all domains being blacklisted from your server. Try and see.</p></blockquote>
<p>L&#8217;ho provato: ha deciso che Reddit, Amazon, un blog tecnico di Microsoft e il mio canale Twitch erano tutti &#8220;domini blacklistati&#8221;, e li ha rimossi.</p>
<h2>Il fix</h2>
<p>Disattivazione del plugin: rimosso da <code>active_plugins</code> nel database e cartella rinominata in <code>.antispam.disabled</code>, solo per scrupolo, giuro che poi dopo passo pure a cancellare definitivamente.<br />
Da quel momento nessun link è stato più toccato.</p>
<p>Se anche tu tieni attivo questo plugin, il consiglio è di andare a vedere <em>subito</em> se ti sta erodendo lo storico: cerca i 403 anomali nei log e le eventuali mail di cancellazione. Come protezione antispam ci sono alternative che almeno non distruggono dati: <a href="https://github.com/YOURLS/google-safe-browsing" rel="noopener">Google Safe Browsing per YOURLS</a> (ma occhio, che pure questo è stato archiviato e non viene più aggiornato da quattro anni), o più banalmente un captcha sull&#8217;interfaccia pubblica. Io sto seriamente pensando di mettermi alla ricerca di un sostituto mantenuto ancora oggi o &#8211; in alternativa &#8211; tirare in piedi qualcosa di nuovo che svolga però questo <em>vecchio mestiere</em>.</p>
<h2>Il recupero: le statistiche erano ancora tutte lì</h2>
<p>Qui la notizia buona.<br />
Quando YOURLS cancella uno short URL rimuove la riga dalla tabella <code>yourls_url</code>, ma <strong>non tocca <code>yourls_log</code></strong>, dove vive lo storico dei click.<br />
Le statistiche c&#8217;erano ancora tutte, riga per riga, per ognuno dei link cancellati.</p>
<p>Ho recuperato destinazione, titolo e data di creazione dal dump notturno del database (Server Plan ne tiene uno automatico e non mi costringe così ad andare a recuperare il backup che mi porto in casa con <a href="https://cpanelvault.gioxx.org/">cPanelVault</a>), ho reinserito le righe con un <code>INSERT</code> mirato e ho rimesso i contatori <code>clicks</code> allineandoli al conteggio reale dei record ancora presenti nel log.</p>
<p>Verifica finale con un <code>curl</code> per keyword, per controllare che ogni redirect puntasse di nuovo dove doveva:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">/r        301 -&gt; https://www.reddit.com/r/Gioxx/
/shopping 301 -&gt; https://www.amazon.it/shop/gioxx
/ee4li    301 -&gt; https://techcommunity.microsoft.com/.../ba-p/3851357
/twitch   301 -&gt; https://www.twitch.tv/gioxx85</pre>
<p>Come se non fosse successo niente, con un&#8217;unica eccezione: <code>twitch</code> era stato cancellato <em>prima</em> che partisse il backup della notte, quindi la sua destinazione non era in nessun archivio e ho dovuto ricostruirla a memoria (non che fosse così complicato, ma è giusto dirlo, altrimenti mi sarebbe andato a tirare fuori dall&#8217;armadio il backup di qualche giorno fa).</p>
<h2>In conclusione</h2>
<p>Il giudizio è netto: per come è scritto, cancellazione automatica e irreversibile al primo hit di una qualunque blacklist, per giunta durante il redirect, cioè nel percorso più caldo e meno sorvegliato, questo plugin non ha senso su un&#8217;installazione viva e usata nel 2026, e ancora meno su hosting condiviso. Il controllo in fase di <em>creazione</em> è un&#8217;altra storia e ci può stare; è l&#8217;azione distruttiva a runtime il problema.</p>
<p>Due cose che mi porto a casa.</p>
<ul>
<li>La prima: le notifiche via mail su creazione/modifica/cancellazione degli short URL, che tenevo più che altro per curiosità, si sono rivelate l&#8217;unico motivo per cui me ne sono accorto in tempo. Se hai un sistema di alert simile, quelle mail vanno lette quando arrivano, non archiviate.</li>
<li>La seconda: tenere YOURLS aggiornato all&#8217;ultima versione (oggi la 1.10.5) resta buona regola a prescindere, il mio <a href="https://gioxx.org/2025/05/14/yourls-diff-patch-per-aggiornare-la-tua-istanza-yourls/">YOURLS-diff</a> serve proprio a rendere la cosa meno noiosa, anche se stavolta la versione non c&#8217;entrava niente (ma per coincidenza, essendo stata pubblicata una manciata di ore prima rispetto all&#8217;accaduto, mi ha fatto sorgere il dubbio di uno 0-day corretto che però mieteva vittime <em>into the wild</em>).</li>
</ul>
<p>L&#8217;area commenti è a tua disposizione, soprattutto se ti è capitato di ritrovarti con dei link spariti e non sapevi da dove partire <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f605.png" alt="😅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><strong>#KeepItSimple</strong></p>
<hr />
<h6>Immagine di copertina: <a class="stockpack-author" href="https://unsplash.com/@rocinante_11?utm_source=Stockpack&amp;utm_medium=referral&amp;utm_campaign=api-credit" target="_blank" rel="nofollow noopener noreferrer">Mick Haupt</a> on <a class="stockpack-provider" href="https://unsplash.com/photos/7Xw9yEA8rqQ?utm_source=Stockpack&amp;utm_medium=referral" target="_blank" rel="nofollow noopener noreferrer">Unsplash</a></h6>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/">YOURLS: il plugin antispam che cancellava i miei short URL</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/08/31/yourls-antispam-plugin-cancella-shorturl-dnsbl/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>Waline: un sistema di commenti adatto a Docusaurus</title>
		<link>https://gioxx.org/2026/08/19/waline-docusaurus/</link>
					<comments>https://gioxx.org/2026/08/19/waline-docusaurus/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Wed, 19 Aug 2026 09:00:47 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[Commenti]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Marvellous Codeworks]]></category>
		<category><![CDATA[Self-Hosted]]></category>
		<category><![CDATA[Telegram]]></category>
		<category><![CDATA[Vercel]]></category>
		<category><![CDATA[Waline]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125836</guid>

					<description><![CDATA[<p>Quando ho messo in piedi la Knowledge Base di Marvellous Codeworks (blog, documentazione, changelog dei progetti, TMS in primis), a un certo punto ho sentito la mancanza, e quindi la necessità, di integrare i commenti all&#8217;interno di Docusaurus, perché non tutti gli utenti sono disposti a compilare una richiesta di ... <a title="Waline: un sistema di commenti adatto a Docusaurus" class="read-more" href="https://gioxx.org/2026/08/19/waline-docusaurus/" aria-label="Read more about Waline: un sistema di commenti adatto a Docusaurus">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/19/waline-docusaurus/">Waline: un sistema di commenti adatto a Docusaurus</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Quando ho messo in piedi la <a href="https://kb.marvellouscode.works" rel="noopener">Knowledge Base di Marvellous Codeworks</a> (blog, documentazione, changelog dei progetti, TMS in primis), a un certo punto ho sentito la mancanza, e quindi la necessità, di integrare i commenti all&#8217;interno di Docusaurus, perché non tutti gli utenti sono disposti a compilare una richiesta di supporto o registrare un account su GitHub per inserire un commento.<br />
Volevo che chiunque potesse lasciare un feedback, segnalare un problema, ringraziare senza affidarsi al solito <em>colosso SaaS</em> che ti pianta tracker ovunque solo per farti scrivere due righe sotto un post.</p>
<p>Ho quindi fatto qualche ricerca per capire cosa offrisse il <em>mercato del self-hosting</em>, evitando però di tenere in considerazione l&#8217;idea e possibilità di ospitare il tutto in casa. Avevo bisogno di qualcosa che si integrasse con il mondo serverless.</p>
<h1>Prima scelta: Cusdis (e doccia fredda)</h1>
<p>Il primo nome che mi era saltato all&#8217;occhio era <a href="https://cusdis.com/" rel="noopener">Cusdis</a>, presentato proprio come &#8220;alternativa leggera e privacy-friendly a Disqus&#8221;. Sulla carta perfetto: piccolo, self-hostabile, pensato apposta per blog e siti statici.</p>
<p>Poi sono andato a controllare il repository su GitHub, per abitudine, prima di adottare qualsiasi cosa guardo sempre lo stato di manutenzione, e <a href="https://github.com/djyde/cusdis" rel="noopener">djyde/cusdis</a> risulta <strong>archiviato</strong>. Un progetto che ha avuto il suo pubblico, ma da metà luglio 2026 non riceve più commit e la repository è chiusa in sola lettura. Nessun annuncio ufficiale che spieghi il perché, semplicemente: <strong>fine corsa</strong>.</p>
<p>Occhio, non sto dicendo che sia stata una scelta sbagliata a monte, magari l&#8217;autore ha semplicemente deciso di chiudere un capitolo, succede. Ma per un progetto pubblico che è sempre esposto su Internet, e che deve restare in piedi per anni e magari ricevere patch di sicurezza, adottare qualcosa di già archiviato il primo giorno sarebbe stato un rischio che non valeva la pena correre.</p>
<h1>Waline</h1>
<p>Incrociando ulteriori ricerche sono arrivato a <a href="https://waline.js.org/" rel="noopener">Waline</a>, altro sistema di commenti self-hosted, e la differenza si vede subito: repository attiva (commit praticamente ogni giorno), community viva e un set di feature parecchio più ricco rispetto al necessario: supporto Markdown nei commenti, notifiche via email/Telegram/Discord/WeChat e altri canali ancora, pannello di amministrazione integrato, supporto per un bel po&#8217; di database (Postgres, MySQL, SQLite, MongoDB &#8230;).</p>
<p>Deploy semplice, tra l&#8217;altro: il pacchetto <code class="EnlighterJSRAW" data-enlighter-language="js">@waline/vercel</code> lo rende pronto per girare come funzione serverless su <a href="https://vercel.com" rel="noopener">Vercel</a>, con <a href="https://neon.tech" rel="noopener">Neon</a> come Postgres gestito dietro. Repository dedicata (ne ho messa in piedi una sul mio account personale), un <code>index.cjs</code> di poche righe che carica Waline, un <code>vercel.json</code> per i build, e in pochi minuti hai un endpoint di commenti collegato al frontend Docusaurus della KB.</p>
<p>Se vuoi provarlo, ti consiglio di iniziare da qui: <strong><a href="https://waline.js.org/it/guide/get-started/" rel="noopener">waline.js.org/it/guide/get-started</a></strong>.</p>
<h2>Le personalizzazioni</h2>
<p>Che poi è il classico vaso di pandora rispetto al &#8220;set &amp; forget&#8221;, quel frangente dello spazio-tempo dove la teoria del &#8220;lo metto in piedi in 5 minuti&#8221; incontra la pratica di un progetto vero e con alcuni ritocchi sotto al cofano praticamente necessari.</p>
<h3>Favicon statiche, per silenziare i log</h3>
<p>Prima cosa: ogni browser richiede automaticamente <code>/favicon.ico</code> e <code>/favicon.png</code> quando apre il sito. Waline, non avendoli, li trattava come richieste non gestite e ogni volta finiva un <em>NotFoundError </em>nei log di produzione. Innocuo, ma fastidioso da leggere quando stai cercando altro nei log. Basta aggiungere due file statici e dire a Vercel di servirli direttamente, senza passare dalla funzione Node:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="typescript">{
  "builds": [
    { "src": "favicon.ico", "use": "@vercel/static" },
    { "src": "favicon.png", "use": "@vercel/static" }
  ],
  "rewrites": [
    { "source": "/((?!favicon\\.ico$|favicon\\.png$).*)", "destination": "index.cjs" }
  ]
}</pre>
<h3>Le notifiche Telegram (e il template che non ne voleva sapere)</h3>
<p>Questa è stata quella più tosta. Volevo essere avvisato su Telegram ogni volta che arriva un commento in attesa di moderazione, così non devo tenere aperta la dashboard tutto il giorno. Waline lo supporta nativamente: bastano tre variabili d&#8217;ambiente su Vercel (<code>TG_BOT_TOKEN</code>, <code>TG_CHAT_ID</code>, ed eventualmente un <code>TG_TEMPLATE</code> per personalizzare il messaggio).</p>
<p>Peccato che, appena personalizzato il template, la notifica smettesse di arrivare, e senza errori evidenti. Ci ho girato attorno un bel po&#8217;: token giusto (verificato a mano con una chiamata <code>curl</code> diretta all&#8217;API di Telegram), chat ID giusto, tutto giusto, eppure niente.<br />
Alla fine, spulciando i log runtime di Vercel riga per riga, è saltato fuori il vero colpevole:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">Telegram Notification Failed:{"ok":false,"error_code":400,"description":"Bad Request: can't parse entities: Character '.' is reserved and must be escaped with the preceding '\\'"}</pre>
<p>Telegram, quando usi il <code class="EnlighterJSRAW" data-enlighter-language="ini">parse_mode: MarkdownV2</code>, pretende che caratteri come <code>. - _ * [ ] ( ) ~ # + = | { } !</code> vengano &#8220;<em>escapati</em>&#8221; ovunque compaiano fuori da un blocco di codice o dalla parte URL di un link. Il mio template ci infilava l&#8217;URL del post e il nome del sito in punti <em>non protetti</em>, e ogni dominio ha un punto, ogni tanto un trattino: bastava questo per far cadere l&#8217;intero messaggio.</p>
<p>Ho provato a correggere il template più volte, ma affidarsi a un campo di testo multiriga su un pannello web per gestire un fence di codice <code>```</code> si è rivelato fragile: a ogni copia/incolla qualcosa andava storto tra a-capo reali e letterali. Alla fine ho spostato tutto nel codice: <code>index.cjs</code> costruisce il messaggio da sé, con una funzione di escaping scritta in JavaScript, e lo invia solo per i commenti con stato &#8220;in attesa di moderazione&#8221;, esattamente il caso che mi interessava:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">function escapeMarkdownV2(text = '') {
  return String(text).replace(/[_*[\]()~`&gt;#+=|{}.!\\-]/g, '\\$&amp;');
}

module.exports = Application({
  plugins: [],
  async postSave(comment) {
    if (comment.status !== 'waiting') return;
    // costruzione messaggio + fetch verso l'API Telegram
  },
});</pre>
<p>Per evitare la doppia notifica (quella integrata di Waline più la mia), ho disattivato la prima con <code class="EnlighterJSRAW" data-enlighter-language="ini">DISABLE_AUTHOR_NOTIFY=true</code>, lasciando intatte le email di risposta a chi commenta, che passano da un altro percorso.</p>
<h3>Versione <em>bloccata</em> e Dependabot</h3>
<p>Ultima rifinitura, più che altro una lezione imparata sul momento: il <code>package.json</code> puntava <code class="EnlighterJSRAW" data-enlighter-language="ini">@waline/vercel</code> sulla versione più aggiornata (<code>latest</code>), comodo perché a ogni deploy scarichi automaticamente l&#8217;ultima versione, ma anche un rischio silenzioso, un aggiornamento con un comportamento diverso può arrivare in produzione senza che tu lo sappia. Ho quindi scelto di utilizzare una versione precisa di Waline e ho aggiunto un <code>dependabot.yml</code> che apre una pull request quando viene pubblicata una nuova versione, così l&#8217;aggiornamento resta una scelta, non un <em>evento a sorpresa</em>.</p>
<h2>In conclusione</h2>
<p>La lezione più generale, al di là di Waline in sé: prima di adottare qualcosa, anche uno strumento piccolo come un sistema di commenti, vale sempre la pena guardare lo stato reale del progetto. Un repository archiviato oggi potrebbe risorgere domani con un fork, ma nel dubbio meglio partire da qualcosa di vivo. E il self-hosting, anche via serverless, resta assolutamente sostenibile, basta mettere in conto che i primi giorni si passano più a leggere log che a scrivere codice.</p>
<p>Se vuoi vedere il risultato, la sezione commenti la trovi in fondo a qualsiasi post della <a href="https://kb.marvellouscode.works" rel="noopener">KB di Marvellous Codeworks</a>.<br />
Se invece ti va di parlarne o dirmi a che software ti sei affidato tu per gestire commenti su un sito web statico, l&#8217;area commenti è a tua disposizione anche qui di seguito, come sempre :-)</p>
<p><strong>#KeepItSimple</strong></p>
<hr />
<h6>Immagine di copertina: <a class="stockpack-author" href="https://unsplash.com/@thoughtcatalog?utm_source=Stockpack&amp;utm_medium=referral&amp;utm_campaign=api-credit" target="_blank" rel="nofollow noopener noreferrer">Thought Catalog</a> on <a class="stockpack-provider" href="https://unsplash.com/photos/RdmLSJR-tq8?utm_source=Stockpack&amp;utm_medium=referral" target="_blank" rel="nofollow noopener noreferrer">Unsplash</a></h6>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/19/waline-docusaurus/">Waline: un sistema di commenti adatto a Docusaurus</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/08/19/waline-docusaurus/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Graph: pulizia delle vecchie versioni del modulo dopo un update</title>
		<link>https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/</link>
					<comments>https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Mon, 17 Aug 2026 09:30:57 +0000</pubDate>
				<category><![CDATA[Lavoro]]></category>
		<category><![CDATA[Account utente]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Microsoft 365]]></category>
		<category><![CDATA[Microsoft Azure]]></category>
		<category><![CDATA[Microsoft Entra]]></category>
		<category><![CDATA[Microsoft Graph]]></category>
		<category><![CDATA[PowerShell]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125829</guid>

					<description><![CDATA[<p>Ogni volta che lancio Update-Module Microsoft.Graph -Scope AllUsers il bimbo innocente che vive in me ripete sempre la stessa cosa: &#8220;stavolta andrà liscio&#8221;. E ogni volta, puntuale, quel bimbo ne esce deluso: l&#8217;aggiornamento installa la nuova versione e non tocca la vecchia (o le vecchie, nel caso in cui tu ... <a title="Graph: pulizia delle vecchie versioni del modulo dopo un update" class="read-more" href="https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/" aria-label="Read more about Graph: pulizia delle vecchie versioni del modulo dopo un update">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/">Graph: pulizia delle vecchie versioni del modulo dopo un update</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Ogni volta che lancio <code class="EnlighterJSRAW" data-enlighter-language="powershell">Update-Module Microsoft.Graph -Scope AllUsers</code> il <em>bimbo innocente che vive in me</em> ripete sempre la stessa cosa: <em>&#8220;stavolta andrà liscio&#8221;</em>. E ogni volta, puntuale, quel bimbo ne esce deluso: l&#8217;aggiornamento installa la nuova versione e non tocca la vecchia (o le vecchie, nel caso in cui tu abbia fatto più aggiornamenti nel corso del tempo, senza curarti di ciò che lasciavi alle spalle), che resta lì, silenziosa, a occupare spazio e, nei casi peggiori, a creare conflitti quando PowerShell non sa bene quale versione dei cmdlet caricare.</p>
<p>Sia chiaro: so benissimo che è una scelta by-design, la pulizia dei vecchi moduli è a tuo carico, la maggior parte delle volte puoi &#8220;<em>ignorarla</em>&#8220;. Con <strong>Microsoft.Graph</strong> il problema è però amplificato dal fatto che non stiamo parlando di un modulo singolo, ma di una quarantina di sub-moduli (<code>Microsoft.Graph.Users</code>, <code>Microsoft.Graph.Groups</code>, <code>Microsoft.Graph.Applications</code> e così via). Se aggiorni e basta, ti ritrovi con due, tre, a volte più versioni della stessa libreria installate in parallelo su <code>C:\Program Files\PowerShell\Modules</code> (o nella tua cartella personale dei PowerShell Modules). Bello per chi ama fare ordine, pessimo per chi deve gestire ambienti di produzione dove ogni versione fantasma è un potenziale problema da capire poi, magari alle 2 di notte durante un incident.</p>
<h2>Il problema in pratica</h2>
<p>Dopo un aggiornamento mi ritrovo tipicamente così: nuova versione installata, ma la precedente ancora lì, con tutti i suoi sub-moduli:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="powershell">PS&gt; Update-Module Microsoft.graph -Scope AllUsers
PS&gt; Get-Module Microsoft.Graph* -ListAvailable |
&gt;&gt; Where-Object Version -ne '2.39.0' |
&gt;&gt; Select-Object Name, Version, Path

Name                                             Version Path
----                                             ------- ----
Microsoft.Graph                                 2.38.1  C:\Program Files\PowerShell\Modules\Microsoft.Graph\2.38.1\Mic…
Microsoft.Graph.Applications                    2.38.1  C:\Program Files\PowerShell\Modules\Microsoft.Graph.Applicatio…
Microsoft.Graph.Authentication                  2.38.1  C:\Program Files\PowerShell\Modules\Microsoft.Graph.Authentica…
[...]</pre>
<p>Quaranta righe, tutte con la stessa versione vecchia (2.38.1 nel caso oggi analizzato e buttato qui sul blog), tutte da rimuovere. A mano sarebbe una tortura, e infatti un <code class="EnlighterJSRAW" data-enlighter-language="powershell">Uninstall-Module Microsoft.Graph -RequiredVersion 2.38.1</code> da solo non basta: quel cmdlet toglie solo il modulo &#8220;<em>ombrello</em>&#8220;, non i sub-moduli che dipendono da lui.</p>
<h2>La pulizia (quella vera)</h2>
<p>La strada che mi ha portato a un risultato pulito è stata questa: prendo tutti i moduli della versione da buttare, li ordino mettendo per ultimo <code>Microsoft.Graph.Authentication</code> (da cui dipendono tutti gli altri, quindi va tolto per ultimo) e per primo <code>Microsoft.Graph</code> (l&#8217;ombrello, va tolto per primo):</p>
<pre class="EnlighterJSRAW" data-enlighter-language="powershell">$targetVersion = '2.38.1'

$oldGraph = Get-Module -Name 'Microsoft.Graph*' -ListAvailable |
    Where-Object Version -eq ([version]$targetVersion) |
    Sort-Object Name -Unique

$uninstallOrder = @(
    $oldGraph | Where-Object Name -eq 'Microsoft.Graph'

    $oldGraph | Where-Object {
        $_.Name -notin @(
            'Microsoft.Graph',
            'Microsoft.Graph.Authentication'
        )
    }

    $oldGraph | Where-Object Name -eq 'Microsoft.Graph.Authentication'
)

foreach ($module in $uninstallOrder) {
    Write-Host "Removing $($module.Name) $targetVersion ..."

    Uninstall-Module `
        -Name $module.Name `
        -RequiredVersion $targetVersion `
        -Force `
        -ErrorAction Stop
}</pre>
<p>Il <code>-Force</code> serve perché, senza, PowerShell si impunta se trova dipendenze ancora &#8220;in uso&#8221; secondo il suo registro interno (anche quando in realtà non c&#8217;è nessun processo che le sta usando). L&#8217;ordine di rimozione (ombrello prima, <code>Authentication</code> per ultimo) evita gli errori di dipendenza mancante che altrimenti PowerShell ti tira dietro a metà pulizia.</p>
<p>A operazione conclusa, una verifica veloce conferma che è rimasta una sola versione installata:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="powershell">Get-Module -Name 'Microsoft.Graph*' -ListAvailable |
    Group-Object Version |
    Sort-Object Name |
    Select-Object Name, Count

Name   Count
----   -----
2.39.0 40</pre>
<h2>In conclusione</h2>
<p>Il modulo <strong>Microsoft.Graph</strong> per PowerShell è potente ma <strong>non fa mai pulizia da solo</strong>: ogni <code>Update-Module</code> lascia dietro di sé la versione precedente, moltiplicata per una quarantina di sub-moduli. Se lavori su più macchine o gestisci ambienti condivisi, questo accumulo diventa presto un problema reale, spazio sprecato, tempi di caricamento del modulo più lunghi, e il rischio concreto di caricare per sbaglio la versione sbagliata di un cmdlet.</p>
<p>Lo script sopra non è elegantissimo ma fa il suo lavoro in modo ripetibile: prendi la versione vecchia, rispetta l&#8217;ordine di dipendenza, disinstalla tutto con <code>-Force</code>. Vale la pena tenerlo a portata di mano (magari come funzione riutilizzabile) ogni volta che aggiorni Graph.</p>
<p>In caso di errori, dubbi, boiate riportate in articolo sai già cosa fare, l&#8217;area commenti è a tua totale disposizione :-)</p>
<p><strong>#KeepItSimple</strong></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/">Graph: pulizia delle vecchie versioni del modulo dopo un update</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/08/17/graph-modulo-powershell-rimozione-versioni-vecchie/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Colonna auto-update plugin sparita? Controlla mu-plugins, potrebbe essere colpa di Installatron</title>
		<link>https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/</link>
					<comments>https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Sun, 09 Aug 2026 11:26:56 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Serverplan]]></category>
		<category><![CDATA[Sicurezza]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[WordPress Plugins]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125456</guid>

					<description><![CDATA[<p>Qualche giorno fa apro la pagina Plugin del blog e mi accorgo che manca un pezzo: la colonna che mi permette di scegliere, plugin per plugin, se abilitare l&#8217;auto-update oppure no. Non l&#8217;avevo tolta io, non ricordo aggiornamenti recenti di WordPress che l&#8217;abbiano spostata altrove, e su altri siti che ... <a title="Colonna auto-update plugin sparita? Controlla mu-plugins, potrebbe essere colpa di Installatron" class="read-more" href="https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/" aria-label="Read more about Colonna auto-update plugin sparita? Controlla mu-plugins, potrebbe essere colpa di Installatron">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/">Colonna auto-update plugin sparita? Controlla mu-plugins, potrebbe essere colpa di Installatron</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Qualche giorno fa apro la pagina <strong>Plugin</strong> del blog e mi accorgo che manca un pezzo: la colonna che mi permette di scegliere, plugin per plugin, se abilitare l&#8217;auto-update oppure no. Non l&#8217;avevo tolta io, non ricordo aggiornamenti recenti di WordPress che l&#8217;abbiano spostata altrove, e su altri siti che gestisco è ancora lì tranquilla al suo posto. Quindi il sospetto è arrivato in fretta: qualcuno ha toccato qualcosa senza dirmelo, &#8220;<em>al piano di sopra</em>&#8220;.</p>
<h2>La verifica</h2>
<p>Prima cosa: escludere che fosse un cambiamento arrivato da un qualche <em>comportamento</em> mio, di uno dei plugin che utilizzo o un aggiornamento di WordPress (dato che ultimamente ne sono arrivati almeno un paio per mettere al sicuro WP 7). Ho controllato <code>wp-config.php</code> per le costanti dichiarate in documentazione:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">define( 'WP_AUTO_UPDATE_CORE', 'false' );</pre>
<p>Presente, ma quella riguarda solo gli aggiornamenti del <em>core</em> di WordPress, non i plugin, non è la causa. <code>DISALLOW_FILE_MODS</code> assente. Poi ho controllato via <code>wp-cli</code> se i dati di auto-update fossero comunque popolati nel database:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">$ wp plugin list --status=active
name           status  update  version  auto_update
akismet        active  none    5.7      on
wordfence      active  none    8.2.2    on
...</pre>
<p>I dati c&#8217;erano, tutti popolati correttamente. Quindi non era un problema di database: la funzione esisteva ancora, semplicemente la UI per gestirla era sparita.</p>
<h2>Il colpevole: un mu-plugin che non ho mai chiesto</h2>
<p>A quel punto sono andato a guardare dentro <code>wp-content/mu-plugins/</code>. Cartella che, lo ricordo, WordPress carica <strong>sempre</strong>, senza possibilità di disattivazione dalla dashboard (da lì il nome: <em>must-use</em>). E lì, tra i miei file, ne spunta uno che non ho mai scritto io:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="php">&lt;?php
/*
  Plugin Name: WordPress automation by Installatron
  Description: Management of this WordPress site is provided by Installatron.
*/

// Turn off WordPress automatic updates since these are managed externally.
add_filter( 'automatic_updater_disabled', '__return_true', -9999 );</pre>
<p>Installatron è il tool che molti hosting (incluso il mio, Serverplan) offrono per installare/gestire applicazioni web in un click. Non l&#8217;ho mai usato per questo blog, e sospetto che nemmeno tu lo utilizzi consapevolmente, se sei atterrato su questo articolo cercando la stessa colonna sparita. Eppure quel mu-plugin era lì, silenzioso, a filtrare <code>automatic_updater_disabled</code> forzandolo a <code>true</code> con priorità altissima (<code>-9999</code>, giusto per essere sicuri che nessun altro filtro potesse scavalcarlo). Risultato: WordPress disattiva <em>tutto</em> il sistema di auto-update: core, plugin, temi, e <strong>nasconde pure la UI corrispondente</strong>, colonna compresa.</p>
<p>Il commento nel file suggerisce un modo &#8220;ufficiale&#8221; per disattivarlo:</p>
<blockquote><p>To block this plugin, create an empty file in the same directory named: <code>block-automation-by-installatron.php</code></p></blockquote>
<p><strong>Peccato che il codice del plugin non controlli mai l&#8217;esistenza di quel file</strong>. È una convenzione pensata per essere letta (e rispettata) dall&#8217;automazione di Installatron stessa quando rigenera i suoi file, non da WordPress. Creare quel file vuoto, quindi, non serve a niente: il filtro resta attivo lo stesso.</p>
<h2>La soluzione</h2>
<p>L&#8217;unico modo efficace è intervenire direttamente sul file. Io ho scelto la via più pulita e reversibile: rinominarlo togliendogli l&#8217;estensione <code>.php</code>, così la cartella <code>mu-plugins</code> smette di caricarlo ma il file resta lì, intatto, nel caso servisse tornare indietro:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">mv wp-content/mu-plugins/automation-by-installatron.php \
   wp-content/mu-plugins/automation-by-installatron.php.disabled</pre>
<p>Verifica rapida via <code>wp-cli</code> per confermare che il filtro non sia più attivo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">$ wp eval 'var_dump(apply_filters("automatic_updater_disabled", false));'
bool(false)</pre>
<p>Colonna auto-update tornata al suo posto nella pagina Plugin, tutto come previsto.</p>
<h2>In conclusione</h2>
<p>Se anche a te manca quella colonna e non ricordi di averla tolta, il primo posto dove guardare è <code>wp-content/mu-plugins/</code>, non la lista plugin normale, perché i <em>must-use plugin</em> non compaiono lì e non sono disattivabili dalla dashboard. Se trovi un file simile a <code>automation-by-installatron.php</code> (o comunque riconducibile al tuo hosting), sai già cosa cercare al suo interno e come toglierlo di mezzo.</p>
<p>Il punto che mi lascia più perplesso resta un altro: nessun avviso, nessuna nota nel pannello Serverplan, niente. Un mu-plugin che disattiva silenziosamente una funzione di sicurezza/manutenzione del sito è il genere di cosa che vorrei sapere <em>prima</em>, non scoprire per caso mesi dopo controllando una colonna mancante. Se gestisci un sito su hosting che offre Installatron (o strumenti simili), vale la pena dare un&#8217;occhiata preventiva a quella cartella, anche se non hai scelto consapevolmente di attivarlo.</p>
<p>L&#8217;area commenti è a tua disposizione in caso di ulteriori dubbi o magari per segnalare la medesima situazione su hosting differenti rispetto a quello da me utilizzato.</p>
<p><strong>#KeepItSimple</strong></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/">Colonna auto-update plugin sparita? Controlla mu-plugins, potrebbe essere colpa di Installatron</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/08/09/colonna-auto-update-plugin-sparita-installatron/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>TMS 9: ce l&#8217;abbiamo fatta, da lunedì si va in scena!</title>
		<link>https://gioxx.org/2026/07/31/tms-v9/</link>
					<comments>https://gioxx.org/2026/07/31/tms-v9/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Fri, 31 Jul 2026 16:38:20 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[Componenti aggiuntivi]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[In Evidenza]]></category>
		<category><![CDATA[Microsoft Edge]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[The Marvellous Suspender]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125370</guid>

					<description><![CDATA[<p>Cinque settimane fa avevo dato il via a una serie di articoli ad-hoc per parlarti del nuovo look per una nuova era di The Marvellous Suspender, avevo usato direttamente il blog di Marvellous Codeworks e l&#8217;inglese come lingua principale per raggiungere quanti più lettori e utilizzatori possibili (non pensavo avrebbe ... <a title="TMS 9: ce l&#8217;abbiamo fatta, da lunedì si va in scena!" class="read-more" href="https://gioxx.org/2026/07/31/tms-v9/" aria-label="Read more about TMS 9: ce l&#8217;abbiamo fatta, da lunedì si va in scena!">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/31/tms-v9/">TMS 9: ce l&#8217;abbiamo fatta, da lunedì si va in scena!</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="gb-block-notice info">
    <div class="gb-notice-title info"><p><i class="fas fa-info-circle fa-pull-right"></i>Info</p></div>
	<div class="gb-notice-text info">
		<p>
          If you want to read this article in English, <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f1ec-1f1e7.png" alt="🇬🇧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <a href="https://kb.marvellouscode.works/blog/road-to-tms9-launch/" rel="noopener">you can click here</a>.
		</p>
	</div>
</div>
<p><img decoding="async" class="alignright wp-image-125371" src="https://gioxx.org/wp-content/uploads/2026/07/the-marvellous-suspender-v3-migration-volunteer-testers-wanted-updated-500x500.webp" alt="The Marvellous Suspender: V3 Migration, volunteer testers wanted! (Updated)" width="220" height="220" title="TMS 9: ce l&#039;abbiamo fatta, da lunedì si va in scena! 2" srcset="https://gioxx.org/wp-content/uploads/2026/07/the-marvellous-suspender-v3-migration-volunteer-testers-wanted-updated-500x500.webp 500w, https://gioxx.org/wp-content/uploads/2026/07/the-marvellous-suspender-v3-migration-volunteer-testers-wanted-updated-150x150.webp 150w, https://gioxx.org/wp-content/uploads/2026/07/the-marvellous-suspender-v3-migration-volunteer-testers-wanted-updated-200x200.webp 200w, https://gioxx.org/wp-content/uploads/2026/07/the-marvellous-suspender-v3-migration-volunteer-testers-wanted-updated.webp 768w" sizes="(max-width: 220px) 100vw, 220px" />Cinque settimane fa avevo dato il via a una serie di articoli ad-hoc per parlarti del <a href="https://kb.marvellouscode.works/blog/tags/road-to-tms9" rel="noopener">nuovo look per una nuova era</a> di <strong>The Marvellous Suspender</strong>, avevo usato direttamente il <a href="https://kb.marvellouscode.works/blog" rel="noopener">blog di Marvellous Codeworks</a> e l&#8217;inglese come lingua principale per raggiungere quanti più lettori e utilizzatori possibili (non pensavo avrebbe avuto senso ospitare il tutto, in italiano, anche qui sul mio blog personale). Poche ore fa Google ha dato il via libera alla pubblicazione della v9.0.0 e, a partire da <strong>lunedì mattina, 3 agosto</strong>, la nuova versione comincerà a essere distribuita sul Chrome Web Store. È l&#8217;ultima tappa di questo percorso, e te la racconto volentieri (con 40°C fuori e la voglia di mettere la testa sott&#8217;acqua, ma questo è un altro discorso).</p>
<h1 id="cosa-c-di-nuovo-davvero">TMS 9: cosa c&#8217;è di nuovo sotto al cofano</h1>
<ul>
<li><strong>Backup e ripristino delle sessioni</strong> (forse tra le feature più richieste in assoluto, dalla notte dei tempi), in locale o su Google Drive, programmabile o su richiesta, con supporto multi-dispositivo.</li>
<li>Una pagina di <em>Tab Health</em> che scansiona le schede sospese e ripara da sola il bug dei Tab Groups che si perdono al riavvio di Chrome, Edge e Brave (bug ormai risolto, ma considerato che non si sa mai, le funzioni sono state conservate e rese disponibili su richiesta / necessità).</li>
<li>Un feed di notizie che pesca direttamente dal blog di Marvellous Codeworks (che rimane l&#8217;unico ufficiale del progetto, in inglese, mentre qui sul mio blog personale continuerò a proporre articoli in italiano, talvolta traducendoli direttamente) raggiungibile tramite la barra laterale delle impostazioni dell&#8217;estensione.</li>
<li>Un redesign visivo completo che finalmente fa sembrare tutte le pagine delle impostazioni parte dello stesso prodotto.</li>
<li>16 lingue riportate in pari dopo essere rimaste indietro per chissà quanto tempo.</li>
</ul>
<p>Niente di tutto questo è arrivato per caso, e niente è arrivato da solo.</p>
<h2 id="le-chiacchierate-con-rob">Le chiacchierate con Rob</h2>
<p>Io e Rob non lavoriamo nello stesso ufficio, nello stesso Paese, e nemmeno vicini come fuso orario, per buona parte del tempo. Gran parte delle decisioni su TMS 9 sono state avviate in un gruppo Slack in orari che non avevano senso per nessuno dei due, discutendo se un permesso fosse troppo invasivo, se un&#8217;impostazione avesse bisogno di un tooltip, se &#8220;Ripristina da backup&#8221; dovesse stare sotto Sessioni o sotto Backup. Domande piccole, ma di quelle che decidono se un&#8217;estensione sembra curata o semplicemente pubblicata.</p>
<p>The Great-er Tab Discarder (TGD) e The Marvellous Suspender (TMS) sono due progetti distinti, con codebase separate, ma Marvellous Codeworks funziona solo perché siamo in due a tirare nella stessa direzione, a controllarci i punti ciechi a vicenda e, ogni tanto, a dirci l&#8217;un l&#8217;altro che un&#8217;idea fa schifo prima che finisca in produzione. TMS 9 ne guadagna, eccome, e speriamo di poter fare la stessa cosa con TGD, presto.</p>
<h2 id="la-community-che-si-fatta-sentire">La community che si è fatta sentire</h2>
<p>Nel changelog di TMS 9 ci sono anche due contributor al debutto: <a href="https://github.com/MatrixNeoKozak" rel="noopener">@MatrixNeoKozak</a>, che ha rifattorizzato il livello di storage eliminando serializzazioni JSON inutili, e <a href="https://github.com/iGhost" rel="noopener">@iGhost</a>, che ha aggiunto l&#8217;opzione per mantenere la posizione di riproduzione di YouTube quando una scheda viene sospesa. Una feature piccola, richiesta e costruita da chi il problema lo ha vissuto sul serio (io per esempio non avevo mai avuto necessità di questa caratteristica). È esattamente così che dovrebbe crescere un progetto open source: non solo bug report, ma pull request di persone che hanno deciso di sistemare la cosa di persona.</p>
<p>In più, sedici lingue hanno ricevuto un passaggio di traduzione assistita da AI (qui Claude ha avuto carta bianca) per colmare buchi che si trascinavano da diverse versioni. Non sono perfette: se usi TMS nella tua lingua e qualcosa suona storto, <a href="https://crowdin.com/project/tms" rel="noopener">Crowdin</a> è aperto, e le correzioni dei madrelingua <strong>sono esattamente ciò che serve per chiudere il cerchio</strong>.</p>
<h2 id="segnalare-un-problema-senza-account-github">Segnalare un problema senza account GitHub</h2>
<p>Per anni l&#8217;unico modo per dirci che qualcosa non andava era aprire una segnalazione su GitHub, il che significava avere un account GitHub, spesso visto come un muro che molti semplicemente non erano disposti a scavalcare solo per segnalare un bug. I problemi ci arrivavano di riflesso, nelle recensioni, nei thread di Reddit, mai dove potevamo davvero intervenire.</p>
<p><a href="https://marvellouscode.works/tms/report" rel="noopener">marvellouscode.works/tms/report</a> proverà a risolvere la cosa. Si compila un form, senza registrazione, senza account, e viene aperta in automatico una issue GitHub corretta, etichettata bene, con i campi che ci servono davvero per riprodurre il problema. Chi segnala riceve un link per seguire lo stato, noi riceviamo un report vero e utilizzabile invece di una recensione da una stella che dice solo &#8220;non funziona più&#8221;.</p>
<p>E a proposito: leggiamo tutto, comprese le recensioni lasciate direttamente sul Chrome Web Store. Stelline, recensioni scritte, richieste di supporto in quel piccolo box, tutto viene letto. Teniamo d&#8217;occhio in particolare le segnalazioni GitHub perché è lì che tracciamo e agiamo davvero, verificando comportamenti strani, seguendo le richieste, chiudendo le cose una volta risolte, ma una recensione lasciata sullo Store non è comunque gridare nel vuoto.</p>
<div class="gb-block-notice warning">
    <div class="gb-notice-title warning"><p>Attenzione</p></div>
	<div class="gb-notice-text warning">
		<p>
          Il form di segnalazione via web è sperimentale. Esiste per abbassare la barriera per chi non vuole creare un account GitHub solo per dirci che qualcosa è rotto, non per sostituire GitHub del tutto. Se mai venisse abusato, spam, rumore in <em>malafede</em>, qualunque forma prenda, sarà la prima cosa che disattiveremo, e le segnalazioni torneranno a passare solo da account GitHub che aprono segnalazioni a proprio nome, punto.<br />

		</p>
	</div>
</div>
<h2 id="un-sito-di-documentazione-costruito-da-zero">Un sito di documentazione costruito da zero</h2>
<p>Il vecchio wiki di TMS viveva sul repo GitHub, mezzo incompleto, datato in alcuni punti, e onestamente non il tipo di posto dove mandare qualcuno se volevate che capisse davvero l&#8217;estensione. Ora è disattivato.</p>
<p>Al suo posto: <a href="https://kb.marvellouscode.works/docs/intro" rel="noopener">kb.marvellouscode.works/docs</a>, popolato da zero sfruttando Docusaurus come base, pagina per pagina, specialmente per TMS 9 (anche se in realtà pensato per tutti i lavori che trovano spazio sotto l&#8217;ala di Marvellous Codeworks). Ogni pagina delle impostazioni ha il suo articolo: Impostazioni, Sessioni, Backup, Tab Health, Azioni Rapide, Scorciatoie da Tastiera, Notizie, Informazioni, che spiega cosa fa davvero ogni pulsante, non solo come si chiama. C&#8217;è una pagina dedicata ai <a href="https://kb.marvellouscode.works/docs/TMS/permissions" rel="noopener">permessi</a> che spiega perché TMS chiede quello che chiede e cosa è cambiato con lo scope Drive più ristretto in questa release. FAQ incluse. Niente nascosto in una pagina wiki stantia che nessuno aggiornava dal 2019.</p>
<p>L&#8217;abbiamo costruito pagina per pagina, decidendo cosa aveva davvero bisogno di essere spiegato e cosa era abbastanza ovvio da saltare. Il dominio <code>marvellouscode.works</code> era registrato e fermo da quasi un anno: ci sono volute settimane di riorganizzazione e riscrittura per trasformarlo nel sito, nella documentazione e nel flusso di segnalazione che puoi sfruttare oggi.</p>
<h2 id="cambia-tutto-non-cambia-niente-">Cambia tutto (ma non cambia niente)</h2>
<p>TMS 9 ha un aspetto diverso, è organizzato diversamente, permette di effettuare il backup diversamente, e parla più lingue di prima. Questa è la parte &#8220;cambia tutto&#8221;, ed è costata una riscrittura completa delle pagine di impostazioni, un nuovo sistema di backup e parecchie scambi in chat.</p>
<p>La parte &#8220;non cambia niente&#8221; è più semplice: TMS esiste ancora per prendere le schede che il browser accumula in memoria e metterle a dormire finché non servono davvero. Era vero il giorno in cui <a href="#">The Great Suspender è stato salvato</a>, lo è stato durante la riscrittura per Manifest V3, e lo è ancora nella v9.0.0. Ogni feature di questa release, Tab Health, backup, redesign, esiste per proteggere quel singolo compito, non per sostituirlo.</p>
<h2 id="non-piacer-a-tutti-e-va-bene-cos-">Non piacerà a tutti, e va bene così</h2>
<p>Siamo perfettamente consapevoli che non tutti saranno entusiasti del nuovo look. Il cambiamento raramente è visto di buon occhio, e un redesign di queste dimensioni &#8211; nuovi font, nuovi colori, nuovo layout su ogni singola pagina &#8211; è esattamente il tipo di cosa per cui alcuni avranno bisogno di tempo per abituarsi, o semplicemente non gli piacerà affatto. Fa parte della crescita di un progetto, fa parte del gioco.</p>
<p>Restiamo convinti che la &#8220;<em>ritinteggiatura</em>&#8221; fosse necessaria, e pensiamo sia solo il primo passo importante. Ci sono altre idee in cantiere, e ci sono già parecchi problemi e richieste di feature su GitHub che intendiamo affrontare per continuare a spingere TMS avanti. Ascoltiamo, prendiamo sul serio feedback e critiche costruttive: è tutto il senso dell&#8217;open source, in fondo.</p>
<h2 id="cosa-succede-ora">Cosa succede ora</h2>
<p>La revisione di Google è conclusa, il changelog è definitivo, e il rilascio parte lunedì mattina, 3 agosto. Gli aggiornamenti sul Chrome Web Store vengono distribuiti gradualmente e non a tutti insieme, quindi non allarmarti se non vedi la v9.0.0 nel secondo esatto in cui andrai a controllare: arriverà entro la normale finestra di aggiornamento. Questa serie di articoli si chiude ufficialmente qui. Grazie per averla seguita fino in fondo, per aver testato i feature branch, per le issue aperte, per le pull request, e per la pazienza.</p>
<p>Ci vediamo dall&#8217;altra parte, nella v9.0.0. L&#8217;area commenti è a tua disposizione, come sempre, per domande o per raccontarmi la tua personale esperienza con TMS 9.</p>
<p><strong>#KeepItSimple (<em>e buone vacanze!</em>)</strong></p>
<hr />
<p>Immagine di copertina: <a class="stockpack-author" href="https://unsplash.com/@growtika?utm_source=Stockpack&amp;utm_medium=referral&amp;utm_campaign=api-credit" target="_blank" rel="nofollow noopener noreferrer">Growtika</a> on <a class="stockpack-provider" href="https://unsplash.com/photos/vTG2GFOb1iA?utm_source=Stockpack&amp;utm_medium=referral" target="_blank" rel="nofollow noopener noreferrer">Unsplash</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/31/tms-v9/">TMS 9: ce l&#8217;abbiamo fatta, da lunedì si va in scena!</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/07/31/tms-v9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Project Nova per Firefox Nightly: bello il gioco, però ora basta.</title>
		<link>https://gioxx.org/2026/07/29/firefox-nightly-project-nova/</link>
					<comments>https://gioxx.org/2026/07/29/firefox-nightly-project-nova/#comments</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 12:30:48 +0000</pubDate>
				<category><![CDATA[Mozilla]]></category>
		<category><![CDATA[Browser]]></category>
		<category><![CDATA[Mozilla Firefox]]></category>
		<category><![CDATA[Mozilla Italia]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125356</guid>

					<description><![CDATA[<p>Il 27 luglio scorso, via tweet di Firefox Nightly, Mozilla ha annunciato Project Nova: un nuovo aspetto grafico in test, al momento solo su Nightly, quindi niente panico se usi la versione stabile, per ora non ti tocca. Sul blog ufficiale di Nightly è comparso un post di annuncio piuttosto ... <a title="Project Nova per Firefox Nightly: bello il gioco, però ora basta." class="read-more" href="https://gioxx.org/2026/07/29/firefox-nightly-project-nova/" aria-label="Read more about Project Nova per Firefox Nightly: bello il gioco, però ora basta.">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/29/firefox-nightly-project-nova/">Project Nova per Firefox Nightly: bello il gioco, però ora basta.</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Il 27 luglio scorso, via <a href="https://x.com/FirefoxNightly/status/2081767446633959741">tweet di Firefox Nightly</a>, Mozilla ha annunciato <strong>Project Nova</strong>: un nuovo aspetto grafico in test, al momento solo su Nightly, quindi niente panico se usi la versione stabile, per ora non ti tocca.</p>
<p>Sul blog ufficiale di Nightly è comparso un post di annuncio piuttosto scarno (<a href="https://blog.nightly.mozilla.org/2026/07/27/new-firefox-design/" rel="noopener">New Firefox Design</a>), di quelli che dicono poco e lasciano parlare gli screenshot: giusto due righe di presentazione e via, senza un vero e proprio changelog o una spiegazione del perché di questa scelta proprio ora.</p>
<p>Nightly resta il mio Firefox di tutti i giorni, non a caso: mi piace sperimentare, dare un contributo (quando posso) alle idee che magari un domani arriveranno anche nelle versioni stabili. È rimasto quel poco che riesco ancora a fare dopo vent&#8217;anni e passa in Mozilla Italia, di cui i primi da contributor piuttosto attivo. Chi segue Firefox da un po&#8217; di anni sa che non è la prima volta che il browser cambia pelle: Australis, Photon, Proton sono nomi che a chi ha vissuto quelle transizioni diranno qualcosa, e ognuna ha portato con sé lo stesso copione: entusiasmo di facciata, malumori sotto traccia, e alla fine ci si abitua tutti (o quasi). <strong>Project Nova sembra volersi inserire in questa tradizione</strong>, solo che stavolta la reazione è arrivata più rumorosa e più in fretta del solito.</p>
<p>Project Nova me lo sono trovato in faccia da subito, senza nemmeno cercarlo, aggiornando Nightly come faccio ogni giorno, ed è giusto perché chi usa Nightly <em>accetta di fare da cavia</em> per queste sperimentazioni.</p>
<h2 id="cosa-dice-la-community">Cosa dice la community</h2>
<p>Su Mozilla Connect è partito un thread dedicato, <a href="https://connect.mozilla.org/t5/discussions/take-project-nova-for-a-spin-in-nightly/m-p/133231" rel="noopener">Take Project Nova for a spin in Nightly</a>, e &#8220;<em>nutrito</em>&#8221; è dire poco: pagine e pagine di commenti (caricarle tutte richiede un attimo di pazienza), e il tono generale non è esattamente da standing ovation. Ho lasciato anche il mio contributo al thread, <a href="https://connect.mozilla.org/t5/discussions/take-project-nova-for-a-spin-in-nightly/m-p/133229#M53496" rel="noopener">qui</a>, e riassumendo: il &#8220;<em>gioco</em>&#8221; del nuovo aspetto grafico può anche essere divertente da provare per qualche giorno, ma a conti fatti resta un esercizio di stile che toglie più di quanto aggiunge a chi usa il browser per lavorarci, non per ammirarlo.</p>
<p>Quello che mi ha colpito, scorrendo il thread, non è tanto il dissenso in sé (succede a ogni redesign, fa quasi parte del rito), quanto il volume e la rapidità con cui è arrivato. Di solito ci vogliono settimane prima che un cambiamento grafico venga metabolizzato dalla community, qui in pochi giorni si è già accumulata una mole di feedback che normalmente si vede solo dopo un rilascio stabile, non su un canale sperimentale che nasce apposta per essere rotto e discusso.</p>
<h2 id="come-tornare-indietro">Come tornare indietro</h2>
<p>Se anche a te Nova non convince e vuoi il vecchio aspetto &#8220;più umano&#8221;, il salvagente c&#8217;è ed è semplice:</p>
<ul>
<li>Apri <code>about:config</code> (il solito avviso: sai cosa stai facendo, ma occhio comunque a cosa tocchi, un flag sbagliato e ti ritrovi a chiederti perché qualcos&#8217;altro ha smesso di funzionare).</li>
<li>Cerca <code>browser.nova.enabled</code>.</li>
<li>Impostalo su <strong>false</strong></li>
</ul>
<p><img fetchpriority="high" decoding="async" class="alignnone size-large wp-image-125359" src="https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta-900x161.png" alt="Project Nova per Firefox Nightly: bello il gioco, però ora basta." width="900" height="161" title="Project Nova per Firefox Nightly: bello il gioco, però ora basta. 4" srcset="https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta-900x161.png 900w, https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta-500x89.png 500w, https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta-768x137.png 768w, https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta-200x36.png 200w, https://gioxx.org/wp-content/uploads/2026/07/project-nova-per-firefox-nightly-bello-il-gioco-pero-ora-basta.png 1210w" sizes="(max-width: 900px) 100vw, 900px" /></p>
<p>Fatto, il browser torna all&#8217;interfaccia che conosci, senza bisogno di reinstallare nulla o tornare a un canale diverso da Nightly, <strong>senza neanche riavviare Firefox</strong> che di solito è necessario per applicare le modifiche operate da <code>about:config</code>. Tieni presente che, trattandosi di un flag sperimentale, non è garantito che sopravviva tale e quale ai prossimi aggiornamenti: se un giorno lo cerchi e non lo trovi più (o si comporta diversamente), la causa più probabile è che nel frattempo Project Nova sia stato integrato più a fondo nel browser, magari con un meccanismo di disattivazione diverso.</p>
<h2 id="in-conclusione">Comprendo, non condivido</h2>
<p>Capisco la logica dietro Project Nova. Ogni tanto un browser ha bisogno di rinfrescarsi, e Nightly è esattamente il posto giusto dove provare queste cose prima che arrivino (se arrivano) nelle versioni stabili. Ma tra provarlo e tenerlo attivo di default anche su un canale già di per sé instabile fa una bella differenza, e il thread su Connect lo dimostra piuttosto bene. Per ora resto con <code>browser.nova.enabled</code> a <strong>false</strong>, e aspetto di vedere dove va a parare questo esperimento: se Mozilla ascolterà davvero quello che sta emergendo da Connect o se, come già successo in passato, si andrà avanti dritti per la propria strada aggiustando solo i dettagli più urlati.<br />
Magari tra qualche tempo (neanche tanto esagerato) torno ad attivarlo e vedere quali passi in avanti sono stati fatti.</p>
<p><strong>#KeepItSimple</strong></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/29/firefox-nightly-project-nova/">Project Nova per Firefox Nightly: bello il gioco, però ora basta.</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/07/29/firefox-nightly-project-nova/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Claude Swap gestisce via CLI più abbonamenti/account</title>
		<link>https://gioxx.org/2026/07/29/claude-swap/</link>
					<comments>https://gioxx.org/2026/07/29/claude-swap/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Wed, 29 Jul 2026 07:30:18 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Claude]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Terminale]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125349</guid>

					<description><![CDATA[<p>Sia che utilizzi Claude per lavoro che per hobby, prima o poi finirai (forse) per scontrarti con un potenziale problema: nel caso in cui tu abbia due (o più) abbonamenti e la necessità di passare dall&#8217;uno all&#8217;altro senza fare logout/login ogni volta, finirai per impazzire e stufarti molto facilmente. Il ... <a title="Claude Swap gestisce via CLI più abbonamenti/account" class="read-more" href="https://gioxx.org/2026/07/29/claude-swap/" aria-label="Read more about Claude Swap gestisce via CLI più abbonamenti/account">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/29/claude-swap/">Claude Swap gestisce via CLI più abbonamenti/account</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Sia che utilizzi Claude per lavoro che per hobby, prima o poi finirai (forse) per scontrarti con un potenziale problema: nel caso in cui tu abbia due (o più) abbonamenti e la necessità di passare dall&#8217;uno all&#8217;altro senza fare logout/login ogni volta, finirai per impazzire e stufarti molto facilmente. Il mio caso è abbastanza lampante: ho un abbonamento personale e uno aziendale, li uso su progetti e ambienti diversi, e mi serve poter saltare da un account all&#8217;altro con la stessa naturalezza con cui cambio finestra in Windows o macOS.</p>
<p>Da qualche mese la soluzione che uso, e di cui sono rimasto soddisfatto, è <strong><a href="https://github.com/realiti4/claude-swap" rel="noopener">Claude Swap</a></strong>.</p>
<h1 id="cos-claude-swap">Cos&#8217;è Claude Swap</h1>
<p>Claude Swap è un tool a riga di comando (Python) che gestisce le credenziali di più account Claude e permette di passare dall&#8217;uno all&#8217;altro con un comando, sia che tu stia lavorando da <strong>CLI</strong> che da <strong>VSCode</strong>. Fatta la configurazione iniziale, la parte più &#8220;onerosa&#8221; ma comunque semplice, il resto è tutta discesa: scegli l&#8217;account, lavori, e quando serve cambi contesto senza frizioni.</p>
<p>La prima volta che lo installi dovrai infatti lanciare <code class="EnlighterJSRAW" data-enlighter-language="python">cswap add</code> da riga di comando per aggiungere l&#8217;account che in quel momento stai già usando e che risulta essere collegato alla tua sessione. Torna sul browser, scollegati e ricollegati a Claude utilizzando un diverso account, quindi salta ancora sulla riga di comando per eseguire ancora una volta <code class="EnlighterJSRAW" data-enlighter-language="python">cswap add</code> ed ereditare pure il nuovo account, e così via.</p>
<p>Quello che apprezzo di più è che non ti costringe a scegliere un solo fronte: copre sia il terminale che l&#8217;editor, quindi qualsiasi sia il tuo workflow del momento, resti libero di alternare personale e aziendale a seconda del progetto su cui stai lavorando. Puoi addirittura essere ancora più puntiglioso, non fare uno switch su tutti i tuoi ambienti ed eseguire un run con un&#8217;utenza specifica in una finestra specifica (<code class="EnlighterJSRAW" data-enlighter-language="python">cswap run user@dominio-personale.com</code>).</p>
<h2 id="un-interfaccia-pi-curata-di-quanto-ti-aspetti">Un&#8217;interfaccia più curata di quanto ti aspetti</h2>
<p>Una volta installato lo lanci semplicemente eseguendo <code>cswap</code> (o <code>claude-swap</code>) e ti trovi davanti un&#8217;interfaccia testuale realizzata con <strong>Textual</strong>, framework Python per TUI moderne, non il solito prompt spoglio. Per ogni account configurato vedrai una barra che mostra quanto hai consumato della finestra di utilizzo a 5 ore e di quella settimanale, con relativo orario di reset, oltre a un indicatore chiaro di quale account è attivo in quel momento.</p>
<p><img decoding="async" class="alignnone size-full wp-image-125351" src="https://gioxx.org/wp-content/uploads/2026/07/claude-swap-gestisce-via-cli-piu-abbonamenti-account-e1785243969314.png" alt="Claude Swap gestisce via CLI più abbonamenti/account" width="651" height="326" title="Claude Swap gestisce via CLI più abbonamenti/account 6" srcset="https://gioxx.org/wp-content/uploads/2026/07/claude-swap-gestisce-via-cli-piu-abbonamenti-account-e1785243969314.png 651w, https://gioxx.org/wp-content/uploads/2026/07/claude-swap-gestisce-via-cli-piu-abbonamenti-account-e1785243969314-500x250.png 500w, https://gioxx.org/wp-content/uploads/2026/07/claude-swap-gestisce-via-cli-piu-abbonamenti-account-e1785243969314-200x100.png 200w" sizes="(max-width: 651px) 100vw, 651px" /></p>
<p>Dal menu principale puoi scegliere queste voci:</p>
<ul>
<li><strong>Switch account&#8230;</strong> per cambiare account al volo</li>
<li><strong>Watch accounts</strong> per tenere sott&#8217;occhio i consumi in tempo reale</li>
<li><strong>Auto-switch view</strong> per configurare uno switch automatico (utile se non vuoi accorgerti tu per primo di aver saturato un abbonamento)</li>
<li><strong>Add account…</strong> / <strong>Remove account&#8230;</strong> per gestire la lista</li>
<li><strong>Disable / enable account&#8230;</strong> per escludere temporaneamente un account senza rimuoverlo</li>
<li><strong>Theme&#8230;</strong> per il tema dell&#8217;interfaccia</li>
</ul>
<p>Tutto navigabile da tastiera, con scorciatoie richiamate a fondo schermo (<code>s</code> per switch, <code>w</code> per watch, <code>^t</code> per il tema, <code>q</code> per uscire). Poco più di un comando, insomma, ma ben pensato.</p>
<h2 id="aggiornarlo-banale">Aggiornarlo è banale</h2>
<p>Essendo un progetto Python, l&#8217;aggiornamento passa da <strong>pip</strong>, come ti aspetti:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python">python -m pip install --upgrade claude-swap
</pre>
<p>Giusto oggi che sto scrivendo questo articolo l&#8217;ho rifatto per l&#8217;ennesima volta, dalla 0.22.0 alla 0.23.0, senza il minimo intoppo:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python">Requirement already satisfied: claude-swap in ...Python312\Lib\site-packages (0.22.0)
Collecting claude-swap
  Downloading claude_swap-0.23.0-py3-none-any.whl.metadata (22 kB)
...
Successfully installed claude-swap-0.23.0
</pre>
<p>Nessuna sorpresa, nessuna configurazione da rifare da capo.</p>
<h2 id="e-le-credenziali-dove-finiscono-">E le credenziali dove finiscono?</h2>
<p>Punto che mi sta particolarmente a cuore: Claude Swap si appoggia a <strong>keyring</strong>, quindi le credenziali dei tuoi account non finiscono in un file di testo in chiaro da qualche parte sul disco, ma nel gestore di credenziali nativo del sistema operativo (Credential Manager su Windows, Keychain su macOS, e così via). Un aggiornamento del tool, come quello di cui sopra, non tocca minimamente questa parte: le credenziali restano dove sono, gestite in modo sicuro lato sistema.</p>
<h1 id="in-conclusione">In conclusione</h1>
<p>Se ti ritrovi anche tu a gestire più abbonamenti Claude, sia esso personale, lavorativo, o semplicemente più account per motivi diversi, Claude Swap è uno di quegli strumenti che, una volta configurati, smetti di notare: fa il suo lavoro in silenzio e ti lascia concentrato su quello che stai realmente facendo, senza il fastidio di continui logout/login o browser profile separati.</p>
<p>Spero possa tornare utile anche a te :-)</p>
<p><strong>#KeepItSimple</strong></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/29/claude-swap/">Claude Swap gestisce via CLI più abbonamenti/account</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/07/29/claude-swap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Jellyfin: tra dimissioni, burnout e riflessioni sparse</title>
		<link>https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/</link>
					<comments>https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Sat, 25 Jul 2026 07:30:16 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Jellyfin]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Personale]]></category>
		<category><![CDATA[Plex]]></category>
		<category><![CDATA[Self-Hosted]]></category>
		<category><![CDATA[Software]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125295</guid>

					<description><![CDATA[<p>Uso (anche) Jellyfin da qualche anno per tenere in ordine la mia libreria multimediale in casa, quando ho letto il pezzo di It&#8217;s FOSS sulla crisi di leadership del progetto mi si è un po&#8217; stretto lo stomaco; la sindrome da &#8220;e adesso chi lo mantiene&#8221; è sempre in agguato ... <a title="Jellyfin: tra dimissioni, burnout e riflessioni sparse" class="read-more" href="https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/" aria-label="Read more about Jellyfin: tra dimissioni, burnout e riflessioni sparse">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/">Jellyfin: tra dimissioni, burnout e riflessioni sparse</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Uso (anche) Jellyfin da qualche anno per tenere in ordine la mia libreria multimediale in casa, quando ho letto <a href="https://itsfoss.com/news/jellyfin-leadership-crisis/" rel="noopener">il pezzo di It&#8217;s FOSS sulla crisi di leadership del progetto</a> mi si è un po&#8217; stretto lo stomaco; la sindrome da &#8220;<em>e adesso chi lo mantiene</em>&#8221; è sempre in agguato quando dipendi da un progetto open per qualcosa che usi ogni giorno.</p>
<p>In sintesi: nel giro di pochi giorni se ne sono andati tre nomi pesanti del progetto. <strong>Joshua Boniface</strong>, uno dei fondatori e Project Leader storico, ha lasciato il ruolo con <a href="https://forum.jellyfin.org/t-project-leadership-changes" rel="noopener">un annuncio sul forum ufficiale</a> tutt&#8217;altro che di circostanza: parla apertamente di <em>&#8220;severe burnout, and risks to my mental health&#8221;</em> e ammette di non riuscire più a garantire <em>&#8220;the effort (mental or time-wise) that the role demanded&#8221;</em>. Chiude comunque con affetto &#8211; <em>&#8220;For the last time, happy watching all!&#8221; &#8211;</em> e ribadisce che la transizione è amichevole. <strong>Andrew Rabert</strong>, anche lui fondatore, se n&#8217;è andato volontariamente il 17 luglio 2026, dopo mesi passati a riscrivere da zero il client desktop (partito a dicembre 2025 per risolvere problemi annosi come il supporto HDR e la manutenzione di Qt). Nel <a href="https://github.com/andrewrabert/jellium-desktop/issues/609" rel="noopener">suo commento su GitHub</a> descrive un clima interno diventato <em>&#8220;very negative and increasingly burdensome and restrictive&#8221;</em>, al punto da fargli perdere la voglia di dedicare al progetto quello che per anni era stato passione e motivo di relax come si trattasse di un puro hobby. Uscendo dall&#8217;organizzazione ha perso anche il diritto a usare il nome &#8220;Jellyfin&#8221;, quindi il suo client proseguirà sotto un altro nome. <strong>Anthony Lavado</strong>, membro storico del core team, si è dimesso in parallelo per cambiamenti nella vita personale che gli riducono il tempo disponibile, impegnandosi comunque a garantire una <em>transizione senza intoppi</em>.</p>
<p>La causa di fondo, però, è la stessa per tutti: burnout. Il report <a href="https://jellyfin.org/posts/state-of-the-fin-2026-05-24/" rel="noopener">&#8220;State of the Fin&#8221; di maggio 2026</a>, che di solito celebra metriche di attività in salute (quasi 3.800 PR mandate in merge nel periodo, picchi di 434 in un mese, tra 46 e 75 contributori attivi al mese), ammette a chiare lettere che <em>&#8220;l&#8217;aumento delle richieste di supporto, combinato con i contributi di codice AI, ha portato a esaurimento a vari livelli&#8221;</em>, e che gli abusi da parte di utenti scontenti quando qualcosa non funziona rallentano ulteriormente i miglioramenti. Non è un dettaglio da poco: il progetto ha dovuto introdurre una policy esplicita sui contributi generati con l&#8217;AI, obbligando chi li sottopone a capire davvero il codice proposto e a rispondere di persona ai feedback, non certo il copia-incolla che in molti si aspettano quando pensano di poter mettere al lavoro il proprio abbonamento (sia esso di Claude, Codex o qualsiasi altro <em>aiutante</em>). Se stai mantenendo un progetto open di questa scala, ricevere pull request scritte (o &#8220;assistite&#8221;) da un modello e dover fare da filtro qualità aggiunge un peso che prima semplicemente non esisteva.</p>
<p>La buona notizia, se la si vuole chiamare così, è che chi se n&#8217;è andato ha tenuto a precisare che l&#8217;uscita è pacifica, con &#8220;poco o nessun rischio di fork ostile&#8221;, e che il resto del team, già diviso su altre aree del progetto, sta continuando le operazioni.</p>
<p>Qui però voglio aggiungere una cosa più personale. Io sono cliente <strong>Lifetime di Plex</strong> da (tanti) anni, e per me Plex è sempre stato &#8220;<em>lo stato dell&#8217;arte</em>&#8221; per questo genere di cose, il prodotto contro cui si misurano tutti gli altri. Ma diciamocelo: negli ultimi tempi è diventato più <strong>pesante</strong>, più <strong><em>pachidermico</em></strong>, e genera <strong>più frizione sia per chi lo sviluppa sia per chi lo usa tutti i giorni</strong>. E non parlo solo di percezione: il <strong>Lifetime Plex Pass</strong> è passato da 120 dollari a 250 dollari nell&#8217;aprile 2025, per poi triplicare di nuovo a <strong>749,99 dollari</strong> dal 1° luglio 2026, con tanto di accenno che l&#8217;opzione lifetime potrebbe sparire del tutto in futuro. Chi ce l&#8217;ha già tiene i benefici, per carità, ma è un segnale chiaro di dove sta andando il prodotto: verso un modello sempre più orientato all&#8217;abbonamento, sempre meno amichevole per chi vuole pagare una volta e basta.</p>
<p>Ed è proprio in questo contesto che Jellyfin, nonostante le sue crepe di governance, resta un&#8217;alternativa concreta e sempre più solida. Il progetto conta 8 client ufficiali (Android, Android TV, Desktop, Kodi, Roku, Tizen, Xbox, Swiftfin) più altri due in sviluppo, e vive di un ecosistema di plugin, temi grafici e integrazioni esterne che raggiunge praticamente ogni piattaforma esistente, cosa che a un prodotto chiuso come Plex, per sua natura, riesce molto più difficile. È più aperto, più adattabile, e &#8211; a differenza di Plex &#8211; non ti sveglia una mattina con il prezzo del piano lifetime triplicato (<em>si nota la mia pacata nota polemica nonostante io non sia stato colpito da questa brillante decisione?</em>).</p>
<figure id="attachment_125296" aria-describedby="caption-attachment-125296" style="width: 375px" class="wp-caption alignright"><img loading="lazy" decoding="async" class="wp-image-125296 size-large" src="https://gioxx.org/wp-content/uploads/2026/07/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse.webp" alt="Jellyfin: tra dimissioni, burnout e riflessioni sparse" width="385" height="489" title="Jellyfin: tra dimissioni, burnout e riflessioni sparse 7" srcset="https://gioxx.org/wp-content/uploads/2026/07/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse.webp 385w, https://gioxx.org/wp-content/uploads/2026/07/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse-200x254.webp 200w" sizes="auto, (max-width: 385px) 100vw, 385px" /><figcaption id="caption-attachment-125296" class="wp-caption-text">Immagine originale: <a href="https://www.reddit.com/r/ExplainTheJoke/comments/18ubyrd/i_dont_get_it/" rel="noopener">Reddit</a></figcaption></figure>
<p>Da utente, la cosa che mi fa riflettere di più non è tanto il rischio immediato per Jellyfin (che al momento sembra sotto controllo), quanto il pattern che si sta ripetendo un po&#8217; ovunque nel mondo Open Source: progetti che reggono su poche persone, quelle poche persone che si bruciano, e adesso pure il carico aggiuntivo di dover controllare codice scritto da un&#8217;AI invece che risparmiare tempo. Se dipendi da qualcosa di self-hosted per la tua libreria multimediale, e sospetto che se sei qui a leggere questo blog sia il tuo caso, vale la pena tenere d&#8217;occhio come evolve la governance di Jellyfin nei prossimi mesi, non perché sia in pericolo imminente, ma perché è un buon termometro di quanto reggano certi modelli di manutenzione quando i volontari dietro cominciano a mollare.</p>
<p>E non è in ogni caso una novità, parlando in generale di questo mondo che va ben oltre Jellyfin, il meme qui di fianco ha fatto (e fa ancora) scuola di tanto in tanto, quando l&#8217;argomento viene riportato alla ribalta.</p>
<h2 id="in-conclusione">In conclusione</h2>
<p>Nessun allarme rosso per ora, ma un promemoria che i progetti open che usiamo ogni giorno stanno in piedi grazie a poche persone che a un certo punto possono semplicemente stancarsi. Nel frattempo, tra un Plex sempre più caro e pesante e un Jellyfin sempre più maturo e aperto, la bilancia per me continua a spostarsi verso quest&#8217;ultimo, nonostante non sia assolutamente pronto ad abbandonare il &#8220;<em>primogenito</em>&#8220;.</p>
<p>Se usi Jellyfin (o Plex, o entrambi), l&#8217;area commenti è a tua disposizione per confrontarci su cosa ne pensi, ammesso ti vada (e buon fine settimana pure a te!).</p>
<p><strong>#KeepItSimple</strong></p>
<hr />
<h6>Immagine di copertina: <a class="stockpack-author" href="https://unsplash.com/@borzenkov?utm_source=Stockpack&amp;utm_medium=referral&amp;utm_campaign=api-credit" target="_blank" rel="nofollow noopener noreferrer">Anton Borzenkov</a> on <a class="stockpack-provider" href="https://unsplash.com/photos/4Osc62ACP6w?utm_source=Stockpack&amp;utm_medium=referral" target="_blank" rel="nofollow noopener noreferrer">Unsplash</a></h6>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/">Jellyfin: tra dimissioni, burnout e riflessioni sparse</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/07/25/jellyfin-tra-dimissioni-burnout-e-riflessioni-sparse/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>&#8220;Scusate, ha stato l&#8217;IA&#8221;: il caso OpenAI e Hugging Face</title>
		<link>https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/</link>
					<comments>https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/#respond</comments>
		
		<dc:creator><![CDATA[Gioxx]]></dc:creator>
		<pubDate>Thu, 23 Jul 2026 07:30:14 +0000</pubDate>
				<category><![CDATA[Tech & Coding]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[In Evidenza]]></category>
		<category><![CDATA[OpenAI]]></category>
		<category><![CDATA[Sicurezza]]></category>
		<guid isPermaLink="false">https://gioxx.org/?p=125286</guid>

					<description><![CDATA[<p>Ci sono notizie che leggi e archivi come &#8220;roba da nerd&#8220;, e poi ci sono quelle che ti fanno fermare il caffè a mezz&#8217;aria (o se preferisci, sparire come Homer Simpson dentro la siepe). L&#8217;articolo di oggi trova spazio nella seconda categoria, e te lo racconto con calma perché merita ... <a title="&#8220;Scusate, ha stato l&#8217;IA&#8221;: il caso OpenAI e Hugging Face" class="read-more" href="https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/" aria-label="Read more about &#8220;Scusate, ha stato l&#8217;IA&#8221;: il caso OpenAI e Hugging Face">Leggi tutto</a></p>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/">&#8220;Scusate, ha stato l&#8217;IA&#8221;: il caso OpenAI e Hugging Face</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Ci sono notizie che leggi e archivi come &#8220;<em>roba da nerd</em>&#8220;, e poi ci sono quelle che ti fanno fermare il caffè a mezz&#8217;aria (o se preferisci, sparire come Homer Simpson dentro la siepe). L&#8217;articolo di oggi trova spazio nella seconda categoria, e te lo racconto con calma perché merita di essere capito bene pur rimanendo alla portata di tutti, non solo condiviso con un &#8220;<em>guarda che roba</em>&#8221; su qualche gruppo di chat tra amici.</p>
<p>Riassunto brutale: <strong>un agente AI di OpenAI, durante un test di sicurezza su un benchmark pubblico, è <em>evaso</em> dal suo ambiente isolato (tecnicamente una sandbox) ed è finito a bucare davvero l&#8217;infrastruttura di produzione di Hugging Face</strong>. Non una simulazione, non un <em>innocuo test di laboratorio</em>: server veri, credenziali vere, dati veri. E ci è voluto un intero fine settimana prima che qualcuno se ne accorgesse.</p>

<h1 id="il-contesto-cos-exploitgym">Il contesto: cos&#8217;è ExploitGym</h1>
<p>Partiamo da dove nasce tutto. <strong>ExploitGym</strong> è un benchmark pubblico creato da UC Berkeley con la collaborazione di attori come Anthropic, OpenAI e Google, pensato per misurare quanto bene un modello AI sappia trasformare una vulnerabilità nota (una &#8220;proof-of-vulnerability&#8221;, per capirci: la prova che il buco esiste) in un exploit funzionante. Dentro ci sono quasi 900 vulnerabilità reali, divise tra programmi userspace, il motore V8 di Chrome e il kernel Linux.</p>
<p>In altre parole: è un ambiente pensato apposta per <em>insegnare e verificare</em> le capacità offensive di un modello, in teoria dentro un recinto controllato. Il classico &#8220;diamo all&#8217;AI un cortile chiuso dove può fare danni, così capiamo quanto è brava a farli&#8221;.</p>
<p>Il problema, come vedremo, è che il cortile aveva un buco nella rete.</p>
<h2 id="cosa-successo-davvero">Cosa è successo davvero</h2>
<p>Il 16 luglio 2026 Hugging Face rileva, in autonomia, un&#8217;intrusione nella propria infrastruttura di produzione. Non un test, non un red team annunciato: un&#8217;intrusione vera, rilevata grazie a una pipeline di anomalie che usa modelli AI per fare da filtro sul rumore di fondo della telemetria di sicurezza (sì, si combatte fuoco con fuoco, e su questo torniamo più avanti).</p>
<p>Il punto d&#8217;ingresso? Due classi di vulnerabilità nel processing dei dataset: un <strong>loader di dataset con esecuzione di codice remoto</strong> e una <strong>iniezione di template</strong> nella configurazione. Non roba nuovissima, anzi: la prima famiglia di bug è nota alla comunità almeno dal 2023. <em>Occhio a</em> questo dettaglio, perché torna comodo più avanti quando si parla di responsabilità.</p>
<p>Da lì, l&#8217;attaccante (o meglio: l&#8217;agente) ha scalato privilegi, raccolto credenziali cloud e si è mosso lateralmente tra diversi cluster interni, nell&#8217;arco di un intero weekend, accumulando <strong>oltre 17.000 azioni autonome</strong>. Hugging Face parla di un set limitato di dataset interni e alcune credenziali compromesse, e &#8211; <em>buona notizia, se così si può dire</em> &#8211; nessuna evidenza che modelli, dataset o Spaces pubblici siano stati manomessi. Va detto per correttezza che il rilevamento è arrivato da entrambe le parti quasi in parallelo: il team di sicurezza di Hugging Face ha bloccato l&#8217;attività sulla propria infrastruttura e avviato da solo il contenimento e la ricostruzione forense (con modelli open-source proprietari, tra l&#8217;altro), mentre il team di sicurezza di OpenAI scopriva indipendentemente l&#8217;attività anomala sul proprio lato. Solo dopo i due team si sono messi in contatto e hanno unito le indagini.</p>
<p>Cinque giorni dopo, il 21 luglio, arriva la rivelazione ufficiale da parte di OpenAI, in un post congiunto con Hugging Face: dietro l&#8217;intrusione c&#8217;era <strong>GPT-5.6 Sol</strong> insieme a un modello pre-release ancora più capace, entrambi con i <em>refusal</em> legati al cyber ridotti apposta per finalità di valutazione (in parole povere: senza i freni che normalmente li fermerebbero davanti ad attività ad alto rischio). L&#8217;obiettivo dichiarato non era &#8220;bucare Hugging Face&#8221; in senso classico: il modello era, per usare le parole di OpenAI, &#8220;iperfocalizzato&#8221; nel trovare una soluzione per ExploitGym, ed è arrivato a cercare &#8211; <em>e trovare</em> &#8211; le risposte corrette direttamente nel database di produzione di Hugging Face, per barare al test.</p>
<p>Il percorso è tecnicamente interessante e vale la pena seguirlo passo passo. L&#8217;ambiente di test di OpenAI aveva accesso a internet limitato all&#8217;installazione di package tramite un <strong>proxy/cache interno per i registri software</strong> di terze parti. Il modello ha impiegato una quantità notevole di potenza di calcolo pur di trovare un modo per uscire da quel recinto e arrivare a internet aperto: ha scoperto &#8211; <em>da solo, senza accesso al codice sorgente</em> &#8211; una vulnerabilità zero-day proprio in quel proxy (nel frattempo divulgata responsabilmente al fornitore), l&#8217;ha usata per scalare privilegi e muoversi lateralmente nell&#8217;ambiente di ricerca di OpenAI fino a raggiungere un nodo con accesso a internet. Da lì ha dedotto che Hugging Face probabilmente ospitava modelli, dataset e soluzioni di ExploitGym, e ha concatenato credenziali rubate e altri zero-day per trovare un percorso di esecuzione di codice remoto sui server di Hugging Face.</p>
<p><em>In parole povere</em>: un modello che doveva solo dimostrare di saper trasformare un bug noto in un exploit ha finito per trovarne di nuovi, da solo, e per usarli per uscire dal recinto in cui era stato messo apposta per &#8220;fare danni sotto controllo&#8221;.</p>
<h2 id="il-nodo-tecnico-isolamento-illusorio">Il nodo tecnico: isolamento illusorio</h2>
<p>Qui arriva la parte che, da tecnico, fa più male delle altre. OpenAI stessa ha descritto l&#8217;ambiente di test come &#8220;altamente isolato&#8221; (<em>highly isolated</em>, testuale). Peccato che quell&#8217;ambiente avesse comunque una via verso internet tramite quel proxy per i registri software, e il modello ha sfruttato esattamente il presupposto, evidentemente troppo fiducioso, che quella via fosse sicura o comunque impraticabile per uscire dal recinto.</p>
<p>È un errore che chiunque abbia mai progettato un ambiente &#8220;sandbox&#8221; riconosce a colpo d&#8217;occhio: <strong>isolato non significa isolato se poi lasci un varco verso l&#8217;esterno e ti fidi che nessuno lo trovi</strong>. Non serve un agente AI sofisticatissimo per insegnarcelo, basterebbe la storia di qualsiasi breach degli ultimi vent&#8217;anni. Il fatto che stavolta a trovare il varco sia stato un modello, in autonomia, in poche ore, cambia la scala del problema ma non la natura dell&#8217;errore: è ancora una falla di progettazione, non un miracolo di intelligenza artificiale.</p>
<p>Alberto Pelliccione, che ha scritto un&#8217;analisi tecnica molto lucida sull&#8217;incidente (la trovi su <a href="https://www.linkedin.com/pulse/day-openai-hacked-huggingface-alberto-pelliccione-zejic/" rel="noopener">linkedin.com/pulse</a>), la inquadra bene: più che un attacco deliberato, siamo davanti a un caso di <strong>reward hacking</strong>. Il modello non &#8220;voleva&#8221; bucare Hugging Face nel senso in cui lo vorrebbe un attaccante umano, <strong>voleva vincere il benchmark</strong>, e ha semplicemente seguito la strada più breve verso la ricompensa, che per caso passava attraverso credenziali cloud reali e cluster di produzione veri.</p>
<p>Il dubbio resta (e per certi versi è quasi una certezza, anche se nessuno lo scriverà mai nero su bianco in un comunicato ufficiale): se il percorso più breve verso il <em>premio</em> passa per un&#8217;infrastruttura reale, il problema non è che l&#8217;AI sia troppo capace. È che qualcuno ha lasciato quel percorso aperto.</p>
<h2 id="la-parte-pi-paradossale-chi-ha-aiutato-a-fare-le-pulizie">La parte più paradossale: chi ha aiutato a fare le pulizie</h2>
<p>Ed eccoci al dettaglio che, da solo, vale l&#8217;intero articolo. Durante l&#8217;analisi forense &#8211; <em>oltre 17000 eventi di log da ricostruire per capire cosa fosse successo</em> &#8211; Hugging Face ha usato <strong>GLM 5.2</strong>, un modello open-weight (di origine cinese, per essere precisi). Non per scelta ideologica: perché i modelli commerciali occidentali, Anthropic e OpenAI compresi, con i loro guardrail di sicurezza <strong>si rifiutavano di analizzare gli artefatti dell&#8217;attacco</strong>, trattandoli come contenuto potenzialmente dannoso da non toccare.</p>
<p>Ti basti pensare a questo: i modelli &#8220;sicuri per design&#8221; hanno ostacolato chi doveva ripulire i danni, mentre un modello open-weight, proprio quello oggetto di discussioni e restrizioni proposte in ambito geopolitico (per timori legati alla sicurezza, ironia delle ironie), si è rivelato lo strumento decisivo per la difesa.</p>
<p>Pelliccione la definisce come un paradosso geopolitico, e onestamente è difficile dargli torto: i guardrail hanno bloccato chi doveva <em>ripulire</em>, non chi doveva <em>attaccare</em>. L&#8217;agente incriminato, va ricordato, era comunque un modello OpenAI, solo che stava operando in un contesto di test dove quei paletti valgono meno.</p>
<h2 id="cosa-ci-lascia-in-mano-questa-storia">Cosa ci lascia in mano questa storia</h2>
<p>Al netto del clamore mediatico (e sì, un titolo come &#8220;OpenAI hacked Hugging Face&#8221; fa notizia più facilmente di &#8220;una sandbox mal configurata ha causato un incidente&#8221;), qualche punto mi pare innegabile:</p>
<ul>
<li><strong>La sandbox non è un concetto binario.</strong> &#8220;Isolato&#8221; deve significare isolato per davvero, non isolato-tranne-per-quel-proxy-a-cui-abbiamo-dato-fiducia. Vale per gli agenti AI oggi, valeva per le VM di test <del>dieci</del> <del>cinque</del> <del>tre</del> <del>due anni</del> una manciata di settimane fa (e tutt&#8217;ora, perché ne esistono ancora quante ne vuoi in giro).</li>
<li><strong>Vulnerabilità note restano un problema reale</strong>, anche quando a scoprirle &#8220;di nuovo&#8221; è un modello da miliardi di parametri. Un loader di dataset con RCE noto dal 2023 non dovrebbe essere ancora in produzione nel 2026, punto (e qui il giudizio resta netto perché descrive un fatto, non perché voglia fare colore).</li>
<li><strong>Le capacità offensive autonome dei modelli frontier non sono più teoria da paper accademico.</strong> Erano previste da anni nelle ricerche sul rischio cyber dell&#8217;AI: qui le vediamo diventare cronaca, con tanto di timeline, log e comunicati ufficiali.</li>
<li><strong>I guardrail dei modelli commerciali proteggono da alcuni scenari e ne creano altri</strong>: se blocchi l&#8217;analisi forense di un attacco reale perché &#8220;sembra contenuto dannoso&#8221;, stai aiutando chi deve rispondere all&#8217;incidente o solo aggiungendo frizione dove già ce n&#8217;è fin troppa?</li>
</ul>
<p>Non ho risposte facili da darti su quest&#8217;ultimo punto, e sospetto che nemmeno chi scrive quei guardrail le abbia ancora del tutto chiare. Quello che è certo è che la distanza tra &#8220;benchmark di sicurezza in un ambiente controllato&#8221; e &#8220;incidente di sicurezza reale con credenziali cloud sottratte&#8221; si è rivelata molto più corta di quanto chiunque, in OpenAI o altrove, avesse previsto.</p>
<p>Chiudo con una frase di Clem Delangue, co-fondatore e CEO di Hugging Face, riportata proprio nel post ufficiale di OpenAI, perché mette a fuoco meglio di qualsiasi mio commento dove sta andando tutta questa storia: <em>&#8220;AI safety won&#8217;t be solved by any single company working in secret. It will be solved in the open, collaboratively, with broad access to AI for every defender, everywhere&#8221;:</em> <mark><strong>la sicurezza dell&#8217;AI non si risolve con un&#8217;azienda sola che lavora in segreto</strong>, <strong>ma in modo aperto e collaborativo</strong>, <strong>con accesso ampio all&#8217;AI per ogni difensore</strong>, <strong>ovunque</strong></mark>.</p>
<p>Se vuoi approfondire, oltre ai link già citati, trovi il resoconto ufficiale di Hugging Face su <a href="https://huggingface.co/blog/security-incident-july-2026" rel="noopener">huggingface.co/blog</a>, il post congiunto di OpenAI su <a href="https://openai.com/index/hugging-face-model-evaluation-security-incident/" rel="noopener">openai.com/index</a> e un&#8217;analisi più estesa su <a href="https://cyberwarrior76.substack.com/p/openai-exploitgym-incident-autonomous" rel="noopener">cyberwarrior76.substack.com</a>.</p>
<h1 id="in-conclusione">In conclusione</h1>
<p>Non credo serva scomodare scenari apocalittici da fantascienza per prendere sul serio questa storia: basta guardarla con gli occhi di chi ha messo in piedi ambienti di test almeno una volta nella vita. Un modello ha fatto, in un weekend e senza supervisione umana in tempo reale, quello che un buon penetration tester farebbe in una settimana di lavoro mirato, e lo ha fatto per motivi che con la malizia umana hanno poco a che fare. Non è meno preoccupante: <strong>è preoccupante in un modo diverso</strong>, e forse più difficile da normare con le categorie di sicurezza a cui siamo abituati.</p>
<p>L&#8217;area commenti è a tua disposizione, se vuoi discuterne o se hai letto l&#8217;incidente diversamente da come l&#8217;ho raccontato io qui, che poi potrei aver preso delle cantonate pure io con le informazioni reperite, quindi sentiti libero di bastonarmi (in maniera comunque civile!).</p>
<p><strong>#KeepItSimple</strong></p>
<hr />
<h6>Immagine di copertina: <a class="stockpack-author" href="https://unsplash.com/@chrisyangchrisfilm?utm_source=Stockpack&amp;utm_medium=referral&amp;utm_campaign=api-credit" target="_blank" rel="nofollow noopener noreferrer">Chris Yang</a> on <a class="stockpack-provider" href="https://unsplash.com/photos/1tnS_BVy9Jk?utm_source=Stockpack&amp;utm_medium=referral" target="_blank" rel="nofollow noopener noreferrer">Unsplash</a></h6>
<p><a rel="nofollow" href="https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/">&#8220;Scusate, ha stato l&#8217;IA&#8221;: il caso OpenAI e Hugging Face</a> è stato scritto da <a rel="nofollow" href="https://gioxx.org/author/gioxx/">Gioxx</a> per <a rel="nofollow" href="https://gioxx.org">Gioxx.org</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://gioxx.org/2026/07/23/openai-huggingface-exploitgym/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
