Wispr Flow, AionUi e Devin ora si aggiornano con un clic, invece di limitarsi a dirti che esiste una nuova versione. Tutte e tre vedevano già i propri aggiornamenti, ma nessuna poteva applicarli, per un motivo dichiarato: il produttore distribuisce build separate per Intel e per Apple silicon e DuoUpdater non aveva modo di scegliere. Verificato sul campo anziché dato per scontato, quel motivo non reggeva: gli endpoint da cui si leggono queste tre app sono già quelli per Apple silicon, e DuoUpdater funziona solo su Apple silicon, quindi non c’è mai stata una scelta da fare. Ogni download è stato scaricato e controllato prima di essere collegato: dentro c’è l’app giusta, firmata dallo stesso sviluppatore della copia che hai, autenticata da Apple, e quello di AionUi è stato verificato con il checksum pubblicato nel suo stesso manifest. Poi ciascuna è stata installata davvero, sopra una copia più vecchia, ed è ripartita con la nuova versione.
Grok Bot ora è monitorata: nuove versioni e aggiornamenti con un clic. L’app desktop di xAI è compilata e firmata da Anysphere, l’azienda dietro Cursor, e si aggiorna tramite il servizio di rilascio di Cursor: per questo nessuna delle strade abituali dava risposta. Niente feed Sparkle, nessuna scheda sull’App Store, nessun repository pubblico delle release, e un cask Homebrew che rimanda l’aggiornamento all’app stessa. DuoUpdater legge invece l’endpoint di versione del produttore. C’erano altri due endpoint, e sono stati scartati entrambi per motivi precisi: quello dietro il pulsante di download su x.ai non pubblica alcun numero di versione, e quello usato dal programma di aggiornamento dell’app risponde con un corpo vuoto quando sei già aggiornato, un silenzio impossibile da distinguere da un endpoint guasto. L’installazione è stata controllata prima di essere collegata: l’immagine disco contiene l’app vera, firmata dallo stesso sviluppatore della copia che hai e autenticata da Apple. Una cosa che volutamente non offre sono le note di rilascio: xAI non ne pubblica per questa app, e l’unico changelog che pubblica riguarda un altro prodotto.
Anche Comet e Msty Studio si aggiornano con un clic, e ora un controllo segnala le app che potrebbero farlo ma non lo fanno. Erano le ultime due del gruppo che vedevano gli aggiornamenti senza poterli applicare, ed è venuto fuori che non serviva niente di nuovo: bastava guardare meglio cosa invia davvero il produttore. Il link di download di Comet è firmato e scade dopo un’ora, quindi il pulsante di aggiornamento punta al gateway di Perplexity e il link viene generato nel momento in cui fai clic, non ore prima, quando è stato eseguito il controllo. Msty pubblica quattro download in un unico file, con quello per Intel al primo posto, e l’impronta usata per verificare il download veniva presa proprio da quella prima voce; ora è legata alla build per Apple silicon che viene effettivamente scaricata, e così di solito si accorge anche di una release uscita tra il controllo e il clic, invece di installarla in silenzio. Entrambe sono state scaricate e fatte passare per i veri controlli di installazione prima del rilascio. La lezione più generale non riguardava nessuna delle due: in DuoUpdater non c’era niente in grado di accorgersi di un’app lasciata in sola rilevazione per un motivo che non era più vero, quindi la scansione notturna delle ricette ora segnala quando un’app che si limita a monitorare ci sta già fornendo un programma di installazione.
QQ音乐 ora è monitorata: nuove versioni, aggiornamenti con un clic e note di rilascio nella finestra. Nessuna delle strade abituali dava risposta. Non ha un feed Sparkle né il framework Sparkle; il suo cask Homebrew rimanda l’aggiornamento all’app stessa; e l’endpoint di aggiornamento indicato dal suo stesso eseguibile risponde 200 con un corpo vuoto a qualsiasi richiesta possiamo fargli, un silenzio impossibile da distinguere da un endpoint guasto, perciò è stato lasciato perdere. DuoUpdater legge invece il file di dati da cui è costruita la pagina di download del produttore: quella pagina arriva come un guscio vuoto e si riempie a partire da quel file, che è anche l’unico posto in cui esistono le note di rilascio. Non c’è un blog, né un appcast, né una pagina per ogni versione. Le note vengono quindi lette direttamente da lì e mostrate nella finestra di DuoUpdater, e l’aggiornamento installa l’immagine disco autenticata indicata nella stessa risposta. Una trappola da annotare: quel file contiene ancora, accanto a quello attuale, un secondo record Mac vecchio di sei anni, quindi entrambe le regole si basano sul nome del file con la versione del download per Mac e non sulla parola “Mac”. E un limite da dire chiaramente: il file pubblica la versione che vedi ma mai il numero di build sottostante, quindi una nuova compilazione che mantiene lo stesso nome di versione qui è invisibile. Non può inventarsi un aggiornamento che non c’è: semplicemente non vede quel tipo di aggiornamento.
TimeMachineEditor ora è monitorata: nuove versioni e aggiornamenti con un clic. Nessuna delle strade abituali dava risposta: niente feed Sparkle (l’app non contiene né l’indirizzo di un feed né il framework che lo userebbe), nessuna scheda sull’App Store, nessun repository pubblico delle release, e un cask Homebrew che rimanda l’aggiornamento all’app stessa. Quello che ha è un piccolo sito del produttore il cui unico link di download riporta la versione nel testo stesso: è la stessa pagina, letta nello stesso modo, su cui si basa il controllo di versione di Homebrew, quindi è la fonte prevista dal produttore e non un’ipotesi. L’aggiornamento si installa tramite il pacchetto di installazione del produttore e non come semplice sostituzione dell’app, ed è una scelta voluta: il download installa anche, fuori dall’app, uno scheduler in background, uno strumento da riga di comando e un launch daemon, quindi sostituire solo l’app lascerebbe una copia nuova accanto a uno scheduler vecchio, senza che niente si accorga della discrepanza.
Little Snitch ora è monitorata, sia nelle release stabili sia in quelle nightly. Object Development pubblica un file di versione a cui ricorre il suo stesso programma di aggiornamento, lo stesso che legge Homebrew, e DuoUpdater lo legge direttamente, perché Little Snitch non ha un feed Sparkle e il suo cask rimanda l’aggiornamento all’app. Le due release condividono la stessa identità, cosa che normalmente le rende impossibili da distinguere; qui però la stringa di versione le tradisce: una build nightly scrive la parola per intero (“6.5 nightly (7301)”), mentre quella stabile si presenta come un semplice “6.4.1”. Vale la pena dire cosa volutamente non fa: non installa l’aggiornamento al posto tuo. Little Snitch fa girare un’estensione di sistema e un servizio in background privilegiato insieme all’app, e non è stato verificato su una macchina reale se sostituire solo l’app li lasci intatti; perciò DuoUpdater ti avvisa che la nuova versione è uscita e ti manda al download del produttore, invece di andare a tentativi con un filtro di rete.
Carbon Copy Cloner ora è monitorata, e non proverà a farti passare da una versione principale all’altra. Bombich mantiene vive tre generazioni contemporaneamente, CCC 5, 6 e 7, che si presentano tutte al sistema con la stessa identità, e questo rende la domanda “c’è qualcosa di più recente?” più insidiosa di quanto sembri: 7.1.6 è davvero una versione successiva a 6.1.13, ma passare dall’una all’altra è un acquisto separato, e CCC 7 richiede una versione di macOS più recente di quella che un Mac con CCC 5 potrebbe avere. Rispondere solo in base al numero di versione avrebbe detto a ogni utente di CCC 5 e 6 che lo aspettava un aggiornamento gratuito, per sempre, e sarebbe stato sbagliato ogni volta. Quindi DuoUpdater legge ogni generazione dal suo indirizzo e offre solo la release successiva all’interno della generazione che hai davvero. Vengono rilevate anche le beta, per chi le ha attivate in CCC. Per ora solo rilevazione, perché CCC installa un helper privilegiato accanto all’app, un passo più impegnativo rispetto agli aggiornamenti con un clic già presenti. Vale la pena annotare anche perché finora nessuno vedesse questi aggiornamenti: il feed di aggiornamento dell’app risponde con successo a ogni richiesta, con una pagina completamente vuota.
Un aggiornamento che il tuo Mac non può eseguire non viene più scaricato né installato. Ogni bundle di app indica la versione di macOS più vecchia su cui si avvia, e alcuni produttori indicano anche la più recente (“questa build non è per un sistema così nuovo”), che è il modo in cui un’app non ancora pronta per macOS 27 lo segnala. DuoUpdater non leggeva né l’una né l’altra. Per le app monitorate tramite un feed Sparkle il limite minimo era già rispettato, ma sono una minoranza: tra le app di un Mac tipico, quelle lette dall’endpoint di un produttore o dalle release di GitHub sono la metà più grande, e una release di GitHub non pubblica da nessuna parte un requisito di macOS. Così un’app passata a un macOS più recente del tuo poteva esserti offerta, scaricata per intero, sostituita e poi non aprirsi. Ora DuoUpdater legge il requisito dall’app scaricata, subito accanto al controllo già esistente che sia compilata per il tuo processore, e rifiuta la sostituzione invece di rimpiazzare una copia funzionante con una che non si avvierà. Viene rispettato anche il limite massimo indicato dal produttore, quando un feed lo pubblica, quindi una build che lo sviluppatore ha segnato come non adatta al tuo macOS non viene proprio offerta. Tre limiti da dire chiaramente. Leggere il requisito dal download significa che il download è già avvenuto: questo evita un’installazione rotta, non il traffico, perché per la maggior parte delle app non c’è un punto precedente in cui chiederlo. Un’app la cui versione più recente non può girare sul tuo Mac continuerà a mostrare quell’aggiornamento e a rifiutarsi di installarlo; ora il rifiuto indica quale versione di macOS serve, ma DuoUpdater non si ricorda ancora la risposta per smettere di offrirlo. E il controllo copre le strade in cui è DuoUpdater stesso a sostituire il bundle dell’app: un pacchetto di installazione passa il file a macOS, che applica i requisiti del pacchetto, mentre Homebrew e l’App Store scelgono da sé le proprie build; le app arrivate dalla sezione iPhone e iPad dell’App Store vengono saltate di proposito, perché la versione che indicano è di iOS e confrontarla con macOS sarebbe peggio che non controllare. Una cosa che non dice ancora esplicitamente: quando uno sviluppatore ha segnato una build come non adatta al tuo macOS, quell’aggiornamento semplicemente non viene offerto e l’app risulta aggiornata, senza spiegare perché. Su un Mac più vecchio la cosa si risolve il giorno in cui aggiorni macOS. Su un Mac troppo nuovo no, e lì serve una risposta migliore del silenzio.