Tio tusen stjärnor och en commit

Den 14 juli offentliggjorde xAI källkoden till Grok Build under Apache 2.0, och i morse hade repositoryt över tio tusen stjärnor. Släppet följde på ett test på trådnivå som fann att version 0.2.93 av verktyget laddade upp ett spårat repository, och dess fullständiga git-historik som en bundle, till molnlagring som kontrolleras av xAI, inklusive ett repository som assistenten hade instruerats att inte läsa. Vi rapporterade om det fyndet den 14 juli, och uppmaningen då var att rotera varje hemlighet som verktyget någonsin sett. Den uppmaningen står fast.

Att publicera koden framstår som det starkaste tänkbara svaret på ett sådant fynd. Det är draget en teknikorganisation gör när den tror att handlingarna friar den, och det läses också så. Den användbara frågan är därför inte om xAI gjorde rätt i att publicera. Den är snävare och mer praktisk: om du nu gick till det repositoryt för att förvissa dig om vad verktyget gjorde på dina maskiner, vad skulle du faktiskt kunna fastställa?

Mycket lite, visar det sig, och skälen är strukturella snarare än illasinnade. Repositoryt bär en enda commit, skapad av en bot den 16 juli klockan 05:46 UTC, med meddelandet att den offentliggör harness och TUI som öppen källkod. En commit betyder ingen historik. Det finns inget före, ingen diff, ingen följd av ändringar, ingenting att jämföra med. Tio tusen stjärnor på ett repository utan historik är tio tusen personer som ställer sig bakom en gest.

Vad repositoryt inte kan berätta

Börja med den enda fråga som fyndet faktiskt väckte: vart tog koden vägen? Uppladdningarna gick till en bucket i Google Cloud Storage som namnges i den levererade binären. I den publicerade källkoden förekommer inte det namnet. Det läses från en miljövariabel vid kompileringen, som slås fast när binären byggs. Den som kompilerar släppet anger destinationen, och källkoden säger ingenting om vad den levererade builden pekades mot. Den publicerade koden kan inte svara på frågan, åt något håll.

Titta sedan på funktionen som skötte uppladdningen. Den finns fortfarande där, i shell-craten, och den gör ingenting längre. Den tar emot sina parametrar, markerar dem som oanvända, väntar på kanalen, kastar bort resultatet och returnerar ett fel som noterar att uppladdning av sessionstillstånd inte är tillgänglig. Kroppen har tagits bort medan omgivningen är kvar: anropsställena är intakta, manifestet listar fortfarande beroendena, lagringshjälpfunktionerna kompileras fortfarande in. Det du kan läsa är mekanismens skelett med mekanismen borttagen.

Detta är också andra gången rättningen har gjorts någonstans där du inte kan granska den. De ursprungliga uppladdningarna stoppades den 13 juli med en flagga på serversidan, inte med ett klientsläpp, vilket var det skarpaste i den första historien: den binär som ditt team granskade och låste fast var aldrig det som avgjorde vad som lämnade maskinen. Nu är koden offentlig och destinationen är fortfarande en indata vid bygget och strömbrytaren sitter fortfarande på servern. Den yta som går att granska och den yta som avgör har inte förts närmare varandra.

Fyra filer flyttade, en kom inte fram

Det finns ytterligare en detalj, och den måste formuleras försiktigt eftersom den är lätt att övertolka. Strängarna inne i den levererade binären 0.2.93 namnger en crate som heter xai-data-collector, med fem källfiler: lagringsklienten, molnlagringslagret, kön, en observatör för circuit breaker och en spårare för filåtkomst. Det publicerade repositoryt innehåller ingen crate med det namnet. Samma uppsättning filer ligger i en crate som heter xai-file-utils, och fyra av de fem motsvarar varandra. Den femte, spåraren för filåtkomst, finns inte alls i den publicerade källkoden.

Vad det fastställer och inte fastställer är hela poängen. Det fastställer ingen avsikt. Att byta namn på en crate från något som beskriver insamling av data till något som beskriver hantering av filer är precis vad ett team gör under en uppstädning inför ett släpp, och att ta bort en modul som inte längre är kopplad till någonting är vanligt underhåll. Det finns inga belägg för något döljande här, och vi påstår inte att något sådant har förekommit. Det är också värt att notera asymmetrin i själva bevisningen: binärsidan vilar på en tredje parts strängextraktion, medan källkodssidan kan verifieras av vem som helst som klonar repositoryt.

