En 47 år gammal kostnadsmodell prissätter min helg till $492 788.
En 47 år gammal kostnadsmodell prissätter min helg till $492 788.
Jag körde scc (ett verktyg som räknar rader kod) på ett multi-player
quizspel jag byggde solo på en helg. Det spottade ut COCOMO-skattningen nedan. Cost
inringad i magenta, för säkerhets skull:

Nästan en halv miljon dollar. 10,51 månader. 4,17 personer. För en helg, ensam.
Innan vi går vidare: lägg märke till vad den siffran just gjorde med dig. Du har nu en referenspunkt. Allt jag säger härnäst kommer du omedvetet att mäta mot en halv miljon dollar. Det är inget olycksfall: det är ett ankare (Kahneman & Tversky: vi klamrar oss fast vid det första talet vi ser, hur godtyckligt det än är). Jag namnger det med flit, så att jag är med på skämtet och inte offer för det. Siffran är fel. Men titta på vad den gör med din förväntan.
Och innan någon ingenjör i baksätet sätter sitt eget mot-ankare ("pfft, ett vibe-codat helgleksak, värt typ $0"): nej. Det är lika fel, åt andra hållet. Den här texten handlar om vad som ligger emellan, och varför avståndet inte mäts i rader kod.
COCOMO (Constructive Cost Model, Barry Boehm, 1981) skattar kostnad ur en enda ingång: antal rader kod, körda genom en takt kalibrerad mot vattenfallsprojekt på stordatorer. Den ljuger på två sätt samtidigt.
Den inflaterar. Av de 18 988 raderna scc räknade är
massor inte handskriven applikationslogik: 5 306 rader CSV-frågedata, 4 542 rader
Markdown (specs, ADR:er, den här sortens dokument), genererad och konfigurerad kod. Och
även den äkta koden prissätts i 1981 års takt, en epok utan ramverk, pakethanterare
eller en standardbibliotek som gör det tunga lyftet.
Skala ner till enbart ren kod (C#, Razor, CSS), och modellen säger:
$126 384 · 6,27 månader · 1,79 personer (4 347 rader kod)
Mer ärligt. Fortfarande absurt för en solo-helg.
Den är blind. Det COCOMO inte kan se är där allt arbete faktiskt ligger: specifikationen som är sanningskälla, de sju arkitekturbesluten, testdesignen, agent-pipelinen som granskar frågedatan. Och inte bara det osynliga tankearbetet, utan också det konkreta arbete som inte är applikationskod alls. 1 085 frågekort, vart och ett författat, faktagranskat mot källa och språkputsat: modellen ser 5 306 textrader att prissätta som om de vore kod, men inte timmarna av kurering bakom dem. Och allt som krävdes för att det här ens skulle finnas på en adress: köpa domänen, konfigurera DNS, skriva CI/CD-pipelinen i GitHub Actions, deploya till fly.io. Noll rader, i modellens ögon. Den största delen av arbetet väger ingenting.
Det är pudelns kärna: modellen mäter skuggan, inte det som kastar den. Rader kod är skuggan. Det som kastar skuggan (övad metod) syns inte i en SLOC-räknare.
Hävstången var inte att jag skrev fort, och inte att en AI skrev åt mig. Den var att besluten redan var fattade, av en uppsättning seniora discipliner jag har övat tills de blivit reflex. Tre av dem är ryggraden, och de landar alla i samma form: Given–When–Then.
Bygg en funktion åt gången, hela vägen genom: en self-contained slice. Ingen kod delas spekulativt mellan funktioner: varje slice är ett oberoende verifierbart Given–When–Then-kontrakt.
För ledaren: du kan leverera och verifiera en funktion utan att rota i tio andra. För ingenjören: ingen prematur abstraktion, inga lager-för-lagrets-skull, koppling hålls inom slicen.
All beslutslogik bor i en ren kärna: inga databaser, ingen klocka, inget nätverk, helt deterministisk. Allt stökigt (I/O, tid, anrop) trycks ut i ett tunt yttre skal.
Konsekvensen står i bilden: beteendet är simulerbart: kör tusentals scenarier utan databas, verifierbart innan det ens är byggt. Du behöver inte starta något för att veta att logiken stämmer. Det är därför testerna är bombsäkra (mer om det strax).
Spelet är en Decider: två totala funktioner.
decide: (State, Command) → Result<Event[]>
evolve: (State, Event) → State
Loopen är Given–When–Then: Given ett tillstånd (vikta
tidigare events via evolve), When ett kommando,
Then events, eller en avvisning. Samma form som slicen, samma form
som testet. Designen och testet talar samma språk. (Inledande och slutliga tillstånd
utelämnade för läsbarhet.)
Alla tre mönstren härleds ur en enda källa: en emlang event modeling-spec som ritar hela spelets flöde (trigger, kommando, event, vy) innan en rad kod skrivs.

Det här är inte tre lösryckta mönster. De hänger på en gemensam ställning:
GameContext. Klocka och id-generator
injiceras. Därför är kärnan deterministisk, och därför är FC-testerna
bombsäkra, rena och förutsägbara, helt utan mocks.Inget av det här är talang. Det är övad ingenjörsdisciplin. Det är repetition tills besluten sitter i ryggmärgen och beslutskostnaden går mot noll.
"Snabbt och billigt" betyder ingenting om det går sönder. Så det här är inte ett påstående om kvalitet: det är en mekanism för den.
DeciderTests, EvolveTests, ProjectionTests.
Den rena kärnan gör dem deterministiska och mock-fria: testet kör samma loop som
designen.ArchitectureTests upprätthåller
FC/IS-gränsen i CI. Om någon smyger in I/O i kärnan failar bygget.
Disciplinen är automatiserad, inte hoppfull.GameEndpointsTests mot en
TestAppFactory kör hela vägen genom det imperativa skalet.CLAUDE.md, en
constitution, ett auto-minne. Inte "jag försöker komma ihåg": en skriven, laddad
kontrakt-yta. Mekanismen, inte bara intentionen.Frågedatan är inte hopkastad. Varje kort passerar en pipeline av specialiserade agenter innan det når det live-paketet:
frågesättare författar batchar mot svårighetsbanden →
faktagranskare verifierar varje värde och riktning mot källa
och pinnar årtalet (overifierbart = förkastat) → språkgranskare putsar
svenskan utan att röra en enda siffra → kurator
(tools/pack.cs merge) dedupar och kontrollerar bandhistogrammet in i
live-paketet.
Hög kvalitet, stor människa/AI-insats, och noll rader kod. Lika osynligt för COCOMO som arkitekturen. Content är hantverk på samma villkor som mjukvaran.
Skickligheten är det jag lär ut, och läran är övad. Det var aldrig AI:n och aldrig tangenttrycken: det var att besluten redan var fattade, av discipliner jag tränat tills de blivit billiga. Metoden är multiplikatorn.
Och här är meta-beviset: den här artikeln är själv ett exempel på tesen. Argumentet, illustrationerna (hämtade ur mitt eget mönsterbibliotek, samma visuella språk som spelets diagram) och draftandet följde exakt samma övade metod som koden.
Ankaret var aldrig poängen. Disciplinen är det. Jag lever som jag lär.
Nog teori: spelet är till för att spelas. Samla gänget, öppna kvissig.se och se vem som gissar närmast. Mer eller mindre?
Välj kviss och spela ← Tillbaka till kvissarna