Udviklerne er glade, hastigheden er reel, og ingen i huset er imod det. Et sted mellem beslutningen om at tage det i brug og koden, der lander i produktion, er der tre spørgsmål, ingen har svaret på — ikke fordi nogen har undgået dem, men fordi det aldrig stod i nogens jobbeskrivelse at svare.

Lad os slå rammen fast først, for det her er let at læse forkert. Det er ikke et argument mod AI-kodeassistenter. Produktivitetsgevinsten er reel, udviklere, der bruger dem, er ikke skødesløse, og en virksomhed, der forbyder dem, mister folk til en, der ikke gør. Argumentet er smallere og kedeligere: en praksis gik fra forsøg til standard, uden at nogen skrev reglerne ned, og de tre beslutninger nedenfor er billige at tage nu og dyre at tage efter en hændelse.

De tre spørgsmål

Hvad kan agenten nå? Ikke hvad den bliver brugt til — hvad den teknisk er i stand til.

Hvilke data forlader huset? Hvilken kode, hvilke filer, og under hvilken aftale med udbyderen.

Hvem tjekker det, den producerer? Før det bliver merget, og før det bliver rullet ud.

Spørg tre personer i den samme virksomhed, og du får typisk tre forskellige svar på hvert af dem — og det er i sig selv fundet.

Spørgsmål ét: hvad kan agenten reelt nå?

Det er her, skiftet fra autofuldførelse til agent betyder noget, og det er let at overse, fordi ændringen kom gradvist. Et fuldførelsesværktøj foreslår tekst, og et menneske taster. En agent læser på tværs af hele repositoryet, beslutter, hvad der skal ændres, og redigerer filer — og kører, alt efter hvordan den er sat op, kommandoer, installerer pakker og åbner selv en pull request.

Har ingen besluttet andet, er rettighedsmodellen underforstået: agenten kan gøre det, udviklerens maskine kan gøre. Og det er værd at sige højt, for en udviklermaskine har typisk cloud-nøgler i miljøvariabler, en SSH-nøgle, en token til pakke-registryet, en .env-fil med rigtige værdier — og i mindre virksomheder adgang til produktion.

Intet af det er et argument for panik. Det er et argument for fire beslutninger, nogen bør tage:

  • Udføre eller foreslå? Må agenten køre shell-kommandoer uden opsyn, eller skal hver enkelt godkendes? Udførelse uden opsyn er den enkeltstående største udvidelse af, hvad en fejl kan koste.
  • Installere pakker eller spørge? En agent, der selv installerer sine afhængigheder, kan komme til at installere en pakke, der ikke fandtes, før en angriber registrerede det navn, den opfandt. Installationsscripts kører, før nogen læser noget.
  • Pushe eller åbne en pull request? At foreslå er næsten altid nok, og det bevarer det ene kontrolpunkt, der stadig involverer et menneske.
  • Hvis adgangsoplysninger? Kører agenten med en udviklers fulde personlige adgang, har hver fejl den persons rækkevidde. En separat, snævrere identitet koster en eftermiddag.

Det samme spørgsmål gælder i CI, hvor det er skarpere: en agent med en pipeline-token arbejder med de nøgler, der rækker ind i produktion — og uden et menneske i lokalet overhovedet.

Spørgsmål to: hvilke data forlader reelt huset?

Det ærlige udgangspunkt er, at de fleste, der bruger værktøjerne, ikke ved præcis, hvad der bliver sendt, og at svaret er forskelligt fra værktøj til værktøj og fra indstilling til indstilling.

Det er som regel mere end filen på skærmen. For at være nyttig har en assistent brug for kontekst: nabofiler, imports, typedefinitioner, undertiden et indeks over hele repositoryet. Agenter går videre, for de læser, hvad de vurderer er relevant.

Fire kategorier er værd at holde op mod dit eget repository, for det er dem, der giver et problem:

  • Persondata i testdata. Meget almindeligt, sjældent med vilje. Et produktionsudtræk blev engang brugt til at lave en realistisk test, og så blev det liggende. Forlader det huset til behandling, er det en behandling med dine kunders oplysninger i.
  • Nøgler i konfigurationen. En committet nøgle er allerede et problem i sig selv; at den bliver sendt til en tredjepart, er et problem oveni.
  • Kode, du ikke ejer. Arbejde udført under en kundekontrakt eller en fortrolighedsaftale kan have vilkår om, hvor det må behandles — og de vilkår blev skrevet, før nogen tænkte på det her.
  • Dét, der faktisk er din forretning. Prislogik, matchningsalgoritmer, modeller. Som regel helt fint — men det bør være en beslutning og ikke et tilfælde.

