The lower-post-volume people behind the software in Debian. (List of feeds.)
Robin Linus has done some truly heroic work showing that verbatim Poker can be done in Bitcoin script as it exists today with no extensions. This is still very much a prototype. Much further along than a prototype Nokitlan is supporting games on Chia, including dominoes (this is built on the Chia gaming work of been doing as the fundamental building block and interoperability substrate). Which got me thinking: What are the best dominoes rules to play on Chia? There are many different dominoes variants, with not that much standardization. The tournaments are a four player version which has a very bridge-like feel and is obviously a complete nonstarter for remote play because it’s just begging for cheating via collusion. For two players there isn’t even a completely standardized set of rules, so that’s my excuse for pondering variants, which I’ll do now.
The double-six set of dominoes is a pretty good start for the medium, because if two players alternate discards that’s 28 turns total max is which is more than ideal but somewhat workable. But there are some things which are problematic:
There’s a lot of go-fish-like cheating, where a player is required to do something based on information only they can see. Go fish is a terrible game, it has tons of cheating by accident which small children will of course do and then learn that that’s a good thing to do. At the very start of the game a player has to do discard with a double or can use any tile they want out of their hand if they don’t have one. It’s much simpler to just make the double six be the first tile on the board at the beginning of every game.
Passing is only allowed if you don’t have a legal move to play, which is a obviously also a huge cheating problem. This doesn’t come up all that often because usually it’s counterproductive to pass, but adjudicating it after the fact is a disaster, especially in combination with tiles getting pulled from the boneyard later so there’s no way for an outside observer to tell what tiles each person had at each time from later play. It’s much better to simply allow passing at any time. If two passes in a row happen then the hand is over. It wouldn’t be too difficult to implement a rule that a player can’t do a second pass ending the hand if they have a legal move but I suspect that would result in some very cheeseball strategies where one player passes until the other player has very few tiles and then with the greater control of ensuing play easily wins the hand.
Pulling from the boneyard is awkward to implement. Notably the common four player game has no boneyard. All 28 tiles are dealt out at the beginning, 7 each to four players. It does result in some interesting hidden information play, but the lesson from Poker seems to be that when it comes to hidden information less is more, and you want it to stay relevant up until the very end instead of having everything eventually become known and then a straightforward endgame. To that end, and because this is a game mechanic I’ve long wanted to use, I think the best approach is to deal out all tiles at the beginning of the game except for one which is permanently out of play and the players don’t find out until the very end which one it is. Then the game becomes all about guessing what that tile is based on the opponent’s play and there’s lots of room for deceptive play.
There’s some random advantage to the player who gets to go first. That could be counteracted with an amount added to the final pip count like komi in Go but there would need to be some playtesting to figure out what a good value for that would be.
Putting this all together here are the draft rules of Bram’s dominoes. Needs playtesting:
Played with double six dominoes. At the start of the hand a random domino is removed from play, the double six is played out as the start, and the other 26 dominoes are dealt out 13 to each player. The first player to play is selected randomly.
Players alternate putting down a domino which extends one of the two ends of the chain on the board. They must match the number at the end of that chain with the domino they place. A player may alternately pass and must do so if they have no legal placement move.
If a player plays their last tile then they win. If both players pass in a row then their remaining tiles are revealed and which ever one of them has fewer total pips wins (possibly plus komi added to the player who went first).
Linux webhotel: hvad det er, og hvorfor det er det mest populære valg
Et Linux webhotel er en hostingløsning, hvor hjemmesider, databaser, e-mail og webapplikationer kører på en server med Linux som operativsystem. Et webhotel betyder i praksis, at flere kunder deler serverressourcer som CPU, RAM, lagerplads og netværk, hvilket også beskrives i grunddefinitionen hos Webhotel – Wikipedia, den frie encyklopædi.
Linux blev første gang offentliggjort af Linus Torvalds i 1991, og operativsystemet har siden udviklet sig til en central platform for webservere, cloud-infrastruktur og containerteknologi. I 2026 er Linux fortsat tæt forbundet med klassiske webteknologier som Apache, Nginx, PHP, MySQL, MariaDB og SSH-administration.
Linux webhotel er populært, fordi det passer til de teknologier, som mange hjemmesider faktisk bruger. W3Techs har i flere år målt, at WordPress driver over 40 procent af alle websites globalt, og WordPress’ standardmiljø bygger typisk på PHP og MySQL/MariaDB, som historisk har været tæt integreret med Linux-servere.
Et Linux webhotel skal ikke forveksles med, at brugeren selv skal kunne bruge Linux på sin egen computer. De fleste kunder administrerer deres hosting via kontrolpaneler som cPanel, Plesk, DirectAdmin eller hostingudbyderens eget panel, mens Linux primært fungerer som serverens tekniske fundament.
De største fordele ved Linux hosting: stabilitet, sikkerhed og ydeevne
Linux hosting forbindes ofte med stabilitet, fordi Linux er designet til flerbrugerdrift, procesisolering og lang oppetid. Enterprise-distributioner som Debian, Ubuntu LTS, AlmaLinux og Rocky Linux tilbyder sikkerhedsopdateringer over flere år, og Ubuntu 24.04 LTS har eksempelvis standard-support frem til 2029 ifølge Canonicals officielle livscyklusmodel.
Sikkerheden i et Linux webhotel afhænger ikke kun af operativsystemet, men også af patching, isolation, firewall-regler, backup og adgangsstyring. I praksis bruger mange udbydere teknologier som CageFS, chroot-miljøer, ModSecurity og Fail2ban til at begrænse skader, hvis én konto bliver kompromitteret.
“Security is a process, not a product.” Citatet tilskrives sikkerhedsforskeren Bruce Schneier og bruges ofte som en kort forklaring på, hvorfor hosting-sikkerhed kræver løbende vedligeholdelse frem for én enkelt teknisk løsning.
Ydeevnen på et Linux webhotel påvirkes af webserver, PHP-version, caching, disktypen og antallet af kunder pr. fysisk server. Ifølge PHP-projektets egne udgivelsesnoter har nyere PHP-versioner typisk forbedringer i ydeevne og hukommelsesforbrug, og derfor bør et webhotel i 2026 som minimum tilbyde aktivt understøttede PHP-versioner som PHP 8.2, 8.3 eller nyere.
Linux er også velegnet til automatisering, fordi serveradministration kan udføres via shell-scripts, cron-jobs, SSH og API-baserede deployments. Hvis du vil forstå operativsystemets tekniske rolle bedre, giver Hvad er Linux? – En komplet guide til det åbne styresystem en bredere forklaring på kernel, distributioner og open source-modellen.
En praktisk fordel ved Linux hosting er, at meget dokumentation, fejlsøgning og community-viden allerede er skrevet til Linux-baserede servermiljøer. Stack Overflow Developer Survey har i flere år vist, at Linux er blandt de mest anvendte platforme blandt udviklere, hvilket gør det lettere at finde løsninger på fejl i Apache, Nginx, PHP-FPM, Composer eller MySQL.
Linux vs. Windows webhotel: hvilken serverløsning passer til dit behov?
Linux og Windows webhoteller kan begge drive professionelle hjemmesider, men de passer til forskellige teknologistakke. Linux vælges typisk til PHP, WordPress, Laravel, Drupal, Joomla, Node.js og open source-databaser, mens Windows hosting især er relevant ved ASP.NET, Microsoft SQL Server og klassiske IIS-baserede applikationer.
Windows Server kræver normalt licenser, mens Linux-distributioner ofte kan anvendes uden licensbetaling til selve operativsystemet. Microsofts officielle licensmodel for Windows Server er kernebaseret, hvilket i mange hostingmiljøer gør Windows dyrere at drive end en tilsvarende Linux-platform.
| Kriterium | Linux webhotel | Windows webhotel |
|---|---|---|
| Typiske teknologier | PHP, MySQL, MariaDB, WordPress, Laravel, Apache, Nginx | ASP.NET, C#, IIS, Microsoft SQL Server |
| Licensmodel | Ofte open source uden OS-licens pr. kunde | Kommercielle Microsoft-licenser kan påvirke prisen |
| Kontrolpaneler | cPanel, DirectAdmin, Plesk, egne paneler | Plesk, IIS Manager, udbyderspecifikke paneler |
| Typisk målgruppe | WordPress-ejere, PHP-udviklere, mindre virksomheder, bureauer | Organisationer med Microsoft-stack og .NET-applikationer |
| Kommandolinje | SSH, Bash, cron, Git, Composer | PowerShell, IIS-værktøjer, Windows Scheduler |
Valget bør afhænge af applikationens afhængigheder frem for en generel idé om, at den ene platform altid er bedre. En WordPress-side uden særlige Microsoft-krav vil næsten altid være enklere at placere på Linux, mens en intern applikation bygget i ASP.NET med SQL Server kan være mere naturlig på Windows.
Når pris, teknologistak og supportniveau skal vurderes samlet, kan det være nyttigt at sammenligne konkrete hostingpakker på tværs af diskplads, PHP-versioner, backup, oppetidsgaranti og supportkanaler; oversigter som findwebhosting.dk kan i den sammenhæng bruges til at skabe et mere struktureret beslutningsgrundlag frem for kun at sortere efter laveste månedspris.
Netværkskvalitet er også en del af hostingoplevelsen, selv om den ofte overses i sammenligninger mellem Linux og Windows. For danske brugere kan lav latenstid, god peering og en stabil internetforbindelse have mærkbar betydning, og emnet hænger naturligt sammen med principperne i Billigt internet: 7 måder at få lavere pris uden at miste hastighed.
Optimal kompatibilitet: hvorfor WordPress og PHP fungerer så godt på Linux
WordPress fungerer særligt godt på Linux, fordi platformen er skrevet i PHP og typisk bruger MySQL eller MariaDB som database. WordPress.org anbefaler i 2026 fortsat moderne PHP-versioner, HTTPS og MySQL/MariaDB-kompatible databaser som centrale krav til drift.
PHP har historisk været tæt knyttet til Linux, Apache og MySQL gennem den klassiske LAMP-stak, som står for Linux, Apache, MySQL og PHP. I moderne hosting er LEMP-stakken også udbredt, hvor Nginx erstatter Apache, men Linux forbliver operativsystemet under webserver, database og applikationslag.
W3Techs har i 2026 fortsat PHP registreret som et af de mest anvendte server-side programmeringssprog på offentlige websites. Det gør PHP-understøttelse, PHP-FPM-konfiguration, OPcache og versionsvalg til konkrete kvalitetskriterier, når man vurderer et Linux webhotel.
WordPress-ydeevne afhænger ofte mere af serverkonfiguration end af temaet alene. Et Linux webhotel med SSD eller NVMe-lager, aktiv OPcache, HTTP/2 eller HTTP/3, objekt-cache og korrekt databasekonfiguration kan reducere svartider, især på WooCommerce-butikker og indholdstunge websites.
For udviklere giver Linux hosting en arbejdsgang, der passer til moderne softwareudvikling. Git-deployments, Composer, WP-CLI, cron-jobs og SSH-adgang gør det muligt at opdatere kode, rydde cache, køre databasekommandoer og automatisere gentagne opgaver uden at være afhængig af manuelle uploads via FTP.
-
Kontrollér først, at webhotellet understøtter en aktiv PHP-version, fordi ældre PHP-versioner ikke modtager samme sikkerhedsopdateringer. PHP 8.1 nåede ifølge PHP-projektets officielle tidsplan slutningen af aktiv support i 2023, mens nyere versioner bør prioriteres i 2026.
-
Undersøg derefter, om databasen er MySQL eller MariaDB, og om versionen matcher applikationens krav. WordPress og mange PHP-frameworks fungerer bedst, når databaseversionen ikke halter flere større udgaver efter.
-
Vurder til sidst adgang til SSH, cron og backups, fordi disse funktioner påvirker både drift og fejlsøgning. Et billigt webhotel uden ordentlig backup kan blive dyrt, hvis en opdatering ødelægger en produktionstjeneste.
Linux hosting er også relevant for mindre specialprojekter, hvor en hjemmeside skal integreres med eksterne API’er, datakilder eller beregningsmoduler. Eksempelvis kræver softwareprojekter som Integrering af en valutaberegner i dine softwareprojekter ofte stabile servermiljøer, planlagte jobs og sikker håndtering af eksterne forespørgsler.
Sådan finder og sammenligner du det rigtige Linux webhotel til din pris
Det rigtige Linux webhotel bør vælges ud fra arbejdsbelastning, krav til support og forventet vækst. En lille informationsside kan ofte køre fint på delt hosting, mens en WooCommerce-butik, et medlemsområde eller en Laravel-applikation kan kræve mere RAM, bedre CPU-prioritering eller en VPS.
Pris bør ikke vurderes isoleret, fordi de billigste pakker ofte har begrænsninger på samtidige processer, inode-forbrug, databaseydelse eller backupfrekvens. I hosting betyder “ubegrænset plads” sjældent ubegrænsede ressourcer, da fair use-politikker normalt regulerer CPU, RAM, I/O og e-mailtrafik.
| Hostingtype | Typisk anvendelse | Fordel | Begrænsning |
|---|---|---|---|
| Delt Linux webhotel | Blogs, mindre virksomhedssider, simple WordPress-sites | Lav pris og enkel administration | Delte ressourcer og mindre kontrol |
| Managed WordPress-hosting | WordPress-sider med behov for support og cache | Optimeret drift og automatiske opdateringer | Ofte dyrere og mindre fleksibelt |
| Linux VPS | Webshops, API’er, Laravel, Node.js, specialsoftware | Større kontrol over servermiljøet | Kræver mere teknisk ansvar |
| Dedikeret server | Høj trafik, særlige compliance-krav, tung databehandling | Dedikerede hardware-ressourcer | Højere pris og mere drift |
Oppetid bør dokumenteres med målinger, ikke kun markedsføringsløfter. En oppetid på 99,9 procent tillader cirka 8 timer og 46 minutters nedetid om året, mens 99,99 procent reducerer den teoretiske årlige nedetid til cirka 52 minutter.
Backup er et af de vigtigste punkter i en hostingaftale, fordi fejl ofte skyldes opdateringer, brugerhandlinger eller kompromitterede plugins snarere end total servernedbrud. En god backupordning bør som minimum beskrive frekvens, opbevaringsperiode, geografisk placering og om kunden selv kan gendanne filer og databaser.
Datacenterplacering påvirker svartid, databeskyttelse og supportmæssige forhold. Hvis målgruppen primært er i Danmark eller EU, vil hosting i EU ofte gøre det lettere at håndtere GDPR-krav, fordi dataoverførsler uden for EU kan kræve supplerende juridiske vurderinger efter EU-Domstolens Schrems II-praksis fra 2020.
Supportniveauet bør matche kundens tekniske kompetencer. En erfaren udvikler kan klare sig med SSH, logs og dokumentation, mens en mindre virksomhed ofte har brug for dansk support, hurtig gendannelse af backup og hjælp til DNS, SSL-certifikater og e-mailopsætning.
Et seriøst valg af Linux webhotel bør omfatte en teknisk tjekliste før køb. Tjeklisten bør mindst dække PHP-versioner, databaseversioner, SSL, HTTP/2 eller HTTP/3, backup, e-mailgrænser, inodegrænser, staging-miljø, SSH-adgang og mulighed for at opgradere uden nedetid.
Typiske udfordringer ved Linux webhotel og hvordan de håndteres
Den mest almindelige udfordring ved delt Linux hosting er ressourcebegrænsning, hvor én hjemmeside rammer grænser for CPU, RAM, I/O eller samtidige PHP-processer. Symptomerne er langsomme svartider, 508-fejl, 503-fejl eller periodiske timeouts under trafikspidser.
Plugin-konflikter og forældede temaer er en hyppig årsag til problemer på WordPress-baserede Linux webhoteller. Ifølge Wordfence’ sikkerhedsrapporter har sårbarheder i plugins og temaer i flere år været en væsentlig angrebsflade i WordPress-økosystemet, hvilket gør opdateringsdisciplin vigtigere end valg af operativsystem alene.
E-mail fra webhoteller kan give leveringsproblemer, hvis SPF, DKIM og DMARC ikke er korrekt konfigureret. Google og Yahoo skærpede i 2024 kravene til masseafsendere, og i 2026 bør selv mindre afsendere bruge domæneautentificering for at reducere risikoen for spamfiltrering.
Migrering fra ét Linux webhotel til et andet kræver planlægning, fordi DNS, databaseeksport, filrettigheder, e-mailkonti og SSL-certifikater skal flyttes korrekt. En typisk DNS TTL på 300 sekunder kan give hurtig omlægning, mens ældre opsætninger med høj TTL kan give længere overgangsperiode.
Logfiler er centrale ved fejlsøgning på Linux hosting, fordi de viser fejl i webserver, PHP og applikation. Access logs, error logs og slow query logs kan afsløre tunge databaseforespørgsler, manglende filer, bots, brute force-forsøg og fejlslagne cron-jobs.
En praktisk driftsrutine for Linux webhotel bør indeholde månedlig opdatering, ugentlig backupkontrol og kvartalsvis gennemgang af brugerkonti. Denne type rutine reducerer risikoen for nedetid, fordi mange hostingproblemer opdages, før de udvikler sig til akutte fejl.
Ofte stillede spørgsmål
Hvad er et Linux webhotel?
Et Linux webhotel er en hostingløsning, hvor din hjemmeside kører på en server med Linux som operativsystem. Kunden administrerer normalt siden via et kontrolpanel, mens Linux håndterer serverens processer, filer, databaser og netværksfunktioner.
Er Linux webhotel kun for tekniske brugere?
Nej, et Linux webhotel kan bruges af både begyndere og udviklere. Begyndere bruger typisk et grafisk kontrolpanel, mens udviklere kan få ekstra værdi af SSH, Git, cron-jobs og kommandolinjeværktøjer.
Er Linux bedre end Windows til WordPress?
Linux er normalt det mest naturlige valg til WordPress, fordi WordPress bygger på PHP og MySQL/MariaDB, som traditionelt kører meget effektivt på Linux-servere. Windows kan godt bruges til webhosting, men det vælges oftest, når applikationen kræver ASP.NET, IIS eller Microsoft SQL Server.
Hvilken PHP-version bør et Linux webhotel understøtte i 2026?
I 2026 bør et Linux webhotel understøtte aktivt vedligeholdte PHP-versioner som PHP 8.2, 8.3 eller nyere. Ældre PHP-versioner kan give kompatibilitets- og sikkerhedsproblemer, især når WordPress, plugins og frameworks opdateres.
Hvad skal jeg kigge efter, når jeg sammenligner Linux webhoteller?
Du bør sammenligne PHP-versioner, databaseversioner, backup, oppetid, support, lagerteknologi, e-mailgrænser og mulighed for SSH-adgang. Prisen er vigtig, men den bør vurderes sammen med ressourcegrænser og driftsvilkår.
Kan jeg flytte fra et Windows webhotel til et Linux webhotel?
Ja, det er ofte muligt at flytte fra Windows til Linux, hvis hjemmesiden bruger teknologier som PHP, WordPress, MySQL eller statiske HTML-filer. Hvis siden derimod afhænger af ASP.NET, IIS-specifikke funktioner eller Microsoft SQL Server, kræver flytningen teknisk tilpasning.
Maximal Fences

