Toen we naar onze eerste vijf runs in productie keken, waren ze allemaal mislukt. Geen enkele faalde omdat de AI slechte code schreef. Geen enkele kwam ver genoeg om de code ertoe te laten doen.
De lijst is weinig spectaculair: een repository waarvan de standaardbranch niet main heette, een token dat de repository niet kon klonen, een token zonder recht om een merge request te openen, en twee keer een run die eindigde met "Exit code 1" terwijl de log eronder duidelijk zei dat het AI-account geen tegoed meer had.
Dat weegt zwaarder dan het lijkt. Wie voor het eerst een AI-codingtool probeert, leest een mislukte run niet als "mijn token mist een scope". Die leest hem als "de AI werkt niet", en dat beeld bepaalt of iemand terugkomt.
Twee soorten fouten, allebei te voorkomen
Toen we de fouten sorteerden, zagen we twee groepen, en voor geen van beide was een beter model nodig.
- Te weten voordat de run in de wachtrij kwam. Geen repository gekoppeld, de verkeerde standaardbranch, credentials die niet kunnen pushen. Dat is allemaal in seconden te controleren. In plaats daarvan ontdekte een worker het minuten later, en meldde het in woorden die onze foutclassifier niet herkende.
- Bekend na de fout, maar niet getoond. De command-line tool van de agent meldt een leeg account als gewone tekst en stopt daarna met een fout. Wij lazen alleen het veld dat een fout benoemt, dus de uitleg viel weg en "Exit code 1" was alles wat iemand zag.
De tweede groep is een eigen verhaal, over providerfouten die lege resultaten worden. Dit stuk gaat over de eerste.
De remote vragen, niet de metadata
Een repositorykoppeling wordt nu gecontroleerd zoals de eerste run hem gebruikt: tegen de echte remote, met het echte token, in drie vragen.
- Kunnen we hem bereiken? Zo niet, dan zegt de melding waarom, in termen van de oplossing: de URL klopt niet, de repository is niet gevonden of het token heeft er geen toegang toe, de credential is geweigerd, of een organisatie vereist SSO-autorisatie voor het token.
- Bestaat de branch waarop we zouden draaien? Ontbreekt de opgeslagen branch, dan vertelt de controle welke standaardbranch de remote zelf opgeeft, met een knop om die te gebruiken. Een lege repository komt erdoor, want de eerste run maakt de eerste commit.
- Kan dit token pushen? Dit is de vraag die je niet uit de scopes van een token kunt aflezen. Branch protection, SSO-verplichtingen en deploy keys met alleen leesrechten leveren allemaal een token op dat er goed uitziet tot de push. Dus vragen we het aan git: een dry-run push die een branch verwijdert die niet bestaat. De remote doet zijn volledige rechtencontrole en daarna wordt er niets doorgevoerd. Er wordt nooit iets naar je repository geschreven.
De controle draait als je bij een repository op "Verbinding controleren" drukt, en opnieuw automatisch als je de standaardbranch wijzigt, omdat een verkeerd getypte branch anders pas opvalt als een mislukte run. Elke controle staat in de lijst, niet alleen de eerste fout: een token dat kan klonen maar niet pushen is waar mensen het meest van schrikken, en dat zou onzichtbaar zijn achter een groen "bereikbaar".
Een bug in hoe we de standaardbranch vonden
Tijdens het bouwen ontdekten we dat onze eigen detectie van de standaardbranch niet klopte. Die vroeg de branches van de remote op en nam de eerste regel. Die lijst is alfabetisch, niet met de standaardbranch bovenaan, dus een repository met een branch die bisect of develop heette, kreeg het verkeerde antwoord. De controle vraagt de remote nu rechtstreeks naar welke branch zijn HEAD wijst.
Een run weigeren die niet kan werken
Bij het starten van een run controleerden we al de limieten van het abonnement, de gelijktijdigheid en of de taak was goedgekeurd. Niet of het project überhaupt een repository had, dus kwam de run in de wachtrij en ging hij later onderuit met een algemene fout. Dat wordt nu meteen geweigerd, met de melding dat je eerst een repository moet koppelen. De regel die we eraan overhielden: als iets te weten is op het moment dat iemand op de knop drukt, zeg het dan meteen, en laat een worker er niet minuten later achter komen.
Wat de controle niet afdekt
- Pushen en een pull request openen zijn verschillende rechten. De controle bewijst dat het token kan pushen; niet dat het via de API van de provider een pull request of merge request mag openen.
- De volledige repositorycontrole draait niet vóór elke run. Bij het starten van een run kijken we alleen of er een repository gekoppeld is. Wordt een token volgende week ingetrokken, dan merk je dat aan de run, die nu zegt dat de repository de credentials weigerde en hoe je opnieuw koppelt.
- Elke git-aanroep krijgt 30 seconden, dus een heel trage remote kan de controle laten mislukken terwijl een run wel was gelukt.
Evalueer je een AI-codingtool, draai dan de verbindingscontrole voordat je het eerste resultaat beoordeelt. En mislukt de eerste run toch, lees dan eerst de reden en pas daarna de code. Een repository koppelen lees je bij GitHub, GitLab en Bitbucket, en hoe de onboarding eruitziet bij implementatie.