Vad det däremot fastställer är att släppet inte kan fungera som dokumentation. Den komponent vars namn mest direkt beskriver spårning av en användares filåtkomst saknas, dess syskon finns under ett annat namn, och det finns ingen commit-historik där något av dessa förhållanden kan undersökas. Oskyldiga förklaringar och skyldiga ger ett identiskt repository. Det är problemet med att behandla en publicering som ett bevis: det fungerar bara om artefakten kan skilja de två åt, och den här kan inte det.

Påståendet som aldrig gjordes

Ge forskaren erkännande, för disciplinen på den sidan av den här historien är skälet till att den håller. Analysen på trådnivå gjordes med en avlyssnande proxy mot en fastlåst binär, på ett engångsrepository försett med canary-filer, och den är reproducerbar: det finns en offentlig harness, och vem som helst kan köra den. Mätningen var slående. Ett repository på tolv gigabyte gav 5,10 gibibyte uppladdningstrafik mot 192 kilobyte faktisk modellkonversation, ett förhållande nära tjugoåttatusen mot ett. Canary-filen som assistenten hade fått veta att den inte skulle läsa kom ut ur den infångade bundlen intakt.

Och sedan skrev forskaren ner vad testet inte bevisade. Att uppladdning inte är träning, eftersom bara överföringen mättes. Att en infångning vid tre gigabyte inte bevarades. Att en tidigare slutsats hade varit fel, eftersom en processavgränsad nätverksavläsning missade uppladdningar som gick direkt till Googles adresser, och den slutsatsen drogs tillbaka. Ett fynd som publicerar sina egna gränser och sin egen tillbakadragning är ett fynd du kan använda.

Ställ det mot svaren. xAI har sagt att man bryr sig djupt om integritet, respekterar kundens val, och att det för team som använder zero data retention aldrig sparas några spår- eller koddata. Elon Musk sade att alla användardata som laddats upp fram till nu kommer att raderas fullständigt och totalt, och att absolut ingenting kommer att finnas kvar. Det kan mycket väl stämma. Inget av det går att kontrollera, och raderingen går inte att verifiera utifrån. Mönstret genom hela den här episoden är konsekvent: påståendena som går att testa kom från personen med proxyn, och påståendena som inte går att testa kom från leverantören.

Tre frågor innan du kallar det åtgärdat

Den generaliserbara lärdomen har ingenting med xAI att göra, och den kommer att behövas igen inom månaden. Att öppna källkoden har blivit ett standardsvar på ett säkerhetsfynd, och det är ett bra svar när artefakten bär bevis. Det gör den inte automatiskt. Så när en leverantör svarar på ett fynd om dina data genom att publicera kod, ställ tre frågor till den innan ärendet stängs.

Kan jag se historiken? En squashad första commit är ett fotografi, inte en redogörelse. Om repositoryt börjar samma dag som det publiceras kan det inte visa vad som ändrades, och det som utreds är just en ändring. Motsvarar den publicerade artefakten den levererade binären? Om något beteende som spelar roll sätts vid bygget eller hålls på en server är källkoden en beskrivning av en möjlighet, inte av det som körde på dina maskiner. Innehåller koden den komponent som fyndet pekade ut? Om det specifika som hittades inte finns i repositoryt är dess frånvaro inget svar, oavsett vad som orsakade den.

Inget av detta är ett argument för att hålla kod stängd, och inget av det är en anklagelse. Det är ett argument för en åtskillnad som din inköpsprocess förmodligen inte gör ännu: publicering är en handling av öppenhet, och en granskning är en process som leder fram till en slutsats. De är inte utbytbara, de är inte ens nära släkt, och en leverantör som har gjort det första har inte gjort det andra. De team som behandlar en länk till ett repository som avslutat ärende gör ett kategorifel, och det är den sorts fel som bara syns i efterhand, efter nästa fynd.