Urazuke — il corso, parte 2: il progetto ereditato. Normalizzare un sistema che non è nato con il metodo, e poi farlo evolvere

Autore: Pablo Kuschniroff, assistito da Claude Code. Versione 1, 18 ottobre 2026. Questa è la seconda parte del manuale del corso: dà per scontato che tu abbia fatto la prima, o almeno che tu abbia letto le lezioni da 0 a 8, perché qui non torno a spiegare cos'è una voce in sospeso, un test in rosso o un albero semantico. Il metodo di questa parte sta nella pagina del percorso evolutivo-correttivo; qui c'è la pratica, con un secondo progetto guida. Le parole strane, nel glossario del documento principale; i casi reali, nelle referenze. Repository pubblico: github.com/pkuschnirof/urazuke.

Prima di cominciare

Per chi è questa parte

Per chi ha fatto la prima parte e ha scoperto che, nella vita reale, quasi mai gli danno una cartella vuota. Gli danno un sistema che gira già, con utenti che ne dipendono, e gli chiedono "sistema questo" oppure "aggiungici quello". E anche per chi ha "vibecodato" qualcosa qualche mese fa, ha funzionato, e adesso deve continuare a costruirci sopra senza che gli crolli. Sono tutti e due nello stesso posto: con un legacy, anche se uno dei due l'ha scritto lui.

Cosa avrai alla fine

Lo stesso sistema che hai ereditato, che fa le stesse cose che faceva, ma con tutto ciò che il metodo dà per scontato attorno: un patto di convivenza con le regole del legacy, la mappa recuperata del sistema con le marche di dove è uscita ogni affermazione, la lista delle discrepanze fra ciò che il codice fa e ciò che il business crede, un audit trasformato in backlog con le marche di velocità, un ambiente di test con dati anonimizzati, un deployment che si ripete, i segreti fuori dal codice e ruotati, una batteria di caratterizzazione che sorveglia i flussi critici, lucchetti su ciò che già agisce sul mondo, il dimensionamento con numeri misurati, e un backlog dove il debito e la richiesta del cliente convivono, abbinati per modulo. E poi, il primo bug corretto con il suo test in rosso e la prima funzionalità nuova costruita con il metodo completo.

L'ordine di questa parte

TappaLezioniCosa fai oltre alle lezioni
1N0, N1, N2, N3Lettura. Nulla si cambia. Percorri l'albero recuperato con il proprietario, decidi le discrepanze una per una, leggi l'audit. Alla chiusura: la mappa e l'inventario del debito.
2N4, N5La cintura. Ambiente di test con dati anonimizzati, deployment due volte, segreti ruotati, batteria di caratterizzazione con il suo rosso per mutazione. Lucchetti confermati su ciò che già agisce. Alla chiusura: il sistema gira in test e la batteria è in verde.
3N6, N7, R1Misurare, ordinare, correggere. Dimensionamento misurato. Il backlog con le due marche. Il primo blocco: il bug noto, chiuso in modalità correttiva con i suoi abbinati.
4R2Evolvere. Il secondo blocco: la funzionalità nuova, costruita con il metodo completo (lezioni da 5 a 12 della prima parte), con la caratterizzazione come regressione.
5 e 613, 14, 15, 20, 16, 17, 18, 19 della prima parteUscita in produzione. Audit periodico, lucchetti restanti, chiusura della catena verso la produzione, i tre manuali (che il legacy non aveva), e i quattro gradini di qualità operativa precedenti al deployment: osservabilità completa, persistenza con ciò che N6 ha misurato, scansione delle vulnerabilità come cancello, prova di carico con il punto di rottura.
723, 21, 22 della prima parteEsercizio. I due monitoraggi montati con il deployment, con la prima lettura come linea base del legacy; agente residente; retrospettiva con la domanda propria del legacy: quanto è costato normalizzare.

Il progetto guida: "Turnera ereditata"

È lo stesso ambulatorio della prima parte, due anni dopo e su un'altra linea del tempo: Turnera non l'hanno mai fatta con il metodo. Al suo posto, il nipote della responsabile gli ha fatto in un'estate un'applicazione web, "Turnos", che funziona da allora. Oggi ha due receptionist e tre professionisti che la usano tutti i giorni, circa ventimila appuntamenti caricati, e nessuno che la capisca per intero: il nipote è andato a vivere all'estero e risponde a un messaggio ogni due settimane.

Cosa c'è. Un repository su GitHub con il codice (un solo ramo, commit con messaggi tipo "sistemazioni"), un database sullo stesso server dove gira l'applicazione, il deployment a mano copiando i file via FTP, la password del database scritta nel codice, nessun test, un processo pianificato sul server che manda i promemoria tutte le notti, e un foglio di calcolo che la responsabile scarica ogni mese collegandosi al database con uno strumento da scrivania. C'è una copia di backup "automatica" che nessuno ha mai ripristinato.

Cosa fa male. Due cose. La prima, un bug: a volte un paziente riceve il promemoria due volte, e a volte nessuno; la responsabile non sa quando succede, ma ha gli screenshot di pazienti che si lamentano. La seconda, ciò che manca: vogliono chiedere una caparra con un link di pagamento per certi appuntamenti, e vogliono vedere quanti appuntamenti, assenze e cancellazioni ci sono stati nel mese senza scaricare il foglio.

Il proprietario. La stessa responsabile: criterio sull'attività, quindici minuti al giorno, non legge codice. E una novità che conta: lei crede che il sistema faccia cose che non fa, e non sa di cose che il sistema invece fa. È normale in un legacy, ed è ciò che la lezione N2 porterà alla luce.

I flussi critici, con le sue parole: "carico un appuntamento", "cancello un appuntamento", "gli arriva il promemoria", "cerco un paziente", "scarico il foglio del mese". Sono cinque; saranno la batteria di caratterizzazione.

Con questo basta. Tutto il resto è nel sistema, ed è l'agente che lo leggerà.


Tratto di normalizzazione: lezioni da N0 a N7

Queste otto lezioni sono il tratto che la prima parte non aveva. Le prime quattro sono di lettura: non si cambia nulla, e la tentazione di cambiare qualcosa sarà enorme. Le due successive costruiscono la cintura. Le ultime due misurano e ordinano. Solo dopo si tocca la funzionalità.

Lezione N0 — Idoneità di un sistema esistente: prerequisiti che l'agente verifica facendo

