There Is No Spoon 🥄 There Is Only the Spec
Cosa rende una specifica una buona specifica? Le 6 best practice per lo spec-driven development con agenti AI, spiegate con Matrix.
Ho usato OpenSpec per mesi e a un certo punto ho realizzato che non sapevo davvero cosa stessi scrivendo o leggendo. Non tecnicamente — il workflow è semplice: /opsx:propose genera proposta, specifiche, design e task; /opsx:apply esegue; /opsx:archive chiude il ciclo. Ma cosa rende una specifica una buona specifica? Cosa ci va dentro, perché, e come si fa a sapere quando è abbastanza?
Un version control per il tuo pensiero
Nel primo Matrix (1999), una delle scene più enigmatiche è quella del cucchiaio. Un bambino dice a Neo: "non cercare di piegare il cucchiaio — è impossibile. Cerca invece di capire la verità: il cucchiaio non esiste." Per capire cosa è reale, bisogna prima liberarsi di quello che si credeva fosse reale. Anche una specifica, prima di essere definita, va prima disimparata.

Una specifica non è documentazione. Non è un documento aggiornato una volta l'anno. Non è il documento PRD che descrive requisiti e obiettivi di un prodotto scritto per impressionare gli stakeholder. Come descrive Den Delimarsky, attualmente parte del team tecnico di Anthropic, "si tratta di rendere le proprie decisioni tecniche esplicite, revisionabili ed evolvibili. Pensa a questo come al version control per il tuo pensiero" ("Diving Into Spec-Driven Development With GitHub Spec Kit").
Marc Brooker, VP/Distinguished Engineer di Amazon, la declina in modo più tecnico — una specifica è un "super-prompt versionato e leggibile dall'uomo" ("Kiro and the future of AI spec-driven software development"). Non è il prompt che si scrive al momento; è il contesto stabile e strutturato che precede e vincola ogni interazione successiva con l'agente.
Ma la definizione che mi è stata più utile è anche la più semplice. Una specifica è il documento che risponde alla domanda "cosa significa giusto?" prima che qualcuno scriva una riga di codice.
The Big Picture
What is real? How do you define real? - Morpheus
"Che cos'è la realtà?" chiede Morpheus a Neo, smontando un'assunzione che tutti noi facciamo — che la realtà sia qualcosa di condiviso per default. Il filosofo David Hume (1711-1776) direbbe che la realtà è solo la somma delle nostre impressioni sensoriali, e se ognuno ha le sue, ognuno vive in una versione diversa del mondo.

