Blog ·
Documentazione scritta prima della fusione
Due frasi di una nuova pagina di documentazione erano false il giorno stesso della pubblicazione, perché un altro ramo era arrivato prima.
Di Provibr
Una pagina di documentazione è un insieme di affermazioni sul codice. Sembra ovvio finché non si nota che nulla nella build ne controlla alcuna. Le prove affermano cose sul codice. I controlli di tipo affermano cose sul codice. La prosa sul codice afferma cose sul codice e viene verificata da una persona che la legge una volta sola, il giorno in cui è stata scritta.
Abbiamo scritto due nuove pagine di documentazione in un solo turno: una per l’editor delle automazioni, circa 2930 parole inglesi distribuite su otto sezioni, e una per il cruscotto, circa 909. Più una sezione aggiunta a due pagine che esistevano già. Due frasi della pagina sulle automazioni erano già false quando è stata pubblicata.
Nessuno aveva scritto una menzogna. Entrambe le frasi erano esatte rispetto al ramo su cui erano state scritte.
La frase che era vera quando è stata scritta
La documentazione di una funzione si scrive di solito dopo la funzione, il che significa che si scrive mentre altri rami sono ancora aperti. La nostra lo era. La pagina descriveva un nodo di notifica e diceva, in sostanza, che non invia posta elettronica. Sul ramo rispetto al quale era stata scritta era esattamente giusto: il nodo scriveva una notifica nel pannello e nulla usciva dall’edificio.
Un turno parallelo è stato fuso per primo e ha dato al nodo una casella per la posta elettronica, spenta di default, una categoria di disiscrizione tutta sua e una regola per cui una prova di esecuzione non invia mai nulla. Ognuno di quei fatti interessa a chi legge. Nessuno di essi stava sulla pagina, e quello che stava sulla pagina ora diceva il contrario.
La seconda frase descriveva come un piano si collega a un flusso. Diceva che il piano esegue il flusso che gli sta dietro, e veniva da un’epoca in cui quel rapporto era uno a uno. La stessa fusione lo ha sostituito con una giunzione: un piano può appendere al massimo un flusso per momento, su tre momenti, e un flusso a innesco manuale o a webhook non può appendersi affatto. «Non si può collegare» è una risposta migliore di «collegato e in silenzio non fa nulla», ma è una risposta diversa, e la pagina dava ancora quella vecchia.
La riparazione è stata piccola. La parte interessante è come è stata trovata: qualcuno è andato a cercare di proposito, perché un turno che tocca un argomento è l’unico momento in cui qualcuno ha una ragione per rileggere la prosa su quell’argomento.
Che cosa può cogliere una guardia
Su quelle stesse pagine c’è un secondo modo di fallire e, a differenza del primo, si può meccanizzare.
La pagina del cruscotto ha una tabella che elenca le schede che un utente può aggiungere. Quelle schede hanno nomi, in nove lingue, e quei nomi esistono già: sono le etichette nel selettore su cui l’utente clicca davvero. Scrivere una tabella di documentazione significa scriverli una seconda volta.
È andata storta subito, alla prima stesura, in inglese:
| Nel selettore | Sulla pagina di documentazione |
|---|---|
| Integration list | Connections |
| Open tickets | Tickets |
| Credit balance | Credit |
Nessuno di quei nomi è sbagliato come inglese. Tutti e tre sono sbagliati come documentazione, perché chi legge di aggiungere «Connections» cercherà una scheda chiamata Connections e troverà una scheda chiamata Integration list. Lo scostamento è silenzioso per costruzione: entrambi i testi vanno bene da soli, e nessuno mette un manuale accanto a un selettore.
La tabella prende dunque ora le stesse chiavi di catalogo che prende il selettore, e una prova pretende che siano identiche parola per parola in tutte e nove le lingue. La chiave di documentazione è derivata dall’identificativo della scheda invece di essere elencata a mano, così che la settima scheda facoltativa che qualcuno aggiungerà l’anno prossimo venga misurata senza che nessuno si ricordi di aggiungerla qui. È la stessa forma della guardia che teniamo fra le due copie dei messaggi inglesi del server, ed esiste per la stessa ragione: due posti che tengono una sola verità hanno bisogno di una prova che lo dica, non di una convenzione.
I nomi dei pulsanti sulla stessa pagina erano stati indovinati in cinque delle nove lingue. Ora escono anch’essi dal catalogo. E tre lingue avevano tradotto la parola Scripts, che è il nome di una voce di menu non tradotta nel prodotto, così la pagina diceva a chi legge in spagnolo, portoghese e ucraino di cliccare qualcosa che sotto quel nome non esiste.
Un token tecnico non è una parola
Nomi di prodotto, porte, percorsi, nomi di modulo e codici di stato stanno in un token a spaziatura fissa e restano in inglese, ovunque compaiano, in ogni lingua. Quella regola non è nuova. La novità è che scriverla dentro queste pagine si è scontrata con altre due guardie contemporaneamente.
Mettere letteralmente un elemento <code> dentro un array di righe di tabella fa scattare la regola di lint che vuole una chiave su ogni elemento JSX di un array, anche qui, dove il componente della tabella avvolge ciascuna cella in un proprio elemento con chiave e la chiave non viene mai letta. Metterci una chiave fa scattare una guardia diversa, che vede un figlio con chiave accanto a chiamate di traduzione le cui chiavi non riesce a risolvere in quel file.
La via d’uscita è stata una funzione di una riga che restituisce l’elemento. Per la regola di lint è una chiamata di funzione e non un elemento di array; per l’altra guardia non è una chiave. L’uscita disegnata è identica byte per byte. È una cosa piccola, ed è il genere di cosa piccola che si risolve con un commento di disattivazione quando nessuno annota perché le due regole non andavano d’accordo.
Schermate che sembravano riuscite
La misura di queste pagine comprendeva schermate per ancora: scorrere fino a ciascuna sezione, fotografarla, guardarla.
Nove di esse mostravano l’intestazione della pagina.
Il comando del browser che cattura una regione oltre la finestra calcola il proprio ritaglio dalla cima del documento e non dalla posizione di scorrimento corrente. Scorra fino a un’ancora otto schermate più in basso, chieda una regione alle coordinate che l’elemento riporta, e fotograferà invece la cima della pagina, esattamente della misura giusta, in un file con il nome giusto. Ognuna di quelle schermate era un’immagine dall’aria plausibile della cosa sbagliata.
Aggiungere lo scostamento di scorrimento corrente ha risolto. La forma generale è una che continuiamo a incontrare: una misura che fallisce producendo un risultato dall’aria normale è peggiore di una che si schianta, perché lo schianto viene indagato lo stesso giorno.
La parte che nessuna guardia raggiunge
I nomi delle schede si potevano meccanizzare perché entrambi i lati sono stringhe in un solo deposito. Le due frasi invecchiate no, e vale la pena essere precisi sul perché, perché è allettante credere che ogni problema di documentazione abbia una prova che aspetta di essere scritta.
Una frase che dice che un nodo non invia posta elettronica è un’affermazione su un comportamento sparso su quattro file, un valore di default, una casella e un elenco di categorie. Non c’è espressione con cui confrontarla. L’unico meccanismo che la coglierebbe è una prova che disegna il comportamento e legge la frase, cioè una prova da scrivere frase per frase, da qualcuno che già sa che la frase è sbagliata.
Quello che abbiamo fatto invece costava meno e vale la pena chiamarlo pratica: quando la correzione è stata fatta, si è cercata in tutto il sottoalbero della documentazione ogni altra affermazione sulla posta elettronica e ogni altra affermazione su un flusso per piano. Non c’era un terzo posto. Questo è un risultato, non una formalità. Senza di esso il turno avrebbe corretto due frasi e lasciato chi legge con la convinzione ragionevole che la pagina fosse stata controllata.
La stessa disciplina esiste già altrove in questo progetto per un’altra coppia: i nostri articoli lunghi possono invecchiare rispetto all’elenco delle integrazioni attive, e nulla diventa rosso quando accade. Due articoli hanno passato una volta sei settimane a dire che due hypervisor erano ancora in programma mentre entrambi erano già in produzione. La regola che ne è uscita è la stessa: se un turno cambia lo stato di una cosa, cerchi il suo nome nella prosa.
Che cosa annoteremmo
- La prosa sul codice è un’affermazione non provata. Nulla nella build la legge. Va bene, purché tutti lo sappiano e nessuno supponga che una corsa verde dica qualcosa sul paragrafo.
- La documentazione si scrive contro un ramo, non contro main. Se altri turni sono aperti, la pagina è un’istantanea di uno stato che potrebbe non uscire mai. La rilegga dopo la fusione, non prima.
- Un nome che esiste nel prodotto va letto, non ribattuto. Tre nomi di scheda su sei sono scivolati già alla prima stesura. In nove lingue quella è una classe di errori, non un incidente.
- Derivi la chiave di documentazione dall’identificativo. Così la scheda successiva è coperta senza che nessuno si ricordi di questa regola.
- Una parola indovinata in una lingua che non legge è invisibile. Cinque lingue avevano nomi di pulsante indovinati e nulla era rosso.
- Tradurre il nome di un prodotto è un’istruzione rotta. Se il menu dice Scripts in ogni lingua, il manuale dice Scripts in ogni lingua.
- Quando due regole di lint sono in disaccordo, annoti a quale ha obbedito e perché. L’alternativa è un commento di disattivazione che nessuno potrà valutare più tardi.
- Una misura che produce un risultato plausibile quando fallisce non verrà messa in dubbio. Fotografi qualcosa che può riconoscere, e guardi le immagini.
Per chiarezza su che cosa sia: entrambe le pagine sono in produzione in nove lingue, le due frasi invecchiate sono state corrette in tutte e nove, e la guardia sui nomi delle schede è nella suite ed è stata dimostrata rossa prima di essere dimostrata verde. Le affermazioni sulle pagine vengono dalla lettura del codice e non dalla sua esecuzione; l’esempio con curl sulla pagina delle automazioni non è stato lanciato contro un endpoint reale; e ogni traduzione ha avuto una lettrice, non due.
Dal lavoro di piattaforma su Provibr. Le schede a cui quei nomi si riferiscono stanno in una scorciatoia è un riferimento, non un diritto, e quanto costa tenere onesti nove cataloghi si trova in sedicimila chiavi, nove lingue.