Cosa devi capire. Nella lezione 0 ai criteri rispondeva la rilevazione. Qui c'è un sistema, e allora i criteri si possono verificare facendo, dall'agente, senza che nessuno dia un parere: può montare un ambiente completo con sorgenti, dati e persistenza? Può capire il codice? Può scrivere, solo a partire dal codice, un documento che descriva tutta la funzionalità e che la responsabile riconosca come il suo sistema? Può operare le schermate con uno strumento di test ed eseguire un test end to end? Si costruisce con gli strumenti di oggi? Si possono copiare e anonimizzare i dati, e c'è un backup che sia stato ripristinato? Le integrazioni hanno una modalità di prova? Sono sette prerequisiti, e la regola nuova è che un rosso non è un "non va": è un progetto precedente, con un suo perimetro, perché il sistema diventi idoneo.

Prima di inviare il prompt, con le tue mani:

  • docs/INITIAL_SURVEY.md, breve: cosa fa Turnos e per chi secondo la responsabile, cosa fa male (il promemoria doppio, ciò che manca), chi l'ha fatto e quanto ci mette a rispondere, dove gira, chi ha accesso, e che c'è un backup "automatico" che nessuno ha mai ripristinato. Mezza pagina.
  • docs/ELIGIBILITY_CRITERIA.md: la scheda della lezione 0 più i sette prerequisiti del legacy (copiali dalla pagina del percorso evolutivo-correttivo, stazione N0), con tre colonne vuote: verde o rosso, prova, progetto precedente.
  • Accesso in lettura al repository, una copia del database (o la produzione in sola lettura) e un posto dove l'agente possa provare a tirare su il sistema (la tua macchina basta per il corso), con le credenziali fuori dalla chat.
  1. Incollagli il prompt iniziale della stazione N0 (nella pagina del percorso evolutivo-correttivo), tale e quale.
  2. Ci metterà tempo: deve montare l'ambiente, leggere tutto, scrivere docs/FUNCTIONALITY_RECOVERED.md ed eseguire un test. Quando finisce, leggi quel documento con la responsabile: descrive il sistema che lei crede di avere? Ciò che non coincide, annotalo: è la prima lista di discrepanze.
  3. Guarda la scheda: ogni prerequisito deve avere la prova di qualcosa che l'agente ha fatto, non una risposta tua.

Prima di inviare il prompt di chiusura: la tua decisione in una riga e, per ogni rosso, se il progetto precedente si affronta adesso, dopo, o mai.

  1. Incollagli il prompt di chiusura della stazione N0.

Verifica di completezza. Ogni prerequisito ha la prova di qualcosa che è stato fatto, non detto? Esiste il documento di funzionalità recuperata e la responsabile l'ha riconosciuto? Ha eseguito un test end to end reale? Ogni rosso ha il suo progetto precedente come voce in sospeso bloccante?

Consegna. docs/ELIGIBILITY.md, docs/FUNCTIONALITY_RECOVERED.md, e le voci in sospeso bloccanti dei progetti precedenti, se ce ne sono.

Errori tipici. Accettare un verde che l'agente ha risposto senza fare ("sì, il codice è comprensibile"). E trattare un rosso come un rifiuto: il metodo chiede un progetto precedente, non una rinuncia.

Nel progetto guida. L'agente monta Turnos sulla tua macchina con una copia del database (verde), capisce il codice salvo un modulo di report scritto in un vecchio linguaggio di modelli (verde, con nota), scrive il documento di funzionalità e la responsabile ci scopre due cose che non sapeva che il sistema facesse (verde: il documento è meglio della sua memoria), opera quattro schermate su sei ed esegue un test del flusso di caricamento (rosso: due schermate non operabili, progetto precedente: "rendere operabili il calendario e la ricerca"), costruisce con gli strumenti di oggi salvo una dipendenza morta del generatore di PDF (rosso: progetto precedente piccolo), copia e anonimizza i dati (verde) ma il backup non è mai stato ripristinato (rosso: ripristinarlo è il progetto precedente più economico di tutti), e il fornitore di messaggi ha una modalità di prova (verde). Decisione: va, dopo tre piccoli progetti precedenti.

Lezione N1 — Il patto di convivenza per un legacy

Cosa devi capire. Alle sei regole della lezione 1 se ne aggiungono cinque che esistono perché un modello di fronte a codice altrui fa tre cose per riflesso: lo riordina, lo "sistema" dove gli sembra sbagliato, e dà per scontato che ciò che il codice fa in modo diverso da come lui se lo aspetterebbe sia un errore. Le regole del legacy bloccano quei riflessi: non si rifattorizza ciò che non è stato chiesto, si legge prima di toccare, ciò che è strano si annota invece di sistemarlo, il comportamento attuale è la specifica finché il proprietario non dice altro, e nulla entra senza la caratterizzazione in verde.

Prima di inviare il prompt, con le tue mani:

  • Le tue preferenze di lavoro, come nella lezione 1, e una decisione in più: quanto rischio accetti mentre si normalizza. Per il corso: l'agente può distribuire all'ambiente di test da solo; in produzione, mai, fino alla lezione 15.
  • docs/ELIGIBILITY.md chiuso.
  1. Incollagli:

Before we touch anything, we are going to set the working agreement between you and me for a system that already exists and has users. Write docs/WORKING_AGREEMENT.md with the six rules of the method (my time is sacred; zero technical debt; exact scope; documentation in the same commit; never report as done what you have not verified; speak my language), each with one line explaining what it prevents, and these five rules for an inherited system: (7) Nothing is refactored that was not asked for, and no module is rewritten. (8) Code you do not understand is read before it is touched, and what you learn goes into the system map. (9) Anything strange you find (a secret in the code, a dead path, a duplicated rule, a query without an index) is logged as a pending item with its evidence, never fixed in passing. (10) Current behaviour is the specification until the owner says otherwise: a difference between what the code does and what the business says is a discrepancy for me to decide, not a bug for you to fix silently. (11) No change reaches the test environment without the characterization suite green. Add any rules you think this system needs, marked as proposals. If you need to know something about how I work in order to write this, ask me.

  1. Leggi le proposte. Se una dice "modernizzare il codice man mano che si tocca", rifiutala con una motivazione: è la riscrittura travestita.

Prima di inviare il prompt di chiusura: il tuo verdetto su ogni proposta, con una motivazione di una riga, per gli spazi vuoti del prompt.

  1. Chiudi con il prompt di chiusura della lezione 1, senza modifiche.

Verifica di completezza. Ci sono tutte e undici le regole, ciascuna con il guasto che evita? C'è qualche proposta che autorizzi a rifattorizzare o riscrivere?

