Koden är den lilla delen
Den här veckan skrev jag en checklista. Den skulle beskriva allt som måste finnas på plats när vi sätter upp en ny produkt, från namnet till larmet som går när den slutar svara. Jag skrev den medan jag faktiskt satte upp en, så att varje rad skulle vara något jag hade gjort och inte något jag trodde.
Den slutade på drygt femtio punkter. Koden var tre av dem.
Vänstersidan
En app som AI byggt åt dig på en eftermiddag har en användare. Det är du. Den körs på localhost. Nyckeln till AI-tjänsten ligger i en fil i projektmappen. Databasen är en fil bredvid den. Appen är uppe så länge locket på datorn är öppet. Och om något går sönder ser du det i terminalen i samma sekund.
Allt det där är sant och det är inget fel på det. Det är fortfarande det snabbaste sättet att ta reda på om en idé håller. Det är bara inte en produkt.
Högersidan

När samma app ska användas av någon annan än du dyker allt det upp som datorn gjorde åt dig utan att du märkte det.
Någon ska äga den. Inte en person, ett bolag. Domänen, butikskontona, betalningarna och mejlen följer ägaren. Och ett namn som verkar ledigt behöver kollas mot varumärkesregistret och båda appbutikerna innan något köps.
Den ska ha en adress. Domänen ska peka rätt, certifikatet ska utfärdas och förnyas och alla varianter av adressen ska leda till en och samma. En av våra domäner fick inget certifikat för att de publika namnservrarna fortfarande mindes registrarens parkeringssida. Den svarade på kontrollen i stället för oss.
Den ska kunna skicka mejl som inte hamnar i skräpposten. Det betyder SPF, DKIM, DMARC och en avsändare som ser ut som den säger att den är. Och domänens mejl kan bara peka på ett ställe, så någon måste bestämma om appen tar emot mejl eller bara skickar.
Den ska ha en riktig pipeline. Koden ska ligga någon annanstans än på servern den körs på. Vi gick igenom våra egna tjänster förra veckan och hittade fem kodbaser som bara fanns på sin server. Försvinner servern försvinner koden.
Den ska ha konton i appbutikerna, under rätt bolag, med integritetsformulär ifyllda utifrån vad koden faktiskt sparar. Den ska ha inloggning som inte släpper in någon på en testväg. Den ska ha en integritetspolicy skriven ur databasschemat, inte ur en mall.
Datahanteringen
Det här är klustret som flest hoppar över. Där finns det mest som inte syns förrän det går fel.
Vilka personuppgifter sparas, var och hur länge. Vilka underleverantörer som rör dem och om det finns avtal med var och en. Om datan stannar i EU eller om en AI-tjänst i USA tar över när den svenska inte svarar. Hur en användare får sitt konto raderat, på riktigt. Var nycklarna ligger och vem som kan byta dem.
En detalj från en av våra egna tjänster: proxyn framför den lägger varje besökt sökväg i en publik sitemap, för att hjälpa sökmotorerna. Någon lade en nyckel i en länk. Den hamnade i sitemapen. Ingen hade gjort fel i sin egen del. Felet uppstod mellan delarna. Det är där datahanteringen bor.
Bara ett exemplar
Lokalt finns en maskin. Stängs den av märker bara du det.
I produktion går varje förfrågan genom en kedja av maskiner och tjänster. Varje länk har sin egen ström, sin egen disk och sitt eget certifikat. Några av länkarna finns i ett enda exemplar. Proxyn som alla våra produkter går igenom är en. Databasvärden är en. En AI-tjänst som flera produkter anropar står på en dator hemma.
Det är inte nödvändigtvis fel. Det är bara frågor som måste ha ett svar som fungerar när jag sover. Vad händer när servern startar om. När disken blir full. När certifikatet går ut. När en leverantör stänger kontot. När maskinen hemma är avstängd. Lokalt är svaret alltid att jag startar om den. I produktion måste svaret fungera utan mig.
Min egen produkt
Sedan gjorde jag det obekväma. Jag körde checklistan mot en av mina egna produkter. En som har riktiga användare och som jag beskriver som produktion, inte som hobby.
Den klarade sig inte. Övervakning, larm, tester och dokumentation var bra. Men backuperna var inte dokumenterade, det fanns ingen automatisk pipeline, utvecklingen skedde direkt på produktionsservern och flera delar hängde på en enda maskin.
Inte för att jag inte visste bättre. Jag hade skrivit flera av punkterna själv. Det hände för att varje punkt, en i taget, kändes som något man gör sedan. Det är vänstersidans logik och den följer med in i produktion om ingen aktivt tar ut den.
Vad man behöver kunna
Det väcker en fråga jag inte kan låta bli. Behöver den som fattar besluten kunna alla de här stegen?
Inte utföra dem. AI är fantastisk på görandet. Den sätter upp DKIM, skriver deployskriptet och fyller i butikernas integritetsformulär snabbare och oftare rätt än jag. På flera av stegen kan den redan mer än jag kan i dag. Jag låter den göra dem och jag skäms inte för det.
Men görandet är inte det som avgör. Omdömet om stegen kräver att man vet att de finns, varför de finns och vad som händer när de saknas. Den som bara känner till vänstersidan kan inte se vad som fattas på högersidan. Och AI frågar inte efter det som ingen bett den om.
I Den tomma kolumnen delade jag upp omdömet i tre delar. Alla tre gäller här. Att veta vad som spelar roll, eftersom de tio klustren inte väger lika för varje produkt. Att kunna säga nej till en rimlig slutsats, när AI säger att allt är deployat och fungerar och det stämmer om koden men inte om certifikatet, nyckeln eller mejlen. Och att kunna ställas till svars, vilket bara går för en kedja man förstår.
Till de tre lägger jag en fjärde, som checklistan gör tydlig. Att kunna fatta nya beslut. En checklista beskriver hur det såg ut när den skrevs. Sedan byter en leverantör villkor, en butik ändrar sina regler, en ny modell gör en hel klunga steg onödiga och en ny lag gör ett annat kluster till det viktigaste. Då finns ingen tidigare lösning att upprepa. AI föreslår gärna en. Men att väga förslaget mot det som gäller nu, för just den här produkten, är fortfarande omdöme. Att sedan stå för valet likaså. Det är den delen av jobbet som växer när görandet blir billigare.
Det är också därför kalkylen om att ersätta ett team med två personer som är vassa på agenter räknar fel. Den räknar på vänstersidan. Mycket av det som står i den tomma kolumnen är högersidan: varför proxyn sitter där den sitter, att avsändaren måste stämma med serverns namn, att ingen någonsin har provat att läsa tillbaka backupen. Det står inte i repot.
Men min egen produkt visar att det inte heller räcker att kunna. Jag kunde punkterna och de blev ändå inte gjorda. Därför finns checklistan. Den ersätter inte omdömet. Den håller det på plats när varje punkt känns som något man gör sedan. Bred förståelse för alla kluster och djup i några räcker långt. Bredden är det som gör att man ser vad som saknas.
Där ansvaret ligger
Det har blivit vanligt att säga att AI utför och att människan tar ansvar. Jag säger det själv. Men det blir ofta ansvar för koden, för den ändring som godkändes.
Bilden ovan visar varför det inte räcker. Koden är ett av tio kluster. Ett certifikat som går ut klockan tre på natten är inte en kodändring. En mejldomän som hamnar i skräpposten är inte en kodändring. En nyckel i en sitemap är inte en kodändring. Ingen av dem fångas av en granskning av det som AI skrev.
Ansvar för en produkt är ansvar för hela kedjan, från ägarbolaget till larmet. Det är det jag menar när jag säger att mitt namn står på det jag levererar. Inte raden. Kedjan.
Att bygga har blivit billigt. Att drifta kostar lika mycket som förut. Den som säger "det funkar på min dator" har rätt om datorn och har inte sagt något alls om produkten.
Se även: Bygget blev gratis. Flaskhalsen flyttade. (Leverans) om varför bygget slutade vara det som avgör Det funkar i din Claude (Leverans) om vad klienten gör åt dig som inte följer med ut och Den tomma kolumnen (Mandat) om omdömet som inte syns i kalkylen.