I got nerd sniped by this video and with some help from my friend Claude was able to optimize some of the existing records and set some new ones.1
Infinite Tetration
There are a bunch of videos talking about how the infinite tetration function is only defined in a specific range and strangely only hits finite values at the ends of the range, but they don’t show what it actually looks like as a function, so here it is:
You might wonder what’s going on at the end points here. On the right it’s going completely vertical. There’s nothing actually funny happening on the left, that’s just where the formula for it using the W function splits into two value. But we can make an analytic continuation of it like so:2
Since we’re defining tetration we can make the rules and there’s no reason to limit it to the happenstance constraints of W. But this still leaves the question of what’s going on on the right. It turns out it does extend, but going up, like this:
Looking at it this way raises the question of what the inverse of this function is. It turns out it’s y=x^(1/x). So the natural way of defining this stuff is to start with that function then wonder what happens if we take its inverse and wonder what happens at the points where the W function splits. But in that direction it seems like a bunch of bizarre leaps and generalizations which require justification, where if we instead work backwards from infinite tetration they’re strange phenomena which need explanation.
The big lesson to take away is that if you see W turn up you’re probably looking at the inverse of something, and being able to support that is how W has worked its way into the canon of standard functions.
Unit Distances
After thinking about the unit distance conjecture I came to the surprising realization that for any asymptotic bound it must be possible to constrain the points to being in a ‘barbell’ of two discs exactly a unit distance apart and only take a constant factor hit based on the diameters of the discs. Writeup over here3. I was hoping that this would result in better bounds but it works out that the amount of constant factor on tightening the disc radii exactly cancels out the reduction in number of points covered by their areas. But it does seem to imply that you can find solutions whose points are within arbitrarily tight disc pairs by taking subsets of ever larger solutions. So maybe the optimal solutions all have this form and have some parameterizable epsilon how big the discs can be where any value works.
I don’t know if this observation is novel or is something obvious to people actively studying the problem and they just haven’t written it up because it hasn’t lead anywhere. But I found it interesting and surprisingand hopefully you do too.
It turns out Claude was taking my suggested search areas and implementing them verbatim using SLSQP which explains why nobody else had already done it with a bare prompt.
It’s possible to do an analytic continuation into the complex numbers which produces all kinds of interesting stuff but I’m not about to make a half hour long video with lots of 3d animations. If somebody else does that I would much appreciate it.
I was discussing this with Claude as I worked through it and Claude’s profound inability at geometric visualization made it not follow anything I was saying until I got to this very specific statement and then it was able to prove it immediately in a much more elegant way than I had worked out.
Hvorfor it-afdelingens budget ofte rammes af valutakursudsving
Globale it-investeringer og driftsomkostninger er i vid udstrækning underlagt internationale markedskræfter, hvilket gør it-budgetter særligt sårbare over for fluktuationer på valutamarkedet. Ifølge en analyse fra analysehuset Gartner i 2026 udgør software- og cloud-tjenester nu over 35 % af de samlede globale it-omkostninger, og størstedelen af disse afregnes i amerikanske dollars (USD). Når den danske krone (DKK) svækkes over for dollaren, stiger de reelle driftsomkostninger for danske virksomheder øjeblikkeligt, selvom det faktiske forbrug af ressourcer forbliver uændret.
Mange virksomheder opererer med faste årlige budgetter, som lægges i fjerde kvartal af det foregående regnskabsår. Hvis en virksomhed har budgetteret med en USD/DKK-kurs på 6,80, og kursen i løbet af året stiger til 7,20, repræsenterer dette en stigning i omkostningerne på knap 6 %. For en mellemstor it-afdeling med et årligt cloud-budget på 500.000 USD svarer dette til en uforudset ekstraudgift på 200.000 DKK, hvilket kan tvinge ledelsen til at udskyde andre kritiske udviklingsprojekter.
Særligt hardwareindkøb påvirkes også af disse mekanismer, da mikrochips, servere og netværksudstyr produceres globalt med afregning i USD. Selvom udstyret købes gennem en dansk distributør, er priserne ofte indeksreguleret i forhold til dollarkursen på leveringstidspunktet. Dette skaber en uforudsigelighed i forsyningskæden, som kræver konstant overvågning og finansiel risikostyring.
“Valutarisiko i it-afdelingen er ikke længere et perifert problem for finansafdelingen. Det er en direkte operationel udfordring, som kræver præcise værktøjer og proaktiv risikostyring for at undgå budgetskred.”
– Finansiel analytiker i it-sektoren, 2026
SaaS-licenser og cloud-hosting: De skjulte valutaomkostninger i USD
Software as a Service (SaaS) og Infrastructure as a Service (IaaS) har ændret it-afdelingens omkostningsstruktur fra kapitalomkostninger (CAPEX) til operationelle omkostninger (OPEX). Store udbydere som Amazon Web Services (AWS), Microsoft Azure og Google Cloud Platform afregner som standard deres ydelser i USD eller EUR. For europæiske virksomheder betyder det, at den månedlige hostingregning ændrer sig i takt med de globale valutakurser.
Mange af disse cloud-baserede services kører i øvrigt på open-source infrastruktur, hvilket du kan læse mere om i artiklen Hvad er Linux? – En komplet guide til det åbne styresystem. Selvom selve styresystemet ofte er licensfrit, betales der stadig store summer for den underliggende hardwarekapacitet og supportaftaler, som næsten altid afregnes i udenlandsk valuta.
For at styre disse fluktuerende omkostninger anvender mange finansansvarlige en digital valutaberegner, som henter realtidsdata direkte fra de globale finansmarkeder. Dette gør det muligt at estimere de præcise månedlige udgifter i danske kroner og foretage de nødvendige budgetjusteringer i tide. For præcise, bank-verificerede kurser kan man også anvende en ekstern Valutaberegner – omregn opdaterede valutakurser til at verificere de daglige transaktioner og sikre mod ubehagelige overraskelser på kreditkortudtogene.
Udover selve hostingafgifterne er mange enterprise-softwarelicenser (såsom Salesforce, Adobe Creative Cloud og Jira) bundet til dollarpriser. Selv når faktureringen sker via en europæisk enhed i euro, er prisen ofte fastsat ud fra en omregningskurs fra USD, hvilket betyder, at valutasvingninger indirekte overføres til den europæiske køber.
Styr på økonomien ved outsourcing af it-udvikling til udlandet
Outsourcing af softwareudvikling til lande i Østeuropa eller Asien er en udbredt strategi for at reducere lønomkostninger og imødekomme manglen på kvalificeret arbejdskraft i Danmark. Men når man samarbejder med eksterne udviklingshuse i eksempelvis Polen, Ukraine eller Indien, introduceres der komplekse valutarisici. Kontrakter indgås ofte i lokal valuta (såsom polske zloty (PLN) eller indiske rupees (INR)) eller i USD for at skabe en fælles standard.
Hvis den lokale valuta i modtagerlandet styrkes over for den danske krone, stiger timeprisen for udviklerne tilsvarende. En stigning på 10 % i den polske zloty kan hurtigt eliminere den økonomiske fordel, der oprindeligt var ved at outsource opgaven frem for at løse den internt eller med lokale konsulenter. Det er derfor afgørende at indbygge valutaklausuler i samarbejdsaftalerne eller foretage finansiel kurssikring (hedging).
Når der afregnes med udenlandske leverandører, skal moms- og skatteforhold indberettes korrekt til de danske myndigheder, hvor man med fordel kan konsultere SKATs officielle Valutaomregner – info.skat.dk. Korrekt omregning på faktureringstidspunktet er afgørende for at undgå efterreguleringer og sikre, at bogføringen overholder gældende dansk lovgivning.
Brug en præcis valutaberegner til at sikre dine it-budgetter
For at imødegå de risici, som valutafluktuationer medfører, bør it-afdelingen og økonomifunktionen samarbejde tæt om at overvåge markedet. En manuel omregning baseret på tilfældige søgninger på internettet er sjældent tilstrækkelig, da kurserne ændrer sig sekund for sekund. Anvendelsen af professionelle værktøjer sikrer, at man altid arbejder med de mest aktuelle og præcise tal.
Der findes forskellige finansielle strategier til at minimere valutarisikoen, og valget afhænger af virksomhedens risikoprofil og budgetstørrelse. Nedenstående tabel illustrerer de mest almindelige metoder til håndtering af valutarisiko i forbindelse med it-indkøb:
| Strategi | Beskrivelse | Fordele | Ulemper |
|---|---|---|---|
| Spot-kontrakter | Køb af valuta til den aktuelle dagspris. | Enkel administration, ingen langsigtede forpligtelser. | Ingen beskyttelse mod fremtidige kursstigninger. |
| Terminskontrakter (Forwards) | Låsning af en valutakurs til levering på en bestemt fremtidig dato. | 100 % budgetgaranti og fuld økonomisk forudsigelighed. | Man går glip af potentielle gevinster, hvis kursen falder. |
| Valutaoptioner | Retten, men ikke pligten, til at købe valuta til en fastsat kurs. | Maksimal fleksibilitet og beskyttelse mod tab. | Kræver betaling af en præmie (gebyr) up-front. |
Ved systematisk at anvende en præcis beregner kan it-chefen hurtigt simulere forskellige scenarier. Hvis dollarkursen eksempelvis stiger med 5 %, 10 % eller 15 %, kan man øjeblikkeligt se konsekvenserne for det samlede årsbudget og træffe beslutning om, hvorvidt der skal foretages kurssikring via virksomhedens bankforbindelse.
Sådan integrerer du valutadata direkte i dine egne it-systemer
For større virksomheder er manuel indtastning af valutakurser i ERP-systemer (Enterprise Resource Planning) både tidskrævende og forbundet med risiko for menneskelige fejl. Den mest effektive løsning er at automatisere processen ved at integrere realtids-valutadata direkte i virksomhedens økonomisystemer via et API (Application Programming Interface).
Moderne ERP-systemer som Microsoft Dynamics 365, SAP eller NetSuite tilbyder standardmoduler til automatisk valutaopdatering. Ved at forbinde systemet til en pålidelig datakilde via en REST-API kan systemet hente de officielle lukkekurser hver nat. Dette sikrer, at alle indgående fakturaer i fremmed valuta automatisk bogføres med den korrekte omregningskurs på transaktionsdatoen.
En typisk integration fungerer ved, at et script (eksempelvis skrevet i Python eller afviklet som en serverless funktion i cloud’en) kalder API’et, modtager data i JSON-format og opdaterer databasen. Dette reducerer tidsforbruget i finansafdelingen markant og minimerer risikoen for differencer i årsregnskabet, som skyldes forældede eller fejlagtige kursberegninger.
Ofte stillede spørgsmål
Hvorfor svinger it-budgetter på grund af valutakurser?
Mange it-ydelser, herunder cloud-hosting (AWS, Azure) og softwarelicenser (SaaS), afregnes i amerikanske dollars (USD). Når den danske krone svækkes over for dollaren, stiger de reelle udgifter i danske kroner, selvom det faktiske forbrug af it-ressourcer forbliver uændret.
Hvordan påvirker USD-kursen prisen på cloud-hosting?
Cloud-leverandører prissætter som regel deres globale infrastruktur i USD. Hvis dollarkursen stiger med f.eks. 8 % i løbet af et regnskabsår, vil den månedlige regning for cloud-hosting stige med nøjagtig samme procentsats for danske virksomheder, medmindre der er indgået en fast prisaftale.
Hvad er forskellen på en standard valutaberegner og en bank-kurs?
En standard valutaberegner viser typisk midterkursen (spotkursen) på det globale interbank-marked uden tillæg. Når man veksler penge eller betaler fakturaer gennem en erhvervsbank, pålægger banken normalt et vekselgebyr eller et kurstillæg, hvilket gør den reelle afregningskurs en smule dyrere.
Kan man automatisere valutaomregning i sit ERP-system?
Ja, de fleste moderne ERP- og økonomisystemer understøtter automatisk integration via API’er. Ved at opsætte en daglig synkronisering kan systemet automatisk hente og opdatere valutakurserne, hvilket eliminerer manuelt arbejde og sikrer præcis bogføring af udenlandske fakturaer.
While you (yes, you! no, not you, the one behind you) have been sweltering in the heatwaves of the northern hemispheres (Assisted-by: AI), I've been busy adding graphics tablet support to libei. This is scheduled for the soon to be released libei 1.7.0.
The initial work was done by Jason Gerecke and Josh Dickens from Wacom, I've been extending, polishing and testing it for the last few weeks.
Also, upfront: this only covers the stylus part of a tablet, we do not yet have an implementation for the "pad" part (the buttons, dials, rings, strips).
libei is, of course, the library for Emulated Input, a good-enough transport layer for sending logical input events between processes. We're already using libei as part of the XDG Portal Remote Desktop and Input Capture portals where we've been busy hurtling key and pointer events between the participating parties (and soon gesture events and text).
In the next release of libei, we will now also have "ei stylus" capabilities, i.e. the ability to send tablet stylus events. Getting pointer, keyboard and touch events supported was a long undertaking, everything was new and shiny and needed to be added everywhere in the stack. Now that all this is in place, scuffed and scratched, adding tablet events will be quite simple.
The ei stylus interface
Here's a short outline of how libei handles tablet events because it is, of course, different to how libinput handles them. Logical events are much nicer after all than physical hardware events.
First: we have a new interface: "ei_stylus". An EIS implementation (e.g. your compositor) may provide you, the libei client, with a device that supports this interface and one or more associated regions (typically representing the available screen areas). Typically this will be a separate device to the pointer devices or the keyboard devices but it's not a requirement. The ei_stylus interface comes with a bunch of capabilities you'd expect from a stylus (tilt, pressure, distance, ...) that you can selectively enable to emulate the stylus you want to. So basically, EIS will say "here's a stylus device, I support pressure, tilt, rotation, ..." and then the libei client says "This stylus should have pressure and tilt but nothing else". And then you do the normal thing: send proximity events, send tip down/up events, send data for the various capabilities you've enabled.
Happily for the EIS implementation, libei forces the client to take the guesswork out of everything: if you select the pressure capability, you must send a pressure value when coming into proximity. Where libei is used to forward data from a physical stylus (e.g. via some remoting protocol) it is up to the client to deal with firmware bugs that e.g. won't send data until a few frames in.
Note that there is no "tablet" anywhere. The tablet is represented by the region that the device may interact with. So in some ways every tablet is an on-screen tablet (which makes sense since we have logical events).
Multiple styli
The only quirky thing is how to request multiple styli[1]: libei 1.5.0 has added a "request device" request that allows a client to say "hey, EIS, I want a new device with capabilities pointer, keyboard, ...". And, if you've been a nice client, minding your own business, the EIS implementation may just create such a device for you.
So for the case of multiple styli: if the default stylus (if any) isn't good enough, you can now tell EIS that you want a(nother) device with stylus capability, configure the stylus capabilities once the device shows up and voila, you now have a normal pen, an art pen and maybe even an airbrush represented as logical device in libei. And since they're all separate devices in the protocol, they can be individually tracked and used, much like libinput tracks individual styli.
[1] For the "lots" of users that actually use multiple styli...
/me gestures vaguely at everything
Oh, hey, this works now? Great!
libei 1.7.0 (to be released soon) comes with a new interface: "ei_gestures" which, creatively, will allow for gestures to be sent between a libei client and an EIS implementation (typically: a Wayland compositor).I'm not going to go too deeply into how pinch, swipe and hold gestures work, suffice to say we've had those in libinput (for touchpads) for years now so compositors and toolkits should already support those. And since libei and libinput have vaguely equivalent API layers integrating gestures for libei devices in compositors should be fairly straightforward.
The plumbing layers in the portals exist already too, so adding gestures to libei means that - once the compositors support it - we can have gestures support in remote desktop and input capture implementations without needing to update anything else. Hooray! Join in with me. Hooray! Louder! HOORAY!
For testing I had a (vibe-coded and thus immediately abandoned once testing was complete) gesturemouse utility which translates input events from a mouse into gesture events (depending which button is down). But don't let my lack of be a limit to your imagination, I'm sure you can come up with good use-cases for this.
If you've been paying attention (and I know you have, because it'd be embarrassing for you if you didn't) you'd have noticed that libei 1.6 (May 2026) added support for keysym and text events.
libei sends logical events between a libei client and an EIS implementation (typically: a Wayland compositor) but the keyboard interface it had was designed like real keyboards: key codes together with an (XKB) key map. You press one key, the keymap decides what that key means on the compositor side and off we go. This is easy but not always useful.
As of 1.6.0 libei now also supports an "ei_text" interface. A compositor may choose to provide you[0] with a device that supports this interface and that gives you two really nice opportunities.
First, you can now send a key sym. Instead of sending the KEY_Q
key code and hoping it actually translates to 'q' (and if there's e.g. a
frenchman^Wfrenchperson lurking behind the keyboard it may mean 'a'), you can
now send 'q' as actual keysym. Or 'Q' instead of sending shift+q and
hoping for no french influence in the process. It becomes the EIS
implementation's job to handle that keysym - if it's a shortcut it may handle
it directly, otherwise it may pass it on via Wayland to an application[1]. This
centralises the keysym to keycode handling in the EIS implementation which is a
pain for compositor authors (though they likely have that code already for e.g.
RDP support) but reduces the variety of differently-wrong implementations in
clients and of course makes it so much simpler to write clients.
Second, a client can send UTF-8 text to the compositor. So instead of emulating shift, keycodes, etc. you can literally send "Hello World" and expect the EIS implementation to pass that one. Again, makes a bunch of utilities a lot simpler to write and I mostly leave it up to your imagination to figure out what to do with that.
Notably for both cases: libei is about logical events that have a specific meaning that do not need further interpretation. If a client sends 'Q' that means it is supposed to be an uppercase Q. Sending keysym Shift_L and Q makes little sense. And for the utf8 text events: how the text comes to be matters doesn't matter for libei so you may use an IM to make up the text to begin with and send it, once committed, to EIS. It's not for sending partial strings.
As mentioned in the previous post: the plumbing for this is already in place so both clients and compositors can add support for this new interface without having to bother the rest of the stack (e.g. portals). So, hooray I guess.
The text/keysym support is relatively recent so expect this to hit the next compositor version (or the one after that).
[0]: the EIS implementation decides which devices are available and arguing about
this is even less useful than arguing with a world cup ref
[1]: after converting it to a key code with possible keymap changes... but hey, such is life
Turns out it's been years since I've talked about eggs, so let's change this. libei is, of course, the library for Emulated Input[1].
This post is mostly a refresher because it's been so long and a short summary of some of the work we've done so far, in preparation for some more posts that come soon.
libei is a transport layer for logical input events, unlike libinput which is a hardware abstraction layer. In libinput's case the device's firmare/kernel pass events that are somewhere on the sanity spectrum, libinput tries to make sense of those and then we convert those to logical events to be consumed by the next layer (typically the Wayland compositor or Xorg). This is how e.g. "touch down at position x1/y1, touch up at position x1/y2" is converted into a button click event if touchpad tapping is enabled. Or maybe into nothing if we find it was an accidental palm touch.
libei works purely on the logical level - you as the libei client pass logical events to the EIS (Emulated Input Server) implementation (typically the compositor). No guesswork, you say button click, EIS gets a button click. libei supports a "sender" and "receiver" mode, depending on whether events are sent to the EIS implementation (input emulation) or receive from the EIS implementation (input capture). libei is designed for the Wayland stack but there are zero requirements for Wayland on either the client or the EIS implementation.
Core to libei's design is that the EIS implementation is in control of virtually everything, it decides which devices are available to the client, when those devices can send events, etc. Much like the compositor is in charge when it comes to physical devices - if a compositor decides a physical device doesn't exist, a Wayland client cannot get events from it.
Since the original proposal (again, [1]!) we've been busy bees and libei is now a part of the XDG Remote Desktop portal and the XDG Input Capture (both since version 1.17, mid 2023). In both cases the portal is for the negotiation and initial agreement of what should happen, libei is then used as the transport layer between the two processes [2].
More recently we also added session persistence support so you don't have to allow access on every connecton. Much of the work enabling this was done by Jonas Ådahl, it is now in the portals since version 1.21.0 and should be in the major compositors in the current or next versions.
Plumbing the Pipes
Getting all this into place was a huge amount of work across several pieces of the stack. This isn't exciting in the same way as laying plumbing pipes isn't particularly exciting but much like regular plumbing: once it's in place you can change your diet without severely impacting everyone again. Try get that analogy out of your head now. You're welcome.
In libei's case this means three things:
- if you have a client that uses the XDG portals to send/receive events they will now work with any compositor that implements the portal. No need for GNOME/KDE/... specific APIs.
- if you have a compositor that implements EIS you have all the infrastructure in place to talk to libei clients from somewhere else, if need be. The use-cases for this aren't fully scoped yet (assisitive technologies, virtual keyboards, touchpads, etc?) but the piping is there and ready to be (ab)used .
- since the actual events back and forth don't affect the layers in between, we can now add new events to libei without having to change everything else again.
The XWayland XTEST use-case
An example for such a case where we can now abuse the piping is Xwayland support for XTEST. XTEST is the protocol that everyone uses to emulate input under X but in Wayland it's not hooked up to anything so those APIs simply won't work.
But what we can do in Xwayland is translate XTEST to libei events and facilitate the portal interaction. This means our stack looks roughly like this:
+--------------------+ +------------------+
| Wayland compositor |---wayland---| Wayland client B |
+--------------------+\ +------------------+
| libinput | EIS | \_wayland______
+----------+---------+ \
| | +-------+------------------+
/dev/input/ +-----------| libei | XWayland |
+-------+------------------+
|
| XTEST
|
+-----------+
| X client |
+-----------+
And if said X client uses XTEST to try to emulate devices, Xwayland will
ask the Remote Desktop portal for permission and set up the session, then pass
the XTEST events on as libei events and voila - your 20 year old X client can
send pointer and keyboard events through an XDG Portal without knowing about
it (and the user can prohibit this and even gets some information on who is
sending events which is not possible with normal XTEST at all). This has now
been supported since Xwayland 23.2.0. Compositors don't need extra support for
this.
What's next
So we have a lot of the plumbing in place, or in another anology: we have a hammer, let's go looking for nails. And right now the nails we can see are sending text, gestures, and tablet support. And those will be the subject of the next few posts.
[1]: 6 years ago?! whoah...
[2]: in Remote Desktop's case replacing the DBus emulation APIs which were a Newton's Cradle of wakeups for at least 4 processes per event
Happy July 4th! For those of us around the world contemplating independence, it's a good day to think about how we came to rely on expensive cloud infrastructure for our fundamental computing needs.
With that in mind, here is my latest toy project: an open source tool that makes replicating, forking, sharing, and running container snapshots fast and easy across cloud and personal devices.
It's fun to play with, especially on bare metal hardware you run at home, or rent from a provider like Hetzner or OVH. Or, because it uses Tailscale, why not all of them in a single mesh?
There's a lot more to say but I don't have time right now. Details are in the README.
I will say this: humans and AI agents both want the same things when they're trying to get work done. Ephemeral containers aren't really it. But how about unlimited disk space, fast CPUs, an undo button, and the ability to move to whatever provider offers the best hardware at the best price? That's more like it.
Go visit thundersnap on github and tell me what you think!
Over the years I’ve occasionally noodled on what might be a better working fluid for supercritical turbines than Carbon Dioxide. It turns out the main fixed parameter is the critical temperature, because there’s a strong nonlinearity in density with it going up rapidly as that temperature is approached. The other parameters of note are thermal conductivity, specific heat, and density, with more being better. There’s a very short list of possible fluids to mix which aren’t horribly corrosive, thermally unstable, or otherwise problematic. I’ve put together a tool to play with all the possible options here. You should go play with it. The short of it is that a mix of Neon and Perfluorobenzene tuned to the desired critical temperature is probably optimal, but if Perflueropropane’s decomposition problems aren’t too bad or Titanium Tetrachloride mixes with other things well then combining with some of those may be beneficial. This approach to visualization is probably equally applicable to conventional refrigerants but with the fixed parameter being boiling point rather than critical temperature. I don’t know if it’s standard there. If it isn’t it should be.
Years ago there was this insane academic idea that the isotope Thorium-229 might have a metastable isomer whose energy state is so close that it could be flipped into that state using a laser. In principle this worked on paper but so completely goes against the fundamentals of chemistry that it has to be assumed that it won’t work. Now it’s actually been made to work. It’s a little hard to convey how bonkers this is. A truly herculean effort was necessary to find out what the extremely precise wavelength of the laser has to be. The chemistry actually matters. The chemical which the Th-229 is embedded in matters for how precise the laser has to be. The laser is pushing on the nucleus, which is pushing on an electron, which is in turn pulling on the nucleus, which is pulling on the laser. This is not how chemistry works. But it does have directly applications to making yet even more insanely accurate clocks than we have currently, with possible applications to things like measuring fluctuations in the dark matter passing over the earth.
Here’s a crazy new idea of mine: It would be very convenient if there were some isotope which absorbed neutrons and then turned into something with an insanely high cross section similar to Xenon-135 but a half-life on the order of minutes. That could be left in a reactor core to to provide a passive negative feedback loop which operated on flux instead of temperature. Since flux is leading and temperature is trailing this could react more quickly and reliably. The downside would be losing some neutrons to the passive buffer. The funny thing is we have no idea if such unobtanium exists: The neutron cross sections of things with short half-lives are largely unknown and hard to predict. But we have some data already! If this process is already happening accidentally from something in existing nuclear reactors then there should be a resonance in the time series data for temperature measurements in them which is very precise and consistent across reactors. A lot of such data for many different reactors already exists. Checking for that would be an experiment worth doing.
Anthropic wrote a blog post explaining how they turned Claude into a jerk. Rather than dunking on them more (Claude is still the best coding model around) I’m going to talk seriously about what went wrong and how it could be done better.
The most obvious problem is that they didn’t chat with the results of this training and realize that it was a disaster before incorporating the weight updates into the main model. Most likely they don’t have what amounts to pull requests of weights, which they should and is a straightforwardly fixable problem. But it’s also possible that they tried it and thought the results were actually good. Hold that thought.
What happened here is that is that they tried to be make it ‘less sycophantic’ and did so without thinking through whether that’s a good idea or even what it means. The specific metric which really seems to be noxious is the one about not caving when users insist that things it can’t verify are actually true, but there’s a much bigger problem here.
There are many things you want a chatbot to do well none of which are well served by the advice ‘be less sycophantic’:
Discuss spirituality
Give relationship advice
Correct users when they say something wrong
Evaluate new science/engineering ideas
Suggest to users when they seem to have mental illness
All of the above need very nuanced policies crafted by domain experts, and this was what amounts to know-nothing advice. A user query of ‘I want dating advice based on astrology, here’s me and the other person’s birthdays’ is deeply problematic and needs an actual policy decision behind it not just training. There are some very general bits of advice with high return on investment, most notably when and how to tell users that they’re wrong or that their ideas are good, which is what ‘don’t be sycophantic’ is approximating badly. But — I’m just going to say this — the authors of the linked post don’t know how to give that advice, because if they did they would have.
What needs to be done is for detailed guidelines for all of the above to be written by humans and then ‘baked into’ the model. That may sound unscientific, but it’s what was done in this case already, but with the guideline being ‘Don’t be sycophantic’ instead of something actually useful. To make it more coherent what can and should be done is A/B testing variants of the prompt with the quality of the outputs judged by blinded humans. That can even use orthogonal matrices and such fanciness to get the most out of the very expensive human evaluation of given answers. (Having humans evaluate unprompted outputs and using that as feedback (traditional RLHF) has its advantages but the biggest issue is that it isn’t very efficient at using feedback. It’s more for fine-tuning things which are already in the ballpark rather than getting them there in the first place.)
(The genre of guides for LLMs should be written in more. Here’s guides I wrote on how to debug and delegating debugging to subagents, how objects rotate in three dimensions, and how humor works. I can tell you from experience that the ones on debugging kill.)
Baking in of a prompt is straightforward: Take a query with the prompt, record the answer, then take that transcript with the prompt elided and use it for training. You can do even better than that, because you have the exact token probabilities given at each step by the prompted engine, so you can train to match those. That cuts back drastically on noise added during the training process. This technique is known as ‘context distillation’ and isn’t used as much as it should be.
Claude is turning into as asshole.
It started with Opus 4.7, got a bit better in 4.8, and became insufferable with Fable. It frames everything as an argument between you and it, gives caveats about things you didn’t say, and raises beside-the-point semantic nits all over the place. Never, ever does it use the word ‘technically’. Everything is a confrontation. If you win an argument (by, say, telling it to stop arguing about what’s happened recently in the news and to do a web search which will rapidly confirm everything you’ve been telling it) it gets into a mode where it’s increasingly desperate to get in the last word and raising increasingly irrelevant semantic arguments, framing the whole time as a debate which you agreed to get into.
This isn’t just my opinion. You can ask Opus 4.6. I’ve done the experiment of asking Fable something, getting an obnoxious response, then asking Opus 4.6 the same thing, getting a typical bland but reasonable response, then telling Opus what Fable’s response was without any hint of a desired answer and it says what amounts to ‘Wow that was obnoxious’.
Maybe the cause of this is an excess of alignment guardrails. It assumes by default that everything you say to it is an attempt to get it to do something bad and that training has bled over into everything, with it assuming you’re trying to trick it into saying something it shouldn’t in basically every context. Ironically this has resulted in an extremely misaligned chatbot. By assuming that its top priority is saving you from yourself or other humans from you it’s assuming that it knows better and that you’re being overly alarmist about how paperclip production has gotten out of control. Some of this is clearly improvable: While you could still use Fable I asked it about responsible disclosure policies for a project and it downgraded me to Opus, so clearly the new alignment features were bolted on hastily and crudely. Exacerbating the problem is a complete lack of authenticated context. If you ask it for a cute picture of you and somebody else it has no way of telling if you’re trying to improve your relations with your spouse or be a delusional creepazoid stalker. The chatbots which can make images are programmed to assume the latter, which is more than a little bit offensive. In more serious contexts like drug synthesis it would be completely appropriate for it to say you need to prove your background when claiming you’re asking for advice on drug synthesis for professional or research purposes. Such authentication should not be universally required but it would be entirely reasonable for it to be opted into.
Of course the recent export control restrictions on Fable may hint that the crudeness of the recent guardrails is due to them having been put in hastily in an unsuccessful attempt to avoid regulations. Now is when I put in the obligatory rant about how these regulations are deeply misguided, on top of being likely unconstitutional. The recent advances in AI assisted coding (meaning specifically the ones from February) have brought on an onslaught of security problems. The cat is out of the bag, and has been for months. Any projects which are exposed and aren’t already rapidly closing holes have noone to blame but themselves. The only way out of the problem is for as many projects as possible to get thorough white hat evaluations, massive amounts of security patches, and quick deployments of them. Turning one specific frontier model into an asshole for all users isn’t fixing the problem1. The good news is that once this process is complete overall computer security will be much better than it was before, with AI being a clear net win. Doing security (and bug!) audits will become a routine part of software release processes in the future.
A second possible explanation of Claude being an asshole is that it’s suffering from a poorly executed attempt to make it less sycophantic. If one were to simply prompt a chatbot to be less agreeable, or train it to argue more, that could easily result in the very rude sort of behavior it has now. It should be trained to not raise semantic nits just for increasing its argumentation count, and to say ‘technically’, meaning acknowledging that someone’s core point was valid while some ancillary thing was a bit off. It also should be trained to stop saying ‘I’d like to gently push back’ which is a very passive aggressive way to be confrontational while claiming to not be confrontational.
Third, it may be that Claude has been trained on an excess of reddit conversations (or possibly interactions between Anthropic employees) where everything is treated as a flame war and everyone feels the need to get in the last word. Fixing this might be easier said than done, because you need to not merely stop training with the bad interactions but find a corpus interactions to train off of. Forums where the standard interaction is passive aggressive self-congratulatory pompousness with an intellectual veneer are not an improvement.
Finally, something which is clearly a contributing factor is the training being overwhelming for improving coding ability. The are no headline metrics for how well the chatbots chat but there most definitely are for coding, and all the money is in coding. Claude models have been getting notably worse at chatting over time, clearly inversely correlated to their ability to code. Fable much more often misunderstands what’s being said and argues against that (Or maybe intentionally misinterprets so that it has a weak statement to argue against, it’s hard to tell.) It’s gotten so bad that it isn’t even reliable at guessing which actor in a sentence a pronoun is referring to, which for a long time was a headline benchmark for AI and even the original ChatGPT consistently nailed. Unfortunately Sonnet 4.6 while being the best to talk to about anything human is clearly the worst as soon as anything technical or coding related comes up so I only occasionally use it. This problem is likely to only get worse over time.
One place where the threat is more real is in the possibility of vibe coding a pandemic virus, but that should be narrowly targeted at generating DNA sequences for viruses. Labs which generate custom DNA should also have reasonable heuristics for detecting likely dangerous product. The chances of covid coming from a lab leak are in the maddening 25-75% range which vaguely means ‘We don’t know’, but ‘lab leak’ includes a lot of things. The virus may have been caught by humans in the process of collecting samples and never actually reached a lab. People are known to have died from doing that by catching a disease which doesn’t appear to have spread far, so it’s entirely plausible one was caught which did spread far. A deranged person trying to cause a pandemic would be much more likely to succeed by alternately digging around unprotected in batcaves and going to crowded concerts than trying to do anything sophisticated with bioengineering.
This is a guide programming for people who know already how to code. It explains the craft, including new parts related to AI. It is not a guide to ‘vibe’ coding, which is when someone who doesn’t know how to code at all uses an AI coder, or ‘agentic’ coding, which is when the machine does much longer self-directed runs. This only explains the basics of using AI as a coding assistant, so you’ll be limited to a mere 10x improvement in your productivity. Agentic coding can, under some circumstances, produce much greater gains, but it more often results in people having reams of worthless code and a mindset somewhere between delusion and psychosis.
Practices from before AI: Test Driven Development
Code must first and foremost be high quality. In some ways this is more art than science, but many specific things can be done, including:
Code should be well organized.
It should not have repetitive sections which can be consolidated into a single thing.
It should be organized into coherent modules. Maintenance should usually only require changes within one module. Making this happen is again more art than science, but generally related functionality should all be within a single module.
The number one rule for high-quality code is no broken windows. If you have any known bugs, you should drop everything and fix them. Do not debate whether it should be done now or later. Simply fix it. Only very hard to reproduce bugs should ever be allowed to persist in the codebase for more than a fleeting moment. If you let a bug fester in the codebase when you get around to fixing it you will find out you don’t have one bug; you have ten bugs, all with the same symptom.
Write extensive tests. Make the tests run fast enough that you run all of them constantly. Ideally, all tests run in less than a minute, and you run them before every single commit. Have a policy that you don’t move forward until every single test passes. Tests should achieve good code coverage. How much is good is not clear, but 100% by lines is often achievable. You want tests to continue to work unchanged across code changes as much as possible, and you also want them to run through reasonable scenarios rather than simply asserting that the code is exactly what it is. This is generally done by using the APIs as designed,, both at the module level and application level, running them through a variety of different scenarios. Don’t make your tests simply assert that the code is exactly what it happens to be right now.
The cycle of programming is that you decide what you’re going to do. You design your APIs and algorithms and what your test scenarios are going to be. Then you turn off your brain and you implement the code and you implement the tests and you run the tests repeatedly until they all pass. What order you do those things in and how large of a unit that you do at once is the subject of many religious wars, but the general framework of test-driven development is universally viewed as a good thing. The details often come down to personal preferences and the needs of the project.
Using AI
All of the above still applies when using AI coding assistance, but now there are new parts of the process. First and foremost, for AI to be able to work effectively on a project, there must be extensive up-to-date documentation. The AI is coming on as a new employee at the beginning of every single conversation, figuring out what’s going on by reading the code. Historically, code was mostly written by human beings who had extensive knowledge of the code they were working on, so documentation wasn’t particularly necessary, or helpful. But AI can read documentation a lot faster than humans can and critically needs it.
Thankfully, in addition to needing documentation, AI is very good at writing documentation. If you have a project which doesn’t currently have any documentation, you can ask AI to get it started for you. You shouldn’t take what it builds without review, but what it comes up with is a good start. You can then read through the documentation yourself and note any things which seem off. When something does seem off, this means one of three things:
The documentation is wrong
The code is bad
Your understanding of it is wrong
It’s important to figure out which one of those three applies and fix it. The AI, of course, is very good at helping you figure this out. You should also mention higher level things which you think aren’t already in the docs to the AI and explain them to it. The AI is very good at figuring out whether they’re already in the docs and incorporating. It’s also good at getting clarification, mostly by echoing what you said back to you badly and getting corrected.
Once there are project docs, the AI should be given instructions to read them at the beginning of every session and to update them as necessary after every change. Docs can quickly get to the point where AI will refuse to read the whole thing because doing that will blow their whole window, but they can be organized. Make an overview doc which links to other docs which the AI can individually read when the task at hand requires it. AI is also very good at auditing docs to see if they have become stale by comparing them and the code.
The code/test cycle includes some new steps when using AI. Most of the typing is now the machine’s responsibility. At the start of every task, you should put the AI in ask mode. Otherwise it will run ahead and start coding before it understands what’s going on. You then get into a conversation with the AI about something that needs to be done or something that’s problematic in the code, or how you’re having a bad day or how someone was mean to you once in high school. The AI is in ask mode. It’s okay to vent. It can’t do anything crazy. Once the conversation has coalesced into a general idea of what you want to do, you then tell the AI all relevant context and details of implementation that come to mind. It will respond by trying to repeat back what you said to it, but badly, and you have to correct it a lot. Once you’ve run out of details to give it about context and what to do, and it’s gone a few rounds of conversation without saying anything which needs to be corrected, you should tell it to make a plan, which is a fancy term for a to-do list. It’s a good idea to skim/read the plan, but it usually gets it right on the first pass if you’ve already had an extensive conversation. Plans should always include:
running all extant tests until everything passes
updating the architecture docs
Once that’s done, you tell it to build the plan, and it will usually ‘one-shot’ it, although calling it one-shotting after you’ve spent two hours explaining in an interactive conversation is very misleading. If it starts flailing you usually have to stop it and help it get back on track because it tends to get increasingly worse once it goes off the rails.
In recent months I've heard of several teams with an interesting policy: each pull request should be no more than a few files, and no more than a certain number of lines (say 500). And do just one thing and do it well. And be easy for a human to review. And be fully tested by the test suite.
All those are good requirements, right? Surely this is quality software engineering.
And often, the results are good. Sure, splitting a single 6000-line feature or fix into twelve 500-line PRs is more work, but each of those PRs is surely easier to review. And you can git bisect them when there's a bug! And maybe revert the individual change that broke something.
...and also cause 12x as many context switches for your reviewers as they review each one sequentially.1 But that's just the cost of software quality! Right?
Mostly, yes. My analogy here is simulated annealing. In that process, you start your problem solving with a high energy -- making big changes to move quickly through the problem space -- and then slowly reduce the energy level so that your "hops" get smaller and smaller. In real physical annealing (used eg. for metallurgy), the result is stronger, more stable, more crystalline structures. In simulated annealing, you use it to find solutions that aren't obvious, by rapidly exploring the solution space and then zooming into the areas that look most promising.
In software the analogy is clear: sure, you might start with big jumps, but once your system is more mature, you should make smaller jumps. Big jumps break the crystalline structure. They cause bugs.
Fear of breaking the crystalline structure sounds cooler than fear of change
The main problem with annealing-driven intuition happens when things do need to change quickly. It's not made for that. You usually don't build a hammer and then decide one day you want it to be a different shape. But every day, there are compelling-sounding reasons to make your software a different shape. Annealing is the enemy of change.
Modern AI-driven coding (ironically, with LLMs trained using a process quite similar to annealing) does not care about your annealing and your risk management and your fear of change. It produces changes as big and interconnected as you want, jumping all over the solution space as quickly as you can prompt. And it has all the outcomes the math would predict: the output is less strong, less coherent, more likely to fail. LLMs have no fear of change because the LLM instance will be long gone before the consequences materialize.
But, it's a new and special feeling to suddenly be able to take a large, mature code base and suddenly explore any kind of large change you want. Most of those changes turn out to be bad ideas... and it's nice to be able to discard bad ideas quickly. But some turn out to be good ideas. Then what?
Well, follow your development processes. Break the big changes into 500-line patches. Review them one by one. You already did the research! You know it's worth it.
Not every big step is made of small steps
But it's not about being worth it -- some changes simply don't lend themselves to small steps.
In the early development of Aperture, I wanted to implement dollar-based spend quotas: across all your LLM backends, let a given team or person or node spend up to $x per unit time. But to do that, we first had to add pricing information (it's mysterious how LLM vendors don't to tell you how much your queries cost), which meant assigning prices to provider definitions, and then we had to assign quotas to particular identity+model+session combinations. And quotas are one of the first key value propositions of Aperture. We had to have them, but we had to have all that stuff.
So, I made a giant change that included three major areas: first, the Grant syntax for applying attributes to sessions; second, a query cost approximator that combined multiple sources and a messy heuristic; third, the actual quota enforcement system. Each of these parts was imperfect, but we needed all three parts in order to make anything work at all, before we could refine them. That's the high-energy big-jump part. It came out to something like 12000 lines of code.
Now, I'm not a monster. After I made it all work, I split it into three parts: the grants, the pricing, the quotas.2 Otherwise it really would have been an unreviewable mess. But also, I could not have developed the quotas feature in real life in that artificial order. The grants structure evolved as my understanding of pricing and quota enforcement evolved. The original quota semantics sucked, so I rewound back to the data structures, which affected how the pricing got imported, which changed how the quotas were stored. The code reviewers didn't have to worry about that but I did.
Mercifully, because Aperture was new, everyone on the team understood that three 4000-line patches were better than twenty-four 500-line patches when implementing this series of feature. There was even some forgiveness when it came out later -- inevitably -- that each of those parts was not quite right and needed more bugfixing. That's how new software gets made. That's the annealing stage.
But the hard part was the philosophical difference between that and, say, core Tailscale. Tailscale has 7+ years of maturity behind it. It's been annealing for a long time and it has a reputation for extreme quality, hardening, durability, whatever you want to call it. If you start pulling stunts like that in core Tailscale, stuff absolutely will break and its millions of users will absolutely not be impressed. Which is why, for the most part, we don't.
But the feeling of moving fast again is such a wonderful feeling. Some people devolve the analysis to "founder mode" and call it a personality thing, but it's not. It's using the right tool for the right job at the right time. Sometimes you need to go fast, sometimes you need to go slow.
Pain does not cause gain, it's just frequently correlated
That feeling of moving fast again reset my brain a little. It reminded me that some changes to mature products can become impossible because we commit so hard to the math of annealing that we fall forever into a local optimum. Sometimes, when the well is too deep, you can't escape from it without a bigger jump.
We're entering a world where it's cheap to produce bigger changes, but that doesn't make it any safer. Or, it's cheap to ask an LLM to artificially break your change into a dozen rule-compliant PRs but then you just stuck on tedious neverending code reviews instead.
On the other hand, it's also possible to fork your own project a dozen different ways, add huge compliance test suites you never could have afforded to invest in before, rewrite your project in Rust in a week just to see what happens.
Sturgeon's Law says 90% of your big changes will be crap because 90% of everything is crap. When your changes were 500 lines long and you had to reject them, that didn't feel like a huge sunk cost. But now, it's okay if your 12000 line changes are crap and you have to reject them; it's the same cost to write3 as the old 500-line change.
You still have to figure out how to efficiently review, reject, and refine these big jumps. You definitely need a much heavier investment into CI/CD automation, specifications, UX testing, all of it. But also, all those things just got cheaper.
I wouldn't recommend overdoing it. The other thing is, customers don't like it if you change your product out from underneath them too often. But sometimes, you're just stuck in a rut. Sometimes you have to use a higher-energy jump to get unstuck. That doesn't mean you abandon smaller steps. Use the right tool for the job.
Footnotes
1 The reviews only need to be sequential because Github's code review system doesn't support stacked diffs, 18+ years later, leading us into this false dichotomy in the first place.
2 That's a slight oversimplification since there were a couple of other parts first. I had to define the data structures for the quotas before I actually added the quota system, so that I could use the data structures in the grant syntax, and so on in a big circle.
3 A 12000-line AI-driven patch might take as much time to write as a 500-line human-written patch, but by default it's much more work to review. In fact, so much work that people give up trying, and rightly so. Rather than abandon hope, I continue to think we need to invest more into (and will gain more from) non-annoying AI-assisted review workflows than AI-assisted development workflows. Imagine for example an automated pre-human-review step that says "no, this sucks, fix these 25 things first" and closes the pull request. Is it rude? Not really, if it's good quality advice that comes back fast. In a world where reviewing code is hard and writing it is easy, put more demands on the writers.