Consegna. docs/WORKING_AGREEMENT.md con data e versione.

Errori tipici. Accettare una regola di "pulizia progressiva" perché suona ragionevole. Suona ragionevole ed è il modo in cui l'agente si autorizza a cambiare ciò che non gli è stato chiesto.

Nel progetto guida. L'agente propone due regole sue che vale la pena accettare: "in questo sistema nessun invio reale esce dall'ambiente di test: i promemoria in test vanno a una casella fittizia", e "il foglio mensile che la responsabile scarica è un consumatore del sistema e conta come contratto". La seconda è la mappa produttore-consumatore che si affaccia in anticipo, e va bene così.

Lezione N2 — La lettura del sistema: la mappa recuperata e le discrepanze

Cosa devi capire. È la lezione che dà più valore per ora di lavoro di tutto il corso. Nella lezione 2 il file di progetto e l'albero uscivano dalla rilevazione; qui escono dal sistema stesso, e ogni affermazione porta una marca di dove è uscita: [codice], [base], [configurazione], [documentazione], [business] o [dedotto]. Le marche sono ciò che ti permette di verificare senza leggere codice: guardi ciò che è dedotto e lo confermi o lo correggi. E compare un documento nuovo, la lista delle discrepanze: tutto ciò che non coincide fra ciò che il codice fa, ciò che il database impone e ciò che il business crede. Non si risolvono da sole: ciascuna è una tua decisione con la data. Un legacy ha sempre discrepanze; se la lista esce vuota, l'agente non ha confrontato.

