Tradotto automaticamente. Leggi l’originale in inglese: Your performance review is a memory test →
Chiedete a qualsiasi engineering manager chi sia il suo miglior ingegnere. Osservate quanto veloce arriva la risposta. Non c’è esitazione, nessuna riserva, nessun “fammi prima controllare qualcosa”. Lo sanno. Lo hanno sempre saputo.
Ora chiedete loro di mostrare i risultati. Otterrete una storia. Di solito una bella storia, su un incidente gestito da qualcuno alle 2 di notte, o un refactoring che ha sbloccato un trimestre, o la persona che risponde sempre nel canale. Quello che non otterrete è un numero, o un confronto, o un resoconto dei quattro ingegneri il cui lavoro il manager non ha visto in prima persona. La sicurezza non si basava mai su misurazioni. Si basava sul ricordo, e il ricordo è funzione della prossimità.
Ecco la tesi, e tutto ciò che segue ne è la prova. Le prestazioni ingegneristiche vengono giudicate a memoria, la memoria premia la visibilità piuttosto che il valore, e ciò che volete davvero che le persone costruiscano è scritto in una roadmap che non è mai collegata a ciò su cui le valutate. Quei due documenti, la roadmap e la review delle prestazioni, non hanno nulla a che fare l’uno con l’altro in quasi tutte le aziende che ho visto, inclusa la mia fino a poco tempo fa.
Quindi li abbiamo collegati. Ogni pull request unita viene letta da un modello, le viene assegnata una severità, e moltiplicata per quanto la nostra roadmap tiene al componente che ha toccato. Il risultato è una classifica mensile, e alimenta le decisioni sui bonus.
Vi mostrerò la nostra, incluse le parti in cui è imbarazzante e quelle in cui è sbagliata.
La saggezza comune dice che non si può misurare, e la saggezza comune è un’alzata di spalle
La posizione standard sulla misurazione del contributo individuale in ingegneria è che non si deve fare, perché ogni proxy è una trappola. Le righe di codice premiano il gonfiore. Il conteggio dei commit premia la frammentazione. Gli story points sono una negoziazione, non una misurazione. Anche i buoni framework sono deliberatamente a livello di team: DORA misura quattro cose su una pipeline di delivery e non dice nulla sulle persone, una scelta progettuale che i suoi autori rendono esplicita.
Tutto ciò è corretto, e nessuna di queste è una risposta. Rifiutarsi di misurare non produce un’azienda in cui nessuno viene classificato. Produce un’azienda in cui tutti vengono comunque classificati, da un meccanismo senza traccia di audit. La classifica avviene comunque al momento della compensazione. Solo che avviene in una stanza, a memoria, ponderata da chi la persona nella stanza ha frequentato di più.
Chiamatelo il premio dell’ingegnere rumoroso: il divario tra quanto sei valutato e quanto hai effettivamente performato, spiegato interamente dalla tua distanza da chi scrive la tua review. Non è un difetto caratteriale dei manager. È l’output prevedibile del chiedere a un umano di confrontare i contributi tecnici di quindici persone nell’arco di un anno usando solo ciò che è capitato di notare.
Il premio era inevitabile fino a circa due anni fa, perché la materia prima per una risposta migliore era un mucchio di diff che nessuno aveva tempo di leggere. Quel vincolo è scomparso. Un modello può leggere ogni diff nel tuo repository ogni mese per meno del costo di un’ora della riunione in cui attualmente tiri a indovinare.
Leggerli è la parte facile. Decidere quanto vale la lettura è l’intero problema, e non è una questione tecnica.
L’intera formula sta in una riga
Eccola, per intero, dal percorso di scoring in GitRank:
final_score = is_eligible ? severity_base_points × component_multiplier : 0
Non è una semplificazione per il blog. Quella è la riga. Non c’è regressione nascosta, nessuna ponderazione appresa, nessun termine di reputazione, nessun aggiustamento per anzianità. Severità per importanza, o zero.
La metà della severità è una scala fissa. Quattro livelli, quattro valori in punti, impostati una volta e visibili a tutti coloro che vengono valutati:
Una correzione critica vale venti a bassa priorità. Quel rapporto è una dichiarazione di policy, e l’abbiamo scritta invece di lasciarla nella testa di qualcuno.
La metà dell’importanza è la parte che conta davvero, ed è il motivo per cui penso che questo approccio si generalizzi. Ogni componente nel repository ha un moltiplicatore, e il moltiplicatore è impostato da ciò di cui il prodotto ha bisogno in questo trimestre:
Chat è 2.0x perché chat è ciò su cui stiamo puntando il prodotto. Autenticazione è 1.0x perché funziona e vorremmo che continuasse a funzionare in silenzio. Le funzionalità di collaborazione e l’evidenziazione dei documenti sono 2.0x per lo stesso motivo di chat. Nessuno di questi numeri sono giudizi tecnici. Sono la roadmap, riscritta in un campo che paga.
Questa è la mossa. Non il modello, non la classifica, non la gamification. La mossa è che il documento strategico e l’input per la compensazione sono diventati lo stesso documento. Se la roadmap cambia a ottobre, i moltiplicatori cambiano a ottobre, e l’incentivo cambia a ottobre invece che al prossimo ciclo di review annuale tra quattordici mesi.
Lascio che sia chiaro, perché è la parte che tutti saltano. Il problema difficile in un’organizzazione ingegneristica in crescita non è mai stato che le persone sono pigre. È che quaranta persone intelligenti, ciascuna che ottimizza localmente e onestamente, produrranno collettivamente un quarto di lavoro che non si somma a ciò che l’azienda ha detto di volere. Il middle management esiste in gran parte per risolvere questo, portando la strategia in giro nelle conversazioni, una scrivania alla volta, perdendo fedeltà a ogni passaggio. Una tabella dei moltiplicatori fa lo stesso lavoro di instradamento in un solo passaggio e non si stanca, non ha preferiti e non dimentica ciò che le hai detto a gennaio.
Una correzione critica in chat vale quaranta commit di polish nell’API
Metti insieme le due metà e la differenza è netta.
Un P0 in chat vale 100 base per 2,0, quindi 200 punti. Un P3 nell’API vale 5 base per 1,0, quindi 5 punti. La singola pull request più preziosa che puoi unire qui vale quaranta volte la meno preziosa. Non il quaranta percento in più. Quaranta volte.
Quel numero è deliberatamente violento, e fa ciò che gli incentivi gentili non riescono mai a fare. Nessuno riorganizza la propria settimana attorno a una differenza del 15%. Le persone riorganizzano assolutamente la propria settimana attorno a una differenza di 40x.
Guarda cosa succede a una settimana reale sotto questi pesi. Ecco la distribuzione della severità su cinque settimane, con la settimana del 13 luglio espansa:
188 pull request. Il P2 è il 59% di esse, che è ciò che una normale settimana ingegneristica sembra ovunque: per lo più correzioni di media entità con una soluzione alternativa disponibile.
Ora pesale. Quelle 111 P2 valgono 2.220 punti a 1x. Le 50 P1 valgono 2.500. Meno della metà delle pull request portano più della metà del valore della settimana, e il singolo P0 vale quanto venti dei P3 che un conteggio grezzo dei commit avrebbe trattato come lavoro identico.
Questa è l’intera argomentazione per la pesatura, in una settimana di dati reali. Conta le pull request e concludi che la settimana riguardava i P2. Pesa le e scopri che la settimana riguardava cinquanta pezzi di lavoro specifici, e puoi nominare chi li ha fatti.
Due persone erano il 58% dell’output, e non avrei indovinato l’ordine
Torniamo alla classifica, perché è qui che ho smesso di fidarmi della mia intuizione.
Sette sviluppatori, 10.415 punti nell’arco di 30 giorni. Lo sviluppatore in testa ne ha 3.530, che è il 33,9% di tutto ciò che il team ha prodotto in termini di valore. I primi due detengono il 57,7% tra di loro.
Voglio essere attento su cosa questo significa e non significa. Non significa che gli altri cinque siano sottoperformanti, e se lo leggi così hai imparato la lezione sbagliata da questo post. Una concentrazione come questa di solito significa che i primi due stanno lavorando sui componenti con il moltiplicatore più alto, che è esattamente ciò per cui il sistema è progettato e esattamente ciò che abbiamo chiesto loro di fare. Il numero è una descrizione di dove atterra il valore, non un verdetto su cinque persone.
Ma guarda l’ordinamento, perché ha infranto la mia previsione. Ecco chi possiede cosa:
Mulualem-E è l’esperto primario su chat, il nostro componente a 2,0x, con 71 delle sue 230 pull request. È anche l’esperto primario su agents, il nostro componente a 1,5x, con 86 su 148, ovvero il 58% di quell’area. Se mi avessi descritto questo e chiesto chi è in cima alla classifica, l’avrei detto senza esitazione. Lui è secondo.
Il primo posto va a tugberkayartextcortex, con 31 pull request P1 contro le 12 di Mulualem-E. Il mix di severità ha battuto la proprietà del componente. Possedere l’area più importante del prodotto non è la stessa cosa che portare a termine ripetutamente lavori ad alto impatto al suo interno, e fino a quando non abbiamo pubblicato questo non avrei potuto dirti quale di queste due cose la nostra retribuzione stesse effettivamente premiando. Premiava quella che mi era capitato di notare.
Questo è il premio per l’ingegnere rumoroso, colto in flagrante, nella mia stessa azienda. La mia intuizione aveva le due persone giuste e l’ordine sbagliato, e l’ordine sbagliato è ciò che fa un bonus.
La persona che ha scritto più codice è all’ultimo posto
Ora la scoperta che mi ha messo a disagio, che è quella con cui voglio che tu ti soffermi davvero.
karthikmudunuri è l’esperto primario sul presentation maker, con 51 delle 58 pull request di quel componente. Questo è l’88% di un’intera area di prodotto. Il volume non è il suo problema. Lui è ultimo in classifica, con 300 punti.
C’è una combinazione che atterra esattamente su quel numero: quattro pull request P1 in un componente a 1,5x, e nient’altro che punti. 4 × 50 × 1,5 = 300. Il suo badge dice 4 P1, che corrisponde. Non posso dimostrare che questa sia la vera scomposizione da questa dashboard, e voglio segnalare l’imprecisione onestamente, perché la classifica copre 30 giorni mentre i grafici dei componenti coprono dal 6 luglio al 3 agosto, quindi le due finestre sono vicine ma non identiche.
Se la scomposizione è corretta, circa 47 pull request unite hanno prodotto zero punti. Ci sono solo due spiegazioni. O erano rifiniture di bassa gravità, nel qual caso il punteggio è corretto e la conversazione utile è se dovremmo avere una persona che passa un mese con una concentrazione dell’88% su un componente che non abbiamo contrassegnato come importante. Oppure erano lavoro reale che il gate di idoneità ha azzerato, nel qual caso il punteggio è sbagliato e lo strumento gli deve una spiegazione.
Il punteggio è tutto o niente sull’idoneità. Se fallisci un criterio abilitato, e il set predefinito è collegamento a issue, implementazione della correzione, qualità della descrizione della PR, test dove il modello giudica che i test siano richiesti, e un tetto di 3.000 righe, il punteggio è zero indipendentemente dalla gravità. Una correzione veramente critica con una descrizione scadente ottiene lo stesso punteggio di niente.
Non so quale spiegazione sia giusta, e qui c’è la mia vera lamentela: la dashboard dovrebbe essere in grado di dirmelo, per ogni pull request, e oggi mi costringe a fare reverse engineering a partire da un totale. Questa è una vera lacuna nel nostro prodotto e sta venendo corretta. È anche esattamente la modalità di fallimento che le persone temono nei sistemi di punteggio, quindi non fingerò di averla trovata in una revisione di design. L’ho trovata mentre scrivevo questo post.
Dove sono i bug è una decisione di prodotto, non di ingegneria
L’altra cosa che emerge dal valutare ogni pull request è che smetti di discutere sulla qualità basandoti su aneddoti.
740 pull request nei dieci componenti più attivi. 230 di esse, il 31%, erano correzioni di bug anziché nuovo lavoro. Solo Chat ha 230 pull request, un altro 31%, che è l’aspetto che dovrebbe avere un moltiplicatore 2.0x quando funziona.
Poi c’è il presentation maker: 58 pull request, 23 delle quali bug. Questo è un tasso di bug del 40% in un componente con quattro contributori, contro il 25% in chat con sette. E payments ha 44 pull request con 20 bug, un tasso del 45%, nel componente che gestisce il denaro.
Chat e agenti sono pari a 57 bug ciascuno, ma chat li ha prodotti in 230 pull request e agenti in 148. Stesso numero di bug, il 55% di lavoro in più dietro uno di essi. Questo è un segnale sugli agenti che nessuna retrospettiva avrebbe mai portato alla luce, perché nessuna singola persona del team ha unito abbastanza di entrambi per notarlo.
La linea dei bug e quella delle funzionalità salgono insieme nell’intervallo anziché scambiarsi, che è la forma che si desidera e non quella che mi aspettavo. Sto leggendo quel grafico come descrittivo, non come un’affermazione che abbiamo migliorato qualcosa. Copre cinque settimane e la tendenza è all’interno del rumore che si otterrebbe dall’arrivo di un singolo grande progetto.
Ecco dove il nostro stesso strumento è attualmente sbagliato
Se ti mostrassi solo le parti che funzionano, avresti ragione a svalutare tutto. Quindi:
La scheda del prompt non fa ciò che dice nel percorso di produzione. C’è una schermata di amministrazione che ti permette di personalizzare il prompt di valutazione. Guida l’esecutore di valutazione batch. Il percorso webhook e cron che valuta le pull request in produzione usa un prompt hardcoded nel sorgente. Se modifichi quel template aspettandoti che cambi i tuoi punteggi live oggi, non lo farà, e niente nell’interfaccia te lo dice.
La colonna della classifica della dashboard etichettata “PR” non è un conteggio delle pull request. È il punteggio di authorship. Puoi vederlo nello screenshot sopra: la riga superiore mostra 3530 sotto PR e 3530 sotto Score. La pagina della classifica standalone fa questo correttamente, con colonne separate per pull request e authorship, quindi è un’etichettatura errata sull’unica schermata che tutti aprono effettivamente, che è quasi il posto peggiore in cui averne una.
Il nostro README pubblica valori di punti errati. Dice che P2 è 25 punti e P3 è 10. Il database seeda 20 e 5, e lo screenshot di configurazione sopra conferma 20 e 5. La documentazione e il software non concordano sul punteggio, e il software vince.
Il tracciato delle review è quasi morto. Revisionare il codice altrui guadagna punti su una scala di velocità separata, con revisioni più veloci che ottengono punteggi più alti. In tutta quella classifica, esattamente una persona ha punti di review: 90 su 10.415 totali, ovvero lo 0,86% di tutto ciò che è stato valutato. Qualunque cosa pensiamo di incentivare riguardo la revisione del codice, non lo stiamo facendo. La ragione più probabile è che la sincronizzazione delle review ha iniziato a raccogliere solo di recente, ma non l’ho confermato, e finché non lo faccio la lettura onesta è che la funzionalità non sta atterrando.
Il nostro stesso FAQ afferma circa il 90% di accuratezza di classificazione e non posso supportarlo. Non c’è un set di valutazione nel repository, nessuno script di benchmark e nessun corpus giudicato dietro quel numero. È un’affermazione che non accetterei da un fornitore, ed è sulla nostra stessa pagina di marketing. Verrà rimossa.
Una classifica viene aggirata, e la nostra non ha quasi difese
Ho cercato nel nostro codice di valutazione misure anti-gaming. Ecco la lista completa di ciò che esiste.
Le pull request con oltre 3.000 righe modificate non sono ammissibili, il che blocca la forma più grezza di gonfiaggio. Le auto-revisioni valgono zero e sono escluse da ogni query della classifica. Le revisioni provenienti da account con [bot] nel login vengono saltate. Al modello viene chiesto se il codice fa effettivamente ciò che la descrizione afferma, che è la cosa più vicina a un rilevatore di nonsense. Gli amministratori possono sovrascrivere qualsiasi punteggio, e la sovrascrittura richiede una motivazione scritta di almeno dieci caratteri.
Ecco cosa non esiste. Nessun limite di punti settimanale o mensile per persona. Nessun rendimento decrescente per lavoro ripetuto sullo stesso componente. Nessun decadimento temporale di alcun tipo, e la finestra di 30 giorni sulla classifica è un intervallo di date predefinito che chiunque può allargare, non un limite. Nessun rilevamento di duplicati o revert, quindi sistemare qualcosa che hai rotto la settimana scorsa vale quanto sistemare qualcosa rotto da qualcun altro. Nessun rilevamento di collusione tra revisori. E il filtro bot si applica ai revisori ma non agli autori delle pull request, quindi una pull request creata da un bot e mergiata vale quanto una umana, che nel 2026 non è un’ipotesi.
Chiunque sia determinato a sfruttare questo sistema può farlo. Suddividere il lavoro in più pull request, ciascuna con un link a un issue e una descrizione pulita, mirata al componente con moltiplicatore 2.0x. Questo è l’exploit, e voglio chiamarlo con precisione per quello che sembra: sembrano modifiche piccole, ben documentate e ben testate alla parte più importante del prodotto. Il modo più efficace per imbrogliare la nostra classifica è fare ciò che vogliamo. Non è un incidente, è l’obiettivo di design, ed è l’unica difesa contro la legge di Goodhart che abbia mai funzionato. Rendi il proxy costoso da falsificare in qualsiasi modo che non sia la cosa reale.
Non è una difesa completa. La gravità viene assegnata da un modello che legge un diff, e un modello può essere convinto a chiamare un bug medio come alto da una descrizione di pull request sufficientemente drammatica. Non abbiamo misurato quanto spesso accada. Nessuno l’ha fatto. Se stai valutando qualsiasi strumento in questa categoria, incluso il nostro, questa è la domanda da fare, e “circa il 90%” non è una risposta.
Non vi darò il numero di miglioramento, perché non ce l’ho
Ecco l’affermazione che vorrei fare. Da quando abbiamo iniziato a pubblicare questa classifica mensilmente, il lavoro si è visibilmente spostato verso i componenti che abbiamo contrassegnato come importanti, perché gli ingegneri vogliono il punteggio.
Ecco perché non la presento come numero. L’abbiamo attivata a metà del flusso, senza una baseline pulita, senza un repository di controllo e senza una definizione preregistrata di cosa significasse “spostato”. I moltiplicatori sono cambiati durante il periodo. Così come il numero di dipendenti e la roadmap. Qualsiasi percentuale pubblicassi sarebbe un numero scelto dopo aver visto i dati, che non è una misurazione, è una decorazione.
Quello che posso dirvi è qualitativo e lo etichetto come tale. Le discussioni sono cambiate. La gente ha smesso di chiedermi se il loro lavoro fosse apprezzato e ha iniziato a chiedere perché un componente fosse valutato 1.0x. È una discussione molto migliore da avere, ed è l’unica cosa per cui avrei pagato da sola.
Se mai avrò un vero prima e dopo, pubblicherò prima la metodologia e poi il numero. Se lo pubblicherò nell’ordine inverso, non credetemi.
Puntatelo sulla roadmap, poi date il righello alla gente
Voglio concludere al di sopra del prodotto, perché il prodotto è la cosa meno interessante qui.
Il vero lavoro dell’organigramma non è mai stato l’autorità. Era il routing. Portava la risposta a “cosa conta questo trimestre” verso l’esterno dalle persone che lo decidevano, e portava la risposta a “chi ha fatto cosa” verso l’interno, e faceva entrambe le cose male, lentamente e con un’enorme distorsione a ogni salto. Tutto ciò che non vi piace della politica aziendale è un artefatto di compressione di quel routing. I manager non ne erano la causa. Erano l’unico hardware disponibile.
Non sono più l’unico hardware disponibile. Un modello che legge ogni diff più una tabella di moltiplicatori fa il routing verso l’esterno in un salto e il routing verso l’interno in una query. Ciò che resta per gli umani è la parte che è sempre stata il vero lavoro e non ha mai avuto tempo: decidere quali dovrebbero essere i moltiplicatori e stare con le persone i cui punteggi quelle decisioni hanno spostato.
La politica non scompare. Non lasciate che nessuno vi venda questo. Si sposta. Si sposta da “il mio manager si ricorda del mio trimestre?” a “perché il mio componente è valutato 1.0x quando la roadmap dice che è centrale”, e quella seconda battaglia è una battaglia sulla strategia reale dell’azienda, condotta in pubblico, in una tabella che chiunque può leggere. Preferirei avere quella battaglia ogni mese piuttosto che quella attuale, che si svolge una volta all’anno, in privato, da qualcuno che ricostruisce undici mesi a memoria.
Qualcuno gestirà questo male. Qualcuno metterà una classifica su un muro senza spiegazioni di ammissibilità e senza traccia di sovrascritture e licenzierà il decile inferiore, e sarà un disastro, e sarà incolpato il modello piuttosto che la persona che ha scelto i moltiplicatori. Quella è la parte per cui si viene pagati, e non sarà pagata da chi l’ha impostata.
Quindi misuratemi con lo stesso strumento. Se gestite qualcosa di simile, pubblicate tre cose insieme alla classifica: la tabella dei moltiplicatori, così la gente può discutere la strategia piuttosto che il punteggio. La suddivisione per singola pull request, così chiunque abbia ottenuto zero può vedere quale cancello lo ha bloccato e fare appello. E il registro delle sovrascritture, perché il numero modificato da un umano è l’unico numero che vale la pena verificare.
Attualmente pubblichiamo la prima. Facciamo male la terza: una sovrascrittura scrive la sua motivazione sulla riga di valutazione, e cancellare la sovrascrittura elimina anche la motivazione, quindi ciò che abbiamo è una nota che può essere revocata, non un registro. E non pubblichiamo la seconda abbastanza bene, cosa che ho scoperto solo quando uno sviluppatore con l’88% di un componente è finito ultimo nella mia stessa classifica e non sono riuscito a spiegargli perché.
*GitRank è su gitrank.dev ed è concesso in licenza CC BY-NC 4.0. Il punteggio sul percorso di produzione viene eseguito su Claude Haiku 4.5 con temperatura 0.3. Tutti i dati sopra provengono dal repository della nostra piattaforma tra il 6 luglio e il 3 agosto 2026, con un sample size di un’azienda e sette sviluppatori: una descrizione di noi stessi, non un benchmark di nulla.