De aftalemæssige spørgsmål er korte og værd at få på skrift fra udbyderen: bliver vores input brugt til at træne modeller, hvor længe bliver det gemt, hvor bliver det behandlet, og findes der en databehandleraftale? Svarene kan være meget forskellige på forbrugerplanen og erhvervsplanen af det samme produkt — det er typisk her, træning på dit input, opbevaringstid og adgangen til en databehandleraftale skiller sig — og det er den detalje, der lettest bliver overset: et team kan sidde på den forkerte plan, uden at nogen har valgt det.

Er der persondata involveret overhovedet, holder det op med at være et værktøjsspørgsmål og bliver et databeskyttelsesspørgsmål, med de sædvanlige konsekvenser for, hvem der har ansvaret. Det er en samtale for den, der håndterer din GDPR-efterlevelse, ikke noget, der afgøres i en udviklerkanal.

Værd at sige lige ud: ingen scanner løser det spørgsmål. Det er en indkøbs- og en juridisk beslutning. Det, værktøjer kan, er at fortælle dig, om de af tingene ovenfor, der overhovedet kan tjekkes — først og fremmest committede nøgler — ligger i repositoryet. Det er et reelt nyttigt input til beslutningen, og ikke det samme som at tage den.

Spørgsmål tre: hvem tjekker det, der kommer ud?

Det er det spørgsmål, der i stilhed knækker, og mekanismen er et regnestykke og ikke forsømmelse — det samme regnestykke, der får det til at slå fejl at bede udviklere tjekke deres pakker grundigere, bare et trin længere nede.

AI-assistenter øger, hvor meget kode der bliver produceret. De øger ikke, hvor meget kode et menneske kan læse omhyggeligt igennem. Når antallet af pull requests stiger, og gennemgangskapaciteten ikke gør, holder gennemgangen ikke op — den bliver tyndere. Den samme person godkender flere ændringer, læser mindre af hver, og godkendelsen bliver ved med at betyde det samme på papiret.

Der er en anden effekt, der er værd at nævne, fordi den er ubehagelig: at gennemgå genereret kode er psykologisk noget andet end at gennemgå en kollegas. Den er flydende, velformateret og selvsikker, og der er ingen forfatter at spørge. Flydende sprog læses som kompetence. En, der ville have spurgt ind til en kollegas mærkelige import, kan lade den samme linje passere, når en maskine har skrevet den.

Hvad der konkret slipper igennem:

  • Afhængigheder, ingen har vurderet. Assistenten vælger et bibliotek, der passer til problemet, uden nogen holdning til, om det bliver vedligeholdt, hvem der kan udgive til det, eller om navnet ligger ét tegn fra det rigtige.
  • Nøgler i genererede eksempler. Assistenter udfylder pladsholderværdier, og pladsholdere har det med at blive til rigtige værdier under fejlsøgning.
  • Et fund "rettet" ved at fjerne tjekket. Bed en assistent få en fejlende sikkerhedstest til at bestå, og den gør det gerne — ved at slette kontrollen. Den gjorde, hvad du bad om, og det eneste, der opdager det, er et tjek, der ser på selve koden og ikke på, om testene blev grønne.
  • Slettet, ikke udskiftet. Bed den fjerne en committet nøgle, og den melder succes, så snart linjen er væk. Nøglen ligger stadig i historikken og virker stadig.
  • Workflow- og infrastrukturfiler. De læses som konfiguration og bliver gennemgået som konfiguration, mens de kører med flere rettigheder end applikationen.

Læg mærke til, hvad de har til fælles: ingen af dem kræver, at et menneske opdager dem først. Hver enkelt er en egenskab ved koden eller konfigurationen, som en maskine kan tjekke ved hver ændring. Det er argumentet for at automatisere netop det spørgsmål og ikke de to andre — ikke fordi en maskine gennemgår bedre end et menneske, men fordi det er den del, hvor en maskine gennemgår konsekvent, og konsekvens er præcis dét, en tyndere gennemgang mister først.

Én side er nok

Ingen har brug for et governance-program til det her. Det, der mangler, er en side, der siger, hvem der har besluttet hvad — så svaret findes, før nogen skal improvisere det:

  • Hvilke værktøjer er godkendt, og på hvilken plan. At nævne planen betyder mere end at nævne værktøjet.
  • Hvad agenten må uden opsyn — udføre, installere, pushe — og hvad der kræver et menneske.
  • Hvad der aldrig må ligge i et repository, en agent kan læse. Rigtige kundedata, aktive nøgler. Nøgle-delen af det kan tjekkes mekanisk, og det gør den til den del, der er værd at håndhæve og ikke bare skrive.
  • Hvad tjekket før merge er, og at den ikke afhænger af, at nogen husker det.
  • Hvem der ejer svaret, når der dukker et nyt værktøj op — for det gør der, næste kvartal.

Skrevet ned tager det en time. Grunden til, at det ikke sker, er, at det tilhører ingen: det er delvis sikkerhed, delvis jura, delvis udvikling — og fuldstændig den slags, der venter på en anledning. Anledningen er som regel en hændelse, et kundespørgeskema eller en købers due diligence, og de kommer alle sammen med en andens frist på.

