Kolofon
Slik ble dette laget
Hvert valg bak dette nettstedet, hvorfor det gikk den veien og ikke den opplagte, og hva som skulle til for å få meg til å skifte mening.
Dette nettstedet har ingen rammeverk, ingen byggesteg og ingen avhengigheter. Det er PHP-filer på en server med innholdet liggende i JSON ved siden av. Jeg valgte det slik, og nesten alt som står lenger ned følger av det valget.
Oppdraget er uvanlig, og hver eneste begrensning her er valgt for akkurat det: én forfatter, et laboratorium og ikke et produkt, en utrulling som aldri skal trenge en byggemaskin mellom kildekoden og sida, og et krav om at det som kjører ute er nøyaktig det jeg skrev i editoren. Faller én av de fire bort, faller de fleste svarene her med den. Der et valg ville vært feil et annet sted, sier jeg fra.
Prisen står på den andre sida av regnskapet, og den er verdt å nevne: ingen hot reload, intet komponentbibliotek, ingenting som sjekker typer. Det som fanger opp en feil her, er at jeg leser den, eller at røyktesten henter hver eneste side og ser etter hvordan de slutter.
Per 8 October 2026 er dette 62,189 linjer PHP fordelt på 160 filer, 63,700 JavaScript og 22,304 CSS. Rundt 148,193 linjer i alt, og ingenting av det er kompilert, minifisert eller generert.
Hvorfor det ikke finnes en database her
Det ligger ingen database her, og det er ikke en mening om databaser. På alt som er tyngre enn dette henter jeg en tidlig og uten å diskutere det med meg selv. Ekte volum, flere som skriver, noe som trenger en transaksjon eller en join: det er der et relasjonslager hører hjemme, og det er der det meste av det jeg bygger på alvor begynner.
Her er det feil svar, og grunnene er så spesifikke at de ikke ville tålt å bli gjort om til en regel. Innholdet er noen hundre kilobyte og blir aldri mer. Det er nøyaktig én som skriver, og det er meg. Ingenting trenger en transaksjon, en join eller en spørringsplanlegger. En database ville på sin side gitt meg en tjeneste til å holde i live, legitimasjon å oppbevare, et skjema å migrere og en backup-historie ved siden av den filene allerede har. For et laboratorium på denne størrelsen er det kostnad og ingenting annet.
Så hvert prosjekt, hver sangtekst, hvert fotografi og hver melding er en JSON-fil i en katalog utenfor webroten. Det gir meg to ting på én gang: ingenting der inne kan hentes over nettet, og en utrulling kan aldri skrive over noe jeg har skrevet i panelet.
Å vite hvilken av de to situasjonene man står i, er mesteparten av faget. To ting ville snudd det her: én skribent til, eller noe som trenger en transaksjon. Da er det en database, og det med en gang. Radene jeg allerede har, har formen til en tabell, så flyttingen er en ettermiddags arbeid og ikke en omskriving. Det er den egentlige prøven på om et enkelt valg er håndverk eller latskap: om jeg kan si nøyaktig hva som ville fått meg til å ombestemme meg, og hva det kommer til å koste meg den dagen det skjer.
Det som erstatter det en database ellers gir deg
Skrivinga er atomisk. En fil skrives under et midlertidig navn og døpes om over den gamle, så en lagring som blir avbrutt halvveis lar forrige versjon stå hel i stedet for å etterlate halvparten av hver.
Hver skriving tar også vare på det den erstattet. 5 versjoner av hvert register står på ei hylle ved siden av, stemplet til millisekundet. Atomisk skriving var aldri den egentlige faren. Faren er en fullstendig og teknisk korrekt lagring av feil innhold, som ser ut nøyaktig som en god en helt til noen oppdager hva som mangler. Hylla står der på grunn av en dag da noe manglet.
Det er 34 registre i alt. Hvert av dem er sin egen fil, og hvert av dem kan hentes tilbake for seg.
Editoren er blokker og ikke et lerret
Sider settes sammen av blokker med kjente typer i stedet for å skrives inn i et rikt tekstfelt. En contenteditable-flate gir deg HTML som nettleseren har skrevet, og den må vaskes på vei inn og stoles på på vei ut. Her lager sida HTML-en selv, så det er ingenting å sanere, og hver blokk tegnes i sidas egne komponenter.
Det finnes 9 typer. Tekst tar fire merker og ikke flere: fet, kursiv, kode og en lenke. Alt escapes først, så ingenting jeg skriver kan bli til markup ved et uhell.
Dette er den begrensningen jeg ville forsvart dårligst på generelt grunnlag. For et lag som lager hundre sider i uka er det feil bytte, og da tjener en skikkelig editor inn kompleksiteten sin mange ganger. For én person som skriver med omhu fjerner den en hel kategori problemer og koster nesten ingenting.
Tall som teller seg selv
En side kan bære et merke som de i avsnittet over, og det byttes ut med et tall når sida tegnes. Mekanismen finnes på grunn av én bestemt tabbe: her sto det en gang at nettstedet var tre hundre linjer PHP. Det stemte den dagen jeg skrev det, og var bommet med en faktor på femtisju neste gang noen leste det.
En kolofon som ikke har annen verdi enn å stemme, har ikke råd til et tall som råtner. Så tallene som råtner måler jeg i stedet for å skrive dem, og kildekoden telles én gang hver sjette time og ikke ved hvert besøk. Hvert eneste tall på denne sida virker slik, tellingen over inkludert, som ble tatt 8 October 2026 og oppdaterer seg selv. Skulle et tall her noen gang være feil, er det koden som er feil og ikke teksten.
Språket ligger i adressen
Engelsk ligger på de vanlige adressene, norsk under /no/. Det er ikke en smakssak. En adresse skal bety det samme for alle, alltid, og et språk som bor i en informasjonskapsel gjør den om til noe som betyr forskjellige ting for forskjellige folk.
Jeg har målt at det ikke står noen delt cache foran sida i dag. Regelen står likevel, som en forsikring mot den dagen noen setter en der.
Velgeren faller begge veier: finnes det ikke norsk, får du engelsk, og finnes det ikke engelsk, får du norsk. Den sier også fra om hvem som svarte, og det er den ene opplysningen som gjør at panelet kan liste opp alt som viser feil språk akkurat nå, med lenke rett til skjermen som redigerer det. Et felt uten suffiks leses som den engelske kolonnen, så ingenting jeg skrev før delinga gikk tapt.
Forsida er det eneste stedet noen i det hele tatt blir sett på, og den sender uansett no-store fordi bildet roterer. Ber nettleseren om norsk, og du ikke har valgt selv, blir du sendt videre til /no/ med Vary og no-store på selve omdirigeringen. En cachet 302 der ville sendt hele verden til norsk. Signalet er nettleserinnstillingen og aldri en adresse: en nordmann i Berlin og en brite i Trondheim er begge helt vanlige lesere her, og innstillingen har rett om begge to.
Noe av det er engelsk med vilje og skal fortsette å være det. Tavla ga ledetekstene sine på engelsk i Norge også, og det samme gjør loggen fra aggregatet.
Under ligger tre linjer som tar av prefikset, og de femten reglene under dem kjører uendret på det som blir igjen. Den siste av dem bærer med vilje ingen [L], så substitusjonen mates videre. Adressen holder fortsatt på /no/ der PHP leser den, så canonical kommer riktig ut uten at hodet vet at det finnes språk i det hele tatt. Resten er én velger som faller begge veier, og en oversikt over hvilke lagerfelt som er tospråklige, ført for hånd.
Å telle folk uten å følge etter dem
Det er ingen informasjonskapsel her og ingen samtykkeboks, for det er ingenting å samtykke til. En besøkende kjennes igjen på en hash av adresse og nettleser, blandet med en hemmelighet som kastes og byttes ut hver midnatt. Den kan altså skille to personer fra hverandre i dag, og den kan ikke knytte noen til i går.
Det jeg sitter igjen med, er en dagstelling og hvilke sider som ble lest. Ingenting som fører tilbake til et menneske. Det koster meg noe, og jeg later ikke som noe annet: ingen tilbakevendende besøkende, ingen trakter, ingen kohorter, ingenting som følger en person gjennom ei uke. For en bedrift ville det vært et alvorlig tap, og da ville et skikkelig analyseverktøy vært riktig valg. For meg er det verdt mer å kunne se hva folk leser uten å sitte på noe om hvem de er, enn det er å ha grafene jeg ga fra meg.
Alt samles inn av en liten signalsender i stedet for å telles mens sida tegnes. Det koster leseren som har skript av, og det gir meg tre ting: de offentlige sidene betaler ingenting for å bli målt, de fleste robotene faller fra av seg selv, og jeg kan skru meg selv av uten at serveren trenger å kjenne meg igjen.
Kontaktskjemaet gjør jobben, ikke du
Ingen CAPTCHA. I stedet løser nettleseren din en liten hash-nøtt i bakgrunnen mens du skriver, og innen du er framme ved knappen er den ferdig. For én melding er det en brøkdel av et sekund som ingen legger merke til. For den som sender ti tusen er det ekte prosessortid, om og om igjen, og det er den eneste typen hindring som skalerer riktig vei.
En melding skrives ned før e-posten om den går ut. Leveringen er det skjøreste leddet i ethvert kontaktskjema, og et skjema som mister meldinger i stillhet er verre enn en side uten skjema i det hele tatt.
Faksen rundt kontaktskjemaet
Skjemaet over er urørt. Det poster, serveren omdirigerer, og en oppfriskning kan ikke sende det to ganger. Faksen legger sju sekunder rundt innsendingen og sender så for ekte: arket mates inn, linja ringes opp, og meldingen skrives ut én skannelinje om gangen.
Det er kvitteringen og ikke transporten. Uten JavaScript er knappen en knapp, og meldingen kommer fram akkurat like fullt.
Teksten rastres til én bit på et canvas som er 1728 piksler bredt, med en ordnet dither på fire ganger fire. Det er den ekte flekkingen og ikke en myk kant. Arket følger ordene, for en faks rullet ut det den trengte, og et kort brev på et fullt A4-ark leser som en feil på en skjerm.
To tall her er sanne om hver sin ting, og det er verdt å si hvilket som er hvilket. Forestillingen tar sju sekunder fordi noen står og ser på. Rapporten oppgir den tida en ekte Gruppe 3-faks ville brukt på nøyaktig så mange linjer. En faksrapport som lyver om tida er den ene detaljen i en faks noen faktisk ville sjekket.
Kvad-spilleren, og hvordan den følger sangen
Spilleren har et navn, som er en underlig ting å gi en del av et nettsted, og det er gjort med vilje. Kvad er det norrøne ordet for et dikt som framføres i stedet for å leses, og det er nøyaktig det denne viser: kvadet, mens det synges.
Det betyr noe fordi arbeid av dette slaget som regel blir antatt å være hentet et sted fra. Det er det ikke. Jeg skrev den for dette nettstedet, den kjører ingen andre steder, og alt som ligger bak den står her.
En sang bærer et stikkord for hver linje, og hvert stikkord har både et inn og et ut. At begge finnes, er det som gjør en pause til en ekte pause: ingenting blir stående tent gjennom et instrumentalt mellomspill, og spalten har allerede flyttet seg til linja som kommer, så et langt opphold leses som noe jeg har ment og ikke som en stans.
Stikkordene taster jeg inn for hånd, i panelet, ved å holde en tast nede mens sangen går. Alle de andre metodene jeg prøvde først krevde at jeg stoppet musikken for å skrive ned hvor jeg var, og det er den ene tingen man ikke kan gjøre mens man lytter etter et slag.
Hvor tida kommer fra
Den opplagte kilden til tid er lydelementets egen progress-hendelse. Den er feil kilde. Den fyrer omtrent fire ganger i sekundet, som holder fint for en framdriftslinje og er ubrukelig for et ord som skal treffe et slag. Et kvart sekund for sent er ikke en tegnedetalj, det er et annet ord.
Så jeg leser klokka fra skjermen i stedet. En løkke som følger skjermens oppfrisking spør lydelementet hva klokka er ved hver eneste ramme, og på en vanlig skjerm blir det seksti avlesninger i sekundet i stedet for fire. Det koster nesten ingenting, fordi arbeidet i hver ramme er en håndfull sammenligninger.
Hver løkke får et nummer når den starter, og den sjekker nummeret sitt før den tegner. En løkke som har fått et nummer som ikke lenger gjelder, returnerer uten å gjøre noe. Uten den vakta vil det å åpne spilleren en gang til etterlate to løkker som kjører mot det samme elementet og skriver til de samme nodene, og resultatet er et flimmer ingen klarer å framkalle på bestilling.
Hvilket ord som lyser, og når
Hver linje deles opp slik at hvert ord er sitt eget element. Det første forsøket klippet en lys kopi av linja fra venstre, og det virker helt til en linje brekker: et klipp er geometrisk, så det skjærer rett ned gjennom sida og lyser like langt inn i hver synlige rad samtidig. Ord er innebygde bokser, de følger linjebrekket av seg selv, og et ord er dessuten det som faktisk synges.
Hvor hvert ord begynner, lagres én gang, når sangen bygges, som en brøk av linja. Brøken vektes etter antall bokstaver i stedet for å deles likt, fordi en lik deling gir et ord på én bokstav og et på tretten like mye tid hver, og skjevheten inni én linje ser man med det samme. Bokstaver er en grov erstatning for stavelser og en usedvanlig billig en, og de treffer langt bedre enn å telle ord gjør.
Hver ramme regner så ut hvor langt inn i linja musikken har kommet, og teller ord framover så lenge den lagrede brøken er passert. At jeg teller i stedet for å runde av, betyr mer enn det høres ut som: å runde til nærmeste ord tenner det ved midtpunktet, som er et halvt ord for sent, på hvert ord i hver linje. Det var hele forklaringen bak en tidlig klage om at spilleren føltes treg.
Til slutt skyver jeg det hele nitti millisekunder fram. En visning som jager etter stemmen leses som ødelagt. En som ligger så vidt foran den leses som sang. Og bare ordene som har endret seg siden forrige ramme blir rørt, så en ramme der ingenting skjedde koster én sammenligning og null skriving.
Å tilpasse skriften til sangen
Skriften er dimensjonert etter sangen og ikke etter skjermen. Før noe vises i det hele tatt, måles hver linje i sin naturlige bredde, breddene sorteres, og den som ligger på åttiandre persentil blir bredden sangen faktisk trenger. Å dimensjonere etter den lengste linja ville krympet et helt stykke for å få plass til én uvanlig linje, og de få ekte avvikerne strammer jeg inn hver for seg etterpå.
To mindre korreksjoner ligger oppå. Linja som synges tegnes litt større enn de andre, så bredden som er å få er spalten minus den veksten. Ellers klipper uthevingen det siste ordet av den ene linja leseren ser på. Og en siste prosent holder jeg tilbake som slakk, fordi en linje som er målt til nøyaktig den plassen som finnes, likevel brekker ofte nok til at det merkes.
Ingenting av dette ber noen andre om hjelp. Det er ingen teksttjeneste inne i bildet, ingen tredjepart og ingen nettverkskall. Tidene taster jeg inn for hånd i panelet, én linje om gangen, og resten går på det som allerede ligger på sida.
Kommentarer som vet når de skal komme
En sang kan bære tidsatte notater i margen, hvert med et bilde og en bildetekst, på begge språk, og de kommer og går på stikkord. Lytteren bestemmer selv hvor mye av skjermen de får ta.
Notatene merker jeg av ved å holde en tast nede mens sangen går, og det viste seg å være den eneste redigeringsmåten som overlevde møtet med virkeligheten. Alt annet krevde at jeg stoppet musikken for å skrive ned hvor jeg var.
Sida kan leses opp
Alt som er sammenhengende tekst her, kan leses opp. Serveren har ingen nøkkel og ringer ingen tjeneste: lyden ble laget én gang, et annet sted, og ligger her som filer. Derfor virker den med modemlinja oppe og under strømbruddet, og den koster ingenting per avspilling.
Filnavnet er et fingeravtrykk av det som faktisk skal sies, regnet ut av den samme koden sida bruker når den tegner teksten. Avtrykket tas av den talbare teksten og ikke av markupen, så markup kan flyttes uten at lyden pensjoneres. Hadde generatoren hatt sin egen mening om hva som skulle leses, ville de to aldri møtt hverandre, og knappen ville aldri dukket opp. Endrer jeg et ord, peker sida på en adresse som ikke finnes, og knappen går med den. Det er den riktige måten å feile på: heller ingen stemme enn en stemme som leser forrige måned.
Avsnittet som leses markeres i margen, og et klikk hopper dit. Merkene bindes til teksten på ordene og ikke ved å telle. Telling forutsetter at uttrekket og malen går gjennom kroppen i samme rekkefølge, og den dagen en modul tegnes uten å bli lest, er hvert eneste merke etter den feil uten at noe sier fra. Å matche på ord feiler ett avsnitt om gangen, og synlig.
Den lages med ett kall per avsnitt, skjøtet sammen til én fil, og det er det som gir et stikkord per avsnitt i stedet for ett for hele stykket. Det er også det som gjør at man kan hoppe inn i en opplesning i det hele tatt.
Galleriet gjør regnestykket tidlig
Fotografier legges ut i justerte rader, og radbruddene regner jeg ut på serveren i stedet for i nettleseren. Målene på hvert bilde er kjent før noe sendes, så radene ligger fast i markupen og sida kan ikke flyte om mens bildene kommer inn. Gallerier som gjør dette etter innlastinga er de du ser stokke seg på plass.
Kulepanoramaene brettes tilbake rundt den som ser på, av en shader som for hver eneste piksel på skjermen regner ut hvilken retning øyet ser i og hvilken del av bildet som ligger den veien. Ingen kule, ingen trekanter, intet bibliotek, rundt hundre og tjue linjer.
Ingenting leser posisjonen som ligger lagret i et fotografi. Den fjernes ikke i etterkant. Den leses aldri.
Akser, ikke temaer
Utseendet er 4 uavhengige akser: designet, paletten, layouten, og det som driver omkring bak teksten. Ingen av dem vet om de andre, så hver eneste kombinasjon er gyldig, og det finnes 875 av dem.
Ferdigpakkede temaer ville låst farge til skrift, og da hadde jeg aldri oppdaget at én kombinasjon slår begge de helhetlige forslagene den var satt sammen av. Det er hele argumentet for å bygge det på denne måten. Det har lønt seg én gang, og det holdt.
En periode av året kan ta over det hele. Et navngitt datospenn bærer sine egne bilder, sine egne ord over dem og sitt eget utseende, og den smaleste perioden som treffer vinner. Julen slår altså vinteren uten at noen av dem trenger å vite om den andre.
Båndet over tittelen tar bildets egne proporsjoner opp til 660 piksler i høyden, og beskjærer over det. En plate med ord som svever midt i en hel masse tom himmel så verre ut enn en kant som mangler.
Bildet øverst velges av sola og været
Bildet over tittelen er verken tilfeldig eller en liste over årstider. En regel sier når den gjelder, og en variant inne i den sier under hvilken himmel. Radene er sola, kolonnene er været, og en celle er et bilde. Formen er et rutenett fordi en tom celle da er synlig. Med en liste ser du bare det som finnes, og spørsmålet om det finnes noe for en regnfull natt blir et spørsmål du må telle deg fram til svaret på.
En regel som ikke kan tegne noe, er ikke i kraft. Har julen bare et snøbilde og det ikke er snø, trer julen til side og stigen går videre ned til gulvet. Alternativet er et blankt bånd på den ene dagen i året du gledet deg til.
Trekningen mellom flere kandidater er sådd av dagen og aldri tilfeldig, så alle som åpner sida på samme dag ser det samme, og benken i panelet forteller sannheten om en dato i stedet for å kaste en ny mynt hver gang noen ser på den.
Sola og været hører til stedet bildene kommer fra, aldri til den som er innom. Det er et faktum om Melhus og ikke om deg. Sola regner jeg ut i grader over akkurat det stedet, og leser den aldri av en klokke: på 63 grader nord kommer den høyest opp i 3,27 grader midtvinters, og det ligger inne i det båndet som heter kanten, mens sola midtsommernatt står under horisonten. En klokke ville kalt det første dag og det andre natt. Været kommer fra Meteorologisk institutt via den planlagte jobben, og regnes som ukjent så snart det er over tre timer gammelt, så en regel som trenger vær fyrer aldri på en gjetning.
Den sene timen, og sola over Melhus
Etter mørkets frembrudd tegnes forsida mørk. Det er sola over Melhus som avgjør det, regnet ut for 63,29 grader nord med en funksjon PHP allerede har med seg. Solnedgangen her faller like etter halv tre midtvinters og like før halv tolv midtsommers, så vinduet svinger ni timer i løpet av året, og den korteste dagen er fire og en halv time mot tjue og en halv i juni.
Den besøkendes egen klokke var min første tanke. Ingenting i en webforespørsel forteller hva klokka er der leseren sitter, og hver eneste måte å gjette det på er verre enn den forrige. Under den ligger det et problem til. På denne breddegraden ville en linje som sa at det er mørkt der du er, vært usann for det meste av landet en sommerkveld, og en setning som tar feil én gang blir ikke trodd igjen. Sola over én bygd kan jeg regne ut på minuttet, og den ber leseren om ingenting.
Linja over tittelen bærer det begge veier. Etter mørket hilser den på bygda og sier når lyset kommer tilbake. I dagslys sier den når lyset går, og når dagen er kortere enn seks timer eller lengre enn nitten, sier den hvor lang dagen er i stedet, for da er lengden det mer interessante tallet.
Under mørket er hele sida tilslørt, og et utent stearinlys står ved siden av notatet i margen med én linje som ber deg tenne det. Trykker du, løftes sløret og sida kommer opp. Blåser du det ut, kommer natta tilbake. Det lille krysset under tar bort tilbudet, og gir det ikke igjen.
Tenninga huskes i åtte timer, som er én natt. Den første utgaven husket den for godt, og virkningen var at den sene timen skjedde nøyaktig én gang per nettleser: hver natt etter den første var en helt vanlig side, og ingen ville noen gang fått vite hva de gikk glipp av. Et stearinlys brenner ned, så minnet om det brenner ned med det.
Den som har trykket Dagslys får være i fred. Et nettsted som slukker lyset over noens uttalte ønske har sluttet å være til hjelp og begynt å være lurt. Så lenge det er sola som bestemmer, sier temaknappen i toppen Følg lyset i stedet for å navngi et tema, siden det på det tidspunktet ikke er valgt noe tema og mørket på skjermen ikke er en innstilling.
Notatet i margen beholder overskriften sin og bytter det som står under, én gang per tenning, seks ganger. Den sjette blir stående. Rotasjon av det slaget er forskjellen på en spøk og et tapet: det er en belønning for å komme tilbake, og ikke noe som bare skjer med deg.
Har du mus, finnes det et lys til, og det følger pekeren. Det er et hull skåret i slørets egen maske. Å legge en lys flekk oppå et forheng løfter bare fargen på forhenget og gir deg grått. Å ta forhenget vekk viser sida i full styrke, og der går hele forskjellen mellom en side som ser opplyst ut og en som er det. En varm skive rir over hullet og bærer ingenting annet enn fargen på flammen.
Det skriver én gang per animasjonsramme uansett hvor fort musa flyttes, og jeg hopper helt over det der det ikke finnes en ekte peker. En telefon har ingenting å bære et lys med, og en glød parkert i hjørnet av en berøringsskjerm ville vært verre enn ingen glød i det hele tatt.
En kontroll som ikke roper ulv
Lenkeregisteret spør hvert sted omtrent én gang i døgnet om det fortsatt finnes, 12 om gangen, og sier ingenting før ett av dem har feilet 4 dager på rad. Selv da sier det bare fra. Ingenting fjernes noen gang.
Dommen har tre verdier og ikke to, og den tredje er den viktige. Bare to ting regnes som borte: ingenting svarte på det navnet eller den adressen, eller noe svarte og sa at sida ikke finnes. Et sertifikat som ikke lar seg verifisere, en omdirigeringssløyfe, en server som er kort i tonen mot en robot: det er fakta om denne enden eller om været, og de får ingen stemme.
Den tredje verdien finnes på grunn av en feil jeg gjorde under byggingen. På en maskin uten sertifikatbunt kom hver eneste adresse i registeret tilbake som uoppnåelig, og en kontroll som fikk lov til å trekke en slutning av det, ville erklært hele registeret dødt i løpet av fire dager. En alarm som går når ingenting er galt, er en alarm folk lærer seg å overse, og en alarm folk overser er verre enn ingen alarm, for nå tror alle at de er dekket.
Privat betyr fraværende
Halve registeret kan merkes privat. En privat lenke er ikke skjult med et stilark og ikke brettet bak en bryter. Den er ikke skrevet inn i sida i det hele tatt for den som ikke er logget inn.
Å skjule noe og å la være å sende det er to ulike garantier, og bare den ene overlever at noen åpner kildekoden. Enhver side som varierer etter hvem som spør, nekter samtidig å bli mellomlagret, for en kopi som bærer den private halvdelen skal aldri gis videre til neste besøkende fra en kant.
En notisbok serveren ikke kan lese
Bak panelet ligger det en notisbok for de tingene som er verdt å ha med seg: servernotater, lisensnøkler, gjenopprettingskoder, et passord i ny og ne. Serveren lagrer den som én klump chiffertekst og har ingen måte å lese den på.
Nøkkelen er laget av to halvdeler som bor hver for seg. Den ene er en PIN på fire til seks siffer, og den forlater aldri nettleseren. Den andre er en hemmelighet i datakatalogen, som bare deles ut til en forespørsel som allerede har bevist at den er logget inn. Alt som kan leses settes sammen i nettleseren og forsegles igjen før det går tilbake, så en stjålet backup, en stjålet disk eller en nysgjerrig vert får støy.
Fire millioner runder strekking ligger mellom PIN-en og nøkkelen, og det tallet målte jeg i stedet for å kopiere det. De seks hundre tusen alle bruker tok sekstifire millisekunder her, og sekstifire millisekunder mot en million mulige PIN-er er ei helg med maling på én kjerne. Fire millioner er rundt fire hundre millisekunder, og det er en grei pris å betale én gang per opplåsing.
Ingenting av dette endrer taket, og sida som åpner boka sier det høyt. Den som får tak i den kjørende serveren sitter med den andre halvdelen av nøkkelen, og en kort PIN overlever ikke det. Det er en notisbok og ikke et hvelv, og navnet er advarselen. Bank, gjenoppretting av e-post, domeneregistraren, alt som låser opp alt det andre: det hører hjemme i en revidert passordhåndterer med sin egen app, og ingenting av det ligger her.
Leikr, og det som er bygget for å gå galt
Skriv leikr hvor som helst på nettstedet, eller åpne besøkstelleren nederst, og det kommer opp en skjerm med alt her som er bygget for å gå i stykker med vilje. Ordet er norrønt og betyr lek. Hver rad er en akt: noe som skjer med sida, i sidas eget maskineri, med en vei ut. Ingenting går av seg selv før du trykker, og aktene nekter hverandre: den som holder sida sier fra, og de andre venter på tur. De to under har sin egen dør på forsida, ved siden av telleren.
Aggregatet
Trykk på Off-grid, og nettet faller ut. Det som følger er det et teknisk rom ville gjort, i sitt eget ordforråd. UPS-en tar lasten og sier fra under telleren, med en ladning som tappes og en driftstid som krymper. Overføringsbryteren gir opp nettet og sender startsignalet. Reserveaggregatet drar, og lyset på sida dupper for hver omdreining av starteren, fordi starteren mates fra det samme batteriet. Det drar igjen, svakere, og igjen, og sperrer seg selv ute. Batteriet når lavt nivå, alarmen går fra hvert tiende sekund til hvert sekund, sifrene flimrer, og sida blir mørk. Så settes det et stearinlys foran deg, utent, og aggregatet er ditt.
Mørket er den samme masken forsida bruker etter solnedgang, med hullet der flammen står, så sida leses i det lyset du selv bærer. Aggregatet er én tegning, og alt på den tar imot hånda slik den ekte tingen gjør. Lokket går av med tre kvart omdreining. Bensinkanna står et annet sted og heller bare så lenge du holder tuten mot halsen, og det som bommer drypper ned og samler seg i en pøl på gulvet, akkurat der du nettopp satte fra deg lyset. Det sitter en choke der som en kald motor ikke starter uten og en varm ikke går med. Startsnora er en ekte kjede av punkter på ei fjær og vil ha fire drag. Kabeltrommelen har voltmeter, og pluggen dras over gulvet på en kabel som blir liggende der den falt, og som lar seg tråkke på. Når det først går, trimmer to spaker frekvensen og volten, og sida forteller deg hvordan det står til: feil frekvens ruller et bånd over den og legger en brumming under som følger hertzen, feil volt dimmer den, og avlesningen over aggregatet slår om til grønt når begge deler stemmer. Hold det der i ti sekunder, og nettet kommer tilbake.
Det finnes to måter å ødelegge det på. Bærer du flammen bort til bensinen, gløder halsen rødt i to sekunder før aggregatet ligger i biter på gulvet. Skyver du volten forbi to hundre og femti, gnistrer måleren på trommelen i tre før inntaket til nettstedet er stekt. Begge ender i et kort som sier hva som skjedde, med to knapper, og loggen under telleren tar vare på hele forløpet, med klokkeslett.
Hver eneste lyd lages på sida: summetonen fra en UPS-alarm, starteren, hostet, motoren som følger regulatoren og dupper når lasten kommer på, hellingen, lokket, fyrstikken, smellet. De går gjennom et lite betongrom og plasseres der tingen står, fra venstre mot høyre. Ingenting hentes utenfra, og panelet kan bytte hvilken som helst av dem mot et opptak. Hint-knappen skriver hva du skal gjøre videre rett på mørket, og får den delen den nevner til å gløde tre ganger. Meldingene skrives av en hånd, avdekket slik en penn avdekker dem, og hver eneste linje bor i panelet på begge språk.
Under det hele ligger det ikke et eneste bibliotek. Det er en tilstandsmaskin med tre veier inn og to ut; en Verlet-kjede brukt to ganger, én gang som snor på en rekylstarter og én gang som kabel med tyngdekraft og gulv; et hull i et maskebilde som følger et element du drar på; en skriptmotor for overføringen, som kan redigeres uten en utrulling; WebAudio-syntese for et dusin lyder, med et konvolverrom og panorering per kilde; og en canvas-hånd som skriver. Alt sammen henger på prefers-reduced-motion, så den som har bedt om mindre bevegelse likevel får hele spillet, med de delene som beveger seg av seg selv stående stille.
Modemlinja
Det andre merket ved telleren sier 56k. Et kort spør først, fordi dette lager lyd. Sier du ja, blir skjermen grønn på svart, og en terminal ringer opp: ATZ, nummeret, summetone, sifrene, ett ring, og så håndtrykket. Der panelet har et opptak i det fri, er det opptaket som brukes; ellers er håndtrykket bygget på lydgrafen, på samme måte som det ekte var bygget på linja. Svartonen med moduleringen sin, de to endene som presenterer seg for hverandre, en kam av prøvetoner tvers over båndet, og treningsstøyen som ender i den stillheten som betyr at det står. Hastigheten forhandles ved hver oppringing, så den blir ikke den samme to ganger.
Derfra kommer hver side slik sider kom, inne i en nettleser fra 1998: grått rammeverk med Tilbake, Fram, Oppdater og Stopp, en adresselinje, en throbber som går så lenge noe fortsatt er underveis, og en statuslinje under som sier hva den driver med. Sida måles i byte og slippes ut i den takten linja ga, blokk for blokk, i den rekkefølgen en nettleser ville tegnet dem. Tekst klippes ovenfra. Fotografier kommer i fire interlaced pass, slik en GIF kom. Andre bilder skjerper seg i fem. På fotosida kommer bildene som tegn, tegnet fra de ekte pikslene med ett tegn per celle, og de veier det de ser ut til å veie. Rundt det setter tida seg selv tilbake: en marquee, besøkstelleren i lysdioder, merker på 88 × 31, en webring, Best viewed in 800×600, og en statuslinje som begynner å rulle så snart dokumentet er ferdig. Hver av dem er en bryter i panelet.
En linje nederst teller kilobyte, sekunder, en hastighet som vandrer, og tellerskritt, til lavtakst etter fem og i helgene. Nå og da trener modemene på nytt, av og til et hakk ned for godt. Av og til er linja opptatt på første forsøk. Av og til løfter noen i det andre rommet av røret, og da står det Redial. Ti minutter uten et klikk, og leverandøren legger på. En time, og økta er over. Legg på sier det et modem sier, forteller deg hva samtalen kostet, og setter bredbåndet tilbake. Forbindelsen følger deg fra side til side gjennom økta, og ingenting annet blir husket.
Det som holder det oppe: et stempel skrevet inn i hodet før første tegning, så en side som skal komme langsomt ikke først kommer alt på én gang; en progressiv avdekking drevet av målte byte og ikke av tidtakere; canvas-avlesning av bilder fra samme opphav om til tekst; hele sida strippet tilbake med all: revert og kledd opp igjen som 1998; en skriptet terminal der hvert trinn lager lyd; og spillerens egen lyd tatt fra hverandre og sendt gjennom modemets. Det er det samme mønsteret med dør, kort og panel som aggregatet har, og det er grunnen til at den neste tingen med en dør koster meg en formiddag.
The Eagle BBS
I 1992 sto det ei tavle med dette navnet på PC-en på rommet mitt, på PCBoard, med ett modem på familiens ene telefonlinje. Dette er den, tilbake i tjeneste for nettstedet. Kortet på 56k-merket forteller historien og slår det nummeret den hadde. Nummeret er opptatt oftere enn ikke, og oppringingsboksen teller ned til neste forsøk, for én linje betydde én innringer. Når det ringer, hører du håndtrykket, og under boksen står det hva du hører: svartonen, de to tonene som finner takten til hverandre, raspet av linja som blir målt, og stillheten rett før CONNECT.
Derfra er hele sida en skjerm: åtti kolonner ganger tjuefem rader, i nøyaktig de pikslene et VGA-kort tegnet, malt til et canvas celle for celle og skalert som piksler så blokkbokstavene møtes, med de seksten fargene og terminalprogrammets egen statuslinje under. Alt kommer gjennom en kø i den hastigheten modemene ble enige om, så en meny tar ett sekund på 14400 og seks på 2400, og mellomrom hopper over. Én tast gjør én ting. Bulletinene er nettstedets egne tekster. Prosjektene er filer, listet med navn på åtte bokstaver og hentet ned med Zmodem før de kan leses. Fotografiene vises som tegn. Sangene reiser som MIDI og spilles på et lydkort du kanskje ikke har, eller som én firkantbølge på PC-høyttaleren mens ordene tegnes. Det ligger privat post på tavla og venter på den den er til, det er en vegg med plass til én linje hver, en liste over de siste innringerne, en dør med terninger, en sysop som svarer én gang, og førtifem minutter om dagen, talt ned på statuslinja og håndhevet.
Under ligger en terminal av tegnceller med sin egen tegnekø, i takt med den forhandlede linjehastigheten; sida lest som tekst av ett endepunkt, så tavla følger sida; et V.32bis-håndtrykk og en PC-høyttaler bygget på lydgrafen; og General MIDI spilt uten samplinger av webaudio-tinysynth (MIT), der topplinja er tatt ut til høyttaleren. IBMs VGA 8 × 16 kommer fra VileRs Ultimate Oldschool PC Font Pack (CC BY-SA 4.0), og det er grunnen til at skjermen ser ut som skjermen. Det samme rutenettet skrives til et element utenfor skjermen som ren tekst, så en skjermleser får tavla som ord og ikke som et bilde av ord, og på en berøringsskjerm tegnes de tastene ledeteksten vil ta imot som knapper.
Første gangen en nettleser åpner forsida, er ikke sida der ennå. Det som er der, er nettstedets egen historie, spilt på de maskinene den skjedde på, omtrent nitten sekunder av den, og den går én gang per nettleser og aldri mer, uten lyd. En tynn strek nederst viser hvor du er, med årstallene markert der epokene skifter, og Hopp over gjør det den sier. Det samme gjør en hvilken som helst tast, et klikk eller et trykk.
Et billedrør slår seg på. Det er 1992, og The Eagle BBS svarer på én linje: ATZ, ATDT 22106221, en venting mens modemet ringer og de to endene finner hverandre på 2400 bit i sekundet, CONNECT, årstallet i blokksifre, navnet på tavla i blokkbokstaver ved siden av ørnen, spørsmålene fra PCBoard, et passord som ekkoer som prikker, og konferansen SAGA. Så går det fem år i det samme røret: nummeret er 22108057 nå, linja er ISDN gjennom en LASAT Unique 1280mi, og tavla er Worldgroup på to linjer, hvitt og cyan på blått, med en Who's on-boks, en teleconference der to stykker snakker, FidoNet-post klokka fire om natta, og en merknad om at det gamle nummeret gikk tilbake til å være familiens telefon. Bæresignalet faller, og røret kollapser til en strek og en prikk.
Prikken er throbberen til en nettleser i 1998. Den slår 22108057 om igjen, verifiserer brukernavn og passord mens et 56k-modem synger, og kobler opp på 49333. Sida er grå og satt i Times, med et banner som kommer i fire interlaced pass, en marquee, en besøksteller, årstallet som et bilde for seg selv, og dagens bilde i 256 farger. Kamera går inn i det bildet, bildet strekker seg ut i hyperrommet, og ut av blaffet kommer fotografiet slik det er, årstallet slik det er, og sida under med plata hengt opp på spikrene sine.
Fra merket som sier Intro ved telleren, eller fra linja over velkomsten, spilles den om igjen med modemene hørbare: summetonen og sifrene, V.22bis som finner bærebølgene sine i 1992, et klikk og to toner for ISDN i 1997, og hele V.34-seremonien for 56k-anropet i 1998, med svartone, bong, prøvekam, trening og den digitale susen. Kortet ved siden av sier hva alt dette var, i ord, med dagens bilde tidsatt etter farten på hvert stopp.
Reisen er også en side nå, og det er en annen ting enn introen. En film som går én gang per nettleser er feil sted for noe du burde kunne komme tilbake til, og den kan verken søkes i, leses opp eller lenkes til. Så de samme årene står på en side for seg: ni stopp fra 1991 til i dag, hvert av dem kledd i stoffet fra sitt eget tiår, med dørene inn til maskinene stående der de hører hjemme.
Alt sammen går på én WebGL-shader med to epoker i seg: et billedrør med buet glass, skannelinjer, fosfor og flimmer, og en nettside i 256 farger med ordnet dither. Oppå det ligger et rutenett på åtti ganger tjuefem tegn, malt i VGA-fonten, fire oppringinger syntetisert på lydgrafen, og et hopp i hyperrommet gjort som radiale prøver med prosedyrelle stjernestriper. Versjonen er en del av nøkkelen, så en omarbeidet reise spilles om igjen, én gang, for alle som så den gamle.
Et kort teller seks ting sida gjør når den tror ingen ser: aggregatet, parafinlampa, brannmelderen, tavla fra 1992, tavla fra 1997 og disketten. Bare én av dem har et merke å finne. Brannmelderen henger lavt i margen ved siden av velkomsten, tegnet som den ekte tingen med dekselet nede, i sidas eget blekk helt til noen trykker på den og huset flommer rødt. De fire andre finner du ved å bruke dem: riv en fyrstikk og tenn lampa når det er seint, kast hovedbryteren på nettverkssida og se etter noe som tar lasta, slå 22106221 eller 22108057 fra sentralbordet nederst på hvilken som helst side, eller skru på maskinen disketten står i.
Tre tidligere stikk var hyllester, og de er ute av tellingen fra 14. september 2026: en fot ovenfra, tre ringer å holde, en lav overflyging over sida, i ånden av Monty Pythons Flying Circus, Battlefield og Top Gun. Det som ble lånt fra hver av dem, var en idé. Ingenting fra originalene ble noen gang lagt ut: ingen musikk, ingen logo, ingen figur, intet stillbilde, ikke en eneste replikk. Det ene lånte bildet var ikke deres heller. Det var Amors fot fra Bronzinos Venus, Amor, dårskap og tid, malt rundt 1545 og lenge i det fri, som er der sirkuset fant den også.
Ingen av de seks er en demo. Parafinlampa har ni hakk på nøkkelen sin og en brann i enden av dem. Aggregatet startes på ei snor, regulatoren driver, og det mater sida gjennom en kabel du kan snuble i. Brannmelderen er tegnet som gjenstanden, og ordene som er støpt i den er satt som ekte SVG-tekst, så de holder på begge språk. De to tavlene kjører den samme terminalen, 1992 som åtti kolonner VGA-tekst malt til et canvas, og 1997 med en vindusbehandler over det samme. Disketten står i en maskin som faktisk starter, og filsystemet er data og ikke kode. Hver eneste lyd er støy og sinusbølger formet i Web Audio, med unntak av håndtrykket fra 1992, som er et opptak i det fri: to maskiner som forhandler over ei dårlig linje er ikke noe en oscillator klarer å etterligne.
Hver eneste linje leseren møter, på begge språk, redigeres i panelet.
Seglet
To vingede dyr med dragehoder som flankerer et sverd som også er et kors, over ei skive skåret med runer, og to mindre kors hengende under. Det står helt én gang nederst på hver side, og delene av det står der sida allerede setter et merke: ringen ved besøkstelleren, vingefjærene som klasp på streken over bunnen, dyrehodet som den stille døra inn til panelet.
Jeg har tegnet det, ikke plassert det. Et bilde av det ville trengt én fil for dagslys og én for ildlys, fire størrelser for fire skjermer, og det ville fortsatt vært uskarpt på en telefon. En strek er skarp overalt og koster tre kilobyte. Alt er skåret én gang, i én fil, og satt der det trengs med en transform, så hodet på vaktmerket og hodet på seglet ikke kan komme fra hverandre.
Ringen er ikke pynt som later som den er skrift. Den sier ROGER JOHANNESEN i eldre futhark, ett merke per bokstav, med en rombe der mellomrommet står. Hele rekka er dreid et halvt hakk, så bladet går gjennom skiva i en luke og ikke tvers over en rune. Seks av bokstavene er de samme tegningene prosjektene allerede bruker som merker. Fem måtte jeg skjære for dette, og de holdt seg med vilje utenfor den lista, for lekemodusen teller de navngitte runene og stopper heller enn å sette feil navn på noe.
Sverdet er hult i midten, slik en blodrenne er slipt inn i et blad, så kanalen er ekte geometri og ikke en stripe. Legg hånda på seglet, og en ladning faller ned den og sprekker i spissen i forgrenet lyn, formet slik et ekte lyn formes av den lufta det tilfeldigvis finner: del streken, dytt midten til siden, og gjør det om igjen fire ganger. Det slår aldri av seg selv.
Og det er ingen bakgrunn. Et tett, symmetrisk merke bak løpende tekst gjør bokstavene urolige uansett hvor gjennomsiktig det er, og på fem prosent har det sluttet å være et emblem og blitt brevpapir. Det ene stedet det ligger bak sida, er som en levende bakgrunn noen selv har valgt, hugget én gang inn i bunnen og stående helt stille, der nattas fakkel og strømbruddets stearinlys finner det. Begge de dekkene er masker med hull i og ikke slør lagt oppå, så hugget er allerede sterkere inne i hullet, og der lyset passerer tar streken imot og blir ravgul.
Stemmene
Tre ting på dette nettstedet svares av en språkmodell, og ingen av dem er en chat i et hjørne. Page sysopen på The Eagle BBS, og eieren svarer slik han var i 1992, fra rommet sitt, i en maskinskrivers tempo med en og annen feil tast, uvitende om alt etter det året. Spør du om noe på sida, ser han i filområdet, som er sidas eget søk tegnet som prikker, og han legger seg når klokka på tavla eller tålmodigheten hans tar slutt. Ring et internnummer på sentralbordet, ordet nederst på hver side, og møblene på forsida tar telefonen: parafinlampa etter solnedgang, aggregatet i loggform, telleren som har sett hvert eneste besøk siden 1998, draugen fra terningdøra, begge dyra på seglet samtidig, været over Melhus fra METs egne tall, og skalden, som bare snakker i vers. Null og det gamle nummeret er bylinje til tavla.
Skalden jobber også alene. Én gang hver morgen, fra cron og aldri i en sidevisning, får han det sida vet om dagen, altså datoen, sola i grader og timer, værmeldinga, bildet over forsida og tallet nederst på den, og risser fire til seks linjer inn i margen under notatet om overdimensjonering, på engelsk og på norsk som to dikt om de samme fakta. Linjene skraveres av stilarket slik summen lenger ned gjør, brenner seg inn én etter én når leseren kommer dit, og står over en linje med rene data, som er hele vitsen.
Modellen er Claude, snakket med gjennom én forespørselsform over curl, på samme måte som været hentes. Hver figur er et kort med instrukser skrevet her og redigerbart i panelet, reglene under hvert kort sier at den er et program og skal si det når noen spør, og ingenting den sier kan endre noe som helst på sida. Helt til en nøkkel legges inn i panelet, svarer hver linje med de faste ordene den hadde før noe av dette fantes, og når dagens kvote er brukt opp er hver linje opptatt.
Det er en modell brukt som figur og aldri som assistent. Personablokka er cachet, med dagens fakta lagt etter. Det er to verktøy, og begge er lesende: sidas eget søk, og et rør å legge på. Et vers kommer tilbake som strukturert svar på begge språk samtidig. Et avslag håndteres som at linja blir stille. Budsjettet telles per utveksling, per innringer og per døgn, og hver eneste av de grensene sies i figurens egen stemme. Nøkkelen ligger utenfor webroten og når aldri en side.
Tavla fra 1997
I 1997 fikk huset ISDN, og The Eagle fikk Worldgroup. Slå 22108057, fra sentralbordet, fra lista over andre tavler på 1992-tavla, eller fra kortet på Leikr, og linja kobler opp på et sekund uten at det er noe å høre: et klikk og to toner, så CONNECT 64000. Skjermen er blå med cyan rammer, slik Worldgroup tegnet den. Kontoen din fra 1992 er med over, og ved innlogging velger du ANSI-terminalen eller Worldgroup Manager, altså Windows-klienten.
Det 1997 hadde som 1992 ikke hadde, er andre folk. Teleconferencen på kanal SAGA har stamgjester, figurer en språkmodell spiller, flere av dem i samme kall, og skjermen beveger seg mens de skriver. To av dem skrev brev på den gamle tavla. /who, /p og /go virker fra hvilken som helst ledetekst. Who's on lister fire linjer. Registeret sier hvem brukerne er. Forumene bærer FidoNet-ekkotagger. Biblioteket kommer ned på 64000, som er en fil på sekunder der 1992 tok hele kvelden. E-post går ut på Internett med nattkjøringen. Internett-menyen har telnet som nekter, Usenet med bloggen som en nyhetsgruppe, og WebCast, som gir linja videre til weben fra 1998. Bak terningdøra fra 1992 ligger det en hall nå, fortalt ett trekk om gangen av den samme draugen. Sysopen er fem år eldre og kan pages inn i den samme delte skjermen.
Worldgroup Manager er den samme tavla som vinduer: en verktøylinje, et teleconference-vindu med kanalens brukerliste, forum og bibliotek som listevisninger, en nedlastingsdialog med framdriftslinje i linjas eget tempo, bilder som kommer som bilder i stedet for syttiåtte kolonner med skilletegn, og en statuslinje med klokke. Rammeverket er tegnet i stilarket og ikonene for hånd, som et tidsriktig kostyme, og ingenting av det lekker ut i sida. Hvert eneste ord innringeren møter, på begge språk, og kortet til hver stamgjest, redigeres i panelet.
Begge tavlene går på den samme terminalmotoren, fem år fra hverandre. ISDN er modellert som signalering og ikke som sang. Flere stemmer kommer i ett strukturert kall, i sitt eget tempo, mens innringeren fortsatt skriver, og hvilken som helst av dem kan pages privat. Tekstadventuret fortelles ett trekk om gangen. Windows-klienten er tegnet i CSS med sekstenfargers ikoner skåret for hånd, og den kjører det samme innholdet som vinduer og dialoger. Og det går tre broer: 1992-tavla ringer 1997, 1997 ringer weben fra 1998, og sentralbordet ringer begge.
Skapet i racket
Nettverkssida er en liste over ekte infrastruktur som dokumenterer en redundans den aldri har måttet bruke. Så den fikk det som står oppstrøms for alt sammen: skapet, med kursene i drift.
Kursene betyr noe, og reglene er byggets. Ta nettkursen ut, og reserveveien våkner og tar trafikken, som er den failoveren topologinotatet nederst på den sida har lovet i ord siden det ble skrevet. Ta den ut også, og alt der inne går uten at noe kommer til, og det er to forskjellige ord på den sida. Ta serverkursen ut, og hver tjeneste følger verten sin, for sida vet allerede hvilken tjeneste som står på hvilken maskin. Avhengigheten leses i stedet for å skrives ned to ganger.
Hovedbryteren står under lås, og låsen er grunnen til at det ikke er noen dialogboks der. Måten du hindrer at noen kaster en hovedbryter ved et uhell, er ikke en modal. Det er en lås med en lapp på. Å lese lappen er spørsmålet, å ta av låsen er samtykket, og hele greia er riktig prosedyre i stedet for et kostyme av en.
Ingenting huskes mellom besøk. Å slå av en kurs er en fysisk modell og ikke en innstilling, og en side som husket at du hadde slått av serverne, ville vært en side som løy om et ekte rack.
Enhetene er ekte knapper, så de tar imot tastatur og sier hva de er til en skjermleser, og tilstanden bor i ett attributt i stedet for i en parallell modell som kan komme i utakt med det som står på skjermen. En bryter leses som en posisjon og ikke som en farge: ned er av på hvert eneste skap som er laget. Kroppen foldes ut på en rutenettrad som går fra ingenting til én, og ikke på en høyde noen må måle i et skript og bomme på første gang et ord blir lengre.
Disketten
Det ligger en diskett på dette nettstedet, og etiketten på den er skrevet på to ganger. Den øverste linja er strøket over. Det som står nå er IKKE SLETT, og det er hele ledetråden: den forteller deg at noe ble slettet.
Veien videre er fem ekte DOS-ferdigheter, i den rekkefølgen noen faktisk lærte dem: at DIR ikke viser alt, at TYPE leser en fil, at en katalog kan lyve, at slettet ikke er borte, og at maskinen nekter å skrive fordi det sitter en sperre på selve disketten. Da må du klikke på disketten i stasjonen og skyve sperren over. Det er det eneste stedet på dette nettstedet der du må ta på en gjenstand for å komme videre.
Klokka er BIOS-ens og ikke din. Den står på mars 1992, rett etter at den siste fila ble skrevet, og den går mens du sitter der. Før det svarte DATE fra leserens egen maskin, som satte årstallet 2026 på en 386 og ga hele greia bort på én kommando.
Filsystemet er data og ikke kode: én rad per fil, med attributtet, med om innholdet er binært, og med den bokstaven DOS kastet da fila ble slettet. En ny mappe trenger ikke en linje JavaScript. Skjermen er en pre og ikke et canvas, fordi DOS skrev umiddelbart: det er ingen kø å modellere og ingen skrivehastighet å simulere, og en pre gir markerbar tekst og en skjermleser gratis.
Panelet bak sida åpner med fasiten: åtte steg, og hva hvert av dem krever at du kan. Den som setter en gåte er den eneste som ikke kan slå den opp seinere.
Fatterns 486
I desember 1994 kjøpte fattern en 486, og jeg rekvirerte den omtrent med det samme. Den står i museet nå, og den lar seg ta fra hverandre. Ta av lokket, og brettet ligger under, tegnet ovenfra med bakkanten øverst, slik man så på et. Hvert kort kan skrus løs og løftes ut, hver jumper flyttes, hver minnemodul klipses av, prosessoren løftes ut av sokkelen, flatkablene dras av, pluggene på frontpanelet tas av, avstandsbeina under brettet skrus ut. Så setter du den sammen igjen og slår den på.
Alt som kan monteres feil kan monteres feil her, og det som kommer tilbake er et symptom og aldri en melding. En prosessor matet fem volt der den vil ha tre komma tre slutter å være en prosessor, én gang, for godt, og maskinen sier ingenting om det, fordi det som skulle sagt noe er det som er borte. Et skjermkort som blir fortalt at det har dobbelt så mye minne som det har, gjentar øverste halvdel av bildet nederst. En flatkabel snudd tenner disklampa og lar den stå tent. En plugg på frontpanelet satt feil vei er en diode med strømmen feil vei, som ikke er en feiltilstand, det er ingenting. Sytten av dem ligger som en meny, rangert etter hvor langt årsaken står fra symptomet, og menyen sier bare hva maskinen gjør.
Derfor legges ingenting inn uten instrumentet som finner det. En feil du ikke kan nå innenfra maskinen er en vegg og ikke en gåte, så minnekartet, avbruddstabellen, måleren med sine tre stillinger, pipekodene på klistremerket inne i lokket, heftet som fulgte med brettet og servicedisketten er hver eneste en bygget fordi noe trengte dem. Maskinen teller ingenting for deg. Du teller soklene. Du teller pinnene bortover en rekke brettet merker i den ene enden. Du leser de to linjene som står trykt på prosessoren etter at du har tatt av kjøleribba, fordi det er kjøleribba som er i veien.
Tre stemmer sier forskjellige ting om den samme gjenstanden, og de holdes fra hverandre med vilje. Gjenstanden bærer merket sitt: silketrykket på brettet, fargene på ledningene, hjørnet som er kuttet av prosessoren. Papiret bærer regelen, trykt og derfor engelsk på begge sider av dette nettstedet, fordi en manual til et no-name-brett skrudd sammen i Taiwan var engelsk og ingen oversatte den. Og et skilt på veggen bærer meningen, fordi en produsents eget ark aldri kan si at jumpertabellen var et helvete. Arket er helvetet.
Alt i den er data. Brettet er en tabell over deler og posisjoner, så et brett nummer to er en rad og ikke en tegning. Heftet på hylla regnes ut av de samme konstantene maskinen kjører på, så en jumper jeg legger til i modellen dukker opp i boka uten at noen skriver den ned to ganger. Og minnearitmetikken som avgjør om et spill i det hele tatt starter, er én funksjon, lest av maskinen og av servicedisketten. Rundt fem hundre kontroller i språktesten holder det sammen: en plass som ikke mister noe når den tas ut blir avvist, en feil uten et instrument som avslører den blir avvist, og et norsk ord i den engelske kolonnen blir avvist.
Og når den starter, kjører den ekte spill, som er det eneste i museet noen andre har laget. Det ligger tre i esken, og størrelsene sier noe før et ord er lest: Commander Keen fra desember 1990 på 364 kB, Wolfenstein 3D fra desember 1992 på 1,3 MB, og DOOM fra februar 1995 på fem og en halv, som ikke gikk på en diskett i det hele tatt og kom som to. Keen er lisensiert for distribusjon av Apogee, og Apogees egen VENDOR.DOC ligger på disketten, der den sier på trykk at alle oppfordres til å kopiere den og sende den videre. De to andre er id Softwares sharewareepisoder, gitt bort med beskjed om å spre dem, og DOOM sitt installasjonsprogram bærer fortsatt id sine egne to linjer: SHAREWARE VERSION, PLEASE DISTRIBUTE. Alle tre ligger her urørt. Under dem ligger DOSBox, kompilert til WebAssembly av js-dos, som er fri programvare under versjon 2 av GNU General Public License, og kildekoden til alt sammen er utgitt av prosjektene selv. Ingenting annet her er lånt. Brettet og delene, heftet, diskettene, notatboka, skriveren, feilene og hver lyd maskinen lager er tegnet, skrevet og bygget på sida.
Det verten skjuler
Feilvisning er skrudd av på denne serveren og lar seg ikke skru på. En fatal feil gir derfor en side som rett og slett stopper midt i, med status 200 og ingen melding noe sted. Det kostet meg én gang: prosjektregisteret viste én oppføring av sju mens hver eneste sjekk meldte grønt.
Så nå skrives hvert krasj til en logg, legger igjen et merke i HTML-en som røyktesten finner, og skrives ut i sin helhet nederst på sida for den som bærer innloggingskaka. Altså feilvisning, for én person, på en vert som ikke tilbyr det.
Det finnes en helseside som sier rett ut hva som er i stykker, og den finnes av samme grunn som en arbeidsplass fører avviksmeldinger. Feilen ingen får høre om, er den som skjer igjen.
Avlesninga, og sida som spør seg selv
Nederst på hver eneste side står det en linje med stedet, klokka, solhøyden i grader, himmelen, og hvilken bannerregel som er i kraft akkurat dette minuttet. Sida regnet ut alt sammen fra før, og holdt det for seg selv.
Den er tom markup i sida og fylles etterpå, og det er ikke pynt. Et tall skrevet inn i HTML-en er sant for den som genererte sida og en løgn for alle som kanten deler den kopien ut til, og en klokke i en cachet side er den tydeligste utgaven av den feilen. Uten skript er det ingen avlesning i det hele tatt, og det er riktig: det er et instrument og ikke innhold.
Endepunktet som fyller den sender no-store, fordi nesten hver side her kan mellomlagres og flere sender ingen Cache-Control i det hele tatt. Klokka tikker fra serverens egen tid og forskyvning og ikke fra leserens, fordi hele poenget med den er stedet bildene kommer fra. Én henting i minuttet, og ingen i det hele tatt i en fane ingen ser på.
Én gang i timen henter sida sine egne adresser slik en hvilken som helst leser ville gjort, og skriver ned det den fikk tilbake. Sjekken som betaler for seg selv er ikke statuskoden, den er at svaret slutter med sin egen sluttagg. To ganger på én uke gikk sida ut med en fil som manglet, og med feilvisning av på serveren kom hver side tilbake som 200, med riktig innholdstype, og stoppet midt i en setning. Ingenting som ser på statuskoder ville oppdaget noen av gangene.
Og alder er en tilstand. Sjekken kjører på den maskina den spør om, så en maskin som er av kan ikke fortelle noen at den er av. Er øyeblikksbildet eldre enn tre timer, svarer sida ukjent og ikke i orden, og statussida sier det i klartekst. Et grønt lys uten et tidsstempel ved siden av er den ene tingen den sida aldri skal være.
Én planlagt jobb, med vilje
Nesten ingenting her kjører på tidsur. Den daglige sammenbrettinga av besøksloggen skjer når jeg åpner kontrollpanelet, ikke klokka tre om natta, for en jobb ingen ser på kan slutte å kjøre i en måned før noen oppdager det.
Lenkekontrollen er det ene unntaket. Å spørre andre folks servere om de finnes tar sekunder, og det kan ikke henge foran noens sidelasting. Den kjører fra ett lite inngangspunkt, sikret slik at den ikke svarer en fremmed, og avstanden mellom spørsmålene ligger i kontrollen selv og ikke i planen. Kall den hver time, og hver lenke blir fortsatt spurt omtrent én gang i døgnet. Kall den hundre ganger for hånd, og den gjør ingenting hundre ganger.
Blir planen aldri satt opp, går ingenting i stykker. Da blir lenkene bare stående uspurt.
Søk uten indeks
Søket leser hele lageret og leter, ved hvert eneste spørsmål. Det finnes ingen indeks, ingen invertert liste og ingenting som må holdes i takt med innholdet.
For et korpus på noen hundre kilobyte, som er mindre enn ett av fotografiene, ville maskineriet kostet mer enn det sparte, og det ville innført den klassiske feilen der en indeks i det stille er uenig med det den indekserer. Skulle dette noen gang slutte å være raskt, er det fordi nettstedet ble interessant, og det er et godt problem og et løst et.
Registeret som teller seg selv
Registeret er alt sammen i én liste, og det finnes for at menyen skal kunne holde seg kort. Det er derfor lista føres for hånd, med vilje. En løkke over menyen ville sett ryddigere ut og vært feil: en seksjon som tas ut av menyen skal bli stående her.
Det som hindrer at de to driver fra hverandre, er seks kontroller som feiler hvis et menyvalg mangler en rad. Kontrollert ved å fjerne et av dem og se testen slå ut.
Tallene telles mens sida tegnes, med det samme uttrykket seksjonens egen side bruker, så registeret aldri kan bli uenig med sida det peker på. Et tall skrevet inn i en setning blir feil den dagen noe legges til, og det har alt skjedd fire ganger her.
Et tall som lander rett foran et substantiv tvinger dessuten substantivet til å bøye seg etter det, så setningene er skrevet den andre veien, med substantivet først. Da er de sanne ved null, ved én og ved nitti.
Under gulvet
PHP 8.3 bak nginx, driftet i Norge. Ingen Node, ingen pakkehåndterer, ingenting som genereres ved utrulling. Filene som kjører er filene jeg skrev, og en utrulling er de filene kopiert opp. Bilder skaleres ved opplasting, renses for stedsdataene kameraet la igjen, og skrives som progressiv JPEG i fem bredder.
Satt i Young Serif, Literata og IBM Plex Mono, eller de tre bytteren står på i øyeblikket. Sikkerhetskopier tar jeg for hånd fra panelet, og de er ennå ikke satt på plan, som er den ærligste setningen på hele denne sida.