Salta ai contenuti

Revisione IA

Una revisione IA è una singola esecuzione della pipeline pr_review preconfigurata su una pull request aperta. La pipeline apre lo spazio di revisione della PR, distribuisce gli agenti revisori perché leggano il diff nel checkout isolato di quello spazio, ciascuno deposita i propri rilievi come nodi di revisione strutturati, un agente lead li consolida in un percorso guidato e un finalizzatore calcola un unico verdetto: Ship, Hold o Block. Ciò che la pipeline non fa mai è pubblicare: la pubblicazione su GitHub è un passaggio separato e deliberato che compie una persona.

Il resto di questa pagina spiega i pezzi e perché hanno questa forma.

Il contesto di revisione di una PR è uno spazio di messaggistica — modalità review, tipo pr — collegato alla pull request da un’associazione dello spazio di revisione. Viene creato in modo idempotente: la pagina della PR, la pipeline di revisione e le superfici di chat risolvono tutte l’unico spazio di supporto della PR attraverso lo stesso percorso di codice, così un modello che revisiona una PR e una persona che la apre non possono mai ritrovarsi in due stanze diverse a guardare due checkout diversi.

Il worktree isolato dello spazio ha la PR in checkout al suo head ref. Una stanza significa anche un solo checkout: ogni revisore lavora nello stesso spazio invece di ricevere ciascuno il proprio clone dello spazio di lavoro.

Ogni revisore pubblica nel proprio flusso con nome dentro quell’unico spazio, e i rilievi sono messaggi review_node anziché semplice prosa. La raccolta finale a livello dell’intero spazio è deliberata: un verdetto calcolato dai rilievi di un solo thread sarebbe, in silenzio, un verdetto su un solo revisore.

L’associazione porta con sé una scala di stati — requested → in progress → awaiting approval → completed — ed è ciò che sblocca Pubblica su GitHub nella scheda Revisione della PR.

Quanto è profonda una revisione è una policy dello spazio di lavoro con tre livelli, impostata in Impostazioni → Spazio di lavoro → Generale, sulla scheda Criteri dello spazio di lavoro:

Livello Revisori distribuiti Rendicontazione
light Solo l’ingegnere Solo ciò che conta davvero
balanced Ingegnere, QA, architetto (predefinito) La passata ordinaria
thorough Tutti e cinque, inclusi sicurezza e prestazioni Nulla viene declassato

Il livello muove due manopole contemporaneamente: quali revisori vengono distribuiti, imposto dai gate di stato runWhen del modello di pipeline anziché dalla formulazione del prompt — la formulazione del prompt si può ignorare, un gate no — e dove vengono visualizzati i rilievi sotto la soglia. Nessuna delle due manopole elimina mai un rilievo: un livello che segnala meno ne deposita esattamente altrettanti e raggruppa il resto.

Le passate di sicurezza e prestazioni riutilizzano gli agenti architetto e ingegnere preconfigurati anziché introdurne di nuovi. La specializzazione è il brief con cui il revisore viene inviato, non un agente separato per asse: un agente per asse sarebbero cinque righe in più in ogni spazio di lavoro senza alcuna capacità in più. La selezione dei revisori non ispeziona mai il diff per linguaggio o dominio.

Nodi di revisione: i rilievi come dati, non come prosa

Sezione intitolata “Nodi di revisione: i rilievi come dati, non come prosa”

Un rilievo depositato con add_review_node diventa un nodo di revisione sulla PR: è ciò che la scheda Revisione mostra, ciò da cui si calcola il verdetto e ciò che “Pubblica su GitHub” trasforma in un commento inline. Un revisore che restituisce solo prosa produce un’esecuzione di pipeline che sembra riuscita e una superficie di revisione vuota; depositare è la parte che regge il tutto.

Ogni nodo porta con sé:

Campo Valori
Tipo bug, suggestion, recommendation, question, ticket
Priorità P0 (critico) → P3 (dettaglio)
Terna di triage categoria (security, stability, …), gravità, impegno
Ancoraggio Percorso del file, riga iniziale e finale
Correzione suggerita Righe di sostituzione suggerite, un diff opzionale, un prompt di correzione opzionale
Confidenza Un punteggio in [0, 1]
Ragionamento L’analisi, scritta prima del rilievo

Due dettagli sono deliberati. Un suggerimento GitHub con un solo clic viene offerto solo quando il revisore ha fornito righe di sostituzione esatte: ricavarle da un diff unificato sbaglia in silenzio, e un commit con un clic di un’inferenza sbagliata è peggio di nessun pulsante. Inoltre lo schema di add_review_node presenta reasoning prima del rilievo, così un modello che compila l’oggetto nell’ordine dello schema scrive prima l’analisi. Il campo è facoltativo: ometterlo non fa rifiutare il nodo. Un nodo il cui payload è malformato scompare anziché inquinare la revisione.

Un nodo passa attraverso open → consensus-ready → resolved o dismissed. Il passaggio intermedio è il cuore del modello: un rilievo viene promosso solo quando un revisore pari lo conferma, e un agente non può mai confermare un proprio rilievo. Lo strumento MCP publish_review_to_github e l’impostazione predefinita RPC pubblicano ancora solo i rilievi confermati dai pari. Il pulsante Pubblica su GitHub della scheda Revisione invia invece ogni rilievo ancora aperto.

La regola è applicata in tre punti indipendenti — lo strumento di conferma, il finalizzatore e il componente di pubblicazione — così sopravvive a un chiamante difettoso in uno qualsiasi di essi. Tutti i cambi di stato passano da un unico servizio, ed è questo che dà un senso a uno stato: prima, due percorsi parziali potevano non concordare sul fatto che lo stesso rilievo fosse risolto.

Quando i revisori non sono d’accordo — stesso file e stessa riga, priorità distanti due o più livelli, oppure uno che lo chiama bug e l’altro che lo chiama suggestion — il disaccordo viene evidenziato sopra l’elenco dei rilievi. È lì che le opinioni dei revisori divergono e che il giudizio di una persona vale di più.

Scartare un rilievo scrive anche un fatto di soppressione soft nel dominio della memoria, a bassa confidenza: uno scarto è una preferenza, non una regola.

Coorti: ciò attorno a cui si raggruppa la revisione

Sezione intitolata “Coorti: ciò attorno a cui si raggruppa la revisione”

La passata di calcolo della revisione raggruppa i file modificati di una PR in coorti derivate dal grafo del codice: i file modificati mappano ai simboli che toccano, i simboli ai componenti connessi, e le coorti sono ordinate per raggio d’impatto. Una coorte porta con sé un ordine di lettura guidato, diagrammi e approfondimenti, invece di essere un semplice elenco di file.

Due regole di onestà ne determinano la forma. Le chiavi delle coorti derivano dal contenuto e sono stabili tra un push e l’altro, così i rilievi e l’avanzamento della revisione sopravvivono a un rebase o a un force-push invece di restare orfani. E quando il repo non ha un indice del codice, il raggruppamento ripiega sui percorsi semplici e lo dichiara: il fallback non finge mai una confidenza semantica.

Accanto ai rilievi dei revisori, una revisione accumula risultati degli assi: sei assi, di due tipi.

Asse Tipo Ricavato da
correctness, security Guidato dai token I rilievi dei revisori stessi
testGap Guidato dai token I rilievi dei revisori
visual, apiContract Deterministico Calcolato senza spendere token
performance Deterministico Solo enumerazione: nulla nel prodotto ne calcola un risultato

Il verdetto di un asse è pass, warn, fail, partial o unavailable — e solo pass o warn supera un gate. La distinzione tra fail, partial e unavailable è portante: un asse con gate che non ha potuto completarsi o non ha potuto essere eseguito affatto trattiene il verdetto complessivo anziché farlo passare. L’assenza di prove non si converte mai in un gate verde.

