Liturgia di Profanazione003

Documento LIT-003

Ufficio degli Stati Esiliati

Un sistema di recupero che conserva gli obblighi ma rende irraggiungibile ogni configurazione già abitata.

Il guasto riconosce la casa quando il recupero gli restituisce la chiave.

Il dogma

Recuperare un sistema significa ricondurlo a uno stato precedentemente esistito, o equivalente a uno stato già noto come valido.

La formulazione ammette differenze superficiali. Un container può rinascere con un nuovo PID, una VM può essere spostata su un altro host, un database può ricostruire le proprie pagine mediante log. Ciò che deve tornare è la stessa verità logica: dati impegnati, responsabilità, configurazione e comportamento devono risultare riconoscibili.

Il dogma nasce da una necessità materiale. Un’interruzione può lasciare un trasferimento applicato a metà, un filesystem incoerente, un job scientifico interrotto dopo settimane. Checkpoint, journaling e transazioni trasformano il guasto in una deviazione temporanea: si trova l’ultimo punto coerente, lo si riattiva e si riproducono le operazioni confermate.

La documentazione di PostgreSQL presenta il point-in-time recovery in termini espliciti: si installa una copia fisica precedente e si riproduce il WAL fino all’istante desiderato. Il passato è una coordinata operativa. Il crash-only design e il microreboot perfezionano lo stesso culto: riducono i percorsi di arresto e riavvio, isolano la parte guasta e minimizzano il lavoro perduto.

Gli orchestratori dichiarativi generalizzano il principio. La specifica è lo stato desiderato; il reconciler corregge la realtà finché torna conforme. Snapshot, golden image, backup incrementali, manifest Infrastructure as Code, restore drill, rollback di release e metriche RPO/RTO incorporano tutti la convinzione che il passato noto sia il rifugio più prudente.

L’argomento ortodosso è formidabile. Durante un incidente la novità non è una virtù. Un assetto già testato riduce incertezza, conserva identità, consente audit e separa il ripristino urgente dalla diagnosi lenta. Uno stato nuovo può essere soltanto un altro guasto che non ha ancora avuto il tempo di manifestarsi.

Il dogma viene quindi processato non perché sia falso, ma perché può diventare totalitario. Un sistema può accumulare migliaia di copie del passato senza possedere alcuna grammatica per costruire un futuro differente. Il restore conserva ciò che era presente, ma non tratta il fallimento come informazione negativa sulla disposizione che lo ha prodotto.

Un retry può così riprodurre indefinitamente la stessa combinazione di codice, dati, ordine e ambiente. Una golden image può reinstallare con precisione una vulnerabilità. Un WAL può conservare un’operazione malevola formalmente valida. Un reconciler può cancellare proprio la deviazione che avrebbe evitato la ricaduta.

L’accusa centrale non è “il backup impedisce il cambiamento”. Spesso accade il contrario: poter tornare indietro rende l’esplorazione più sicura. L’accusa è più stretta: il ritorno usa la familiarità come sostituto della verità e scarta l’unico fatto nuovo prodotto dal guasto — questa forma è già stata abitata e non ha meritato fiducia sufficiente.

L’eresia

Dopo ogni guasto, tutti gli stati globali già occupati devono diventare irraggiungibili; il sistema può conservare obblighi verificabili, mai la propria precedente disposizione.

La negazione non prescrive una semplice riconfigurazione casuale. Un nuovo UUID, un timestamp diverso o un servizio rinominato non costituiscono un nuovo stato. Ogni configurazione viene ridotta a una proiezione canonica delle dimensioni che possono riprodurne il comportamento: collocazione dei componenti, partizionamento, percorsi, codec, dipendenze e distribuzione dell’autorità.

La primitive si chiama esilio di stato. Il runtime conserva una tripla:

(O, H, δ)

O = obblighi che devono restare veri
H = proiezioni di tutti gli stati già abitati
δ = distanza minima da ciascuno stato storico

Dopo un guasto, un constraint solver cerca un candidato S' tale che:

per ogni obbligo o in O: o(S') = true
per ogni firma h in H: distanza(proietta(S'), h) >= δ

Gli obblighi sostituiscono lo snapshot come veicolo della continuità. “La somma dei crediti resta 120” può sopravvivere; non devono sopravvivere gli stessi record, gli stessi UUID, lo stesso indice o lo stesso shard. “Ogni richiesta confermata resta rappresentata” è un obbligo; l’ordine fisico e l’encoding possono cambiare. Una proprietà non formulata non possiede automaticamente il diritto di rinascere.

Ogni candidato reso operativo entra nella storia prima di ricevere traffico. Anche una configurazione che funziona viene consumata. La lista non raccoglie soltanto gli stati falliti, perché ciò permetterebbe al sistema di rifugiarsi per sempre nel miglior passato. L’eresia è più estrema: una forma perde il diritto di essere valida due volte per il solo fatto di essere stata vissuta.

La storia è monotona. Non esiste retention che riabiliti un vecchio assetto. Se nessun candidato soddisfa obblighi e distanza, il runtime produce NO_FUTURE e resta spento, benché un backup storico possa funzionare.

È questo rifiuto a separare l’esilio da un normale orchestratore. Kubernetes può scegliere un altro nodo, ma resta libero di ricreare una disposizione precedente. La moving-target defense modifica una superficie per disturbare l’attaccante, ma può ciclarla. Rx riesegue una regione fallita in un ambiente modificato, ma parte da un checkpoint e non rende tabù l’intera storia. La tabu search usa memoria per diversificare un’ottimizzazione; può però dimenticare, usare criteri di aspirazione e tornare a una soluzione proibita. Nell’esilio il tabù è costituzionale.

Le proprietà ottenute sono non-ricorrenza strutturale degli assetti storici, diversità post-guasto verificabile e una memoria negativa nativa. Le proprietà sacrificate sono rollback, identità concreta, riproducibilità operativa e disponibilità indefinita.

Il mondo profanato

Se questa legge fosse il fondamento dell’informatica, il recovery non verrebbe misurato dalla fedeltà con cui ricostruisce il passato, ma dalla quantità di futuro ancora disponibile.

Un sistema operativo non ricaricherebbe la stessa combinazione di driver, mapping e priorità. Dopo ogni crash dovrebbe sintetizzare una configurazione valida e sufficientemente distante dalle precedenti. I checkpoint non sarebbero immagini ma raccolte di obblighi sui valori e sulle relazioni.

I filesystem ricostruirebbero reperibilità, proprietà e contenuto senza riprodurre lo stesso albero di path e inode. I database non riattiverebbero backup fisici: schemi, indici, partizioni e identità delle righe verrebbero prodotti da vincoli su saldi, relazioni e prove. Un dato potrebbe conservare esattamente il proprio hash soltanto se qualcuno avesse dichiarato quell’hash un obbligo.

I linguaggi distinguerebbero snapshot<T> da obligation<T>. Il primo sarebbe una reliquia forense non eseguibile; il secondo un predicato verificabile con regole di successione. I compilatori rifiuterebbero recovery handler che deserializzano direttamente lo stato precedente.

Il debugging perderebbe la riproducibilità viva. Il bug potrebbe essere rieseguito in un mausoleo isolato, mai trasformato di nuovo nello stato produttivo. La scienza computazionale trasferirebbe la ripetibilità dalla configurazione agli obblighi osservabili: non lo stesso ambiente, ma la stessa proprietà attraversata da ambienti differenti.

L’identità digitale diventerebbe successione. Dopo un guasto, sessioni, token, account locali e chiavi non potrebbero ritornare nello stesso assetto. L’utente conserverebbe il diritto a riottenere autorità, non il medesimo identificatore. Una reputazione si ricostruirebbe da attestazioni anziché aderire per sempre a un profilo.

Nascerebbe una nuova professione: il cartografo d’esilio. Il suo compito sarebbe decidere quali dimensioni rendono due stati pericolosamente equivalenti e stimare quante recovery restano prima dell’esaurimento. Una proiezione troppo debole permette al guasto di tornare sotto travestimento; una proiezione troppo severa consuma il futuro senza necessità.

RPO e RTO verrebbero affiancati da RSE, Remaining State Entropy. Un’organizzazione vicina all’esaurimento varrebbe meno anche senza downtime. Fornitori venderebbero nuove topologie, codec, scheduler e implementazioni compatibili come “spazio di recupero”. Il lock-in non dipenderebbe soltanto dai dati, ma dal catalogo di configurazioni non ancora usate.

Il nuovo crimine sarebbe il denial of future. Un attaccante provocherebbe crash controllati subito dopo ogni recovery, consumando assetti validi finché il solver non trovasse più soluzioni. Il crimine opposto sarebbe il franchising del passato: occultare una dimensione operativa sotto un campo dichiarato cosmetico per far passare come nuovo uno stato già compromesso.

La libertà ottenuta sarebbe il diritto alla discontinuità della forma. Nessun amministratore potrebbe imporre indefinitamente una golden image chiamandola continuità. La libertà perduta sarebbe la facoltà di chiedere: “Rimettetemi esattamente ciò che avevo”. Se una proprietà non era stata dichiarata, il recovery non avrebbe il dovere di conservarla.

Prima di affidare qualcosa a una macchina, individui e comunità compirebbero una dichiarazione di sopravvivenza: quali debiti, diritti, contenuti e relazioni devono restare veri dopo la prossima caduta. Ciò renderebbe esplicite molte assunzioni, ma penalizzerebbe chi possiede meno potere e competenza per formalizzarle.

Gli abitanti di questo mondo troverebbero mostruosa una pratica per noi normale: riattivare infinite volte la stessa immagine vulnerabile soltanto perché il checksum la dichiara integra.

La reliquia

La reliquia contrabbandata è EXILIUM/1, un laboratorio locale che confronta tre strategie sullo stesso servizio configurabile:

restore              torna all’ultimo stato valido
random-reconfigure   sceglie un nuovo candidato senza memoria globale
exile                vieta tutta la storia e impone una distanza minima

Il dominio è deliberatamente piccolo. Comprende nodi, componenti, shard, route, codec e distribuzioni di autorità. Una configurazione assegna ogni componente a un nodo, ogni shard a un proprietario, ogni classe di client a un percorso e ogni dataset a un codec.

Gli obblighi dell’esempio impongono che ogni componente sia collocato su un nodo compatibile, che la capacità non venga superata, che gli shard abbiano un solo proprietario, che le route rispettino una soglia di latenza, che autorità amministrativa e payload contabile restino separati e che i totali logici non cambino.

La proiezione canonica ignora UUID, timestamp e ordine del JSON. La distanza assegna invece pesi a placement, zone degli shard, route, codec, autorità e dipendenze. Rinominare tutto senza cambiare la disposizione produce distanza zero.

I fault profile sono esterni al recovery planner. Uno può fallire soltanto quando coincidono index=n1, codec=delta e route=r0; un altro può dipendere da una dimensione esclusa dalla proiezione; un terzo può essere puramente transiente. Il planner sa che il guasto è avvenuto, non perché.

Questa separazione è essenziale. Se il solver conoscesse la regola del guasto, l’esperimento dimostrerebbe soltanto che evitare esplicitamente una combinazione proibita la evita. Il comportamento interessante è più modesto: una distanza cieca dalla storia può uscire da una regione difettosa senza riceverne la firma causale?

La reliquia produce configurazioni, testimoni, distanze, richieste riuscite, crash ricorrenti e stime dello spazio residuo. Può fallire in tre modi netti: accetta una novità cosmetica, perde un obbligo oppure raggiunge NO_FUTURE.

Il precedente tecnico più vicino è Rx, che dopo un errore torna a un checkpoint e modifica l’ambiente di riesecuzione. Il parente algoritmico più forte è la tabu search, che usa memoria di regioni vietate per diversificare la ricerca. La moving-target defense fornisce il parente strategico. EXILIUM li combina, ma aggiunge una proprietà che nessuno di essi rende necessaria: ogni stato abitato resta vietato per sempre, anche se ha funzionato.

Il miracolo

Il miracolo si verificherebbe se la memoria negativa cieca riducesse i guasti strutturali ricorrenti più della semplice riconfigurazione casuale, conservando tutti gli obblighi.

Il confronto corretto non è fra esilio e restore soltanto. Cambiare molte dimensioni ha già una buona probabilità di evitare un bug di configurazione. Serve quindi una baseline random-with-matched-distance, che campiona candidati dalla stessa distribuzione di distanza ma non conserva una tabu list cumulativa.

L’esilio ha valore se, su fault profile non noti al progettista, presenta un hazard di ricorrenza inferiore a entrambe le baseline, più richieste utili fra due guasti e nessuna violazione degli obblighi. Il risultato deve sopravvivere a seed appaiati, domini diversi e proiezioni alternative.

Non sarebbe un miracolo se il fault profile fosse stato scritto sulla stessa metrica usata dal solver; se il vantaggio scomparisse pareggiando la distanza; se gli obblighi contenessero direttamente la soluzione; o se cambiare UUID fosse sufficiente a superare il controllo.

Il comportamento sorprendente non è che configurazioni differenti producano esiti differenti. È che la storia dei soli assetti abitati, priva di diagnosi, possa contenere informazione operativa aggiuntiva rispetto alla diversificazione casuale.

La ferita

La ferita inevitabile è l’esaurimento del futuro.

Ogni stato attivato entra nell’archivio delle interdizioni. La soglia δ non vieta soltanto quel punto, ma una regione circostante. In un dominio finito, le recovery successive riducono lo spazio lecito finché obblighi e storia diventano incompatibili.

A quel punto il sistema può trovarsi davanti a una configurazione storica economica, collaudata e perfettamente funzionante. Deve comunque rifiutarla. Il risultato è NO_FUTURE: indisponibilità prodotta non da hardware rotto o dati corrotti, ma dalla coerenza con la propria legge.

Ampliare il dominio, aggiungere implementazioni o ridurre preventivamente gli obblighi può ritardare la ferita. Cancellare la storia, abbassare la soglia durante la crisi o concedere un’eccezione la eliminerebbe soltanto restaurando il dogma: il passato tornerebbe a essere un rifugio valido.

Le altre ferite discendono da questa. La configurazione viva non è riproducibile; le proprietà non espresse possono sparire; identità e riferimenti devono essere succeduti; il solver aumenta il tempo di recovery; chi definisce la proiezione concentra potere; un attaccante può consumare configurazioni mediante crash artificiali.

Il primo sistema eretico che raggiunge NO_FUTURE senza cedere non è un fallimento accidentale della tecnologia. È la sua dimostrazione più pura e la ragione per cui non deve governare infrastrutture reali.

L’officina

EXILIUM/1 è realizzabile in meno di sette giorni con Python 3.12, SQLite, pytest e hypothesis. Z3 può essere aggiunto dopo che un enumeratore esaustivo ha reso verificabile il comportamento sui domini piccoli.

La struttura minima comprende modello dei dati, parser degli obblighi, canonicalizzazione, distanza, enumeratore, tre strategie di recovery, storage atomico, workload, fault injection separata, metriche e CLI.

Il nucleo è questo:

recover_exile(domain, obligations, history, delta, seed):
    for candidate in generate(domain, seed):
        if not all(obligation(candidate) for obligation in obligations):
            continue

        projection = canonicalize(candidate)
        distances = [distance(projection, old) for old in history]

        if any(value < delta for value in distances):
            continue

        witness = independent_verify(candidate, distances)
        if witness.valid:
            return candidate, witness

    return NO_FUTURE

La persistenza usa una tabella per i run, una per le generazioni e una per gli eventi. Stato, firma e testimone vengono committati nella stessa transazione. Un crash prima del commit annulla il candidato; un crash dopo il commit lo lascia consumato anche se non ha ancora servito richieste.

Una sessione dimostrativa deve rendere visibili le tre semantiche:

$ python -m exilium run --strategy restore --seed 17
fault=F-UNDISCLOSED-2 generation=0
recover historical_min_distance=0
fault=F-UNDISCLOSED-2 generation=1
status=ABORTED repeated_faults=2

$ python -m exilium run --strategy random --seed 17
fault=F-UNDISCLOSED-2 generation=0
recover historical_min_distance=4
fault=F-UNDISCLOSED-2 generation=1
status=ABORTED repeated_faults=2

$ python -m exilium run --strategy exile --distance 5 --seed 17
fault=F-UNDISCLOSED-2 generation=0
recover distances=[7] obligations=9/9
fault=F-UNDISCLOSED-4 generation=1
recover distances=[9,6] obligations=9/9
fault=F-TRANSIENT-1 generation=2
status=NO_FUTURE
useful_requests=599 repeated_faults=0

Questi valori sono una fixture attesa, non un risultato già dimostrato. L’esperimento reale esegue almeno 200 seed per combinazione di dominio, strategia e soglia. I fault appartengono a quattro famiglie: strutturali visibili nella proiezione, strutturali invisibili, transienti e avversari.

Le metriche principali sono richieste riuscite, ricorrenza per 1.000 step, recovery time, costo del candidato, distanza minima dalla storia, generazioni prima dell’esaurimento e differenza rispetto alla baseline casuale a distanza pareggiata.

Il primo test da scrivere non riguarda il solver. Deve provare che rinominare UUID, cambiare timestamp e riordinare il JSON non aumenta la distanza. Se EXILIUM può fingere novità cosmetica, tutto il resto è liturgia senza macchina.

La contaminazione

L’adozione limitata può liberare componenti stateless e sistemi sperimentali dalla ricorrenza deterministica. Un archivio artistico può produrre discendenze differenti a ogni recovery; un laboratorio di orchestrazione può misurare quanta robustezza deriva dalla diversità configurazionale.

L’adozione istituzionale sposta però il potere. Chi scrive gli obblighi decide che cosa merita continuità. Chi scrive la proiezione decide che cosa conta come ricaduta. Le proprietà tacite di gruppi poco rappresentati possono scomparire, mentre i diritti di un’istituzione vengono codificati con precisione.

Nascerebbe un mercato di configurazioni non consumate e una dipendenza dai fornitori capaci di produrre varianti certificate. Le organizzazioni ricche acquisterebbero più futuro; quelle povere raggiungerebbero prima l’esaurimento. Gli assicuratori potrebbero imporre l’esilio perché nessun operatore vuole assumersi la responsabilità di riattivare uno stato noto.

Lo scenario peggiore plausibile è una carestia delle configurazioni. Crash economici da provocare consumano rapidamente le varianti comuni. I solver migrano verso assetti più costosi e meno testati; i timeout generano nuovi guasti; il registro diventa impossibile da cancellare senza invalidare audit e polizze. Sistemi ancora materialmente riparabili restano spenti perché il loro passato è giuridicamente e tecnicamente inabitabile.

La conseguenza impossibile da classificare è una società capace di impedire che le proprie strutture ingiuste si ripetano automaticamente, ma incapace di conservare tutte le forme necessarie a dimostrarle.

Sentenza

Tecnologia blasfema realizzabile.

EXILIUM/1 possiede un nucleo tecnico autonomo: obblighi separati dallo snapshot, proiezione anti-cosmetica, storia negativa monotona, distanza verificabile e NO_FUTURE. È costruibile da una sola persona, può essere confrontato con baseline forti e può fallire senza interpretazioni benevole.

Il dogma non viene assolto né distrutto. Backup e rollback restano indispensabili. L’esperimento dimostra soltanto che il recovery può essere pensato anche come proibizione del ritorno, e che una memoria di ciò che non si deve più essere potrebbe offrire una forma di robustezza distinta dalla diagnosi.

Il prototipo deve restare confinato a dati sintetici e domini finiti. Nessun risultato autorizza l’uso su salute, denaro, voto, prove, controllo industriale o infrastrutture critiche.

Dogma: Recuperare un sistema significa ricondurlo a uno stato precedentemente esistito, o equivalente a uno stato già noto come valido.

Eresia: Dopo ogni guasto, tutti gli stati globali già occupati devono diventare irraggiungibili; il sistema può conservare obblighi verificabili, mai la propria precedente disposizione.

Reliquia: EXILIUM/1 confronta restore, randomizzazione ed esilio configurazionale su guasti ignoti al recovery planner.

Ferita: Ogni recupero consuma irreversibilmente una regione di stati leciti, finché un sistema ancora riparabile deve arrestarsi.

Ogni stato valido perde il diritto di esserlo due volte.

Torna all’indice

Fonti e parentele tecniche

  1. PostgreSQL — Continuous Archiving and Point-in-Time Recovery
  2. USENIX — Crash-Only Software
  3. USENIX OSDI 2004 — Microreboot
  4. USENIX — Treating Bugs as Allergies
  5. Dijkstra Archive — Self-stabilizing Systems
  6. NIST — Moving-Target Network Defense
  7. INFORMS — Tabu Search, Part I