Det tause ansvaret

DET TAUSE ANSVARET

ARK 2026: Dokumentene fra foredraget

Samlesiden for foredraget «Tech lead i AI-alderen» på ARK 2026: kontekstfilen, énsideren «Pass Code Review on the First Try» i anonymisert form med tallene før og etter, linjen i PR-malen, TDR-eksempelet, hele tabellen over fast og fritt, utdraget fra agentprofilen, fire tegn på sprik og fire ting å gjøre på mandag.

Dette er samlesiden for foredraget «Tech lead i AI-alderen: Hvordan holde arkitekturen samlet når AI øker farten» på ARK 2026, Dataforeningens arkitekturkonferanse, 14. oktober 2026. Jeg holder det som seniorkonsulent i Ensō. Foredraget er på norsk; siden finnes også på engelsk.

Foredraget viser fire grep, hvert med ett eller to dokumenter på skjermen: kontekstfilen og énsideren, linjen i PR-malen, en TDR, og til slutt tabellen over hvem som eier hvilken regel, med profilen som får reglene fram til agenten. Her ligger de samlet, så du slipper å skrive dem av på mandag. Kontekstfilen, TDR-en og tabellen er eksempler som skal byttes ut med teamets egne. Énsideren er fra mitt eget team, med tallene slik de var.

På siden: Kontekstfilen · Sjekklisten på én side · Forklaringsplikten: linjen i PR-malen · Størrelsen · TDR-eksempelet · Fast og fritt: hele tabellen · Profilen · Fire tegn på sprik · Mandag morgen · Videre lesning

Kontekstfilen

Det første grepet er standarder der arbeidet skjer, og der leser agenten. En kodeagent har ingen kollega som ser skjevt på en funksjon på 300 linjer, og ingen magefølelse for «sånn gjør vi det ikke her», så alt det må stå skrevet i filen den leser. Dette er filen på ni linjer; linjene i ⟨⟩ er teamets egne å fylle ut.

# AGENTS.md · ⟨team⟩ · under 60 linjer, reviewes som kode
Struktur: vertical slices under src/features/. Ingen import på tvers; CI-test feiler ellers.
Logging: strukturert (⟨bibliotek⟩), alltid correlationId. Aldri personopplysninger.
Feilhåndtering: ⟨ett mønster⟩, ProblemDetails mot HTTP. Nytt mønster = TDR i samme PR.
Integrasjon: kun via ⟨API-plattform⟩; aldri direkte mot andre domeners databaser.
Tester: dekk atferden ved grensene: input vi ikke stoler på, feil fra tjenester vi kaller.
Nye biblioteker for mapping, caching, validering: TDR i docs/decisions/, i samme PR.
Org: ⟨én regel fra profilen, som tekst⟩. Resten: les ⟨profilen⟩ først. Avvik krever unntak.
Ikke gjenta det som kan leses ut av koden.

Verktøyene leser ulike filnavn: Copilot leser copilot-instructions.md, Claude Code leser CLAUDE.md, flere leser AGENTS.md. Hold én fil, og la de andre peke på den. Slik vokser filen hos oss: hver gang agenten misforstår oss, lærer vi hva vi egentlig mente, og bytter ut linjen.

Sjekklisten på én side: «Pass Code Review on the First Try»

Den mest nyttige énsideren på teamet mitt heter «Pass Code Review on the First Try», og ordet AI står ikke i den. Den ble til ved at jeg leste seks måneder med review-tråder fra mitt eget team baklengs, mars–august 2026, for å se hva reviewerne måtte si om igjen. Den interne siden navngir kolleger og prosjekt, så dette er en anonymisert versjon: tallene, de fem kategoriene og de ti punktene er de samme.

  • 474 pull requests
  • 726 tråder åpnet av reviewere
  • 61 % merget uten én kommentar

Uten én kommentar er ikke det samme som uten review: nesten ni av ti av dem har en godkjenning fra en annen enn forfatteren, stort sett et «LGTM». Siden handler om de andre 39 prosentene, og de fem som stopper oftest, står under med antall tråder. Ingen av de fem handler om AI.

Stopper oftest Tråder
Antakelser i stedet for målinger 44
Utdatert branch 33
Hardkodede miljøverdier 31
Akseptansekriterier ikke oppfylt 22
Dokumentasjon motsier koden 21

Ti punkter du sjekker på din egen branch før du trykker «Create». Punkt fem er test-linjen fra kontekstfilen i en strengere form. Listen justeres etter hvert som trådene endrer seg. Alle ti avgjøres før revieweren åpner diffen.