Alcuni assi sono consultivi di proposito. L’asse dei gap di test derivato dalle coorti non può vedere la copertura di dependency injection o delle factory: un repo non indicizzato con una suite approfondita e uno senza alcun test appaiono identici da lì, quindi affermare l’uno o l’altro sarebbe una bugia; compare nella dashboard senza fare da gate. Gli assi dei token sono consultivi perché le priorità dei rilievi guidano già il verdetto, e rifare il gate su di essi conterebbe due volte.

Il finalizzatore calcola il verdetto sui rilievi con stato open o consensus-ready:

  • qualunque rilievo P0 con confidenza ≥ 0.7 → Block
  • altrimenti, qualunque P0 (a bassa confidenza) o qualunque P1 → Hold
  • altrimenti → Ship

Il verdetto porta con sé una confidenza aggregata derivata dalla dispersione delle confidenze che vi contribuiscono: l’accordo la alza, la divergenza la abbassa.

Il consolidamento dell’agente lead (CEO) è una passata editoriale, non un secondo elenco: una seconda copia scritta a mano dei rilievi è esattamente ciò che diverge da quella reale. I rilievi duplicati vengono declassati anziché ripetuti: diversi revisori sono puntati sullo stesso diff con ambiti deliberatamente sovrapposti, quindi lo stesso difetto che raggiunge tre volte il finalizzatore è il sistema che funziona; pubblicarlo tre volte è il sistema che lascia filtrare la propria architettura nella posta in arrivo del lettore. A una nuova revisione, i rilievi vengono improntati e messi in diff rispetto al giro precedente, così a emergere è il delta.

Infine subentrano gli assi, e possono solo rendere il verdetto più severo: un asse con gate in stato di errore forza Block — non può essere messo in minoranza dai rilievi — e un asse con gate che non ha potuto completarsi forza almeno Hold.

La pipeline di proposito non pubblica su GitHub; la pubblicazione è soggetta al controllo dell’utente, così una revisione non può mai essere pubblicata due volte. Quando premi Pubblica su GitHub:

  • Viene inviata una sola revisione GitHub. I rilievi già risolti o scartati vengono saltati. Il pulsante pubblica ogni rilievo ancora aperto (selection: all_open). Lo strumento MCP publish_review_to_github usa ancora come impostazione predefinita solo i rilievi confermati dai pari (consensus).
  • I rilievi ancorati a un file e a una riga diventano commenti inline; tutto il resto si ripiega nel corpo del riepilogo, ciascuno con un piè di pagina “— Control Center AI review” perché la fonte sia inequivocabile.
  • Gli ancoraggi vengono riverificati rispetto al diff attuale della PR al momento della pubblicazione. Un commento su codice già riscritto è la cosa che distrugge di più la fiducia che un revisore possa lasciare; se GitHub rifiuta comunque un ancoraggio inline, l’intera revisione viene inviata di nuovo con ogni rilievo ripiegato nel corpo, così nulla viene perso in silenzio.
  • Un verdetto Block viene inviato come REQUEST_CHANGES; Hold come COMMENT; Ship come APPROVE dal pulsante (approve_on_ship: true). Lo strumento MCP lascia Ship come COMMENT a meno che tu non passi approve_on_ship.
  • La revisione viene pubblicata sotto l’identità dell’app del server. Chi ha premuto Pubblica viene registrato per il gate del ruolo e il registro di controllo; non è l’autore GitHub.

La pubblicazione dichiara la classe di azione prPublish, quindi il punto di strozzatura dei guardrail la sottopone a gate come qualsiasi azione di modifica: richiede conferma per impostazione predefinita e fallisce in modo restrittivo quando non è connesso alcun approvatore. Vedi Guardrail.

Gli agenti revisori vengono eseguiti in modalità review: un sandbox di sola lettura e un elenco curato di strumenti consentiti che copre rilievi, commenti, ticket e revisione tra pari, ma nessuna modifica. Un revisore non può correggere il codice che critica; può allegare una correzione suggerita che una persona applica. Il messaggio di rifiuto della modalità dice a un agente che tenta comunque di agire di finalizzare la revisione e di lasciare che l’utente agisca sul riepilogo pubblicato.