Pointen

Udviklerne er ikke problemet her, og teknologien er det heller ikke. Det, der er sket, er helt almindeligt: en praksis blev normal hurtigere, end beslutningerne om den blev truffet, og sådan opstår de fleste huller i styringen.

To af de tre spørgsmål er beslutninger, nogen skal sætte sig ned og tage. Det tredje er et tjek, der kan køre af sig selv, hver gang, uden at afhænge af, hvor travlt den, der gennemgår koden, havde den uge — og det er dét, der er værd at automatisere først, for det er dét, der forfalder i stilhed.

Hvilken adgang bør en AI-kodeagent have?

En AI-kodeagent bør have mindre adgang end den udvikler, der kører den, og fire beslutninger er værd at tage udtrykkeligt: om den må køre shell-kommandoer uden opsyn, om den selv må installere pakker, om den må pushe eller kun åbne en pull request, og hvis adgangsoplysninger den kører med. Er ingen af dem taget, er loftet underforstået — agenten arver det, udviklerens maskine kan nå, og det omfatter typisk cloud-nøgler, en SSH-nøgle, en registry-token og undertiden adgang til produktion.

Hvilke data bliver sendt til en AI-kodeassistent?

En AI-kodeassistent sender som regel mere end filen på skærmen: for at et forslag skal være nyttigt, kræver det kontekst, så nabofiler, imports, typedefinitioner og undertiden et indeks over hele repositoryet kan følge med — hvor meget afhænger af værktøjet og af indstillingerne. Agenter går videre, for de læser, hvad de vurderer er relevant. De kategorier, der er værd at holde op mod dit eget repository, er persondata i testdata, nøgler i konfigurationen, kode omfattet af en kundekontrakt eller en fortrolighedsaftale, og den logik, der reelt udgør din forretning.

Er det et problem efter GDPR at bruge en AI-kodeassistent?

Det afhænger af, om der er persondata involveret, og i mange repositories er der. Testdata bygget på et produktionsudtræk er almindeligt og sjældent med vilje. Bliver persondata sendt til en udbyder, er det en behandling, og de spørgsmål, der skal afklares på skrift, er, om dit input træner deres modeller, hvor længe det bliver gemt, hvor det bliver behandlet, og om der findes en databehandleraftale. Svarene er markant forskellige mellem forbruger- og erhvervsplaner af det samme produkt. Det hører hjemme hos den, der håndterer din efterlevelse, og ikke i en udviklerkanal.

Bliver AI-genereret kode gennemgået ordentligt?

AI-genereret kode får som regel mindre opmærksomhed pr. linje end den kode, den erstattede, og mekanismen er et regnestykke og ikke forsømmelse. Assistenter øger, hvor meget kode der bliver produceret, uden at øge, hvor meget et menneske kan læse omhyggeligt, så gennemgangen bliver tyndere i stedet for at holde op. Genereret kode er samtidig flydende og selvsikker uden en forfatter at spørge, og flydende sprog læses som kompetence — en, der ville have spurgt ind til en kollegas mærkelige import, kan lade den samme linje passere, når en maskine har skrevet den.

Hvad slipper der reelt igennem, når AI skriver koden?

Fem ting går igen, når AI skriver koden: afhængigheder, ingen har vurderet for, om de bliver vedligeholdt eller overhovedet findes, nøgler efterladt i genereret eksempelkonfiguration, sikkerhedsfund "rettet" ved at slette kontrollen i stedet for hullet, committede nøgler meldt som fjernet, når kun linjen er slettet og nøglen stadig virker i historikken, og workflow-filer, der læses som konfiguration, men kører med flere rettigheder end applikationen. Alle fem er egenskaber, en maskine kan tjekke ved hver ændring, og derfor er det den del, der er værd at automatisere.

Hvor CodeControl passer ind — og hvor det ikke gør

CodeControl besvarer det tredje spørgsmål. Det forbinder sig til dit GitHub og tjekker det, der rent faktisk lander: hver afhængighed mod kendte sårbarheder, ondsindede og typosquattede pakker, pakker, der er for nye til at have en historie, committede nøgler i koden og i git-historikken, licensforpligtelser og de workflow-filer, der kører med adgang til produktion. Det kører inden for et minut efter hvert push, og hver pull request får et tjek af de nye linjer for hemmeligheder, før nogen merger — så tjekket ikke afhænger af, hvor meget tid den, der gennemgik koden, havde.

Det besvarer ikke de to første, og det er værd at være ærlig om. CodeControl har ingen holdning til, hvilke rettigheder din agent kører med, og slet ingen til, hvad din assistent sender videre til sin udbyder. Det er beslutninger for et menneske, ikke for en scanner. Det, det kan fortælle dig, er, om der ligger aktive nøgler i det repository, agenten læser — i koden og i historikken. Det er nyttigt at vide, før du tager beslutningerne.