- [ ] Hvert akseptansekriterium er oppfylt av denne diffen, eller endret i saken til det jeg faktisk leverte.
- [ ] Branchen er à jour med main fra i morges.
- [ ] Ingenting i diffen ligger utenfor saken: ingen omdøping i forbifarten, ingen reformatering, ingen naborefaktorering.
- [ ] Ingen hemmelighet, ingen personopplysning og ingen rå exception havner i en logg, et svar eller repoet.
- [ ] Minst én ny test feiler når endringen reverteres, og jeg har sett den feile.
- [ ] Pipeline-loggen viser at den testen kjørte, med navn.
- [ ] Bygget er lenket, miljøet navngitt, helsesjekkene vist.
- [ ] README sier ikke lenger noe denne diffen har gjort usant.
- [ ] Tittelen er under 50 tegn, i imperativ, med nøyaktig ett saksnummer.
- [ ] Beskrivelsen kan leses som commit-meldingen den er i ferd med å bli.

Så virket den? Litt. Talt over alle PR-er, august mot 1. september–8. oktober: runder per PR gikk fra 2,0 til 1,8, og 5 av 7 forfattere med PR-er i begge periodene trenger færre runder enn før. Uten kollegaen bak PR-en med 14 runder er fallet 1,9 til 1,8. Om det er forfatterne som tar med færre ting, eller vi som reviewer som ber om mindre, kan ikke tallene si. Review-botene var i gang i begge periodene. Andelen PR-er uten kommentar falt også, men mest fordi flere i teamet begynte å kommentere; trådene per PR er nesten like.

Alle PR-er Før (august, 116 PR-er) Etter (1. september–8. oktober, 166 PR-er)
Runder per PR 2,0 1,8
Tråder per PR 2,2 2,1
Andel PR-er uten kommentar 35 % 17 %

En runde er en push etter en reviewer-kommentar, pluss den første. Andelen uten kommentar er lavere enn halvårets 61 %, fordi review-botene begynte å kommentere på mange PR-er i august.

«Litt» er det jeg har lært å vente av alt som står skrevet: det kan ta unna noe av det som gjentar seg, og resten er fortsatt dømmekraft. Punktene deres vil være andre enn mine; metoden er den samme. Se etter det reviewerne deres sier for tredje gang. Det er standarden. Skriv den ned der den som skriver PR-en, er, før PR-en åpnes, og lenk til den fra review-kommentaren.

Slik telte jeg

  1. Hent alle PR-er i perioden, med alle kommentartrådene, rett fra API-et til PR-verktøyet. Hos meg: opprettet 1. mars–31. august 2026, i 33 repoer.
  2. Ta ut maskintrafikk. Hos meg var det 182 automatiske PR-er for tilgangsforespørsler; igjen ble 474.
  3. Knytt hver tråd til den som åpnet den, og tell bare trådene en reviewer åpnet. Hos meg: 726.
  4. Grupper trådene etter hva revieweren måtte be om. En agent kan gjøre første runde, men les gruppene selv før du stoler på dem.
  5. Tell runder per PR før og etter at dere tar sjekklisten i bruk, og tell igjen etter en måned.

Forklaringsplikten: linjen i PR-malen

Det andre grepet er review som spør om koden passer inn, og med generert kode: om forfatteren forstår den. Det trengs ikke noe apparat for det; én linje i PR-malen holder lenge.

## Generert?
Er deler av denne endringen generert? Forklar valgene du har godkjent, med egne ord.

Linjen gir revieweren rett til å spørre «hjelp meg å forstå: hvorfor dette mønsteret, og ikke det i naboklassen?» Den er også størrelsesgrensen: kan du ikke forklare 300 linjer, del dem. Alt som kan lintes, lintes først. Gi AI-revieweren den samme kontekstfilen, så den reviewer mot teamets regler.

Størrelsen

Størrelsen er også målt hos oss, på teamets fullførte PR-er fra mars til 8. oktober 2026, 580 i alt. Fire av fem PR-er med én til tre filer gikk gjennom på første forsøk. Av dem over 25 filer, tre av ti.

Filer i PR-en Merget på første forsøk
1–3 80 %
4–10 49 %
11–25 40 %
26+ 29 %

Tabellen sier hva det koster å la være å dele. Grensen er fortsatt den samme: det du kan forklare med egne ord.

TDR-eksempelet

