Det jeg har lært mest av, er ikke at AI kan skrive kode. Det er hvor liten del av jobben det er. Resten er å avgjøre hva som skal ut, hva som aldri skal ut, og når noe er godt nok. Den delen har jeg beholdt selv.
AI gjør jobben, du eier avgjørelsen. Det som aldri skal ut, bør stoppes i systemet og ikke bare i en rutine. Det har jeg ikke fått helt til selv, og det står under. Feil er det du skriver ned, ikke det du skjuler. Resten av saken er hvordan, med eksempler fra en liten side.
gribben.no er min personlige side om løping og teknologi. Den er statisk HTML, uten byggesteg, uten pakkefil og uten Node.js. Verktøyspråket er Python. Det er et valg, og det har holdt: lite kan gå i stykker, og det er lett for både meg og Claude å se hele sida på en gang. Det jeg skal snakke om her er øktdatabasen, med offentlige Strava-økter og analysekort på intervalløktene. Her ligger også to spillsamlinger, Gribbelandet og Skolespillet, men dem lar jeg ligge.
git rev-list --count HEAD, tellet 8. oktober 2026.git log..claude/skills, hvorav én ikke er committet ennå: oppskrifter og lesere som Claude laster når oppgaven passer.data/okter.json, 21 av dem med rundedata. Kilde: fila selv.
Tallet 85 sier ikke hvor mye Claude skrev. Det sier at Claude var med i 85 av 125
endringer. Medforfatterlinjene nevner to modeller: Claude Opus 5 i 74 av commitene og
Claude Fable 5 i 11. Commit-meldingene er skrevet av Claude, og i
CLAUDE.md står det at den ikke skal pushe før jeg ber om det.
Figuren øverst viser veien fra en økt i Strava til en rad på sida. Fargene er poenget: gult er meg, blått er Claude, grønt er kode som kjører likt hver gang. Første og siste trinn er mine. Det er ikke tilfeldig.
| Oppgave | Claude | Jeg |
|---|---|---|
| Nye økter | Henter dem gjennom koblingen og legger dem inn i skriptet | Setter synlighet i Strava og ber om synk |
| Analysekort | Henter runder, slår dem sammen til drag og regner scoringa | Leser notatet og avgjør om kortet sier noe sant |
| Tekst | Skriver utkast i stemmen fra en skill | Retter. Motivasjonssaken gikk fem runder |
| Utseende | Bygger sider og figurer etter stilreglene | Ser på dem og sier fra når noe er feil |
| Når noe er klart | Kjører lesere over utkastet | Bestemmer |
Hver synk går i samme rekkefølge. Claude henter aktivitetene gjennom koblingen til
Strava, og hvordan du setter den opp selv står i
artikkelen om løpetrener og fysioterapeut i Claude.
For øktene som skal ha analysekort, henter den også rundene. Alt legges øverst i en
liste i verktoy/hent_okter.py, og skriptet skriver
data/okter.json. Sida leser fila og tegner tabellen og kortene.
Fila er generert, og jeg redigerer den aldri for hånd. Det står øverst i
CLAUDE.md, fordi en håndredigering forsvinner ved neste synk uten at noe
sier fra. Skriptet gjør også en ting jeg ikke hadde tenkt på selv: det stempler en
innholdshash inn i sida som laster fila, så besøkende ikke får en gammel utgave i
nettleseren etter en synk.
Strava merker hver økt som offentlig, bare for følgere eller bare for meg. Bare de offentlige skal inn. Jeg fant en privat økt allerede i de tre nyeste ved første uttrekk, så dette var aldri teori.
Regelen er at data som ikke skal vises, ikke skal finnes i fila. Å skjule en privat økt med JavaScript er ikke å filtrere den. Den ligger fortsatt i en fil som hvem som helst kan åpne. Derfor sier synk-commitene også hva som ble holdt utenfor, som i synken 5. oktober: «De to private er ikke med.»
Regelen står i skriptets bruksanvisning, i synk-skillen og i CLAUDE.md. Men skriptet sjekker ingenting selv. Det får aldri se feltet for synlighet, fordi øktene limes inn etter at filteret er brukt. Filteret er en rutine Claude og jeg følger, ikke kode som stopper en feil.
Claude har ikke med seg noe fra forrige økt. Det som skal bestå, må stå i en fil som leses først. Derfor har repoet tre lag, og jeg har lært å holde dem fra hverandre:
.claude/LAERT.md: funn med dato, skrevet som påstander. Den handler om prosjektet, ikke om meg.
CLAUDE.md kom som commit nummer 110. Meldinga sier hva den var til for:
fem ting som hadde blitt gjenoppdaget i hver eneste økt. Den burde kommet i commit
nummer ti.
Tre utdrag, uredigert, så du ser hva jeg mener med lagene. Først toppen av CLAUDE.md: reglene som alltid gjelder.
## Det viktigste først **`data/okter.json` er generert. Rediger den aldri for hånd.** Eneste vei inn er `verktoy/hent_okter.py`. Håndredigering forsvinner ved neste synk, og cache-stempelet blir feil uten at noe sier fra. **Private Strava-økter skal aldri inn i repoet.** Filtreringen skjer ved uttrekket, ikke i nettleseren: bare `visibility = "everyone"` skal limes inn i `OKTER`. Skriptet sjekker det ikke selv, for feltet finnes ikke i det som limes inn. Regelen er et steg i prosedyren i `verktoy/hent_okter.py` og `synk-okter`, og den må følges. Data som ikke skal vises, skal ikke finnes i fila. **Ingen Node.js.** Python er verktøyspråket her. Sida har ingen byggesteg, ingen pakkefil og ingen avhengigheter.
Så starten på synk-skillen. Linjene mellom strekene er det Claude leser for å vite om skillen passer.
--- name: synk-okter description: Hent nye Strava-økter inn i øktdatabasen på gribben.no og legg analysekort på intervalløkter. Bruk denne når Magnus ber om å «synke øktene», «hente siste aktiviteter», «legge på analysekort», eller når en ny økt skal inn i data/okter.json. Dekker hele flyten fra Strava-uttrekk til commit, med fallgruvene som ikke står i skriptet. ---
Til slutt starten på en oppføring i minnebanken, den om mølleøkta fra figuren lenger opp.
## 2026-10-05 · Mølleøkter autolapper på kilometeren og skjuler draga **Hva:** `get_activity_laps` for 8 x 1000 på mølle ga tolv runder à 1000 m med fart 4:15 til 5:06 og ingen hvilerunder. Det ser ut som en slapp økt. Den var ikke det: draga gikk på 3:26 til 3:30. Garmin autolappet hver kilometer, så hvert innslag er en blanding av drag og pause.
Utdrag fra arbeidskopien 8. oktober 2026. CLAUDE.md har endringer som ikke er committet ennå.
Rundene fra en mølleøkt var tolv like lange biter uten hvile, og de så ut som en rolig tur. Draga hadde i virkeligheten gått på 3:26 til 3:30 per kilometer. Klokka lapper på hver kilometer når jeg ikke trykker selv, og hvert innslag er da en blanding av drag og pause. Analysekortet regnet gladelig på tallene uten å klage. Nå står det i minnebanken at like lange runder uten hvilerunder er autosplitt, og at strukturen må hentes ut av fartsstrømmen i stedet.
En økt var planlagt som ti drag og ble avbrutt etter seks. De seks som ble løpt traff alle kriteriene i kortet, så kortet ga 100 poeng. Riktig regnet, helt misvisende lest. Kortet kjenner ikke planlagt volum, og det står ingen advarsel noe sted. Det er fortsatt åpent. I mellomtida må notatet under økta bære sannheten.
33 gamle sider hadde et annet utseende enn resten. Jeg forsøkte én fellesløsning: ett overstyringsark som pekte de gamle fargene mot lyse verdier. Bakgrunnen ble riktig, men målingen fant mellom 11 og 121 tekstelementer per side med for svak kontrast, fordi mange paneler hadde mørke farger skrevet rett inn i seg. Jeg rullet tilbake alt. Siden har jeg tatt sidene én og én, med en måling som regner kontrast per element. Det forrige forsøket feilet fordi det ble gjort i blinde.
Da de gamle artiklene ble ført inn i oversikten, hadde mange bare årstall. Claude fordelte datoer etter hva som virket rimelig. Det står fortsatt på listen over teknisk gjeld, med begrunnelsen at feil publiseringsdato er verre enn ingen. Lærdommen er å be AI-en markere gjetninger som gjetninger.
Gjennom motivasjonssaken gikk vi fem runder. Hver runde fant jeg ting Claude ikke så selv: for mange grafer, feil metafor, et ord ingen sier og en regel som ikke stemte med min egen praksis. Leserne er et forsøk på å fange slikt før jeg må.
Det er to skills, les-loping med fem lesere og les-tech med
fire, pluss en arrangør som leser foredragssida. Hver leser er en tenkt person med egne
grunner til å gi opp. Kari har aldri prøvd og vil ikke føle seg dum. Leif skal ta en
beslutning i et styre. Sara er utvikler og vil kjøre noe i kveld. Henrik jobber med
maskinlæring og tåler ikke hype. Rapporten må ha sitat for hvert funn.
De er ikke hooks, og det er med vilje. En hook kjører av seg selv hver gang noe skjer. En hook som kjører fem lesere over hvert utkast blir noe du lærer deg å ignorere, og «nå er den klar» er en vurdering et menneske gjør. De erstatter ikke en ekte leser. De fanger det jeg ellers ville fanget selv, litt tidligere.
CLAUDE.md i uke én, ikke i commit 110.Du trenger ikke et stort prosjekt. En liten side holder.
Her er et utkast du kan lime inn i et nytt prosjekt for å få første versjon av regelfila:
Les prosjektet i denne mappa. Skriv så et utkast til en regelfil på maks en side, med bare det som må være sant hver gang noen jobber her: 1. Hvilke filer som er generert og aldri skal redigeres for hånd. 2. Hva som aldri skal inn i prosjektet, for eksempel private data. 3. Hvilke språk og verktøy vi bruker, og hva vi bevisst ikke bruker. 4. Hvordan prosjektet kjøres lokalt, og hvordan vi sjekker at noe virker. Ikke finn på regler. Er du usikker, still meg spørsmålet i stedet for å gjette. Ting jeg vet allerede: [skriv her det du selv vet må med]
Vil du ha dette som foredrag eller workshop for en gruppe? Se Foredrag og workshop. Er du leder og vil ha det på et bord, begynn med seks spørsmål til neste møte.
Oppdatert oktober 2026. Tallene er tellet i repoet 8. oktober 2026 med git og et lite Python-skript, og øktene er talt i data/okter.json. Av de sju skillsene er seks committet, og gribben-tech ligger ennå bare i arbeidskopien. Hendelsene og sitatene står i commit-meldingene, PLAN.md og .claude/LAERT.md i repoet. Medforfatterlinja i commit-meldinga viser at Claude var med, ikke hvor mye den skrev. Jeg bruker Claude Code, og hva som er mulig der, endrer seg raskt. Modellnavnene er lest i medforfatterlinjene i git-loggen, ikke i Claude Code selv.