Ga naar inhoud

AI-review

Een AI-review is één uitvoering van de meegeleverde pr_review-pipeline op één open pull request. De pipeline opent de reviewruimte van de PR, waaiert reviewer-agenten uit om de diff te lezen in de geïsoleerde checkout van die ruimte, elk legt zijn bevindingen vast als gestructureerde reviewnodes, een lead-agent bundelt ze tot een rondleiding, en een finalisatiestap berekent één oordeel: Ship, Hold of Block. Wat de pipeline nooit doet, is publiceren — posten naar GitHub is een aparte, bewuste stap die een mens zet.

De rest van deze pagina legt de onderdelen uit en waarom ze zo zijn vormgegeven.

De reviewcontext van een PR is een berichtenruimte — modus review, soort pr — die via een koppeling van de reviewruimte aan de pull request hangt. Die wordt idempotent aangemaakt: de PR-pagina, de review-pipeline en de chat-oppervlakken vinden allemaal via hetzelfde codepad de ene onderliggende ruimte van de PR, zodat een sjabloon dat een PR reviewt en een mens die hem opent nooit in twee verschillende ruimtes naar twee verschillende checkouts kunnen kijken.

De geïsoleerde worktree van de ruimte heeft de PR uitgecheckt op zijn head-ref. Eén ruimte betekent ook één checkout: elke reviewer werkt in dezelfde ruimte in plaats van dat ieder zijn eigen kloon van de werkruimte krijgt.

Elke reviewer post in zijn eigen benoemde stream binnen die ene ruimte, en bevindingen zijn review_node-berichten in plaats van vrije tekst. Het verzamelen over de hele ruimte aan het eind is bewust — een oordeel dat uit de bevindingen van één thread wordt berekend, zou stil een oordeel over één reviewer zijn.

De koppeling heeft een statusladder — requested → in progress → awaiting approval → completed — en die bepaalt of Publiceren naar GitHub op het tabblad Review van de PR beschikbaar is.

Hoe diep een review gaat, is werkruimtebeleid met drie niveaus, ingesteld via Instellingen → Werkruimte → Algemeen, op de kaart Werkruimtebeleid:

Niveau Reviewers die uitwaaieren Rapportage
light Alleen engineer Alleen wat materieel van belang is
balanced Engineer, QA, architect (de standaard) De vaste ronde
thorough Alle vijf, inclusief beveiliging en performance Niets gedegradeerd

Het niveau draait aan twee knoppen tegelijk: welke reviewers uitwaaieren, afgedwongen door de runWhen-statuspoorten van het pipelinesjabloon in plaats van door de formulering van de prompt — de formulering van een prompt kun je negeren, een poort niet — en waar bevindingen onder de drempel worden getoond. Geen van beide knoppen verwijdert ooit een bevinding: een niveau dat minder meldt, legt nog steeds precies evenveel vast en groepeert de rest.

De beveiligings- en performanceronde hergebruiken de meegeleverde architect- en engineeragenten in plaats van nieuwe te introduceren. De specialisatie zit in de briefing waarmee de reviewer wordt gestuurd, niet in een aparte agent per as — een agent per as zou vijf extra rijen in elke werkruimte opleveren zonder extra mogelijkheden. De selectie van reviewers kijkt nooit naar de taal of het domein in de diff.

Reviewnodes: bevindingen als data, niet als proza

Sectie getiteld “Reviewnodes: bevindingen als data, niet als proza”

Een bevinding die met add_review_node wordt vastgelegd, wordt een reviewnode op de PR — dat is wat het tabblad Review toont, waar het oordeel uit wordt berekend, en wat “Publiceren naar GitHub” omzet in een inline reactie. Een reviewer die alleen vrije tekst teruggeeft, levert een pipeline-run op die geslaagd lijkt en een review-oppervlak dat leeg is; het vastleggen is het onderdeel dat alles draagt.

Elke node bevat:

Veld Waarden
Soort bug, suggestion, recommendation, question, ticket
Prioriteit P0 (kritiek) → P3 (nit)
Triagedrietal categorie (security, stability, …), ernst, inspanning
Anker Bestandspad, begin- en eindregel
Meegestuurde fix Voorgestelde vervangende regels, een optionele diff, een optionele fixprompt
Betrouwbaarheid Een score in [0, 1]
Redenering De analyse, geschreven vóór de bevinding