Det tredje grepet er beslutningsspor: å skrive ned hvorfor. En TDR svarer på tre spørsmål: hva valgte vi, hvorfor, og hva forkastet vi. Den er en markdown-fil der koden ligger, i samme PR som koden. Målet er en halv side og en time. TDR-en under er et eksempel og ingen ekte beslutning; bytt den gjerne ut med en fra teamet. De tre linjene om modellen, midt i, er de jeg legger til når AI har vært med: hva modellen fikk vite, hva dere sjekket etterpå, og hva dere fortsatt antar.

TDR-014 · Caching av produktbeskrivelser · status: vedtatt · ⟨dato⟩
Kontekst: p95 over 1 s mot registeret; les:skriv ca. 40:1; data kan være 5 min gamle
Valg: lokal cache, TTL 5 min. Pris og lager hentes separat.
Forkastet: delt cache (én tjeneste å drifte); hendelsesdrevet invalidering (ingen hendelser)
Hva modellen fikk vite: trafikkprofil, ingen sanntidskrav
Sjekket etterpå: lasttest med forventet antall instanser; TTL mot endringstakten
Antar fortsatt: instansene kan vise ulik versjon i 5 min; ingen har målt hvor ofte
Vurderes på nytt: etter første release, eller når registeret begynner å sende hendelser

«Antar fortsatt» er linjen jeg aldri dropper, og bak den står ett spørsmål til: hva vet vi ennå ikke? «Det vet vi ikke» er et ansvarlig svar. Da trenger dere en undersøkelse, og en dato.

Fast og fritt: hele tabellen

Det fjerde grepet er tydelige rammer. På skjermen sto fire rader; her er hele tabellen. Øverste halvdel eier organisasjonen, nederste halvdel eier teamet, og høyre kolonne sier hvor raden står. Org-radene er fra organisasjonens egne standarder, oversatt og forkortet; infrastruktur-raden er fra et sted jeg har vært. «Fritt» og teamradene er mine; «fritt» står ingen steder, og det er en del av poenget.

Nivå Fast Fritt Står i
Org · identitet og hemmeligheter Godkjente plattform- eller bibliotekfunksjoner for autentisering, autorisasjon, kryptografi og hemmeligheter; egne mekanismer krever spesialistreview Hvordan roller mappes til rettigheter i domenet Standard for sikker koding (wiki; profilen peker dit)
Org · data og logg Innsamling, lagring, overføring, logging, testbruk og sletting av sensitive data følger sikkerhets- og personvernkravene Loggformat innenfor plattformen Standard for sikker koding (wiki; profilen peker dit)
Org · grenser Input utenfra valideres ved en definert tillitsgrense; autorisasjon håndheves ved den autoritative grensen Hvor valideringen ligger i koden Standard for koding og design (wiki; profilen peker dit)
Org · nye biblioteker Nye vesentlige avhengigheter vurderes for sikkerhet, støtte, lisens, drift og forsyningskjede; ikke alle pakker trenger komitégodkjenning Små verktøypakker innenfor en rad Standard for avhengigheter og bygg (wiki; profilen peker dit)
Org · delte kontrakter Endringer i offentlige grensesnitt, lagrede data, konfigurasjon, hendelser og delte komponenter vurderes med tanke på kompatibilitet, migrering og tilbakerulling Synk/asynk innenfor domenet Standard for koding og design (wiki; profilen peker dit)
Org · infrastruktur (eksempel, fra et sted jeg har vært) Delt infrastruktur i plattformrepoet, én gang per miljø, bak en kontrakt Appens egne ressurser, innenfor kontrakten Plattformrepoet
Team · logging Strukturert, korrelasjons-ID, feltnavn Loggnivå per modul AGENTS.md
Team · feilhåndtering Ett mønster, én mapping til HTTP Retry-parametre, begrunnet i PR AGENTS.md + TDR
Team · nye mønstre TDR i samme PR som første bruk, med revisjonspunkt Eksperiment på branch docs/decisions/

«Fritt» betyr valg innenfor rammen; sikkerhetskravene står fast. Se på høyre kolonne (på mobil: sveip tabellen): alle org-radene fra standardene står på wikien. Det er hullet vi jobber med.

Profilen: hvordan agenten skal oppføre seg

Hos oss ligger det en agentprofil i ett repo som alle teamets repoer er koblet inn i, og agenten blir bedt om å lese den før tekniske endringer når den startes fra kontrollrepoet; starter du den rett i ett repo, står profilen ikke der. Her er et utdrag, oversatt og forkortet:

