Una libreria viene pubblicata, il numero di versione aumenta e la pipeline la considera immediatamente disponibile. È un comportamento comodo, finché non ci chiediamo chi abbia verificato quella versione nei minuti successivi alla pubblicazione. La risposta, molto spesso, è nessuno. Non perché manchino strumenti di sicurezza, ma perché abbiamo progettato il flusso di aggiornamento per premiare la novità e trattare la prudenza come un ritardo.
Con .NET 11 Release Candidate 2, pubblicata il 13 ottobre 2026, NuGet introduce un controllo interessante: la possibilità di stabilire un’età minima per le versioni selezionabili da una sorgente di pacchetti. È una novità piccola rispetto a runtime, linguaggio e librerie, ma apre una domanda più importante della sintassi del comando: quanto tempo deve passare prima che un componente esterno possa entrare automaticamente nel nostro software?
Un pacchetto appena uscito non è necessariamente un pacchetto pronto
La data di pubblicazione dice quando un archivio è stato reso disponibile, non se il suo contenuto sia stato controllato, se l’account del manutentore fosse compromesso o se una modifica apparentemente innocua introduca una regressione. Esiste però un fatto operativo: una versione nuova ha avuto meno tempo per essere installata, osservata, segnalata e, se necessario, ritirata. Un periodo di attesa non trasforma una dipendenza in affidabile; evita semplicemente che la nostra pipeline sia obbligata a correre nella prima fila.
Questo è il senso del minimum package publication age. Non si tratta di un antivirus, di una verifica crittografica né di una reputazione del manutentore. È una regola di selezione temporale. E proprio perché è un controllo limitato, possiamo ragionare seriamente su dove inserirlo senza attribuirgli poteri che non possiede.
Che cosa cambia davvero in NuGet con .NET 11 RC2
Le note ufficiali NuGet della RC2 documentano l’opzione --min-publish-age-hours per i comandi dotnet nuget add source e dotnet nuget update source. Il valore viene registrato nella configurazione nuget.config come minPublishAgeHours. Non è un timer che aggiorna le dipendenze da solo: è un criterio che limita quali versioni possono essere considerate eleggibili quando un comando deve sceglierne una.
dotnet nuget update source public --min-publish-age-hours 48 --configfile nuget.configCon questa configurazione, la sorgente denominata public applica un’attesa minima di 48 ore nella selezione delle versioni supportata dal nuovo comportamento. Le note specificano che dotnet package add e dotnet package update rispettano il cooldown; un aggiornamento segnala quando una versione più recente viene esclusa perché troppo giovane. Per i progetti che usano versioni fluttuanti, se non resta alcuna versione eleggibile, il ripristino delle dipendenze fallisce con NU1020.
Quest’ultimo dettaglio merita più attenzione del parametro. Una policy di selezione è credibile soltanto se il sistema non può aggirarla silenziosamente per completare il lavoro. L’errore esplicito obbliga chi mantiene la pipeline a vedere il conflitto fra disponibilità richiesta e regola impostata. Non è una garanzia universale per qualsiasi forma di riferimento a pacchetti: bisogna verificare concretamente il comportamento del proprio SDK, dei propri feed e del modo in cui si fissano o si lasciano fluttuare le versioni.
Il vero controllo è decidere quando fermarsi
Immaginiamo un progetto con versioni fluttuanti e un job notturno che risolve automaticamente le dipendenze. Una nuova versione viene pubblicata alle 18, il job parte alle 19 e la incorpora. In assenza di una regola, il sistema ha fatto esattamente quello che gli abbiamo chiesto. Il problema è che forse gli abbiamo chiesto la cosa sbagliata: massimizzare la freschezza senza definire un confine di rischio.
Con un’attesa configurata, quel job può continuare a utilizzare una versione eleggibile più vecchia, oppure fallire se la configurazione non lascia alternative. Entrambi gli esiti possono essere corretti, a seconda della politica aziendale. Quello che non dovrebbe essere accettabile è registrare una pipeline verde quando la regola è stata ignorata. Un controllo che non modifica il comportamento nel momento critico è spesso soltanto una dashboard ben vestita.
Una policy non vale per quello che promette quando tutto funziona. Vale per ciò che impedisce quando la scorciatoia diventa conveniente.
Cooldown, lockfile, integrità e audit non sono sinonimi
Qui è facile sommare parole rassicuranti e perdere il controllo reale. Il cooldown chiede: questa versione è abbastanza vecchia da poter essere selezionata? Il lockfile prova a stabilire quale versione è stata risolta. Una verifica di integrità confronta i byte ricevuti con un riferimento affidabile. Un audit cerca vulnerabilità conosciute o condizioni di rischio nel grafo delle dipendenze. Sono quattro domande diverse, che devono avere risposte diverse.
Nel precedente approfondimento su lockfile e integrità dei package manager il punto era proprio la distanza fra una versione fissata e il codice effettivamente consegnato. Il cooldown aggiunge un confine a monte, al momento della scelta. Non sostituisce la verifica a valle. Una release malevola che resta online per settimane supera tranquillamente un’attesa di 48 ore. Un pacchetto legittimo appena pubblicato può invece essere escluso. È un compromesso, non un giudizio morale sui pacchetti.
Anche gli strumenti di automazione degli aggiornamenti usano concetti analoghi: la documentazione di Renovate descrive una finestra minima prima di proporre nuove versioni. Ma aspettare prima di aprire una pull request e impedire al package manager di selezionare una versione durante il restore sono controlli collocati in punti diversi della filiera. Per una politica coerente bisogna sapere quale passaggio governa ciascuno.
Quanto aspettare? Non esiste un numero magico
Ventiquattro o quarantotto ore possono essere una scelta iniziale sensata per un progetto che non deve inseguire ogni release, ma non sono una soglia scientifica di sicurezza. Una libreria che corregge una vulnerabilità critica potrebbe richiedere un aggiornamento immediato; una dipendenza marginale potrebbe tranquillamente attendere più giorni. La risposta non può essere identica per un’applicazione interna, un sistema di pagamento e un prototipo.
Per questo eviterei di trasformare minPublishAgeHours in una regola copiata da un tutorial e dimenticata. Servono almeno un criterio per le eccezioni, la tracciabilità di chi le autorizza, test automatici sul grafo effettivamente risolto e un modo per distinguere l’aggiornamento urgente dal desiderio di avere l’ultima versione. Se una correzione di sicurezza deve bypassare l’attesa, il bypass dovrebbe essere esplicito, circoscritto e verificabile, non una disattivazione permanente della policy.
La RC2 è utilizzabile in produzione. Non significa che sia la scelta giusta per tutti
Microsoft accompagna .NET 11 RC2 con una licenza di supporto go-live, quindi non stiamo parlando di una preview priva di supporto per ogni uso produttivo. Ma la policy ufficiale distingue esplicitamente go-live e release generalmente disponibile. La RC2 porta anche cambiamenti a librerie, runtime, SDK, NuGet e altri componenti; il catalogo dei breaking changes di .NET 11 è ancora un documento in evoluzione.
Il fatto che una versione sia supportata non cancella il lavoro di test, compatibilità e rollback. Per chi gestisce sistemi esistenti, il nuovo cooldown è un buon argomento per studiare la RC2, non un motivo sufficiente per aggiornare oggi tutti i runtime. Un’organizzazione dovrebbe separare la decisione di adottare .NET 11 dalla decisione di applicare una politica sulle dipendenze. Le due cose si incontrano nello strumento, ma non sono lo stesso progetto.
Una pipeline affidabile sa dire di no
La lezione interessante non è che NuGet abbia aggiunto un flag. È che la selezione delle dipendenze sta diventando una decisione governabile, anziché un automatismo che prende sempre il pacchetto più nuovo consentito dai vincoli. Chi progetta software dovrebbe pretendere che questa decisione sia visibile: quali versioni sono state considerate, quali escluse, quale regola ha prevalso e che cosa succede quando non esiste una soluzione accettabile.
Un buon sistema non elimina il rischio con un’attesa di 48 ore. Rende esplicito il rischio che abbiamo deciso di non accettare automaticamente. La differenza è sostanziale: il primo è uno slogan, il secondo è un comportamento verificabile. E nel software che deve funzionare domani, il comportamento conta decisamente più del nome della funzionalità.
Domande frequenti
Che cosa fa minPublishAgeHours in NuGet?
Definisce, per una sorgente NuGet, l’età minima in ore delle versioni considerate eleggibili durante le operazioni supportate. Non analizza il codice e non certifica che un pacchetto sia sicuro.
Come si configura il cooldown in .NET 11 RC2?
Si può impostare la proprietà minPublishAgeHours in nuget.config oppure usare –min-publish-age-hours con dotnet nuget add source o dotnet nuget update source, come indicato nelle note ufficiali della RC2.
Quando compare l'errore NU1020?
Per progetti con versioni fluttuanti, il restore può fallire con NU1020 quando il periodo minimo di pubblicazione non lascia alcuna versione eleggibile. Il fallimento rende esplicito il conflitto con la policy.
Un cooldown di 48 ore sostituisce lockfile, audit e controlli di integrità?
No. L’attesa limita la selezione delle versioni appena pubblicate; lockfile, controlli dei byte e analisi delle vulnerabilità rispondono a domande diverse. Le misure vanno progettate insieme, con eccezioni motivate per aggiornamenti urgenti.
