Unknowns-Driven Development: progettare partendo da ciò che non sai 🧭

Quante volte un progetto parte con una sicurezza quasi commovente? I requisiti sembrano chiari, il cliente annuisce, la roadmap è elegante, e qualcuno pronuncia la frase che porta sfortuna più di un deploy il venerdì: “in fondo è solo un’integrazione”. Poi si scopre che il sistema esterno ha documentazione parziale, ownership creativa e dati che sembrano usciti da un esperimento sociale.
Il punto è semplice: molti progetti non falliscono perché manca il talento, ma perché si costruisce sopra assunzioni non validate. E quando l’assunzione sbagliata tocca un’integrazione critica, il software smette di essere un prodotto e diventa un atto di fede.
L’idea dietro l’Unknowns-Driven Development è meno esotica di quanto sembri: prima di definire tutto in modo definitivo, bisogna capire cosa non sappiamo, quanto pesa, e come ridurre quell’incertezza senza trasformare il progetto in un laboratorio permanente.
Le incognite non sono un difetto del progetto: sono il materiale grezzo della progettazione seria.
Il problema non è l’incertezza, ma la finzione di certezza 🎭
Ogni progetto ha unknowns. Alcuni sono innocui, altri sono bombe con il timer già avviato. Il guaio nasce quando li trattiamo come dettagli minori, o peggio, quando li nascondiamo sotto una coperta di slide, backlog e ottimismo organizzato.
Un database esterno senza schema affidabile, un’API descritta con screenshot, un protocollo “praticamente standard” ma con eccezioni folkloristiche: questi non sono dettagli implementativi. Sono vincoli architetturali mascherati da note a margine.
Qui l’errore classico è invertire l’ordine delle cose. Prima si promette, poi si scopre. Prima si stima, poi si verifica. Prima si scrive codice, poi si capisce il contratto reale. È l’equivalente tecnico di comprare i mobili prima di sapere se la casa ha i muri dritti.
Per questo l’Unknowns-Driven Development parte da una domanda meno glamour ma molto più utile: quali sono le incognite che possono deformare requisiti, tempi e architettura?
Le incognite vanno trattate come asset 🚧
Dire che un progetto ha delle incognite non basta. Bisogna mappare, classificare e prioritizzare. Non tutte meritano lo stesso livello di attenzione.
Se un’incognita ha alto impatto, alta probabilità e alta dipendenza, non è qualcosa da annotare in fondo a una board. È qualcosa che dovrebbe influenzare direttamente l’ordine del lavoro. In pratica, le unknowns critiche diventano il vero backlog iniziale.
Questo approccio ha molto in comune con il risk-driven thinking e con gli spike tecnici: prima riduci l’ambiguità che può bloccare tutto, poi investi nello sviluppo esteso. Non è lentezza; è evitare di correre nella direzione sbagliata con grande efficienza.
Un buon segnale operativo è questo: se una feature dipende da un sistema che non comprendi davvero, quella feature non è pronta per essere considerata “chiara”. È ancora in fase di scoperta, anche se il backlog la guarda con aria convinta.
Non sviluppare funzionalità critiche sopra sistemi che non comprendi: stai solo spostando il problema verso una fase più costosa.
Il contratto prima dell’accesso diretto 🤝
Quando entra in gioco un sistema esterno, la tentazione più pericolosa è spesso anche la più comoda: accedere direttamente al suo database, leggere “quello che serve” e sperare che il modello dati resti stabile abbastanza a lungo da non umiliarti in produzione.
Peccato che un database esterno non sia un contratto. È una fotografia parziale di decisioni altrui, spesso senza semantica esplicita e quasi mai pensata per essere consumata da un altro dominio. Se la tua integrazione dipende da quello, la tua architettura è appesa al buon cuore di qualcuno che probabilmente non sa nemmeno che esisti.
Molto meglio ragionare in termini di contratto di integrazione: API, eventi, schemi dati, versioning, error handling, SLA minimi. Se il cliente non è in grado di fornirlo, allora conviene proporlo tu e farlo approvare. Sì, è più faticoso all’inizio. Anche mettere il casco richiede un gesto in più, ma nessuno lo considera un inutile rallentamento.
Se però dal cliente o dal sistema esterno non arrivano informazioni chiare, precise e complete, allora conviene mettere sul tavolo un’opzione più sana: invertire l’ordine dell’integrazione. Invece di rincorrere noi il loro caos, proponiamo che siano loro a integrarsi con i nostri sistemi, sui contratti che definiamo e rendiamo espliciti. Detta brutalmente: se il cliente non riesce a spiegare bene come entrare nel suo mondo, non è ragionevole chiedere al progetto di indovinarlo.
E qui c’è anche una verità poco glamour ma utilissima: il cliente deve metterci comunque del proprio. O fornisce documentazione seria, referenti chiari e informazioni verificabili, oppure investe tempo e responsabilità nell’integrarsi lui verso un perimetro più controllato. In entrambi i casi partecipa. L’alternativa, cioè lasciare tutto l’onere interpretativo al team che sviluppa, non è collaborazione: è outsourcing dell’ambiguità.
Questo vale ancora di più nei contesti event-driven, dove il payload non è “solo un JSON”, ma una promessa pubblica. La guida su event design, contratti e schema evolution lo spiega bene: senza un contratto esplicito, ogni consumer finisce per interpretare i dati secondo folklore locale.
Spike, adapter e anti-corruption layer: la parte adulta del progetto 🧱
Uno spike tecnico ben fatto non è una scappatoia elegante per rimandare le decisioni. È il modo più economico per scoprire se stai per fare una scelta costosa e sbagliata. Se un’integrazione è critica, il progetto dovrebbe pretendere presto una risposta chiara: funziona, non funziona, oppure funziona ma a certe condizioni.
Il risultato dello spike non dovrebbe essere un’impressione, ma un esito operativo: accesso reale possibile, mock affidabile, limiti noti, dati sporchi, dipendenze non documentate, fallback necessari. Solo così le stime smettono di essere narrativa motivazionale.
Sul piano architetturale, il principio sano è quasi banale: isolare l’incertezza. Adapter, ACL e boundary chiari servono proprio a questo. Non eliminano il rischio, ma evitano che contamini il cuore del dominio. È lo stesso tipo di disciplina che rende sensato parlare di modularità e contratti in Una questione contrattuale.
Se poi la complessità esterna cresce troppo, la soluzione non è amplificare il caos con altro caos. È ridurre la superficie di dipendenza, scegliere pattern compatibili con il contesto e tenere d’occhio il costo reale delle integrazioni, come ricordano anche gli architecture patterns.
La resilienza non è un accessorio da post-produzione 🛟
Quando un sistema esterno è incerto, la resilienza non si aggiunge alla fine come il prezzemolo. Deve comparire presto nelle decisioni: timeout espliciti, retry con backoff, circuit breaker, osservabilità, compatibilità di versione, modalità degradata, cache locali, perfino la possibilità di disabilitare un’integrazione senza spegnere mezzo prodotto.
In altre parole, il famoso “piano B” non è pessimismo. È rispetto per la realtà. Un progetto adulto non si limita a sperare che il sistema esterno sia disponibile, coerente e gentile. Assume che, prima o poi, smetterà di esserlo.
Questo punto si collega anche a un tema che ritorna spesso quando si parla di AI e sistemi complessi: il contesto conta più dell’illusione di controllo. In Context engineering il principio è applicato agli agenti intelligenti, ma la lezione è la stessa: decisioni solide nascono da informazioni affidabili, aggiornate e ben organizzate. Il resto è teatro computazionale.
Usare agenti AI senza un prompt chiaro, preciso e completo è molto simile a integrare un sistema esterno senza contratto: all’inizio sembra veloce, dopo diventa solo un modo elegante di automatizzare i malintesi.
Un metodo più onesto per parlare di requisiti 📐
Forse il vantaggio più interessante dell’Unknowns-Driven Development non è tecnico, ma culturale. Costringe a dire una cosa che in molti ambienti si evita con cura: alcuni requisiti non possono essere considerati stabili finché le incognite critiche non sono state risolte.
Non significa sabotare il progetto. Significa impedire che il progetto saboti sé stesso. Quando distingui tra requisiti chiari e requisiti dipendenti da unknowns aperti, migliori la conversazione con stakeholder, clienti e team. Le stime diventano più difendibili, le priorità più sensate, le scelte architetturali meno decorative.
E, dettaglio non trascurabile, smetti anche di premiare il comportamento più tossico della professione: fingere sicurezza per non sembrare difficili. La verità è che dichiarare un’incertezza in tempo è un atto di responsabilità. Nasconderla fino a quando esplode, invece, è solo marketing interno.
L’onestà tecnica non rallenta il progetto: evita che il progetto acceleri verso il muro.
Un template minimo per iniziare davvero 🧩
Se tutta questa filosofia ti convince ma il foglio bianco ti guarda con l’aria di chi sa già che improvviserai, allora conviene partire da un template esplicito. Non perché i template risolvano i problemi da soli, ovviamente. Sarebbe bellissimo, ma purtroppo non funziona così. Servono però a costringere il team a fare domande giuste prima di produrre risposte premature.
Qui sotto trovi un esempio in puro markdown, utile come base per discovery, spike e decisioni di integrazione:
|
|
Non è un documento burocratico da compilare per sport. È un modo per rendere visibili le zone opache del progetto prima che decidano loro la tua roadmap.
Conclusione: prima capire, poi promettere 🧭
L’Unknowns-Driven Development non è l’ennesima metodologia da incollare su una slide con frecce colorate. È una disciplina mentale: identificare le incognite, misurarne il rischio, validare presto ciò che conta, progettare contratti chiari e costruire sistemi capaci di degradare con dignità.
In pratica, il messaggio è meno romantico ma molto più utile di certi mantra agile da tazza motivazionale: prima capisci dove finisce la tua conoscenza, poi decidi dove iniziare a costruire.
Se un progetto ha molte integrazioni, molti attori e molta nebbia, la domanda iniziale non dovrebbe essere “quanto ci mettiamo?”, ma “quali unknowns dobbiamo togliere dal tavolo per non raccontarci favole?”. Il resto viene dopo. E, sorprendentemente, viene anche meglio.