# agentprofil.md · utdrag, oversatt · 157 linjer i kontrollrepoet
Autoritet: organisasjonens standarder for vedlikeholdbar kode, med sju støttestandarder.
Eier: vedlikeholderne av agentoppsettet. Gjennomgås minst årlig; er datoen passert, meld det.
Et repo kan skjerpe profilen. Det kan ikke svekke en obligatorisk kontroll.
Agenter kan ikke godkjenne egne produksjonsendringer. Uavhengig review gjøres av en annen person.
Manglende eller upålitelige sjekker er et hull i styringen. Meld det i stedet for å finne på bevis.
Et punkt på gjeldslisten, en TODO eller «slik har vi alltid gjort» er ikke et unntak.

Profilen åpner med at wikien fortsatt er styringsautoriteten, og at profilen sier hvordan agenten skal oppføre seg. Ett av repoene våre har tatt neste steg: kontekstfilen peker på en avstemt kopi av standardene i repoet. For resten er neste steg å få reglene inn som tekst, med bare det en agent kan handle på i en diff.

En foreslått TDR er ikke et ja. Hos oss sier standarden at et unntak lages før en obligatorisk kontroll omgås, med ansvarlig eier og godkjenner, kompenserende tiltak og en utløpsdato, og profilen ber agenten stoppe når unntaket mangler eller er utløpt. TDR-en er begrunnelsen; unntaket er ja-et. Sikkerhet eier gjerne en rad øverst, og det er den raden jeg aldri ville flyttet til «fritt». En ramme som fungerer, merker du på at teamet slutter å spørre deg om lov, og begynner å spørre om rammen fortsatt stemmer.

Fire tegn på sprik

Alt over handler om å forebygge sprik. Fire tegn for å se det, alle billige; de to siste er for dere som ser på tvers av team.

  1. Samme behov, flere løsninger: søk på tvers av repoene og tell varianter. Eksempel: rg -l ⟨bibliotek⟩ ⟨repo⟩ | wc -l, én gang per variant og repo. Hos oss fant et kodesøk på default-branchene og en gjennomgang av nye pakker i fullførte PR-er, mars–september 2026, fire caching-biblioteker i fem repoer, tre logging-oppsett, minst to retry-mønstre og to måter å mappe på. Ingen valgte det; hver av dem var rimelig da den ble skrevet.
  2. Handler mange review-kommentarer om ting forfatteren kunne sjekket selv? Da har forfatteren ikke sett standarden før PR-en, og det er énsideren som må bli bedre. Hos oss var rundt fire av ti tråder slik, sortert av en modell, så veiledende.
  3. Lockfilen får et nytt bibliotek uten TDR ved siden av. På tvers av mange repoer: tell bare biblioteker som er nye for hele organisasjonen, i kategoriene dere har en rad for.
  4. TDR-er med status «foreslått» som aldri blir avgjort. Gjelder de en org-rad, er det avvik i produksjon som rådet ikke har sett. Merk dem med raden, så kan en jobb samle dem til én liste før rådsmøtet. I en regulert virksomhet må den som eier raden, godkjenne avviket før det går i produksjon.

Og før alt dette: repoer uten en eneste TDR. Hos oss var det 30 av 38 i oktober.

Mandag morgen

Fire ting å gjøre uten å be noen om lov, og den siste er for arkitektene.

  1. Start i ett repo. Rett én linje i kontekstfilen, eller skriv den første hvis filen mangler.
  2. Legg linjen i PR-malen: «Forklar valgene du har godkjent, med egne ord.»
  3. Til neste design review: ta med én forkastet løsning og én antakelse som fortsatt må sjekkes.
  4. Arkitekter: ta regelen rådet oftest gjentar. Skriv den inn i profilen, som tekst. Så: en pipeline ut i hvert repo, og ett tall til rådet: hvor mange repoer har gjeldende versjon.

Og mål to ting, før og etter: runder per PR, og hvor mange varianter dere har av samme behov. Det første viser køen, det andre arkitekturen. Send de to tallene, uten kode og navn, til hei@tauseansvaret.no, så publiserer jeg dem anonymisert i november, uansett hva de viser.

Videre lesning

Argumentet bak foredraget står i Tech lead i AI-alderen: Fra ekspert til rammesetter. Hvordan en énsider som denne blir en del av hverdagen, står i AI usage guidelines som faktisk etterleves, og TDR-formen med et lengre eksempel i TDR-er i AI-alderen. Vil du ha tekstene etter hvert som de kommer, kan du melde deg på Tirsdagsbrevet, én kort e-post i uken.