Nei team senza una specifica, succede qualcosa di simile — ognuno lavora sulla propria versione del progetto e riempie i gap con le proprie assunzioni. È il problema dell'ubiquitous language assente — come spiego nel mio articolo sul Domain-Driven Design - le stesse parole significano cose diverse per persone diverse, e la traduzione costante tra significati introduce distorsioni silenziose. Come nota Brooker, una specifica è the bigger picture — il contesto condiviso che tiene insieme le decisioni.
Con gli agenti, però, questo problema si amplifica fino a prendere un nome — context rot. Nelle attività a lungo orizzonte, la conversazione si allunga, il contesto si degrada, e gli agenti perdono gradualmente il filo — fino all'intent drift.
Se la specifica deve accompagnare un progetto, deve evolvere con esso — non essere scritta una volta e abbandonata. Una specifica che avvia il progetto ma non lo accompagna non è spec-driven development (SDD).
È spec-once.
Scrivere le specifiche allinea sviluppatori e stakeholder, e dà all'AI un contesto stabile su cui lavorare senza perdersi su codebase complesse. Ma se la specifica deve evolvere, cosa deve contenere?
Best practice per una buona specifica
Una specifica dovrebbe rispondere alla domanda "cosa significa giusto?" da almeno sei angolazioni diverse.
1. Risultati attesi osservabili
Il primo punto è che giusto deve essere osservabile, non semplicemente costruisci un flusso auth, ma qualcosa come:
un utente può registrarsi con email e password, ricevere un'email di verifica e accedere senza errori. La sessione persiste attraverso aggiornamenti di pagina.I nomi delle feature non bastano. Le dichiarazioni di risultato sì, la differenza non è stilistica — è strutturale. Un nome di feature ("implementa notifiche email") lascia aperta la domanda su cosa significhi "fatto". Una dichiarazione di risultato ("un utente loggato può attivare o disattivare le notifiche per ciascuna categoria in modo indipendente; le preferenze persistono tra sessioni") la chiude.
Addy Osmani lo chiama goal-oriented spec: la specifica deve rispondere a tre domande prima di qualsiasi altra cosa — chi è l'utente, di cosa ha bisogno, e come appare il successo.
2. Confini in-scope e out-of-scope
Giusto deve avere un perimetro. Gli agenti espandono lo scope se non viene definito esplicitamente — "OAuth è fuori scope" non è ovvio per un agente che ha imparato che i sistemi di autenticazione di solito lo includono.
Il vincolo più comune nei 2.500 file di configurazione analizzati da GitHub? "Never commit secrets." Non per ingenuità degli sviluppatori — ma perché senza un confine esplicito nella specifica, l'agente non sa che quel limite esiste.
Una specifica efficace non usa una lista piatta di regole, ma un sistema a tre livelli:
- ✅ Sempre: azioni che l'agente esegue autonomamente — "esegui i test prima di ogni commit"
- ⚠️ Prima chiedi: azioni ad alto impatto — modifiche allo schema del database, nuove dipendenze
- 🚫 Mai: stop assoluti — "mai fare commit di segreti o API key"
Questo non è stile, è gerarchia cognitiva: l'agente sa quando procedere, quando fermarsi, e quando chiedere.
3. Vincoli e assunzioni
"Giusto" ha dei limiti dati — tecnologie esistenti, rate limit di API di terze parti, requisiti di performance. Se influenza le scelte di implementazione e non è ovvio dalla codebase, appartiene alla specifica.
Due livelli da separare: i vincoli specifici di un task vanno nella spec del task. Quelli trasversali — stack tecnologico, standard di sicurezza, convenzioni architetturali — appartengono a un documento separato (in Spec Kit è constitution.md, in OpenSpec è AGENTS.md) che ogni spec include per riferimento, senza riscriverlo ogni volta.
4. Decisioni già prese
Déjà vu is usually a glitch in the Matrix. It happens when they change something - Trinity