Twee details zijn bewust. Een GitHub-suggestie met één klik wordt alleen aangeboden als de reviewer exacte vervangende regels heeft aangeleverd — die uit een unified diff afleiden gaat stilletjes mis, en een verkeerde afleiding met één klik committen is erger dan helemaal geen knop. En het schema van add_review_node zet reasoning vóór de bevinding, zodat een model dat het object in schemavolgorde invult, eerst de analyse schrijft. Het veld is optioneel: het weglaten ervan verwerpt de node niet. Een node met een misvormde payload verdwijnt in plaats van de review te vervuilen.

Een node doorloopt open → consensus-ready → resolved of dismissed. De middelste stap is het hart van het model: een bevinding gaat pas verder als een peer-reviewer hem bevestigt, en een agent kan zijn eigen bevinding nooit bevestigen. De MCP-tool publish_review_to_github en de RPC-standaard publiceren nog steeds alleen door peers bevestigde bevindingen. De knop Publiceren naar GitHub op het tabblad Review verstuurt juist elke resterende open bevinding.

De regel wordt op drie onafhankelijke plekken afgedwongen — de bevestigingstool, de finalisatiestap en de publicatiestap — zodat hij een foutieve aanroeper in een van die drie overleeft. Alle statuswijzigingen lopen via één service, en dat is wat een status betekenis geeft: daarvoor konden twee halve paden het oneens zijn over of dezelfde bevinding was opgelost.

Als reviewers het oneens zijn — hetzelfde bestand en dezelfde regel, prioriteiten twee of meer niveaus uit elkaar, of de een noemt het een bug terwijl de ander het een suggestion noemt — wordt het meningsverschil boven de bevindingenlijst getoond. Daar lopen de meningen van de reviewers uiteen en is het oordeel van een mens het meest waard.

Het verwerpen van een bevinding schrijft ook een zacht onderdrukkingsfeit weg in het geheugendomein, met lage betrouwbaarheid — één verwerping is een voorkeur, geen regel.

Cohorten: waar de review omheen is gegroepeerd

Sectie getiteld “Cohorten: waar de review omheen is gegroepeerd”

De review-compute-ronde groepeert de gewijzigde bestanden van een PR in cohorten die uit de codegraaf zijn afgeleid: gewijzigde bestanden verwijzen naar de symbolen die ze aanraken, symbolen naar verbonden componenten, en de cohorten worden gerangschikt op blast radius. Een cohort heeft een begeleide leesvolgorde, diagrammen en inzichten in plaats van een platte bestandslijst.

Twee eerlijkheidsregels bepalen dit. Cohortsleutels zijn van de inhoud afgeleid en stabiel over pushes heen, zodat bevindingen en reviewvoortgang een rebase of force-push overleven in plaats van verweesd te raken. En als de repo geen code-index heeft, valt de groepering terug op gewone paden en zegt dat ook — de terugvaloptie doet nooit alsof er semantische zekerheid is.

Naast de bevindingen van de reviewers verzamelt een review asresultaten: zes assen, van twee soorten.

As Soort Bron
correctness, security Token-gedreven De bevindingen van de reviewers zelf
testGap Token-gedreven De bevindingen van de reviewers
visual, apiContract Deterministisch Berekend zonder tokens te verbruiken
performance Deterministisch Alleen enum — niets in het product berekent een resultaat

Het oordeel van een as is pass, warn, fail, partial of unavailable — en alleen pass of warn passeert een poort. Het onderscheid tussen fail, partial en unavailable is essentieel: een as met een poort die niet kon afronden of helemaal niet kon draaien, houdt het totale oordeel tegen in plaats van het te laten passeren. Afwezigheid van bewijs wordt nooit een groene poort.

