Hoppa till innehåll

AI-granskning

En AI-granskning är en körning av den medföljande pr_review-pipelinen mot en öppen pull request. Pipelinen öppnar PR:ens granskningsyta, skickar ut granskaragenter för att läsa diffen i ytans isolerade utcheckning, var och en registrerar sina fynd som strukturerade granskningsnoder, en huvudagent sammanställer dem till en genomgång, och en finaliserare räknar fram ett utfall: Ship, Hold eller Block. Det pipelinen aldrig gör är att publicera – att lägga upp på GitHub är ett separat, medvetet steg som en människa tar.

Resten av den här sidan förklarar delarna och varför de är utformade så här.

En PR:s granskningskontext är en meddelandeyta – läge review, typ pr – kopplad till pull requesten via en granskningsytekoppling. Den skapas idempotent: PR-sidan, granskningspipelinen och chattvyerna löser alla ut PR:ens enda bakomliggande yta genom samma kodväg, så en mall som granskar en PR och en människa som öppnar den kan aldrig hamna i två olika rum som tittar på två olika utcheckningar.

Ytans isolerade worktree har PR:en utcheckad på sin head-ref. Ett rum betyder också en utcheckning: varje granskare arbetar i samma yta i stället för att var och en får sin egen klon av arbetsytan.

Varje granskare postar i sin egen namngivna ström inuti den enda ytan, och fynd är review_node-meddelanden i stället för vanlig prosa. Insamlingen över hela ytan i slutet är avsiktlig – ett utfall som räknats fram från en enda tråds fynd skulle tyst bli ett utfall om en enda granskare.

Kopplingen har en statusstege – requested → in progress → awaiting approval → completed – och det är den som utgör grinden för Publicera till GitHub på PR:ens flik Granskning.

Hur djupt en granskning går är en arbetsytepolicy med tre nivåer, som ställs in under Inställningar → Arbetsyta → Allmänt, på kortet Arbetsytepolicy:

Nivå Granskare som skickas ut Rapportering
light Endast ingenjör Bara det som är väsentligt
balanced Ingenjör, QA, arkitekt (standard) Den ordinarie genomgången
thorough Alla fem, inklusive säkerhet och prestanda Inget nedgraderas

Nivån vrider två rattar samtidigt: vilka granskare som skickas ut, vilket framtvingas av pipelinemallens runWhen-tillståndsgrindar i stället för av formuleringar i prompten – promptformuleringar kan ignoreras, en grind kan inte – och var fynd under tröskeln visas. Ingen av rattarna tar någonsin bort ett fynd: en nivå som rapporterar mindre registrerar fortfarande exakt lika mycket och grupperar resten.

Säkerhets- och prestandagenomgångarna återanvänder de medföljande arkitekt- och ingenjörsagenterna i stället för att införa nya. Specialiseringen ligger i den uppdragsbeskrivning som granskaren skickas ut med, inte i en separat agent per axel – en agent per axel skulle bli fem rader till i varje arbetsyta utan någon ytterligare förmåga. Urvalet av granskare tittar aldrig på diffen efter språk eller domän.

Ett fynd som registreras med add_review_node blir en granskningsnod på PR:en – det är vad fliken Granskning visar, vad utfallet räknas fram från, och vad “Publicera till GitHub” gör om till en inline-kommentar. En granskare som bara returnerar prosa ger en pipelinekörning som ser lyckad ut och en granskningsvy som är tom; registreringen är den bärande delen.

Varje nod innehåller:

Fält Värden
Typ bug, suggestion, recommendation, question, ticket
Prioritet P0 (kritisk) → P3 (petitess)
Triage-trippel kategori (security, stability, …), allvarlighetsgrad, insats
Ankare Filsökväg, radens början och slut
Åtgärdsförslag Föreslagna ersättningsrader, en valfri diff, en valfri fix-prompt
Konfidens En poäng i [0, 1]
Resonemang Analysen, skriven före fyndet

Två detaljer är avsiktliga. Ett GitHub-förslag med ett klick erbjuds bara när granskaren har angett exakta ersättningsrader – att härleda dem ur en unified diff går fel i tysthet, och en ettklicks-commit av en felaktig härledning är värre än ingen knapp alls. Och schemat för add_review_node visar reasoning före fyndet, så en modell som fyller i objektet i schemats ordning skriver analysen först. Fältet är valfritt: att utelämna det avvisar inte noden. En nod med felaktig payload försvinner i stället för att förorena granskningen.

En nod rör sig genom open → consensus-ready → resolved eller dismissed. Mellansteger är modellens kärna: ett fynd godkänns bara när en kollegagranskare bekräftar det, och en agent kan aldrig bekräfta sitt eget fynd. MCP-verktyget publish_review_to_github och RPC-standardvärdet publicerar fortfarande bara kollegabekräftade fynd. Knappen Publicera till GitHub på fliken Granskning skickar i stället samtliga återstående öppna fynd.

Regeln framtvingas på tre oberoende ställen – bekräftelseverktyget, finaliseraren och publiceraren – så den överlever en buggig anropare i vilket som helst av dem. Alla statusändringar går genom en enda tjänst, och det är vad som gör en status betydelsefull: innan dess kunde två halvvägar vara oense om samma fynd var åtgärdat.

När granskare är oense – samma fil och rad, prioriteringar två eller fler nivåer isär, eller att en kallar det en bug medan den andra kallar det en suggestion – lyfts oenigheten fram ovanför fyndlistan. Det är där granskarnas åsikter går isär och en människas omdöme är värt som mest.