Prima di inviare il prompt, con le tue mani e con il proprietario:

  • Accesso in lettura per l'agente a tutto: il repository intero, lo schema del database (sola lettura, credenziale fuori dalla chat), la configurazione del server con i valori dei segreti coperti, i log recenti, e quel che c'è di documentazione (in Turnos, un'email del nipote con "come caricare le modifiche").
  • In docs/INITIAL_SURVEY.md, una sezione nuova scritta con la responsabile: ciò che lei crede che il sistema faccia, caso d'uso per caso d'uso, e le regole che ricorda ("un appuntamento non si può cancellare con meno di due ore", "il promemoria parte alle otto di sera"). Non verificarlo contro il sistema: quel confronto è il lavoro dell'agente.
  • La lista di ciò che vive fuori dal repository: il processo pianificato dei promemoria e il foglio mensile che si collega al database.
  • docs/WORKING_AGREEMENT.md chiuso.
  1. Incollagli:

We are going to recover the map of this system from what exists. Read the whole repository (every branch), the database schema (read-only), the configuration of each environment, the recent logs and whatever documentation there is; if some part cannot be read from where you are, tell me and mark it as a gap; do not fill it by guessing. Then write three things. First, complete docs/INITIAL_SURVEY.md in the form the method expects (what the system does and for whom; what it does NOT do; who uses it; the technology; the environments; what an error costs), with every statement tagged by its source: [code], [database], [configuration], [documentation], [business] for what the survey already says, or [inferred]. Second, PROJECT.md, three hundred lines at most, and docs/SEMANTIC_TREE.md: the domains and, under each one, the actors, the processes (each with trigger, steps, outcome and exceptions as the code actually implements them), the entities with the attributes, states and transitions the database and the code enforce, the screens, the external integrations and the scheduled jobs; every node tagged the same way. Third, docs/DISCREPANCIES.md: everything where the code, the database, the documentation and what the business says in the survey do not agree, with the evidence on each side. Do not resolve any discrepancy and do not fix anything: list them. Create docs/STATUS.md for the living state. Reply in my language.

Gli stai chiedendo di leggere tutto e dichiarare ciò che non ha potuto leggere, la rilevazione e l'albero con le marche, i processi come il codice li implementa (non come dovrebbero essere), i processi pianificati, e le discrepanze elencate senza risolverle.

  1. Percorri l'albero con la responsabile, nodo per nodo. Ogni [dedotto] si conferma o si corregge. Ogni [codice] si confronta con ciò che lei crede: dove non coincide, c'è una discrepanza che forse l'agente ha già elencato, e se non l'ha elencata, la aggiungi tu.
  2. Decidi ogni discrepanza con lei, in una riga, con la data. Ci sono tre risposte possibili: "il sistema è a posto, il business se n'era dimenticato" (si conferma come regola), "il sistema è sbagliato, bisogna cambiarlo" (si apre una voce in sospeso), oppure "non lo so, lo vediamo dopo" (resta aperta con una data; non troppe).

Prima di inviare il prompt di chiusura: la lista dei nodi confermati e corretti, e la lista delle discrepanze con la tua decisione e la data, una riga ciascuna.

  1. Chiudi con:

I confirm these nodes: [list]. Correct these: [list]. The discrepancies are decided as follows: [one line each: discrepancy, my decision, today's date]. Finalize docs/INITIAL_SURVEY.md, PROJECT.md and docs/SEMANTIC_TREE.md with today's date, keeping the source tags. Write each discrepancy decision in docs/DECISIONS.md with my exact words, and open a pending item in docs/PENDING.md for every discrepancy where I decided the system must change; for the ones where I decided the current behaviour stays, write it next to the node as a confirmed rule. Add to PROJECT.md the instruction to read this file, the tree and the working agreement at the start of every session.

  1. La prova di lettura, come nella lezione 2: sessione nuova, senza contesto, "cosa NON fa questo sistema? quale processo gira da solo di notte?". Deve rispondere con la mappa.

Verifica di completezza. Ci sono nodi marcati [dedotto]? (Se non ce n'è nessuno, l'agente non distingue ciò che ha letto da ciò che ha supposto.) C'è almeno un processo pianificato nell'albero? La lista delle discrepanze ha più di zero voci? Ciascuna ha una decisione con la data o è rimasta aperta di proposito? Le marche sono sopravvissute alla chiusura? Ha superato la prova di lettura?

Consegna. docs/INITIAL_SURVEY.md completo con le marche, PROJECT.md, docs/SEMANTIC_TREE.md, docs/DISCREPANCIES.md deciso, docs/DECISIONS.md con le decisioni, docs/STATUS.md.

Errori tipici. Risolvere le discrepanze "sistemando il codice perché faccia ciò che la responsabile dice", senza deciderle una per una: parecchie di quelle discrepanze sono regole che il business ha dimenticato e il codice ricordava. E lasciare che l'agente cancelli le marche alla chiusura "perché resti più pulito": un albero senza marche non si può più verificare.

Nel progetto guida. L'albero di Turnos ha il dominio Agenda che la responsabile si aspettava, e due cose che non si aspettava: uno stato dell'appuntamento "riprogrammato" che esiste nel database e che nessuna schermata mostra [base], e un processo pianificato che, oltre a mandare i promemoria, cancella gli appuntamenti annullati da più di un anno [codice]; la responsabile non sapeva che venissero cancellati. Le discrepanze tipiche sono otto: la regola delle due ore per cancellare non esiste nel codice (si cancella sempre); il promemoria parte alle otto secondo lei e alle sette secondo la configurazione; il telefono del paziente non è obbligatorio nel database anche se lei crede di sì; e così via. Quella della cancellazione è quella che la sorprende di più, e la decide in un minuto: "quello non si cancella più". Voce in sospeso.

Lezione N3 — L'audit come inventario del debito

Cosa devi capire. La lezione 13, ma all'inizio invece che alla fine, e con un campo in più per ogni rilievo: se blocca (va risolto prima di qualunque modifica), se si paga quando si tocca il modulo, o se può aspettare. Senza quel campo, un legacy sottoposto ad audit ha quaranta rilievi e nessuno sa da quale cominciare. Cosa blocca lo decidi tu, non l'auditor: in generale, un segreto esposto, una schermata che non si può operare, un deployment che non si può ripetere, la mancanza di backup, e ciò che può danneggiare dati o far pagare più del dovuto.

Prima di inviare il prompt, con le tue mani:

  • Una sessione nuova dell'agente, con un clone pulito e un file di istruzioni che dica "sei un auditor; non hai letto e non toccherai questo sistema". Accesso in sola lettura al database e al server.
  • PROJECT.md, docs/SEMANTIC_TREE.md e docs/DISCREPANCIES.md di N2, perché non riscopra ciò che è già scritto.
  • Il tuo criterio di cosa blocca, in due righe, per lo spazio vuoto del prompt. Per Turnos: segreto esposto, schermata non operabile, deployment non ripetibile, nessun backup provato, qualunque cosa cancelli o mandi senza controllo.
  1. Incollagli:

Audit this system for integrity, security, performance, code quality and deployability, as the inventory of what must be normalized before and during its evolution. Read-only: change nothing except writing your report to docs/AUDIT_[date].md. If auditing some part requires access you lack (the database, the logs, the server), tell me and mark that part as not audited; do not pass it as fine. Go through all of the code, not a sample, and read docs/SEMANTIC_TREE.md and docs/DISCREPANCIES.md first so that you do not report what is already known. For every finding: where it is (file and line), the risk, the evidence that proves it (the command, the query, the number), its priority (P0 must be fixed now, P1 soon, P2 when possible), and one more field: whether it BLOCKS (must be fixed before any change, by my criteria: [an exposed secret, a screen that cannot be driven by a program, a deployment that cannot be repeated, no tested backup, anything that deletes or sends without control]), whether it is PAID WHEN TOUCHED (fixed together with the first change that enters its module), or whether it CAN WAIT. Grade every dimension you audited. End with every finding turned into a proposed pending item, blocking ones first. Reply in my language.

  1. Leggi il rapporto. Scegli due rilievi e chiedigli la prova. Rivedi le marche di velocità: tu puoi alzare o abbassare qualunque marca, con una motivazione.

Prima di inviare il prompt di chiusura: il rapporto letto, i due rilievi verificati, e la sessione del costruttore aperta (la chiusura va al costruttore, non all'auditor).

  1. Torna alla sessione del costruttore e incollagli il prompt di chiusura della lezione 13, aggiungendogli alla fine: "Each pending item keeps the speed mark of its finding."

Verifica di completezza. Dice di cosa non ha potuto fare l'audit? C'è almeno un "blocca"? Ogni rilievo ha file, riga e prova? I bloccanti sono già voci in sospeso?

Consegna. docs/AUDIT_[data].md con le marche di velocità, e le voci in sospeso bloccanti aperte.

Errori tipici. Tutto in "può aspettare", per un auditor che non vuole disturbare. Oppure tutto in "blocca", per un proprietario spaventato: allora non si può mai cominciare nulla. Fra tre e otto bloccanti è la norma in un sistema piccolo.

Nel progetto guida. L'audit di Turnos trova, come bloccanti: la password del database nel codice (e nella storia di git, quindi bisogna ruotarla, non solo spostarla); il deployment via FTP senza registro di quale versione giri; il processo pianificato che cancella appuntamenti senza lucchetto; le due schermate non operabili. Come "si paga quando si tocca": la ricerca dei pazienti senza indice (modulo pazienti), la query dell'agenda del giorno che fa una query per appuntamento (modulo agenda), l'invio dei promemoria senza idempotenza (modulo messaggi; è la pista del bug). Come "può aspettare": una dipendenza vecchia senza vulnerabilità note, e il codice duplicato del formato della data in tre posti.

Lezione N4 — La cintura di sicurezza

Cosa devi capire. È il cancello duro di questo percorso: finché la cintura non è in verde, non si cambia una riga di funzionalità. La cintura ha cinque pezzi: un ambiente di test con dati anonimizzati, un deployment che si ripete, i segreti fuori dal codice e ruotati, l'integrazione continua che esegue quel che c'è, e la batteria di caratterizzazione. Quest'ultima è la lezione 8 al contrario: il test nasce in verde, perché cattura ciò che il sistema fa oggi, difetti inclusi, e la prova che serve è che va in rosso quando rompi il flusso di proposito. Senza quel rosso per mutazione, è un test che passa perché non guarda nulla.

Prima di inviare il prompt, con le tue mani e con il proprietario:

  • docs/ENVIRONMENTS_SURVEY.md, che l'agente ha redatto in N2 con le marche e che tu completi: dove girerà l'ambiente di test (per il corso basta un servizio gratuito o un contenitore sulla tua macchina), come si distribuisce oggi, dove vivranno i segreti sul server.
  • La decisione sull'anonimizzazione con la responsabile: nomi, telefoni, email e documenti dei pazienti si sostituiscono con valori falsi; le date e le quantità si conservano. È un obbligo di legge, non un dettaglio tecnico.
  • La lista dei flussi critici per la caratterizzazione: i cinque della responsabile.
  • Il backup ripristinato sulla tua macchina (la condizione di N0). Se non l'hai fatto, fallo adesso: l'agente copierà il database di produzione e devi sapere che c'è una strada per tornare indietro.
  • Accesso dell'agente al server in sola lettura e al posto dell'ambiente di test con la scrittura, credenziali fuori dalla chat.
  1. Incollagli:

We are going to build the safety belt around this system before changing anything in it. Read the environments survey, docs/AUDIT_[date].md and docs/SEMANTIC_TREE.md. Evaluate whether you have what is needed (read access to the server where it runs and to its database, write access to where the test environment will run, the way it is deployed today); if anything is missing, ask me before starting. Then set up, without touching any functionality: (1) a test environment that runs the system exactly as production does, with a copy of the data where the personal fields I listed are anonymized; (2) a reproducible deployment to that environment, run twice, showing me that the second run changed nothing; (3) every secret found in the repository or in the code moved to the server configuration (environment file or vault), with the list of what you moved so that I rotate each one; (4) continuous integration running whatever test suite exists today, even if it is a single smoke test, on every push; (5) docs/GATES.md with the gates of this project, including: nothing reaches the test environment without the characterization suite green, and nothing reaches production without the full suite green with the exact version. Document all of it in docs/DEPLOYMENT.md so that a person can do it by hand without you. Take a screenshot of the system running in the test environment and show it to me. Reply in my language.

  1. È un compito lungo, con andate e ritorni. Quando ti mostra lo screenshot, apri tu l'URL: si deve vedere Turnos con i dati. Cerca un paziente reale per nome: non deve esserci.
  2. Ruota ogni segreto della lista che ti ha dato. Tu, nel pannello che serve, oggi.

Prima di inviare il prompt della batteria: l'ambiente di test aperto da te, i segreti ruotati, e la lista dei cinque flussi critici per lo spazio vuoto del prompt.

  1. Incollagli:

We are going to write the characterization tests of these critical flows: [load an appointment; cancel an appointment; the reminder reaches the patient; search a patient; download the monthly sheet]. A characterization test captures what the system does today, exactly as it does it, defects included; it is not a test of what the system should do. For each flow: drive it from the screen as a user would and check the effect in the backend (the row, the state, the message queued). Every test must pass against the current code. Then prove that each test actually watches its flow: break the flow deliberately with a temporary change, show me the red output, revert the change, show me the green. If a flow cannot be driven from the screen, do not simulate it: say so and open a pending item marked as blocking. If while writing these tests you find behaviour that looks wrong, do not fix it: add it to docs/DISCREPANCIES.md with the evidence. Record the command to run the suite in docs/STATUS.md, and make the suite the gate for the test environment as docs/GATES.md says. Reply in my language.

Gli stai chiedendo il test che nasce in verde e dimostra di servire andando in rosso per mutazione; niente simulazioni di ciò che non si può operare; e ciò che sembra sbagliato, annotato come discrepanza, non sistemato.

  1. Le due schermate non operabili (la voce in sospeso bloccante di N0) si risolvono qui, prima della batteria o come parte di essa: chiedigli di chiudere quella voce con la routine della lezione 8, e di scrivere poi i test di caratterizzazione di quei flussi.
  2. Esegui tu la batteria con il comando di docs/STATUS.md. Deve essere in verde.

Verifica di completezza. Hai aperto l'ambiente di test e non hai trovato un nome reale? Il deployment è stato eseguito due volte e la seconda non ha cambiato nulla? La ricerca di segreti nel repository è tornata vuota, e hai ruotato quelli che ha trovato? Ognuno dei cinque flussi ha il suo test e il suo rosso per mutazione a vista? Hai eseguito tu la batteria?

Consegna. L'ambiente di test che gira con dati anonimizzati, docs/DEPLOYMENT.md, docs/GATES.md, i segreti ruotati, l'integrazione continua in verde, e la batteria di caratterizzazione in verde con i suoi cinque rossi dimostrati.

Errori tipici. Lasciare la batteria "a dopo" e cominciare a sistemare il bug: la cintura a metà è la causa numero uno di rompere ciò che funzionava. Dati di test "di esempio" invece della copia anonimizzata: i bug di un legacy vivono nei dati reali (il promemoria doppio di Turnos compare solo con certi pazienti). E spostare il segreto senza ruotarlo: era nella storia di git; non è più un segreto.

Nel progetto guida. Il test di caratterizzazione del promemoria è il più interessante: cattura che il processo notturno manda un messaggio per ogni appuntamento del giorno dopo alla casella fittizia, e passa. Mentre lo scrive, l'agente nota che se il processo viene eseguito due volte manda due volte, e lo annota come discrepanza con la prova. È la pista del bug, e ancora non si sistema: il comportamento attuale è la specifica fino alla lezione R1. Il rosso per mutazione: l'agente commenta la riga che mette il messaggio in coda, il test fallisce, la decommenta, passa.

Lezione N5 — Lucchetti e mappa produttore-consumatore dal codice

Cosa devi capire. Le lezioni 14 e 11, fatte per inventario su ciò che esiste già, prima di cambiare qualunque cosa. L'agente troverà nel codice più di quanto il business ricordi che il sistema faccia verso l'esterno: invii, cancellazioni, processi notturni. Il confronto fra le due liste è il risultato. E ogni lucchetto porta una proposta di "adesso" o "quando si tocca": un lucchetto su qualcosa che manda messaggi va adesso; uno su un'esportazione mensile può aspettare il blocco che toccherà quel modulo.

Prima di inviare il prompt, con le tue mani e con il proprietario:

  • In docs/INITIAL_SURVEY.md, la lista di ciò che la responsabile sa che il sistema fa verso l'esterno: manda promemoria, e nient'altro, secondo lei.
  • Accesso dell'agente alle attività pianificate del server.
  • La lista di ciò che vive fuori dal repository (il foglio mensile), per la mappa.
  • L'ambiente di test di N4 che gira.
  1. Incollagli:

Go through the code, the database triggers and the scheduled jobs of the server looking for everything that charges, sends, approves, deletes, notifies outwards or runs on a schedule, and write docs/CONSEQUENTIAL_ACTIONS_SURVEY.md with every statement tagged by its source. Compare it with the list the business wrote in docs/INITIAL_SURVEY.md: whatever the code does that the business did not list, or the other way round, ask me about before going on. For every action: what triggers it, whether it can run twice, whether it is reversible, what lock exists today if any, and what the way back is. In the same pass, build docs/PRODUCER_CONSUMER_MAP.md: for every contract in the system (a service, a table, a file format, a list of values), who produces it and who consumes it, including the things outside the repository I told you about. If there are parts you cannot see, say so instead of leaving them out. Present me the actions table with a proposed lock for each (explicit confirmation, double safety, dry-run mode, daily limit, a human in the loop) and a proposal of which locks go NOW, before any change, and which can go when the module is touched. Do not implement anything yet: I confirm lock by lock. Reply in my language.

  1. Conferma lucchetto per lucchetto con la responsabile, e la marca "adesso" o "quando si tocca" di ciascuno.

Prima di inviare il prompt di chiusura: la tabella con il tuo verdetto riga per riga, e la lista dei lucchetti "adesso" per lo spazio vuoto del prompt.

  1. Chiudi con il prompt di chiusura della lezione 14, elencando solo i lucchetti "adesso"; gli altri restano nel backlog con la loro marca.

Verifica di completezza. La lista dell'agente ha più azioni di quella della responsabile? (Se ha le stesse, non ha guardato le attività pianificate.) Ogni lucchetto "adesso" ha il suo test in rosso contro la versione senza lucchetto? Il foglio mensile è nella mappa come consumatore?

Consegna. docs/CONSEQUENTIAL_ACTIONS_SURVEY.md, docs/PRODUCER_CONSUMER_MAP.md, docs/LOCKS.md con i lucchetti "adesso" implementati e provati.

Errori tipici. Implementare tutti i lucchetti adesso "già che ci siamo": è la regola delle due velocità violata, ed è tempo che non si dedica al bug che il cliente ha chiesto.

Nel progetto guida. L'agente trova tre azioni che la responsabile non aveva elencato: la cancellazione notturna degli appuntamenti annullati vecchi, un'email che il sistema manda al professionista quando un appuntamento viene cancellato (lei non lo sapeva), e l'esportazione che alimenta il foglio. Lucchetti "adesso": la cancellazione notturna passa in modalità di prova (registra ciò che avrebbe cancellato) finché lei non decide, e l'invio dei promemoria riceve un limite giornaliero. "Quando si tocca": idempotenza dell'invio (modulo messaggi, entra con il bug), conferma nella cancellazione (modulo agenda). La mappa ha sei contratti, e il foglio mensile è consumatore della tabella degli appuntamenti: se qualcuno le cambia una colonna, il foglio si rompe in silenzio.

Lezione N6 — Dimensionare con numeri reali

Cosa devi capire. La lezione 3 con un vantaggio: i dati primari sono nel database e nei log. Non si chiedono, si misurano, con un misuratore con test (lezione 7). La responsabile apporta solo ciò che non è da nessuna parte: quanto si aspettano di crescere, e se il sistema verrà venduto ad altri ambulatori.

Prima di inviare il prompt, con le tue mani:

  • Accesso in sola lettura al database di produzione, o la copia completa di N4 (l'anonimizzazione non ha toccato date né quantità), e ai log di accesso.
  • Le due risposte del business: crescita attesa ("come adesso, forse un professionista in più") e il "per dieci" ("se funziona, mia sorella ha un altro ambulatorio").
  • Un caso noto per il test del misuratore: il numero di professionisti, che sono tre.
  1. Incollagli:

Before changing anything we are going to size this system with its real numbers. With read-only access to the production database (or the complete test copy) and to the logs, measure instead of asking: rows per table and growth per month from the timestamps, events per entity, peak concurrency from the access logs, data size today and projected at five years, and the slowest queries. Write a meter for each number (a script that lives in the repository, with a test against a known case I will give you) and show me every number together with the command that produces it; audit each meter in both directions (is everything that should be counted, counted? does everything counted exist?). Write docs/VOLUME_SURVEY.md with every figure tagged [database] or [log], and ask me only for what cannot be measured: the growth the business expects and whether the system will serve more than one site. Then write docs/SIZING.md: what breaks first if everything is multiplied by ten, which of the current architecture choices hold and which do not, and which asymmetric decisions we take now, before evolving, because they are cheap today and expensive later. Do not change any code. Reply in my language.

  1. Esegui tu un misuratore (quello delle righe per tabella, per esempio). Ti deve dare lo stesso risultato. Rifai un conto a mano.

Prima di inviare il prompt di chiusura: il conto rifatto che coincide, e la tua decisione su ciò che non regge il "per dieci", se c'è qualcosa.

  1. Chiudi con il prompt di chiusura della lezione 3, scegliendo fra le opzioni che avrà proposto oppure confermando che l'attuale regge.

Verifica di completezza. C'è qualche numero primario senza misuratore? Ne hai eseguito uno tu? È scritto il "per dieci"?

Consegna. docs/VOLUME_SURVEY.md con le marche, i misuratori con il loro test, docs/SIZING.md.

Errori tipici. Accettare "il database è troppo grande per contarlo, stimo centomila". Un database grande si conta con una query; quello è un misuratore.

Nel progetto guida. Ventimila appuntamenti in due anni, mille al mese e in crescita lenta; sessantamila messaggi; due utenti nel picco; il database occupa poco; la query più lenta è la ricerca dei pazienti per nome (senza indice, lo diceva già l'audit). Il "per dieci" regge su tutto tranne che su quella ricerca e sull'invio notturno, che impiega un tempo proporzionale agli appuntamenti. Decisione asimmetrica: l'interfaccia di invio dei messaggi passa ad avere una coda, anche se oggi non serve, perché la caparra (lezione R2) userà lo stesso canale.

Lezione N7 — Il backlog di normalizzazione, abbinato alla richiesta del cliente

Cosa devi capire. La lezione 5 con due colonne in più. Una sola coda dove convivono il debito (audit, discrepanze, schermate, lucchetti in sospeso, decisioni del dimensionamento) e la richiesta del cliente (ciò che non funziona, ciò che manca), ogni voce con la sua marca di velocità e il suo tipo, e ogni voce del cliente con la lista di quelle di normalizzazione che toccano lo stesso modulo e che conviene pagare insieme a lei. Questa è la regola "si paga quando si tocca" resa operativa.

Prima di inviare il prompt, con le tue mani e con il proprietario:

  • La richiesta del cliente per questa tappa, in docs/blocks/STAGE_01_REQUEST.md, in due liste con le parole della responsabile. Ciò che non funziona: "a volte il promemoria arriva due volte, e a volte non arriva; ho gli screenshot di tre pazienti della settimana scorsa". Ciò che manca: "voglio chiedere una caparra con un link di pagamento per gli appuntamenti di prima visita", "voglio vedere i numeri del mese senza scaricare il foglio".
  • Tutti gli artefatti da N2 a N6 chiusi. Se ne manca uno, non aprire questo prompt.
  • Le voci in sospeso bloccanti di N0, N3 e N4 chiuse.
  1. Incollagli:

We are going to turn the normalization and the client's request for this stage into one queue of numbered pending items in docs/PENDING.md, each with its full specification as the method asks (number, title, node of the semantic tree, origin, description, business rules with decision and date or marked as missing, data in and out, screens, edge cases, acceptance criteria as given, when, then, how it will be verified, status). Sources for the normalization items: docs/AUDIT_[date].md, the discrepancies I decided to change, the screens that cannot be driven by a program, the secrets to rotate, the locks that are not implemented yet, and the decisions in docs/SIZING.md; each one keeps its speed mark: BLOCKS, PAID WHEN TOUCHED, or CAN WAIT. Sources for the client's items: the client's request for this stage; each one marked CORRECTIVE (something that fails today, with the way to reproduce it in the client's words) or EVOLUTIVE (something new). For every client item, list the normalization items that touch the same modules and should be paid together with it. If the request is ambiguous on any point such that you cannot write a verifiable item, ask me; do not resolve it by assuming. Order: blocking items first, then the client's items in the priority I gave you, each with its paired normalization. Reply in my language.

  1. Leggi la specifica di ogni voce del cliente come se fossi la responsabile, proprio come nella lezione 5. E rivedi gli abbinamenti: ha senso pagare quel debito con quella richiesta?
  2. Aggiungi al patto la routine di ogni sessione della lezione 5, senza modifiche.

Verifica di completezza. Resta qualche "blocca" aperto? Ogni correttivo dice come si riproduce con le parole del cliente? Ogni voce del cliente ha le sue abbinate?

Consegna. docs/PENDING.md con tutto, e la routine nel patto.

Errori tipici. Un backlog con cinquanta voci in "può aspettare": è la riscrittura travestita da lista. Archivia ciò che non si pagherà e dillo. E aprire il primo blocco con un bloccante aperto "perché è piccolo".

Nel progetto guida. Il backlog di Turnos resta con tre voci del cliente: il promemoria doppio (correttivo, modulo messaggi, abbinato all'idempotenza dell'invio e alla coda dei messaggi del dimensionamento), la caparra (evolutivo, modulo nuovo dei pagamenti, abbinata alla conferma nella cancellazione perché tocca la stessa schermata), e il rapporto mensile (evolutivo, modulo rapporti, abbinato all'indice dei pazienti e al contratto del foglio, che viene sostituito). E una dozzina di voci di normalizzazione, di cui tre "possono aspettare" e lo si dice.


Il ciclo sul legacy: lezioni R1 e R2

Lezione R1 — Il primo blocco: il bug, in modalità correttiva

Cosa devi capire. Una voce in sospeso correttiva è un bug noto. Nella lezione 8 il rosso si fabbricava; qui il rosso è il bug stesso: il test che riproduce il guasto, operando il flusso come l'utente che l'ha segnalato, deve fallire contro il codice attuale. Se non fallisce, hai riprodotto un altro bug. Quel rosso è la prova che stai sistemando la cosa giusta, e vale più di qualunque spiegazione dell'agente su ciò che "deve stare succedendo" Ref. 22. E la causa radice si dice in prosa prima di toccare, perché a volte la causa radice è una regola di business che nessuno ha scritto, e quella la decidi tu.

Prima di inviare il prompt, con le tue mani:

  • La voce in sospeso correttiva in docs/PENDING.md con la riproduzione nelle parole della responsabile, e un caso concreto: i tre screenshot della settimana scorsa, con il nome (falso, in test) dei pazienti e la data. Senza un caso, non c'è test.
  • La batteria di caratterizzazione in verde, con il comando in docs/STATUS.md.
  • Le voci abbinate a questa, elencate in essa.
  • La responsabile avvisata che oggi le farai una domanda di business.
  1. Apri il blocco con la routine di ogni sessione: l'agente annuncia quale voce in sospeso prende e rilegge la specifica.
  2. Incollagli:

This pending item is a correction: [some patients receive the reminder twice and some receive none; three cases from last week are attached in the item]. Before changing anything: (1) Reproduce the failure with a test that drives the flow from the screen and checks the effect in the backend, and show me that it fails against the current code; that red is the proof that you reproduced the right defect. If you cannot reproduce it, tell me what you tried and what you need; do not fix what you cannot see. (2) Find the root cause and tell me in prose, with the evidence, before fixing. If the root cause is a business rule nobody wrote down, stop and ask me. (3) Fix at the root, not where it hurts, and nothing else: anything else you find goes to a pending item. (4) Show me the test green, the characterization suite still green, and the regression of the neighbouring items. (5) If the fix changes a current behaviour that someone may depend on, say so explicitly: that is a decision for me, not a side effect. Close the paired normalization items of this module in the same block, each with its own evidence. The commit message says "proved red against [version]" and the test counts. Reply in my language.

Gli stai chiedendo la riproduzione prima della diagnosi, la causa radice in prosa prima di toccare, la radice e nient'altro, la caratterizzazione come regressione del sistema intero, e che un cambio di comportamento sia una tua decisione.

  1. Leggi la causa radice prima di autorizzare la correzione. Se ti chiede una regola di business, decidila con la responsabile e rispondi con il formato di chiusura della lezione 6.
  2. Alla chiusura: esegui tu la batteria di caratterizzazione. E usa il sistema nell'ambiente di test per un po' di tempo, come la receptionist: lo sguardo umano non si delega.

Verifica di completezza. Hai visto il rosso del test che riproduce il bug, con i numeri? La causa radice era scritta in prosa prima della correzione? La caratterizzazione è ancora in verde? Le abbinate sono state chiuse con la loro prova? Il commit dice "provato in rosso"?

Consegna. Il bug chiuso con la routine completa, le abbinate chiuse, e la batteria di caratterizzazione ampliata con il test del bug.

Errori tipici. Autorizzare la correzione senza leggere la causa radice: in Turnos, la prima ipotesi dell'agente è di solito "il processo gira due volte" ed è metà della verità. E lasciare che il "già che ci sono" metta in ordine il modulo dei messaggi: regola 7.

Nel progetto guida. Il test riproduce il doppio invio con un appuntamento che era stato riprogrammato: il processo notturno manda un promemoria per ogni riga di appuntamento del giorno dopo, e un appuntamento riprogrammato ha due righe (quella vecchia, nello stato "riprogrammato", che nessuna schermata mostra, e quella nuova). Quelli che non ne ricevono nessuno sono quelli riprogrammati dopo l'invio. Causa radice: lo stato "riprogrammato" comparso nella lezione N2. La domanda di business: "un appuntamento riprogrammato è un appuntamento nuovo o lo stesso appuntamento?". La responsabile decide: lo stesso appuntamento, con uno storico. La correzione alla radice tocca lo stato, non l'invio; l'idempotenza abbinata si paga nello stesso blocco; il rosso dice "2 messaggi per 1 appuntamento" e il verde "1 messaggio per 1 appuntamento". E il cambio di comportamento si dichiara: gli appuntamenti riprogrammati smettono di comparire due volte nel foglio mensile, che è consumatore della tabella; la responsabile lo approva.

Lezione R2 — Il secondo blocco: la caparra, in modalità evolutiva

Cosa devi capire. Il nuovo sul vecchio si costruisce con il metodo completo, tali e quali le lezioni da 5 a 12 della prima parte: specifica nella voce in sospeso, decisioni con la data, test in rosso, prova end to end, rapporto onesto. Due differenze. La regressione delle vicine è il sistema intero, e la batteria di caratterizzazione è quella che lo dice. E quando il blocco entra in un modulo, le voci di normalizzazione marcate "si paga quando si tocca" di quel modulo entrano con lui, con la loro prova. Non si fa al modulo nuovo ciò che il legacy ha fatto a quello vecchio.

Prima di inviare il prompt, con le tue mani:

  • La voce in sospeso evolutiva della caparra in docs/PENDING.md, con la sua specifica completa letta da te, le sue abbinate, e le decisioni di business che la responsabile può già prendere: quali appuntamenti richiedono la caparra, quanto, cosa succede se non si paga.
  • La rilevazione delle azioni con conseguenze (N5) con la riga "incassare la caparra" aggiunta, perché è un'azione nuova che agisce sul mondo: lucchetto prima di costruire, come nella lezione 14.
  • La batteria di caratterizzazione in verde.
  1. Apri il blocco con il prompt di apertura della lezione 5, sulla richiesta della caparra, e leggi la specifica come la responsabile.
  2. Prima di costruire, il lucchetto: incollagli il prompt di chiusura della lezione 14 per l'azione "incassare la caparra", con la modalità di prova per prima.
  3. Costruisci con la routine della lezione 8, voce per voce, con le abbinate nello stesso blocco.
  4. Alla chiusura del blocco: la batteria completa end to end (quella di caratterizzazione più i test nuovi), con il prompt di chiusura di blocco della lezione 8, e un po' di tempo tuo a usare il sistema.

Verifica di completezza. La caparra ha un lucchetto con test in rosso prima che l'incasso esista? La caratterizzazione è ancora in verde dopo il blocco? Le abbinate del modulo sono state pagate? C'è qualcosa del modulo vecchio che è stato "migliorato" senza una voce in sospeso?

Consegna. La caparra che funziona nell'ambiente di test, in modalità di prova, con la sua specifica, il suo lucchetto, i suoi test e la sua prova end to end; le abbinate chiuse.

Errori tipici. Costruire la caparra "in fretta, come è fatto il resto" perché si incastri: il modulo nuovo nasce con il metodo completo, sempre. E dimenticare il lucchetto perché "è un link di pagamento, non incassiamo noi": il link si manda a un paziente; quella è un'azione verso l'esterno.

Nel progetto guida. La caparra usa lo stesso canale dei promemoria, che adesso ha una coda (la decisione asimmetrica di N6 che si ripaga da sola). Lucchetto: conferma esplicita della receptionist e importo fissato dal professionista; modalità di prova per un periodo registrando "avrei chiesto la caparra a". L'abbinata della schermata di cancellazione (la conferma) si paga in questo blocco perché la caparra cambia cosa succede quando si cancella. Alla chiusura, la batteria esegue sette flussi: i cinque di caratterizzazione, quello del bug di R1 e quello della caparra.


Dopo: uscita in produzione ed esercizio

Da qui in avanti, il legacy è un sistema con metodo, e le lezioni da 13 a 22 della prima parte si applicano tali e quali, con quattro note. La prima riguarda i sei gradini di qualità operativa: l'osservabilità minima e la scansione delle vulnerabilità sono già entrate con la cintura, le misurazioni di persistenza sono già in N6, e la prova di carico si esegue con quei volumi prima del primo deployment; i due monitoraggi partono con la prima lettura come linea base del legacy, e ciò che era già sbagliato il primo giorno diventa una voce in sospeso con la sua marca. Le altre tre note sono queste. L'audit della lezione 13 si confronta con quello di N3: quanto debito è stato pagato, quanto resta. I manuali della lezione 20 in un legacy di solito non esistono, e si generano a partire dal sistema com'è e dalle voci in sospeso chiuse, che adesso sì documentano ciò che è stato fatto. E la retrospettiva della lezione 23 ha una domanda propria di questo percorso: quanto è costato normalizzare (in ore, in token, in tappe prima della prima modifica), e quanto del debito marcato "può aspettare" è finito per costare lo stesso. Quella risposta è quella che correggerà il calendario di questa parte nella prossima versione.

Lista di uscita dal tratto di normalizzazione

Le otto condizioni che il proprietario verifica senza leggere codice, prima di aprire il primo blocco. Sono le stesse della pagina del percorso evolutivo-correttivo; le ripeto qui perché sono la consegna di questa parte.

  1. Esistono tutti gli input delle tappe precedenti (rilevazione, idoneità, patto, file di progetto, albero, ambienti, volumi, dimensionamento, cancelli), con le marche di origine, e il proprietario ha confermato ogni nodo dedotto (N2).
  2. Ogni discrepanza ha una decisione con la data, e quelle che cambiano il sistema hanno una voce in sospeso (N2).
  3. L'audit esiste e ogni rilievo ha la marca di velocità (N3).
  4. La cintura è in verde: ambiente di test con dati anonimizzati, deployment eseguito due volte, segreti fuori e ruotati, integrazione continua, batteria di caratterizzazione con il rosso per mutazione dimostrato (N4).
  5. Ogni azione con conseguenze ha un verdetto, e i lucchetti "adesso" hanno il loro test in rosso (N5).
  6. I numeri primari sono misurati con misuratore e test, e il "per dieci" è scritto (N6).
  7. Non resta nessun "blocca" aperto, e ogni voce del cliente ha le sue abbinate (N7).
  8. Il patto ha le cinque regole del legacy, e una sessione nuova supera la prova di lettura (N1, N2).

Allegato — Ciò che questa parte ancora non ha