Sommige assen zijn bewust adviserend. De test-gap-as die uit cohorten is afgeleid, kan dependency-injection- of factory-dekking niet zien — een niet-geïndexeerde repo met een grondige testsuite en een repo zonder enige test zien er van daaruit identiek uit, dus het een of het ander beweren zou een leugen zijn; de as verschijnt in het dashboard zonder een poort te zijn. De token-assen zijn adviserend omdat de prioriteiten van de bevindingen het oordeel al sturen, en er opnieuw een poort van maken zou dubbel tellen.

De finalisatiestap berekent het oordeel over de bevindingen met status open of consensus-ready:

  • elke P0-bevinding met betrouwbaarheid ≥ 0,7 → Block
  • anders, elke P0 (met lage betrouwbaarheid) of elke P1 → Hold
  • anders → Ship

Het oordeel draagt een samengestelde betrouwbaarheid die is afgeleid van de spreiding van de betrokken betrouwbaarheden — overeenstemming verhoogt die, verdeeldheid verlaagt die.

Het bundelen door de lead-agent (CEO) is een redactionele ronde, geen tweede opsomming: een met de hand geschreven tweede kopie van de bevindingen is precies wat van het echte overzicht af gaat wijken. Dubbele bevindingen worden gedegradeerd in plaats van herhaald — meerdere reviewers worden met bewust overlappende opdrachten op één diff gezet, dus hetzelfde defect dat drie keer bij de finalisatiestap aankomt, betekent dat het systeem werkt; het drie keer publiceren betekent dat het systeem zijn eigen architectuur in de inbox van de lezer laat lekken. Bij een nieuwe review krijgen bevindingen een vingerafdruk en worden ze met de vorige ronde vergeleken, zodat het verschil naar boven komt.

Ten slotte wegen de assen mee, en die kunnen het oordeel alleen strenger maken: een gefaalde as met een poort dwingt Block af — bevindingen kunnen daar niet tegenop stemmen — en een as met een poort die niet kon afronden, dwingt minstens Hold af.

De pipeline post bewust niet naar GitHub; publiceren blijft aan de gebruiker, zodat een review nooit dubbel kan publiceren. Wanneer je op Publiceren naar GitHub drukt:

  • Er wordt één GitHub-review ingediend. Bevindingen die al zijn opgelost of verworpen, worden overgeslagen. De knop publiceert elke resterende open bevinding (selection: all_open). De MCP-tool publish_review_to_github gebruikt standaard nog steeds alleen door peers bevestigde bevindingen (consensus).
  • Bevindingen met een anker naar een bestand en regel worden inline reacties; al het overige komt in de samenvattingstekst terecht, elk met een voettekst “— Control Center AI review”, zodat de bron ondubbelzinnig is.
  • Ankers worden op het moment van publiceren opnieuw geverifieerd tegen de huidige diff van de PR. Een reactie op code die al is herschreven, is het meest vertrouwenvernietigende dat een reviewer kan achterlaten; als GitHub een inline anker toch weigert, wordt de hele review opnieuw verstuurd met elke bevinding in de tekst opgenomen, zodat niets stilzwijgend verdwijnt.
  • Een Block-oordeel wordt ingediend als REQUEST_CHANGES; Hold als COMMENT; Ship als APPROVE vanaf de knop (approve_on_ship: true). De MCP-tool laat Ship als COMMENT tenzij je approve_on_ship meegeeft.
  • De review wordt geplaatst onder de app-identiteit van de server. Wie op Publiceren heeft gedrukt, wordt vastgelegd voor de rolpoort en het auditlogboek; diegene is niet de GitHub-auteur.

Publiceren declareert de actieklasse prPublish, dus het controlepunt van de beveiligingen houdt het net als elke muterende actie tegen — het vraagt standaard om goedkeuring en faalt gesloten wanneer er geen goedkeurder is verbonden. Zie Beveiligingen.

Reviewer-agenten draaien in de modus review: een alleen-lezen sandbox en een zorgvuldig samengestelde allowlist van tools voor bevindingen, commentaar, tickets en peerreview — maar geen mutaties. Een reviewer kan de code die hij bekritiseert niet repareren; hij kan wel een voorgestelde oplossing meesturen die een mens toepast. Het weigeringsbericht van de modus zegt tegen een agent die het toch probeert, dat hij de review moet afronden en de gebruiker op de gepubliceerde samenvatting moet laten reageren.