Projektlederen træder ind
Nogen reviewede en af vores pull requests ordentligt, linje for linje, og godkendte den — mens forfatteren stadig pushede til branchen. Godkendelsen landede på en version, der ikke længere fandtes. Det er et symptom; sygdommen er, at et code review her kunne bestilles på fire forskellige korrekte måder og derfor nåede ingen. Om køer der ikke er køer, hvad kodeagenter gjorde ved vores evne til at reviewe, og hvorfor løsningen begynder med at slette et af de steder, vi spørger. Projektlederen træder ind.
Min uddannelse er i økonomistyring. Ikke datalogi.
Det er den indadvendte slags: ekstern regnskabsaflæggelse producerer de tal, omverdenen får at se, økonomistyring producerer de tal, de mennesker, der driver forretningen, har brug for for at kunne beslutte. Effektivitet, planlægning, budgettering, ledelse — fire ord, der ligner fire fag, og som i virkeligheden er ét spørgsmål stillet på fire måder. Hvor går en knap ressource hen, og hvordan ville man opdage, at den gik et sted hen, den ikke burde.
Ret det mod softwareleverance, og det ord, der først skifter form, er effektivitet. Det holder op med at betyde at arbejde hurtigere og begynder at betyde ikke at bruge den samme knappe ressource to gange. Og ressourcen er ikke penge, og det er ikke udviklertimer. Det er opmærksomhed — den vedholdende slags, der skal til for at læse en andens kode ordentligt.
Min titel er solutionarkitekt og teknisk projektleder. Folk spørger til den første halvdel, og den er den nemme: jeg tegner arkitekturen for de nye services, vi bygger, og gentegner de dele af det, vi allerede kører, som trænger til det. Det er arbejdet med tegninger til.
Ingen har nogensinde spurgt mig om noget som helst ved den anden halvdel, og det er den halvdel, der afgør, om den første nogensinde bliver leveret. En arkitektur, ingen kan finde opgaven til, få et review på eller høre om, når den er klar, er en tegning. Så: roadmappet, opgavestyring, GitHub, og hvordan folk finder ud af, at der er sket noget.
Jeg giver dommen først, for et indlæg, der holder den tilbage for at lyde afbalanceret, spilder din tid. Måden, vi bestiller og får code reviews på, er noget rod — intet enkelt sted svarer på spørgsmålet “hvad venter på mig”, og der findes ingen mekanisme i det overhovedet ud over, at folk husker. På et tidspunkt havde vi over hundrede pull requests åbne og markeret klar til review. Jeg har været med til at bygge det. Det virker ikke.
Og en økonom ville give den bunke et mindre mildt navn end backlog. Hundrede færdige, ikke-merged ændringer er varelager: arbejde, der allerede er betalt fuldt ud, som vi ikke har realiseret noget af, og som ligger på et lager og stille taber værdi, mens kodebasen bevæger sig videre under det. Det er det dyreste, afdelingen ejer, og intet af det står nogen steder i regnskabet.
Et review krævede nogle gange, at jeg rykkede en kollega
Ikke altid, og ikke alle. Men ofte nok til at lægge mærke til det, og ofte nok til at det blev en del af jobbet, jeg ikke havde regnet med at skulle lave.
En pull request er åben. Den er lille, den er klar, og den har ligget. Alt er, hvor det skal være: branchen er pushet, beskrivelsen fortæller hvad der er ændret og hvorfor, revieweren er sat på. Der sker ingenting, så går jeg hen og spørger. Nogle gange spørger jeg igen.
Nogle af vores har ligget i månedsvis. Ikke blokeret, ikke uenighed om, ikke ventende på en beslutning. Bare åbne, siden foråret.
Jeg vil være præcis omkring fejlen, for den oplagte forklaring er forkert. Ingen afviser noget. Ingen synes, ændringen er dårlig. Der er ikke uenighed nogen steder i det, og det er netop det, der gør det så tosset — det er ren friktion, som hverken producerer information eller beslutninger, kun forsinkelse.
Vi gjorde det billigt at skrive kode
Vi bruger kodeagenter i stor stil, og denne blog har brugt flere indlæg på at være begejstret for dem. Her er regningen.
En agent gør det muligt for én person at have flere ting i luften ad gangen. Det er reelt, og det er det meste af produktivitetsgevinsten. Men arbejde i luften er ikke gratis. Hver tråd optager en plads i hovedet, og pladserne bliver ikke flere, bare fordi det går hurtigere at taste.
Så gennemløbet af at producere ændringer steg, og kapaciteten til at reviewe dem flyttede sig ikke en tøddel. Review er stadig ét menneske, der læser, i menneskefart, og det kræver præcis den vedholdende opmærksomhed, som parallelt arbejde er designet til at bryde op.
To ting følger, og de forstærker hinanden. Der kommer flere pull requests. Og de folk, der burde læse dem, holder hver især tre tråde af deres eget, hvilket er nøjagtig den tilstand, hvor en andens branch er nemmest at udskyde.
Jeg har skrevet her før, at agenter har gjort rewrites billige at producere og ikke en krone billigere at gennemgå. Det er den samme sætning rettet mod almindeligt arbejde. Flaskehalsen forsvandt ikke, da vi blev hurtigere. Den flyttede sig til review, og vi flyttede ikke med.
Vi har aldrig valgt
Den anden årsag har intet med AI at gøre og alt med os at gøre.
Vi har et opgavesystem. Vi har GitHub. Vi har en chatkanal, der er lavet specifikt til at lægge pull requests op, som ønskes reviewet. Alle tre er rigtige. Alle tre er i daglig brug. Og et review kan legitimt bestilles i hvilken som helst af dem — som en GitHub review request, som en kommentar på opgaven, som et opslag i kanalen, eller ved at vende sig om og sige det højt.
Fire ruter til én forespørgsel. Hver især forsvarlig; kombinationen uforsvarlig.
Det er værre end almindeligt kaos, for fra hver enkelt vinkel ser det fint ud. Hver forespørgsel røg et fornuftigt sted hen. Hvert system bliver brugt efter hensigten. Ingen gør noget forkert. Men intet enkelt sted rummer svaret på “hvad venter på mig lige nu”, så ingen har en kø. De har fire delvise, og at samle den rigtige kø koster mere end at læse selve pull requesten ville have gjort.
Det er hele fejlen, og det er ikke en værktøjsfejl. Hvert eneste af de systemer virker. Vi drukner i ikke at have valgt mellem dem.
Dørklokken
Under ruteproblemet ligger et mindre og mere ondskabsfuldt et.
En kommentar på en opgave notificerer ingen. Folk skriver en omhyggelig kommentar, på den rigtige opgave, med den rigtige detalje, og venter så. Der sker ingenting, for ingen fik det at vide. Kommentaren ligger præcis, hvor den hører hjemme, og præcis hvor ingen kigger.
Så sagde mine kolleger, ganske rimeligt: hvis jeg skal læse noget, så tag mig. Fair nok. En mention er det, der gør en besked til en notifikation — ikke beskeden, ikke kanalen, mentionen. Og der er en fælde indeni: ingen bliver notificeret om sin egen besked, så hvis du skriver på en andens vegne under dit eget navn, er den ene person, det med sikkerhed ikke når frem til, dig selv.
Jeg begyndte at tagge. Det hjalp. Det løste det ikke.
En notifikation er en dørklokke, og en dørklokke virker kun, hvis nogen er hjemme. Tag en person, der er tre tråde nede i sit eget arbejde, og du har leveret en afbrydelse, vedkommende bevidst udskyder — og en udskudt afbrydelse bliver ikke gemt nogen steder. Den er væk i det øjeblik, den næste ting ankommer.
Det ville være nemt at skrive det her som en klage over kolleger, der glemmer. Det er ikke det, der sker, og det er ikke rimeligt. Hvis en proces afhænger af, at folk husker, er processen allerede brudt sammen — det at huske er det bærende led, og menneskelig hukommelse er det forkerte materiale til det. Mine kolleger er ikke defekten. Et system, hvis eneste mekanisme er “tag dem og håb”, er defekten, og det system har jeg bygget.
“Klar til review” betyder ingenting
Vend tilbage til det tal. Ikke hundrede pull requests åbne — hundrede markeret klar, hvilket er hundrede påstande om, at en ændring var færdig og ventede på nogen.
Og så det her. Nogen tog én af dem, reviewede den ordentligt, linje for linje, og godkendte den. Forfatterens reaktion var, at opgaven ikke var færdig: han arbejdede stadig på den og havde pushet til branchen, mens den blev læst.
Så godkendelsen landede på den forrige version. Revieweren brugte sin opmærksomhed på kode, der ikke længere fandtes, da han var færdig — og medmindre repositoryet afviser forældede godkendelser, når der kommer nye commits, sidder det grønne flueben nu på kode, ingen har læst. Værre end en ureviewet pull request, som i det mindste ser ureviewet ud.
Ingen brød en regel. Det er pointen: der var ingen. “Klar til review” var et mærkat, hvem som helst kunne sætte på når som helst, og som betød alt fra “det her er færdigt, læs det venligst” til “denne branch findes”. Et signal, der kan betyde to ting, betyder ingenting, og hundrede af dem betyder ingenting hundrede gange.
Det forklarer også månederne. En pull request, der har ligget åben siden foråret, er ikke en, nogen bliver ved med at beslutte at udskyde; ingen beslutter noget som helst om den. Den holdt op med at være en forespørgsel den dag, den ikke længere kunne skelnes fra de andre nioghalvfems — derefter er den en række i en liste og en branch, der stille ældes op mod en kodebase, der er kørt videre under den.
Hvad jeg gjorde rigtigt, og hvad det ikke rørte ved
Alt, jeg har indført her, kommer af én sætning: hvert faktum findes i præcis ét artefakt.
Hvad der er brug for og hvorfor bor i opgaven. Hvad der er ændret og begrundelsen bor i pull requesten. At der ønskes et review bor i selve forespørgslen. Hvorfor en ikke-oplagt linje ser ud, som den gør, bor i en kodekommentar.
Pointen er ikke ordentlighed, men omkostning. Det samme faktum fire steder koster den, der skriver det, og som taster det igen — og hver eneste læser bagefter, der nu har fire kilder, som var enige den dag de blev skrevet, og som har drevet fra hinanden lige siden. At gentage opgaven i pull requesten og pull requesten i chatbeskeden er den største enkeltkilde til oppustethed i det, vi producerer — og oppustethed er ikke et stilproblem. Det er grunden til, at ingen læser noget af det.
Der, hvor det har virket, er dokumenter. Opgavebeskrivelser har loft på fyrre linjer, struktureret som Problem, Forventet, Acceptkriterier. Pull request-beskrivelser har loft på 250 ord, og en triviel ændring får fem linjer og ingen overskrifter: ingen testtal, ingen “CI grøn”, ingen filoversigter, for CI melder sin egen status, og diffen viser sine egne filer. At skrive det ud igen producerer bare en mere forældet kopi af det, der allerede står på skærmen, og skubber det ene, kun forfatteren ved — hvorfor — længere ned på siden.
Min favorit, og den folk diskuterer: når din forståelse af en opgave ændrer sig, omskriver du beskrivelsen. Du tilføjer ikke. Ingen “revideret”, ingen “erstatter”, ingen dateret ændringslog inde i beskrivelsen. Det føles som at ødelægge beviser, og det er det ikke — værktøjet gemmer historikken, ligesom git gør. Dagbogsudgaven efterlader læseren med selv at regne ud, hvilket afsnit der stadig er sandt, hvilket er præcis det arbejde, beskrivelsen fandtes for at gøre for dem. En opgave siger, hvad der er sandt nu.
Den regel virker, fordi den styrer hvor et faktum skrives ned, og at skrive er en bevidst handling, en konvention kan gribe. Den har ikke det mindste tag i, hvor en forespørgsel bliver besvaret. En konvention kan fortælle dig, hvor du skal lægge noget. Den kan ikke få nogen til at samle det op.
Og det er den ærlige facon på mine første måneder her. Jeg skrev regler for artefakterne, fordi artefakterne er den del, en nyankommen kan ændre alene, og gik så ud fra, at den menneskelige halvdel ville følge dokumenterne ind i orden. Det gjorde den ikke. Dokumenterne er blevet klart bedre. Flowet omkring dem er det samme rod som før, og nu er det et rod med velformateret indhold.
At vælge er at fjerne noget
At vælge lyder som at tilføje en regel. Det er det ikke. Hele bevægelsen går ud på at fjerne noget.
Ét sted at spørge, og det er GitHub. Et review bestilles på pull requesten, med GitHubs egen review request. Det er hele rutebeslutningen.
Ingen code review-kanal. Det er den del, der koster noget, for kanalen virker — folk skriver i den, det er en rimelig ting at gøre, og jeg er den, der har bedt kolleger om at bruge den. Den ryger alligevel. Et andet korrekt sted at spørge er det, der skabte problemet, og at beholde det, fordi det er harmløst i sig selv, er præcis sådan, vi endte med fire ruter. Man kan ikke halvvejs vælge.
GitHub vinder af grunde, der intet har at gøre med, at det er bedre software. Forespørgslen bor ved siden af det, der bliver spurgt om, så der er intet mellemrum mellem notifikationen og arbejdet. Dens tilstand overlever alt — en genstart, en ferie, en glemt mention. Og den afhænger ikke af, at nogen husker, hvilket er den egenskab, alle de andre muligheder manglede.
Opgavesystemet beholder sit job, som er status, ikke forespørgsler. Opgaven bevæger sig gennem sine statusser, så tavlen er et ærligt billede af, hvor udviklingen faktisk er. Det er ikke der, man beder om et review; det er der, man kigger for at se, hvad der sker.
Snart holder de to op med at blive opdateret i hånden. Når en pull request bliver merged, skal opgaven flytte fra code review til klar til release af sig selv. Det er ét-faktum-reglen rettet mod status i stedet for prosa: om noget er merged, er et faktum, GitHub allerede ejer, og hver manuel statusopdatering er en kopi nummer to af det, holdt i trit af et menneske, der har travlt. Kopier driver fra hinanden. En projektion kan ikke.
Og så vanen: din pull request-indbakke. GitHub har én på github.com/pulls/inbox — alt, der venter på dig, i én liste, med et tal på. Kig i den ofte, og specifikt kig i den, før du starter en ny opgave. Den placering gør det meste af arbejdet: den lægger review på det tidspunkt, hvor du alligevel er mellem to ting, i stedet for at bede dig afbryde dig selv — og den betyder, at køen bliver kortere, hver gang nogen starter noget nyt, i stedet for længere.
Og en pull request forbliver et udkast, indtil forfatteren mener, den er klar til release. Ikke klar til at blive læst — klar til release, med ændringen allerede på staging og gennem accepttest. Udkast er standardtilstanden, og et udkast koster ingenting at åbne.
Det vender det, vi havde, på hovedet. “Klar til review” var standardtilstanden, og det er derfor, det ikke bar nogen information, og derfor nogen kunne godkende en version, forfatteren stadig arbejdede på. Gør “klar” til en bevidst handling, og det begynder at betyde noget igen — og “pusher jeg stadig til den her?” bliver forfatterens spørgsmål at besvare på forhånd i stedet for reviewerens at opdage bagefter.
Én opgave, én pull request. Hvis en opgave kræver mere end én, er den ikke én opgave: bryd den op i delopgaver, og giv hver af dem en pull request. Jeg regner med mere diskussion om det her end om noget andet, og det er den, jeg vil forsvare hårdest, for det er egentlig ikke en regel om sammenkædning. Det er en mekanisme, der fremtvinger opdeling. I det øjeblik man er ved at åbne pull request nummer to på den samme opgave, har opgaven fortalt en, at den var for stor — og den fortæller det på det tidspunkt, hvor det stadig er billigt at dele den, i stedet for fire måneder senere, når nogen skal reviewe resultatet.
Det er også det, der gør automatiseringen mulig. “Når en pull request bliver merged, flyttes opgaven til klar til release” betyder kun noget, hvis en opgave har én pull request. Med tre er den tvetydig, nogen skal træffe afgørelsen, og så er vi tilbage ved et menneske, der holder to systemer i trit i hånden.
Til virkelig stort arbejde får forældreopgaven en feature branch, og delopgavernes pull requests peger på den branch i stedet for master. Forælderen merges én gang, når det hele er færdigt. Det giver ét sted at følge tilstanden på et stort stykke arbejde, uden at nogen lader som om, det nogensinde var én ændring.
Jeg skal være ærlig om modsætningen i den sidste. Jeg har andetsteds argumenteret for at samle os om én langlivet branch, og en feature branch er en langlivet branch. Den skelnen, jeg vil holde fast i, er varighed og ejerskab: denne her lever, så længe én forældreopgave lever, og bliver slettet med den, hvor de development-, staging- og production-brancher, vi er ved at afvikle, lever for evigt og stille samler divergens. Det er en afgrænset undtagelse snarere end en kovending — men det er en undtagelse, og hvis jeg om nogle måneder finder de her brancher stadig i live, tog jeg fejl.
Det svage punkt er værd at sige højt. To af de her er mekanismer, og én er en vane. GitHub som eneste rute kan håndhæves, udkast-som-standard næsten. “Kig i din indbakke, før du starter noget” er en vane — i et indlæg, der i høj grad handler om, at det sidste, jeg byggede på en vane, ikke holdt.
Forskellen er, tror jeg, at indbakken er en faktisk kø og ikke en bøn om at huske. Den har et tal, det er det samme tal i morgen, og den tømmer ikke stille sig selv, når din opmærksomhed flytter sig. Det er et bedre fundament end en chatkanal, man skal komme i tanke om at åbne. Men det er stadig en vane, og hvis den fejler, fejler den på samme måde.
Hvordan et stykke arbejde faktisk ser ud
Der kommer en stor opgave, eller et lille projekt. Og så, nogenlunde i denne rækkefølge:
Jeg designer en løsning på det. Jeg bryder den op i opgaver og delopgaver. Jeg kontrollerer, at hver applikation, tingen rører ved, kan tale med de andre på den måde, designet forudsætter — og det er dér, de fleste ubehagelige overraskelser bor, for at to systemer er enige på et diagram, er ikke det samme som at to systemer er enige om en payload. Jeg kontrollerer, at det er sikkert, i de grænseflader hvor det er nemt at være doven. Og jeg bliver ved med at spørge, om resultatet stadig er noget værd for dem, der bad om det, for det er fuldt ud muligt at designe noget, der er korrekt, velopdelt, sikkert — og uden værdi for nogen.
Det er begge halvdele af titlen i ét stykke arbejde, og det er den ærlige grund til, at de står på samme visitkort. Designet er arkitekthalvdelen. Alt efter den første sætning er projektlederhalvdelen, og den er længere.
Jeg planlægger det meste af det sammen med Claude. Ikke for at få skrevet planen — for at forhøre den. Jeg lægger en tilgang ind og spørger, hvad der er galt med den, beder om de alternativer jeg ikke har tænkt på, spørger hvad hver af dem koster. Den er rigtig god til det, og den er hurtig nok til, at det at vurdere tre designs ikke længere er noget, man springer over, fordi man allerede har brugt en formiddag på det første.
Den har én fejltilstand, man aktivt skal styre: den er imødekommende. Skub en middelmådig idé frem med selvtillid, og du får ofte hjælp til at gøre den bedre frem for et kontant “det her har den forkerte facon”. Så når en beslutning betyder noget, eller når jeg er reelt i tvivl, tager jeg den videre til en anden og nogle gange en tredje kollega.
Det er ikke en formalitet. En model hjælper mig med at tænke, og den fortæller mig ikke, at jeg er den tredje i år, der foreslår det her, eller at sidste forsøg faldt på noget, ingen skrev ned. Institutionel hukommelse bor ikke i et kontekstvindue. Den bor i de mennesker, der var her.
At skære i tre retninger
Det andet initiativ er kedeligere at beskrive og betyder formentlig mere: projekter bliver brudt op i delprojekter, hver især små nok til rent faktisk at blive færdige, hver især med forretningen inde over undervejs frem for til sidst.
Grunden er ikke planlægningsæstetik. En bid, der tager fire måneder, producerer præcis ét øjeblik, hvor nogen uden for arbejdet kan reagere på det, og det øjeblik indtræffer, efter at alle de dyre beslutninger er truffet. Man får ikke feedback, man får en dom. Og den producerer også noget andet, som dette indlæg allerede har brugt to tusind ord på: en pull request, ingen kan reviewe. Bjerget er ikke kun et vaneproblem. Nogle af de brancher er simpelthen for store til at læse, og det var de allerede den dag, de blev åbnet.
Der er en anden grund, og den handler om mennesker snarere end feedback-sløjfer.
Planen er lang. Ét sprog bag det hele, den samme facon i hvert repository, to adminportaler der bliver til én — det måles i sæsoner, og det har jeg sagt offentligt. Sagt i sin helhed motiverer sådan en plan ingen. Den er en mur. Og vi har en stribe af dem i kø, hver især værd at lave, hver især måneder dyb.
At bryde dem op gør dem ikke kortere. Månederne er stadig månederne. Det, der ændrer sig, er, hvor ofte man får bevis for, at tingen virker, og det viser sig at være dét, der afgør, om folk bliver ved. Et dusin projekter på flere måneder er en stemning. De samme tolv, hvor den første skive af hver bliver færdig inden for fjorten dage, er noget, man kan rumme i hovedet og blive ved med at gå efter — for man kan se det bevæge sig.
Det er undervurderet som grund til at planlægge ordentligt. Ikke for at planen er rigtig — det bliver den ikke — men for at afstanden mellem “vi blev enige om at gøre det her” og “der skete noget” er kort nok til, at folk bliver ved med at pege den vej. Det er prognose frem for planlægning: man bliver ikke bedre ved at forudsige hårdere, man bliver bedre ved at forkorte intervallet, før virkeligheden fortæller en noget. Forbeholdet er, at en velopdelt plan er nem at blive ved med at følge, efter den er holdt op med at være rigtig. Skiverne er små, så man kan skifte mening mellem dem, ikke så man slipper for at skulle.
Det er også den mindst synlige del af jobbet. Jeg hjælper vores produktchef med at bygge og vedligeholde roadmappet, og det meste af det arbejde handler ikke om at beslutte, hvad der skal stå på det — idéer er ikke den knappe ressource her — men om at beslutte, hvad en linje på det må betyde. En post, der ikke kan blive færdig inden for et kvartal, er ikke en plan, men et ønske med en dato på. At bryde de poster ned, indtil hver enkelt er noget, der faktisk kan afsluttes, og så blive ved dem til de gør det, er det meste af, hvad “at sikre at vi når vores mål” viser sig at bestå af. Det er uglamourøst, og det er forskellen på et roadmap, der beskriver året, og et der forudsiger det.
Det svære er, at en skive skal tilfredsstille tre publikummer på én gang.
Den skal være til gavn for brugerne — levere noget, en uden for teamet kan bruge, eller i det mindste se. Den skal være overkommelig for udviklerne — lille nok til at rumme i hovedet, reviewe i én ombæring og opgive uden sorg. Og den skal være fornuftig for forretningen — et skridt, nogen kan sige ja eller nej til, i termer der ikke handler om kode.
Rammer man ikke alle tre, gør opdelingen ingenting. Den fejl, jeg har set mest, er at skære efter udviklervenlige linjer, fordi de er nemmest at planlægge: alle datamodellerne, så alle endpoints, så alle skærmene. Fuldstændig fornuftig ingeniørrækkefølge — og den producerer måneders arbejde, som ingen udefra kan vurdere, fordi intet af det er en ting endnu. Man har delt arbejdet op uden at dele risikoen op.
To former, det tager hos os.
Udgiv det til os selv først. Et nyt analyseværktøj går til GolfNext-ansatte alene, i en uge. Derefter udvides det, og det, det udvides til, formes af, hvad alle sagde. Denne blog har før indrømmet, at vi ikke har nogen gradvis udrulningsmekanisme, og at vores første rigtige ring er geografi — nogle få nærliggende klubber og en genopretningsplan, der involverer tyve minutter i en bil. Ansatte-først er en ring, der ligger før den, koster ingenting og kunne findes i denne uge. Det er ikke en canary-deployment. Det er den billigst tænkelige måde at opdage, at noget åbenlyst er galt, før en klub gør det.
Refaktorér ét modul ad gangen. Ikke hele systemet, og heller ikke en tilfældig skive: ét snit, hvor alle tre betingelser holder på én gang. Brugerne får noget, udviklerne får et stykke, de kan gøre færdigt, forretningen får et skridt, det er værd at finansiere. Det er den samme disciplin som sømme-før-rewrites-reglen, jeg har argumenteret for et andet sted. Det nye er, at det at finde snittet er arbejdet. Det er ikke en planlægningsformalitet, man overstår, før det rigtige job begynder.
Jeg vil nødig oversælge det. At skære dårligt er værre end ikke at skære, for et dårligt snit leverer en halv feature og lærer alle, at inkrementel levering betyder ufærdige ting. Kunsten ligger i, hvor kniven sættes, og det tror jeg ikke, man kan skrive ned som en regel. Det er den del af dette job, jeg vil forsvare som noget, der faktisk kræver dømmekraft — hvilket er ubehageligt at indrømme i et indlæg, der ellers argumenterer for, at svaret er færre valg og flere mekanismer.
Spørgsmålet, der ligger under det hele
Vi planlægger at ændre arkitekturen og stakken: ét sprog bag det hele, én facon i hvert repository. Det har jeg skrevet om et andet sted. Det, der betyder noget her, er reaktionen. Mine kolleger er enige i, at det er en god idé. Ikke modvilligt. De synes, det er rigtigt.
Og der skete næsten ingenting i den retning, før Johann og jeg dukkede op.
Det gik mig på et stykke tid, og de dovne forklaringer er alle sammen forkerte. Det var ikke tilladelse — den her virksomhed siger ja til en idé på en dag, og jeg har fået idéer godkendt her hurtigere, end jeg kunne have booket et møde på mit forrige job. Det var ikke evner. Og det var bestemt ikke, at ingen havde tænkt på det: det er folk, der kender dette kodelandskab langt bedre end jeg gør, og jeg tør vædde på, at det meste af det, der står i vores plan, er blevet sagt højt, i en eller anden form, år før jeg kom.
Så hvorfor skete der ingenting?
Fordi enighed ikke er en mekanisme. En ting, alle er enige om, og ingen ejer, har ingen måde at starte på. Der er ingen uenighed at afgøre, så der bliver ikke indkaldt til et møde. Der er ingen kunde, der venter, så den vinder aldrig en tirsdag over noget, der har en. Det hjælper ikke, at arbejdet lignede en udifferentieret klump på flere måneder uden tidlig gevinst, hvilket er præcis den facon, ingen melder sig frivilligt til — og præcis det, opdelingen er til for. Den forbliver ganske enkelt sand og ugjort, og det at være åbenlyst rigtig gør ingenting for at flytte den. Man kan se den samme effekt i hundrede pull requests, ingen er uenige i.
Fordi der i det meste af virksomhedens historie ikke var nogen, hvis job var større end ét projekt. En stor del af vores software blev bygget af eksterne partnere, og de var dygtige. Men man engagerer en partner til at levere en ting. Ingen engagerer en partner til at ordne det, der ligger mellem tingene. Tværgående arbejde har ingen kunde, så under den model bliver det ikke bygget, og tretten års udgave af det samler sig i mellemrummene.
Fordi de folk, der kunne have gjort det, er de samme, alt andet står i kø bag. Det er bus factor set fra en anden side: den, der kender et system bedst, er den, enhver forespørgsel om det venter på, så de har mindst luft, netop fordi de har mest viden. Man omstrukturerer ikke et kodelandskab indefra den position.
Og fordi året har en facon. Golf er sæsonbetonet. Klubberne har travlt om sommeren, så vi har travlt om sommeren, og luften er om vinteren — hvilket gør vinduet for strukturelt arbejde smalt, årligt og nemt at bruge på noget mere højlydt.
Hvilket bringer mig til den ubehagelige del, og til grunden til anden halvdel af min titel.
Det, Johann og jeg kom med, var ikke bedre idéer. Det var en tom kø og lov til at spørge hvorfor. En nyankommen bærer ingen arvet backlog de første måneder, forventes at stille dumme spørgsmål og har endnu ikke internaliseret noget af det lokale “sådan er det bare”. Det er en reel ressource med kort holdbarhed; hver uge her bruger lidt af den.
Så projektlederhalvdelen er ikke der for at påtvinge proces på folk, der klarede sig fint uden. Den er der for at eje de ting, alle er enige i, og ingen har. Nogen skal omsætte enighed til en opgave med et navn på, og det viser sig at være et job snarere end en eftertanke.
Er noget af det sjovere? Dokumenterne er. En opgave, man kan læse på et minut, en pull request, der fortæller hvorfor i stedet for hvad, og betydeligt mindre gentastning af ting, der allerede stod skrevet et andet sted. Reviewflowet er ikke sjovere. Det er diagnosticeret, hvilket ikke er det samme, og hver eneste løsning ovenfor er højst fjorten dage gammel.
Og derfor er køen ubehagelig at skrive om. Det er den samme fejl som den, jeg lige har brugt fire afsnit på at forklare, i mit eget område, på min vagt.
Alle er enige om, at de hundrede pull requests bør reviewes.