Per un agente, riaprire una decisione già presa è esattamente quel glitch: il segnale che qualcosa che doveva restare fisso è stato cambiato. L'assenza di decisioni documentate è la fonte principale di architectural drift: ogni sessione, ogni agente, ricomincia a ragionare sulle stesse scelte. Se la libreria di cifratura, lo schema del database o il design system sono già stati selezionati, appartengono alla specifica — non come promemoria, ma come vincolo.
In OpenSpec questo è il compito di design.md — non descrive cosa costruire, ma perché le scelte tecniche sono quelle e non altre. In Spec Kit è la fase /plan: qui entra lo stack, l'architettura, i vincoli di compliance. Senza questo documento, ogni sessione è un reboot.
5. Scomposizione in task
Giusto deve essere verificabile a ogni passo, non solo alla fine. Più è lungo il task, più istruzioni competono per la stessa attenzione del modello — la ricerca chiama questo effetto curse of instructions.
La scomposizione non è solo parallelizzazione. È il prerequisito per garantire che ogni istruzione riceva l'attenzione che merita. Osmani indica il formato ideale: ogni task deve essere implementabile e testabile in isolamento. Non "build authentication", ma "create a user registration endpoint that validates email format". Questo permette review focali invece di thousand-line code dumps.
In OpenSpec è tasks.md, generato automaticamente da /opsx:propose. In Spec Kit è la fase /tasks. In entrambi i casi, la scomposizione non è un output opzionale — è la condizione che rende la specifica eseguibile.
6. Criteri di verifica
You take the blue pill — the story ends. You take the red pill — you stay in Wonderland, and I show you how deep the rabbit hole goes - Morpheus
Non esiste una mezza pillola. Un criterio di verifica funziona allo stesso modo: rossa o blu, pass o fail, senza una terza opzione. Giusto deve essere falsificabile. Non 'funziona?', ma quali test devono passare e quali casi limite devono essere gestiti. I criteri devono essere binari:
- ❌ "dovrebbe funzionare bene" — non è un criterio
- ✅ "dato un'email già registrata, il sistema restituisce 409 Conflict senza creare un utente duplicato" — lo è
Lo sviluppatore Simon Willison, co-creatore di Django, ha una regola personale: "Non faccio commit di codice che non saprei spiegare a qualcun altro." Con il codice generato da agenti vale doppiamente. Se al termine dello sviluppo serve una discussione per capire se il criterio è soddisfatto, non era abbastanza preciso — era opinabile, non verificabile.
Come capiamo che è abbastanza?
Credo che una specifica risponda alla domanda "cosa significhi giusto" quando supera tre controlli:
- Qualcuno che non era presente nella conversazione originale riesce a eseguirla senza fare supposizioni? Se no, "giusto" contiene ancora ambiguità implicite che solo voi conoscete.
- Al termine dello sviluppo, si può decidere senza discussione se l'obiettivo è stato raggiunto? Se no, "giusto" non è ancora osservabile — è un'intenzione, non un contratto.
- Ogni criterio di accettazione ha un esito binario — pass o fail — verificabile senza interpretazione? Se no, non avete definito "giusto": avete definito "ragionevole". E ragionevole è soggettivo.
Se anche una sola risposta è no, non avete ancora risposto alla domanda. Correggere qui è infinitamente più economico che correggere quando c'è già codice, test e prompt in esecuzione.
La prossima volta che aprite una sessione con un agente, la domanda da porsi prima di scrivere il primo prompt è: ho già risposto a cosa significa giusto?
Livelli di astrazione

Cosa significa, oggi, programmare? Da sempre, i linguaggi di programmazione descrivono come fare qualcosa, step by step.
Nei primissimi computer si programmava in assembly, dove ogni operazione elementare andava descritta esplicitamente, tenendo conto dell'hardware specifico. Negli anni '50 e '60 arrivarono i linguaggi ad alto livello come FORTRAN e COBOL, e con loro un salto importante.
Il programmatore smise di parlare la lingua della macchina e iniziò a ragionare sul problema e il compilatore si occupava del resto. Anche se il livello di astrazione era salito, il paradigma di fondo era rimasto lo stesso: descrivere il come, non il cosa.
Oggi l'AI sta portando un nuovo salto. Per la prima volta è possibile descrivere a una macchina cosa si vuole ottenere, e lasciarle decidere il come. Ma perché questo funzioni davvero, serve qualcosa di più di un prompt. Serve una specifica.
Una specifica è una descrizione di quello che un programma deve fare e dei bisogni che deve soddisfare. Non è un concetto nuovo per i programmatori: esiste già sotto forma di ticket, documenti di requisiti, mockup, conversazioni con i colleghi. Quello che cambia è che la specifica diventa il centro del processo di sviluppo. Una guida per l'agente AI, una memoria condivisa tra sviluppatore e macchina, un documento versionato che non si perde tra un prompt e l'altro.
📚Bibliografia
2006
[0] William Irwin, Pillole rosse. Matrix e la filosofia, Bompiani, 2006
🔗Sitografia
2025
[0] Marc Brooker, Kiro and the future of AI spec-driven software development, Kiro Blog , 15/07/2025
[1] Den Delimarsky, Spec-driven development with AI: Get started with a new open source toolkit, GitHub Blog, 02/09/2025
[2] Den Delimarsky, Diving Into Spec-Driven Development With GitHub Spec Kit, Microsoft, 15/09/2025
[3] Matt Nigh, How to write a great agents.md: Lessons from over 2,500 repositories, GitHub Blog, 19/11/2025
2026
[0] Addy Osmani, How to write a good spec for AI agents, addyosmani.com, 13/01/2026
[1] Redazione, Spec Kit: usa el SDD de GitHub para no improvisar con IA, WebReactiva, 28/03/2026