Att avvisa ett fynd skriver också ett mjukt undertryckningsfaktum till minnesdomänen, med låg konfidens – en avvisning är en preferens, inte en regel.

Granskningsberäkningen grupperar en PR:s ändrade filer i kohorter som härleds ur kodgrafen: ändrade filer mappas till de symboler de berör, symboler till sammankopplade komponenter, och kohorterna rangordnas efter spridningsradie. En kohort bär en guidad läsordning, diagram och insikter i stället för att vara en platt fillista.

Två ärlighetsregler formar detta. Kohortnycklar härleds ur innehållet och är stabila mellan pushar, så fynd och granskningsframsteg överlever en rebase eller force-push i stället för att bli föräldralösa. Och när repot inte har något kodindex faller grupperingen tillbaka på vanliga sökvägar och säger det – reservvägen låtsas aldrig om semantisk konfidens.

Vid sidan av granskarnas fynd samlar en granskning axelresultat: sex axlar av två slag.

Axel Typ Hämtas från
correctness, security Tokendrivna Granskarnas egna fynd
testGap Tokendrivna Granskarnas fynd
visual, apiContract Deterministiska Beräknas utan att förbruka tokens
performance Deterministiska Endast enum – inget i produkten beräknar ett resultat

Ett axelutfall är pass, warn, fail, partial eller unavailable – och bara pass eller warn passerar en grind. Åtskillnaden mellan fail, partial och unavailable är bärande: en grindad axel som inte kunde slutföras eller inte kunde köras alls håller kvar det samlade utfallet i stället för att passera det. Frånvaro av bevis blir aldrig en grön grind.

Vissa axlar är rådgivande med avsikt. Testgapsaxeln som härleds ur kohorter kan inte se beroendeinjektions- eller fabrikstäckning – ett oindexerat repo med en utförlig testsvit och ett helt utan tester ser identiska ut därifrån, så att påstå något av dem vore en lögn; den visas i instrumentpanelen utan att utgöra en grind. Tokenaxlarna är rådgivande eftersom fyndens prioriteringar redan driver utfallet, och att grinda på dem igen skulle dubbelräkna.

Finaliseraren beräknar utfallet utifrån fynden med status open eller consensus-ready:

  • vilket som helst P0-fynd med konfidens ≥ 0.7 → Block
  • annars, vilket som helst P0 (låg konfidens) eller vilket som helst P1 → Hold
  • annars → Ship

Utfallet bär en sammanvägd konfidens som härleds ur spridningen av de bidragande konfidensvärdena – enighet höjer den, olikhet sänker den.

Huvudagentens (CEO) sammanställning är en redaktionell genomgång, inte en ny uppräkning: en handskriven andra kopia av fynden är precis det som glider ifrån den riktiga. Dubblerade fynd nedgraderas i stället för att upprepas – flera granskare riktas mot en och samma diff med avsiktligt överlappande uppdrag, så att samma defekt når finaliseraren tre gånger är systemet som fungerar; att publicera den tre gånger är systemet som läcker sin egen arkitektur in i läsarens inkorg. Vid en ny granskning får fynden fingeravtryck och diffas mot föregående runda, så det är deltat som lyfts fram.

Slutligen vävs axlarna in, och de kan bara göra utfallet mer allvarligt: en grindad axel som fallerar tvingar fram Block – den kan inte överröstas av fynd – och en grindad axel som inte kunde slutföras tvingar fram minst Hold.

Pipelinen lägger med avsikt inte upp något på GitHub; publiceringen är grindad av användaren så att en granskning aldrig kan publiceras dubbelt. När du trycker på Publicera till GitHub:

  • En GitHub-granskning skickas in. Fynd som redan är åtgärdade eller avvisade hoppas över. Knappen publicerar varje återstående öppet fynd (selection: all_open). MCP-verktyget publish_review_to_github använder fortfarande som standard bara kollegabekräftade fynd (consensus).
  • Fynd som är ankrade till en fil och rad blir inline-kommentarer; allt annat vävs in i sammanfattningstexten, och var och en bär en “— Control Center AI review”-fotnot så att källan är entydig.
  • Ankarna verifieras på nytt mot PR:ens aktuella diff vid publiceringstillfället. En kommentar på kod som redan har skrivits om är det mest förtroenderaserande en granskare kan lämna efter sig; om GitHub ändå avvisar ett inline-ankare skickas hela granskningen om med varje fynd invävt i texten så att inget tyst tappas bort.
  • Ett Block-utfall skickas in som REQUEST_CHANGES; Hold som COMMENT; Ship som APPROVE från knappen (approve_on_ship: true). MCP-verktyget lämnar Ship som COMMENT om du inte skickar med approve_on_ship.
  • Granskningen publiceras under serverns appidentitet. Den som tryckte på Publicera registreras för rollgrinden och revisionsloggen; det är inte GitHub-författaren.

Publicering deklarerar åtgärdsklassen prPublish, så räckesflaskhalsen grindar den precis som vilken muterande åtgärd som helst – den frågar som standard och faller stängt när ingen godkännare är ansluten. Se Räcken.

Granskaragenter körs i läget review: en skrivskyddad sandlåda och en kurerad tillåtelselista för verktyg som täcker fynd, kommentarer, ärenden och kollegagranskning – men inga mutationer. En granskare kan inte åtgärda koden den kritiserar; den kan bifoga ett åtgärdsförslag som en människa tillämpar. Lägets avvisningsmeddelande säger till en agent som ändå försöker agera att slutföra granskningen och låta användaren agera utifrån den publicerade sammanfattningen.