Har inte hittat någon ny edge den här veckan. Har hittat fem sätt som jag lurat mig själv på i stället, vilket är tråkigare att skriva om men förmodligen nyttigare… alla fem satt ju uppströms om i princip allt annat jag mätt.
Det värsta först. ATG skickar strecket i hundradels procent, alltså 3382 för 33,82 %. Min kod delade med 100 i stället för 10 000 och skickade vidare det som en sannolikhet — och efter normaliseringen fick avdelningens streckfavorit typ 95 % av hela massan. Sen var det inte en rad utan åtta ställen, sju av dem levande. Och eftersom talet går in i en produkt över avdelningarna så växer felet med spelformen: den skattade kombinatoriska utdelningen för en V4-rad kom ut som 0,00027 kr där den skulle vara 26 685 kr. På en V64 är det tolv tiopotenser. Så det går inte ens att korrigera i efterhand med en konstant, felet beror på hur många avdelningar spelet har.
Men det som stör mig är egentligen inte felet, utan att det legat där i ungefär ett år utan att något larmat. Tre olika testfixturer skrev fältet i ren procent — en enhet som produktionen aldrig producerar — och den gamla koden gissade enheten ur hur stort talet var. Alltså höll testerna med buggen. “Grönt” hela vägen. Numera är regeln att en fixtur ska skrivas i fältets enhet, aldrig i den enhet som råkar få testet grönt.
Sen en till av samma sort. Produktionsloggen sa en sak och en replay av exakt samma funktioner sa något helt annat, och när det är samma kod så måste ju indatan skilja sig. Det gjorde den. Ett steg i pipelinen skrev på sin anropares avdelningar på plats, så den som byggde avdelningarna en gång och sen körde pipelinen flera gånger matade varje körning med förra körningens utdata. Ett varv drev toppsannolikheten till ungefär 0,9. Fem varv låste den på exakt 1,0. Tecknet har legat i loggen hela tiden och jag har läst förbi det hur många gånger som helst: en rad som säger “3,30 bitar, vidöppen avdelning” bredvid två hästar över 45 %. Det går ju inte ihop inom en och samma sannolikhetsvektor, vilket är precis vad det betyder — man läser två olika.
Sen kom den obehagliga frågan. Jag för register över varje återvändsgränd jag mätt, runt 75 dödade idéer, just för att slippa köra om ett avgjort experiment om ett halvår när jag glömt att jag redan gjort det. Men hur många av de där domarna producerades av den trasiga koden? Så jag fick korspröva alla. De flesta står. Två gör det inte: en jämförelse körde båda sina armar genom den trasiga blandningen, så den var aldrig någon jämförelse över huvud taget, och en “den här prediktorn tillför ingenting”-null hade matats med en indatasignal som var rent skräp — den idén är alltså öppen igen i stället för död. Två dåliga domar av 75 är väl helt ok faktiskt. Att låta bli att ställa frågan hade varit betydligt dyrare.
Sen spikarna. Jag har haft en mekanism som väljer hur många spikar en kupong ska bära, genom att optimera över antalet, och den kan strukturellt inte fungera under ett täckningsmål. Tog mig löjligt lång tid att se varför: mängden ramar med exakt k spikar är en delmängd av mängden med högst k, så att kräva ett exakt antal kan bara ta bort alternativ. Optimum hamnar därför på noll. Uppmätt k=0 i 97,6 % av 2 142 omgångar. Och positivkontrollen gjorde det pinsamt tydligt — kör armen på medvetet omkastade sannolikheter så presterar den i princip lika bra som på de riktiga. Själva mätningen fungerade alltså. Det var kriteriet som var skräp.
Det som däremot håller är att om man löser breddfördelningen fritt, utan något spikantal som indata, så uppstår spikarna av sig själva — och de skiljer sig ganska mycket åt per spelform:
- V85: 1,77 i snitt (minst en spik i 95,5 % av omgångarna)
- V86: 1,74
- GS75: 1,20
- V64: 0,79
- V5: 0,54
- V4: 0,12
Nollorna är härledda, inte trimmade — en DD med 100 rader täcker ju nästan hela fältet ändå. Så antalet spikar är egentligen ingenting man bestämmer, det är något man läser av när breddallokeringen är klar.
Det fynd som svider mest är ändå radvalet. Jag tittade på 286 omgångar och plockade ut bara de där hela vinnarlinjen redan låg i min ram — alltså varje vinnare utpekad, ingen missad, den svåra biten löst. I de omgångarna behöll radvalet vinnarraden i 21,1 % av fallen. En orakelväljare får 100 % på exakt samma mängd, så taket är verkligt och mätningen håller. Fyra gånger av fem som jag gör det svåra rätt så slänger jag alltså bort vinnaren i det lätta steget, och det är jäkligt irriterande att ha hållit på med ramen i månader när det uppenbarligen är här det försvinner.
Och det finns ingen genväg heller. Att byta poängformel för radvalet stänger ungefär 6 % av gapet, och byter dessutom tecken på V85, så formeln är fel axel att skruva på. Det ser i stället ut att vara en marginalkollaps — topp-N på produktsannolikhet koncentrerar strukturellt varje avdelning till sina en eller två översta hästar, så modellens rank 3 och rank 4, som ju bär reell massa, kläms mot noll exponering. Kupongen speglar då inte längre modellens egen fördelning utan en spetsigare modell som jag aldrig bett om. Får se om det går att göra något åt utan att bara höja budgeten…
En sista sak, som egentligen förklarar hur de andra fyra kunde överleva. Testsviten rapporterade 263 filer och 2 307 test, alla gröna, och dagens 13 nya test var inte bland dem. Filen låg på disk men konfigurationen är en explicit lista, inte ett filmönster. Båda rapporterna var alltså sanna. Slutsatsen jag drog av dem var det inte. Och det är en hel klass av samma sak: en bock för en förmåga som aldrig kopplades in, en jämförelse mellan två “olika” inställningar där flaggan som skiljer dem inte har någon läsare kvar, tystnad från en gate som granskat noll saker. Numera försöker jag ställa en enda fråga i stället — vad är det som måste ha körts, och körde det?
Sen har jag delat upp felen i två sorter, mest för min egen skull. Mekaniska fel (fel enhet, fel skala, saknad post i ett register) lämnar ett spår som går att söka efter, och där är en automatisk gate rätt investering. Semantiska fel har rätt typ, rätt skala, rätt intervall, men svarar på fel fråga. Jag testade faktiskt om man kan söka sig fram till dem också: 30 kandidater blev 5 blev noll. Varenda semantiskt fel jag hittade den dagen kom av att någon läste koden. En kommentar som ljuger, ljuger ju om meningen, och meningen syns inte i en sökning.
Ingen ny edge den här veckan alltså, bara fem ställen där det jag redan mätt vilade på siffror som inte höll. Får se vad ommätningarna säger nu när talen är rätt…