# Szymon Wilczek - Complete Content Corpus > The full text of every essay published on szymon-wilczek.me by Szymon Wilczek (Linux kernel, C, GNU Emacs), newest first. Org markup is kept as written. The map of the rest of the site is at https://szymon-wilczek.me/llms.txt. When quoting, cite the essay's URL given in its header below. --- ================================================================================ ARTICLE: Screenshots of au-themes for GNU Emacs URL: https://szymon-wilczek.me/writings/au-themes-screenshots/ DATE: 2026-10-17 CATEGORY: Emacs TAGS: emacs, themes, accessibility DESCRIPTION: Every au-theme in Emacs Lisp, C, Magit, Dired and Org, as it looks in my own Emacs. ================================================================================ * About these pictures [[https://github.com/szymonwilczek/au-themes][au-themes]] are calm, low-glare colour themes for GNU Emacs, made first of all for autistic people and for anyone who finds most themes too loud to read for long. The code and the test suite live at [[https://github.com/szymonwilczek/au-themes][szymonwilczek/au-themes]]. README explains how the colours are chosen and checked. The screenshots below show the themes as they are on the =main= branch today (17.10.2026). They are taken in my everyday Emacs, not in a clean one: the font is Typus Mono 92 (the story is in [[/writings/the-8-pixel-obsession-typus-mono][8-Pixel Obsession]]), the tabs come from [[https://github.com/szymonwilczek/bufferline.el][bufferline.el]], and the mode line, Evil and the completion stack are my own setup. So this is what the themes look like in real use, not in a demo. Each theme gets four pictures: 1. *Code*: Emacs Lisp from =au-themes.el= next to a small C file in =c-ts-mode=. 2. *Git*: Magit status with staged and unstaged changes, next to a commit that changed a palette. 3. *Dired and completion*: a Dired listing, a =*Help*= buffer, and =M-x= with Vertico and Marginalia. 4. *Org*: a release plan with headings, TODO keywords, tags, a table, a source block and a quote, next to the week agenda. Dark themes are best viewed on a dark page :) * Light themes - [[#au-whispergrove-day][au-whispergrove-day]] - [[#au-whispergrove-morning][au-whispergrove-morning]] - [[#au-aurum-day][au-aurum-day]] - [[#au-parchment-day][au-parchment-day]] - [[#au-salina-day][au-salina-day]] - [[#au-herbarium-day][au-herbarium-day]] ** au-whispergrove-day Muted greens and neutral tones for daylight. #+attr_html: :alt au-whispergrove-day theme code sample :loading lazy [[/assets/au-themes/au-whispergrove-day.png][file:/assets/au-themes/thumbs/au-whispergrove-day.webp]] #+attr_html: :alt au-whispergrove-day theme Magit sample :loading lazy [[/assets/au-themes/au-whispergrove-day-git.png][file:/assets/au-themes/thumbs/au-whispergrove-day-git.webp]] #+attr_html: :alt au-whispergrove-day theme Dired and completion sample :loading lazy [[/assets/au-themes/au-whispergrove-day-dired.png][file:/assets/au-themes/thumbs/au-whispergrove-day-dired.webp]] #+attr_html: :alt au-whispergrove-day theme Org sample :loading lazy [[/assets/au-themes/au-whispergrove-day-org.png][file:/assets/au-themes/thumbs/au-whispergrove-day-org.webp]] ** au-whispergrove-morning A dimmer canvas than the other light themes, for early mornings or a room with little light. #+attr_html: :alt au-whispergrove-morning theme code sample :loading lazy [[/assets/au-themes/au-whispergrove-morning.png][file:/assets/au-themes/thumbs/au-whispergrove-morning.webp]] #+attr_html: :alt au-whispergrove-morning theme Magit sample :loading lazy [[/assets/au-themes/au-whispergrove-morning-git.png][file:/assets/au-themes/thumbs/au-whispergrove-morning-git.webp]] #+attr_html: :alt au-whispergrove-morning theme Dired and completion sample :loading lazy [[/assets/au-themes/au-whispergrove-morning-dired.png][file:/assets/au-themes/thumbs/au-whispergrove-morning-dired.webp]] #+attr_html: :alt au-whispergrove-morning theme Org sample :loading lazy [[/assets/au-themes/au-whispergrove-morning-org.png][file:/assets/au-themes/thumbs/au-whispergrove-morning-org.webp]] ** au-aurum-day Warm earth tones on a muted canvas. #+attr_html: :alt au-aurum-day theme code sample :loading lazy [[/assets/au-themes/au-aurum-day.png][file:/assets/au-themes/thumbs/au-aurum-day.webp]] #+attr_html: :alt au-aurum-day theme Magit sample :loading lazy [[/assets/au-themes/au-aurum-day-git.png][file:/assets/au-themes/thumbs/au-aurum-day-git.webp]] #+attr_html: :alt au-aurum-day theme Dired and completion sample :loading lazy [[/assets/au-themes/au-aurum-day-dired.png][file:/assets/au-themes/thumbs/au-aurum-day-dired.webp]] #+attr_html: :alt au-aurum-day theme Org sample :loading lazy [[/assets/au-themes/au-aurum-day-org.png][file:/assets/au-themes/thumbs/au-aurum-day-org.webp]] ** au-parchment-day Almost monochrome: italics and brightness steps instead of colour. #+attr_html: :alt au-parchment-day theme code sample :loading lazy [[/assets/au-themes/au-parchment-day.png][file:/assets/au-themes/thumbs/au-parchment-day.webp]] #+attr_html: :alt au-parchment-day theme Magit sample :loading lazy [[/assets/au-themes/au-parchment-day-git.png][file:/assets/au-themes/thumbs/au-parchment-day-git.webp]] #+attr_html: :alt au-parchment-day theme Dired and completion sample :loading lazy [[/assets/au-themes/au-parchment-day-dired.png][file:/assets/au-themes/thumbs/au-parchment-day-dired.webp]] #+attr_html: :alt au-parchment-day theme Org sample :loading lazy [[/assets/au-themes/au-parchment-day-org.png][file:/assets/au-themes/thumbs/au-parchment-day-org.webp]] ** au-salina-day The coast in daylight: salt flats, sand dunes, deep cobalt ocean, driftwood and brine pink. #+attr_html: :alt au-salina-day theme code sample :loading lazy [[/assets/au-themes/au-salina-day.png][file:/assets/au-themes/thumbs/au-salina-day.webp]] #+attr_html: :alt au-salina-day theme Magit sample :loading lazy [[/assets/au-themes/au-salina-day-git.png][file:/assets/au-themes/thumbs/au-salina-day-git.webp]] #+attr_html: :alt au-salina-day theme Dired and completion sample :loading lazy [[/assets/au-themes/au-salina-day-dired.png][file:/assets/au-themes/thumbs/au-salina-day-dired.webp]] #+attr_html: :alt au-salina-day theme Org sample :loading lazy [[/assets/au-themes/au-salina-day-org.png][file:/assets/au-themes/thumbs/au-salina-day-org.webp]] ** au-herbarium-day Pressed sage leaves, dried lavender, oak-bark ink and chamomile pollen. #+attr_html: :alt au-herbarium-day theme code sample :loading lazy [[/assets/au-themes/au-herbarium-day.png][file:/assets/au-themes/thumbs/au-herbarium-day.webp]] #+attr_html: :alt au-herbarium-day theme Magit sample :loading lazy [[/assets/au-themes/au-herbarium-day-git.png][file:/assets/au-themes/thumbs/au-herbarium-day-git.webp]] #+attr_html: :alt au-herbarium-day theme Dired and completion sample :loading lazy [[/assets/au-themes/au-herbarium-day-dired.png][file:/assets/au-themes/thumbs/au-herbarium-day-dired.webp]] #+attr_html: :alt au-herbarium-day theme Org sample :loading lazy [[/assets/au-themes/au-herbarium-day-org.png][file:/assets/au-themes/thumbs/au-herbarium-day-org.webp]] * Dark themes - [[#au-whispergrove-night][au-whispergrove-night]] - [[#au-aurum-night][au-aurum-night]] - [[#au-parchment-night][au-parchment-night]] - [[#au-salina-night][au-salina-night]] - [[#au-herbarium-night][au-herbarium-night]] ** au-whispergrove-night Muted greens and earth tones for unlit rooms. #+attr_html: :alt au-whispergrove-night theme code sample :loading lazy [[/assets/au-themes/au-whispergrove-night.png][file:/assets/au-themes/thumbs/au-whispergrove-night.webp]] #+attr_html: :alt au-whispergrove-night theme Magit sample :loading lazy [[/assets/au-themes/au-whispergrove-night-git.png][file:/assets/au-themes/thumbs/au-whispergrove-night-git.webp]] #+attr_html: :alt au-whispergrove-night theme Dired and completion sample :loading lazy [[/assets/au-themes/au-whispergrove-night-dired.png][file:/assets/au-themes/thumbs/au-whispergrove-night-dired.webp]] #+attr_html: :alt au-whispergrove-night theme Org sample :loading lazy [[/assets/au-themes/au-whispergrove-night-org.png][file:/assets/au-themes/thumbs/au-whispergrove-night-org.webp]] ** au-aurum-night Amber and gold on a deep background, with the least blue light of the dark themes. #+attr_html: :alt au-aurum-night theme code sample :loading lazy [[/assets/au-themes/au-aurum-night.png][file:/assets/au-themes/thumbs/au-aurum-night.webp]] #+attr_html: :alt au-aurum-night theme Magit sample :loading lazy [[/assets/au-themes/au-aurum-night-git.png][file:/assets/au-themes/thumbs/au-aurum-night-git.webp]] #+attr_html: :alt au-aurum-night theme Dired and completion sample :loading lazy [[/assets/au-themes/au-aurum-night-dired.png][file:/assets/au-themes/thumbs/au-aurum-night-dired.webp]] #+attr_html: :alt au-aurum-night theme Org sample :loading lazy [[/assets/au-themes/au-aurum-night-org.png][file:/assets/au-themes/thumbs/au-aurum-night-org.webp]] ** au-parchment-night Almost monochrome: italics and brightness steps instead of colour. #+attr_html: :alt au-parchment-night theme code sample :loading lazy [[/assets/au-themes/au-parchment-night.png][file:/assets/au-themes/thumbs/au-parchment-night.webp]] #+attr_html: :alt au-parchment-night theme Magit sample :loading lazy [[/assets/au-themes/au-parchment-night-git.png][file:/assets/au-themes/thumbs/au-parchment-night-git.webp]] #+attr_html: :alt au-parchment-night theme Dired and completion sample :loading lazy [[/assets/au-themes/au-parchment-night-dired.png][file:/assets/au-themes/thumbs/au-parchment-night-dired.webp]] #+attr_html: :alt au-parchment-night theme Org sample :loading lazy [[/assets/au-themes/au-parchment-night-org.png][file:/assets/au-themes/thumbs/au-parchment-night-org.webp]] ** au-salina-night Midnight ocean, dark basalt, phosphorescent turquoise and maritime coral. #+attr_html: :alt au-salina-night theme code sample :loading lazy [[/assets/au-themes/au-salina-night.png][file:/assets/au-themes/thumbs/au-salina-night.webp]] #+attr_html: :alt au-salina-night theme Magit sample :loading lazy [[/assets/au-themes/au-salina-night-git.png][file:/assets/au-themes/thumbs/au-salina-night-git.webp]] #+attr_html: :alt au-salina-night theme Dired and completion sample :loading lazy [[/assets/au-themes/au-salina-night-dired.png][file:/assets/au-themes/thumbs/au-salina-night-dired.webp]] #+attr_html: :alt au-salina-night theme Org sample :loading lazy [[/assets/au-themes/au-salina-night-org.png][file:/assets/au-themes/thumbs/au-salina-night-org.webp]] ** au-herbarium-night Pressed sage, dried lavender, oak-gall ink, terracotta flora and chamomile pollen. #+attr_html: :alt au-herbarium-night theme code sample :loading lazy [[/assets/au-themes/au-herbarium-night.png][file:/assets/au-themes/thumbs/au-herbarium-night.webp]] #+attr_html: :alt au-herbarium-night theme Magit sample :loading lazy [[/assets/au-themes/au-herbarium-night-git.png][file:/assets/au-themes/thumbs/au-herbarium-night-git.webp]] #+attr_html: :alt au-herbarium-night theme Dired and completion sample :loading lazy [[/assets/au-themes/au-herbarium-night-dired.png][file:/assets/au-themes/thumbs/au-herbarium-night-dired.webp]] #+attr_html: :alt au-herbarium-night theme Org sample :loading lazy [[/assets/au-themes/au-herbarium-night-org.png][file:/assets/au-themes/thumbs/au-herbarium-night-org.webp]] As always: ~Signed-off-by: Szymon Wilczek ~ ================================================================================ ARTICLE: Rules of Joker: Silesian Remik URL: https://szymon-wilczek.me/writings/joker-rules/ DATE: 2026-10-03 CATEGORY: Games TAGS: cards, joker, remik, rules, silesia DESCRIPTION: The complete, dated rulebook of Joker - the Silesian variant of rummy - as played at our table, written down once so the arguments can finally stop :) ================================================================================ * Why This Page Exists Joker - or /remik/, as most of Poland calls it - is one of those card games everybody knows and nobody plays the same way. Every region, every family, every kitchen table has its own house rules, and every new game starts with the same ritual: ten minutes of arguing about whether you can take from the discard pile, how much an ace is worth, and what happens to the joker. So I wrote it down. All of it, in one place, with a date attached. What follows is the variant we play - Silesian rummy - spelled out precisely enough that the next argument can be settled by sending a link. The rest of this page is in Polish, because that's the language the game is played in at our table. If you wandered in here from somewhere else: these are just rules of a card game, nothing more. * Pojęcia Żeby nie było żadnych niedomówień, najpierw słownik. Każde z tych słów w dalszej części znaczy dokładnie to, co tutaj. - *Talia* - zakryty stos kart, z którego się ciągnie. - *Stos odrzuconych* - odkryty stos kart obok talii, na który odrzuca się kartę na koniec tury. Ciągnąć z niego można tylko wierzchnią kartę. - *Ręka* - karty, które gracz trzyma i których nie widzą inni. - *Tura* - jeden ruch jednego gracza: od pociągnięcia karty do odrzucenia karty. - *Runda* - jedno rozdanie: od rozdania kart do momentu, w którym ktoś skończy. - *Rozgrywka* - cała gra, czyli tyle rund, ile trzeba, żeby ktoś przekroczył ustalony limit punktów. - *Układ* - co najmniej 3 karty leżące razem na stole, tworzące sekwens albo grupę. - *Sekwens* - co najmniej 3 karty w jednym kolorze, po kolei (np. 5 kier, 6 kier 7 kier ~lub~ 3 kier, 3 pik, 3 karo). - *Sekwens schodkowy* - specjalny rodzaj sekwensu, który obejmuje co najmniej 3 karty w jednym kolorze *tylko* po kolei (np. 5 kier, 6 kier, 7 kier, ~ale nie~: 3 kier, 3 pik, 3 karo) - *Czysty sekwens* - sekwens schodkowy bez ani jednego Jokera. - *Grupa* - 3 lub 4 karty tej samej wartości, każda w innym kolorze (np. 3 kier, 3 pik, 3 karo, 3 trefl). - *Wyłożenie się* - pierwsze położenie własnych układów na stole w danej rundzie. - *Dokładanie* - dokładanie kart z ręki do układów, które już leżą na stole (swoich lub cudzych). - *Skończenie* - pozbycie się wszystkich kart z ręki, co kończy rundę. - *Przełożenie* - przełożenie potasowanej talii przed rozdaniem, połączone z prawem do szukania Jokera (szczegóły niżej). - *Czyszczenie* - zebranie pełnej grupy ze stołu na stos odrzuconych. * Karty i rozdanie - Gra się dwiema taliami po 52 karty plus 4 Jokery - razem 108 kart (dla 2 osób, czyli rozgrywka ~1 vs 1~ często grywa się też jedną talią, wtedy 2 Jokery jedynie). - Każdy gracz dostaje 13 kart. Rozdający dostaje 14. - Rozdaje się po dżentelmeńsku: po jednej karcie, zgodnie z ruchem wskazówek zegara, zaczynając od osoby siedzącej obok rozdającego. Ostatnia karta każdego okrążenia trafia więc do rozdającego, a na sam koniec rozdający daje sobie jeszcze jedną, czternastą kartę. Rozdawanie kończy się podwójną kartą dla siebie - nikt inny nie dostaje niczego "dodatkowego" w trakcie. - Pozostałe karty kładzie się zakryte na środku - to jest talia. Stos odrzuconych na początku jest pusty. - W następnej rundzie rozdaje kolejna osoba zgodnie z ruchem wskazówek zegara. * Przełożenie - Tasuje i rozdaje zawsze ta sama osoba - rozdający danej rundy. - Prawo do przełożenia talii ma osoba następna po rozdającym, zgodnie z ruchem wskazówek zegara - czyli ta, która w następnej rundzie będzie tasować i rozdawać. Lub dowolnie, jeśli zostanie to uzgodnione - kto pierwszy ten lepszy, najczęściej jednak żeby uniknąć chaosu zalecana jest kolejność zgodnie z ruchem wskazówek zegara. - Przełożenie wygląda tak: przekładający sam wybiera moment i miejsce, w którym zdejmuje część potasowanej talii. Ogląda 3 karty z dołu zdjętej części i sprawdza, czy jest wśród nich Joker. - Jeśli jest - może go sobie wziąć. Wtedy rozdający daje mu już tylko 12 kart, bo trzynastą jest Joker znaleziony przy przełożeniu. - Nawet jeśli wśród 3 kart są 2 Jokery, wziąć można *tylko jednego*. - Wzięcie Jokera jest prawem, nie obowiązkiem. Jeśli przekładający go nie weźmie (albo żadnego nie znajdzie), dostaje normalnie 13 kart. * Przebieg tury - Gra toczy się zgodnie z ruchem wskazówek zegara. - Rundę zaczyna rozdający. Ma 14 kart, więc jego pierwsza tura polega wyłącznie na odrzuceniu jednej karty na stos odrzuconych - bez ciągnięcia. To jedyny wyjątek od normalnego przebiegu tury. - Każda kolejna tura wygląda tak: 1. *Początek:* pociągnięcie jednej karty - z talii albo wierzchniej karty ze stosu odrzuconych (zasady ciągnięcia ze stosu odrzuconych niżej). 2. *Środek:* opcjonalnie - wyłożenie się, dokładanie, podmiana Jokera, o ile gracz spełnia warunki. 3. *Koniec:* odrzucenie jednej karty na stos odrzuconych - albo skończenie (które też kończy się odrzuceniem karty). - Gdy talia się wyczerpie, stos odrzuconych - poza wierzchnią kartą - tasuje się i kładzie zakryty jako nowa talia. * Układy - Sekwens jest zdefiniowany na górze strony. - Grupa (/też zdefiniowana na górze/) to 3 lub 4 karty tej samej wartości, każda w innym kolorze. Gramy dwiema taliami, więc istnieją dwie identyczne karty (np. dwie 3 karo) - w jednej grupie może leżeć *najwyżej* jedna z nich (ergo, bez duplikatów). - As może być na dole sekwensu (3-2-A) albo na górze (A-K-D). Nie może być w środku - zawijanie (2-A-K) jest niedozwolone i nie istnieje. - Joker zastępuje dowolną kartę. Nie ma limitu Jokerów w jednym układzie, ale układ nie może składać się z samych Jokerów - musi w nim być przynajmniej jedna normalna karta. * Czyszczenie - Czyszczenie dotyczy tylko grup. - Grupa jest skończona, gdy leżą w niej 4 karty - po jednej z każdego koloru. Nic więcej nie da się do niej dołożyć. - Skończoną grupę można zebrać ze stołu i położyć na stos odrzuconych. Nie jest to obowiązkowe - można, ale nie trzeba. * Wyłożenie się Żeby się wyłożyć, trzeba jednocześnie spełnić oba warunki: 1. *Czysty sekwens* - wśród wykładanych układów musi być przynajmniej jeden *czysty sekwens*. 3-2-A liczy się jako czysty sekwens. 2. *51 punktów* - suma wartości wszystkich wykładanych kart musi wynosić co najmniej 51. Wartości kart przy wykładaniu: | Karta | Punkty | |-------------------+--------------------------------| | 2-10 | wartość z karty | | Walet, Dama, Król | 10 | | As w 3-2-A | 1 | | As w A-K-D | 10 | | As w grupie asów | 10 | | Joker | wartość karty, którą zastępuje | Dalsze zasady: - Dokładać do układów na stole (swoich i cudzych) może tylko gracz, który jest już wyłożony, lub kończy z ręki całą turę - wtedy może dołożyć ile chce, ale nadal potrzebuje *czystego sekwensu* oraz jednej karty do odrzucenia - może natomiast się dołożyć, ale warunkiem jest, że nie zostanie mu żadna karta - czyli skończy na raz. - W turze, w której gracz się wyłożył, nie może jeszcze dokładać. Dokładać może dopiero od swojej następnej tury. * Ciągnięcie ze stosu odrzuconych - Ciągnąć ze stosu odrzuconych można tylko wierzchnią kartę, i tylko zamiast ciągnięcia z talii - nigdy oprócz. - Karta wzięta ze stosu odrzuconych musi zostać użyta w tej samej turze. - *Gracz wyłożony* może ciągnąć ze stosu odrzuconych w każdej swojej turze. - *Gracz niewyłożony* może ciągnąć ze stosu odrzuconych tylko wtedy, gdy w tej samej turze skończy - czyli spełni wszystkie warunki skończenia, łącznie z czystym sekwensem. * Joker - Jokera leżącego w układzie na stole (swoim lub cudzym) można zabrać tylko w jeden sposób: kładąc w jego miejsce dokładnie tę kartę, którą zastępował. - Podmieniać Jokera może tylko gracz wyłożony. Wyjątek: gracz niewyłożony może to zrobić, jeśli w tej samej turze skończy. - Zabranego Jokera trzeba od razu, w tej samej turze, użyć w układzie na stole. Nie można go schować na rękę. - Jokera wolno odrzucić na stos odrzuconych. Zasady tego nie zabraniają - zdrowy rozsądek owszem. Joker pasuje do wszystkiego, a na ręce na koniec rundy kosztuje 100 punktów, więc oddanie go następnemu graczowi to akt hojności, który trudno odróżnić od sabotażu własnej gry. Kto tak robi, ten albo wie coś, czego reszta stołu nie wie, albo jest już lekko pijany. Statystycznie raczej to drugie. * Skończenie - Skończyć to pozbyć się wszystkich kart z ręki: wszystkie poza jedną muszą trafić do układów na stole (własnych albo dołożone do cudzych), a ostatnią *trzeba* odrzucić na stos odrzuconych. - Skończenie *zawsze* kończy się odrzuceniem jednej karty. Nie ma innej drogi. Kto wyłożył wszystkie karty i nie ma czego odrzucić - nie skończył. - Do skończenia potrzebny jest *czysty sekwens* wśród własnych układów gracza na stole. - Można skończyć /z ręki/, czyli w jednej turze wyłożyć się i pozbyć wszystkich kart, bez wcześniejszego wykładania. Nie daje to żadnych dodatkowych punktów ani dodatkowej kary dla pozostałych. - Przy skończeniu z ręki wymagany jest *czysty sekwens*, ale *nie obowiązuje* próg 51 punktów. Kończąc, gracz czyści rękę, a nie zbiera punktację - próg 51 dotyczy tylko zwykłego wyłożenia się. - W turze skończenia wszystko dzieje się naraz, dlatego zasady muszą się tu poprawnie zazębić. Przykład: Ania jest wyłożona, Bartek nie. Bartek ma na ręce czysty sekwens, kartę pasującą do układu Ani i kartę, którą w układzie Ani zastępuje Joker. W jednej turze może: wyłożyć swój czysty sekwens, dołożyć kartę do układu Ani, podmienić Jokera, od razu użyć Jokera w swoim układzie i odrzucić ostatnią kartę. Wszystko to jest dozwolone tylko dlatego, że tą turą kończy - gdyby choć jedna karta mu została, mógłby najwyżej zwyczajnie się wyłożyć (o ile miałby 51 punktów), ale już nie dokładać ani podmieniać Jokera. * Punktacja - Gdy ktoś skończy, runda się kończy. Gracz, który skończył, dostaje 0 punktów. - Pozostali gracze dostają punkty karne - sumę wartości kart, które zostały im na ręce. Karty leżące na stole się nie liczą. | Karta na ręce | Punkty karne | |-----------------------+-----------------| | 2-10 | wartość z karty | | Walet, Dama, Król, As | 10 | | Joker | 100 (buła) | - Punkty karne sumują się przez wszystkie rundy rozgrywki. * Koniec rozgrywki - Przed rozgrywką gracze umawiają się, do ilu punktów grają. Nie ma tu domyślnego limitu - ile się ustali, tyle obowiązuje. Często gramy też pojedyncze rundy (bez zapisywania). - Gdy po którejś rundzie ktokolwiek przekroczy ustalony limit, rozgrywka się kończy. - Podlicza się punkty wszystkich graczy. Wygrywa ten, kto ma ich najmniej. As always: ~Signed-off-by: Szymon Wilczek ~ ================================================================================ ARTICLE: The Cycle of New Software: On Operative Simulacra URL: https://szymon-wilczek.me/writings/the-cycle-of-new-software/ DATE: 2026-09-02 CATEGORY: Philosophy TAGS: philosophy, epistemology, ontology, ai, software-engineering DESCRIPTION: On the operative simulacra of generative code, the breakdown of Brooks' essential complexity, the illusion of historical mastery, and the displacement of human cognitive centrality in computing. ================================================================================ * The Operative Simulacrum and the Confession at the Buffer Let me begin by dismantling the moral pedestal before anyone else has the satisfaction of doing it for me. I am not an off-grid ascetic crafting software on an unnetworked terminal. I use modern large language models daily. I prompt Claude, I explore neural code generation, and I appreciate the astonishing mechanical leverage these systems provide. If anyone wishes to cross-reference this with my recent [[/writings/the-architecture-of-inevitable-hypocrisy/][reflections on unavoidable hypocrisy]] and accuse me of pontificating from a compromised pulpit - by all means, take the shot. I accept the contradiction with open arms. Yet acknowledging leverage does not dissolve the quiet, persistent unease that settles over the room when the terminal screen goes still. When Jean Baudrillard articulated his genealogy of the simulacrum [fn:baudrillard], he examined signs that had severed their relation to underlying physical reality. In Baudrillard's taxonomy, the simulation precedes and determines the real. Yet his analysis remained bounded by a classical media ontology: representations were passive. A broadcast, an advertising billboard, or a suburban theme park could manipulate human perception, but none possessed autonomous causality. Generative software invalidates this passivity. What emerges when I prompt an LLM is an **operative simulacrum**. It exhibits every formal signifier of deliberate human design: strict typing, asynchronous concurrency primitives, cryptographic assertions, and schema definitions. It compiles; it binds to physical network interfaces; it consumes electrical wattage; it mutates persistent state across disks. Yet it refers to no underlying act of human deliberation. No engineer wrestled with the physical constraints of the domain; no user necessitated its existence; no living mind weighed its structural trade-offs. It is necessary here to distinguish the *operative simulacrum* from both traditional automated compilation and technical debt: - A compiler performs deterministic, mathematical transformations of explicit human intent from high-level semantics to machine instructions. The intentionality remains strictly anchored in the human author. - Technical debt represents conscious compromises made by human engineers who understand the ideal architecture but defer implementation due to economic constraints. The debt is recognized, measurable, and conceptually bounded. - The **operative simulacrum**, by contrast, incurs what must be termed **Epistemic Debt**: the compounding distance between the operational behavior of an executing program and the capacity of any living mind to account for its internal necessity. Epistemic Debt is not the presence of bugs; it is the presence of functioning code whose correctness cannot be verified through reason, but only through empirical observation of its failure to crash. * Rule-Following Without a Form of Life To grasp why the operative simulacrum destabilizes engineering, one must turn to the rule-following paradox formulated by Ludwig Wittgenstein in /Philosophical Investigations/ [fn:wittgenstein]. Wittgenstein demonstrated that no course of action could be determined by a rule, because every course of action can be made out to accord with the rule. What anchors a rule - what prevents interpretation from collapsing into arbitrary divergence - is participation in a shared **form of life** (/Lebensform/). A rule is sustained by a community of practitioners who correct errors, share stakes, and establish normative agreement through collective practice. A neural model does not participate in a form of life. It possesses no physical embodiment, experiences no vulnerability, and bears no exposure to the consequences of execution. When a model emits an algorithm for a distributed consensus protocol or an inverted index, it is not "following a rule" in the normative sense. It is producing a statistical continuation across a high-dimensional latent space. When we deploy code generated in this vacuum, a profound displacement occurs: #+begin_quote In the absence of a shared form of life between the generator and the execution environment, the concept of correctness ceases to be normative. It collapses into mere operational persistence: the code is treated as correct simply because no unhandled exception has yet terminated the process. #+end_quote We no longer evaluate software through semantic justification. We observe it behaviorally, as one might observe the weather or an uncontacted biological organism. * The Dissolution of Brooks' Dichotomy For nearly forty years, software architecture relied on the foundational distinction proposed by Fred Brooks in /No Silver Bullet/ [fn:brooks]: the separation between **accidental complexity** (the mechanical friction of syntax, compilers, and manual memory management) and **essential complexity** (the conceptual essence of the domain entities, relationships, and invariants). Brooks assumed that accidental complexity was a contingent tax on human cognition. By automating accidental friction, the engineer would finally be liberated to engage with pure essential complexity. The reality of generative computing shatters this assumption. Generative models do not simply eliminate accidental friction; they fabricate **synthetic essential complexity**. When an engineer prompts an entire backend architecture, the model does not merely write the syntax - it invents the domain entities, specifies their relationships, constructs the middleware validation rules, and designs the persistence schema. The developer does not engage with the essential complexity of the problem. Instead, the developer is presented with an already materialized conceptual framework that *appears* coherent, but whose internal trade-offs were never deduced from real-world requirements. Historically, comprehension preceded implementation: you understood the domain, and therefore you wrote the code. In generative engineering, implementation precedes comprehension: the system exists, runs, and functions, leaving the human in the bizarre position of having to reverse-engineer an architecture they theoretically /"authored"/. * Epistemic Bankruptcy at the Ninety-Percent Cliff Why does the contemporary developer universally abandon generative projects at the ninety-percent mark? Tom Cargill's **Ninety-Ninety Rule** [fn:cargill] - stating that the last ten percent of the code accounts for ninety percent of the development time - is typically treated as an empirical quip about project management. In the era of generative scaffolding, the Ninety-Ninety Rule is an ontological threshold: **the point at which accumulated Epistemic Debt suddenly comes due.** During the initial phase of a generative project, development velocity is asymptotic. The developer prompts, the model emits, and hundreds of files materialize without cognitive friction. Epistemic Debt is incurred with every token: dependencies are imported without architectural review; database constraints are established without operational testing; failure states are glossed over by default exception handlers. As long as the project remains in local development, this debt is costless. The application runs in a vacuum of simulated utility. The ninety-percent cliff is the exact moment the system touches reality: - When real network partitions violate the generated assumptions of consistency. - When an edge case in user input exposes an untested data model invariant. - When production state mutations require an idempotent migration that cannot be prompted away. To cross the threshold requires paying the accumulated Epistemic Debt in the only currency that exists: **deep, unhurried, manual cognitive labor**. Yet because the builder invested no personal friction in the construction of the system, they possess no emotional or cognitive equity in its survival. Abandoning the repository is therefore not an act of laziness; it is an entirely rational economic default on unpayable epistemic debt. Opening a new tab and prompting a fresh repository is the technical equivalent of filing for cognitive bankruptcy. * Radical Reversal: Myth of Prior Mastery At this point, a critical objection must be confronted - one that destabilizes the very foundation of the traditional engineering critique. The classical narrative laments that AI is destroying the engineer's deep mental model of the machine. But this complaint rests upon an unexamined historical fiction: **did the software engineer ever truly possess a total mental model?** Consider the modern computing stack in its brutal material reality: - A contemporary x86 or ARM CPU is not a deterministic instruction executor; it is an asynchronous, speculative supercomputer running proprietary, closed-source microcode that dynamically rewrites machine instructions, speculates on branch paths, and manages out-of-order execution across hidden register files. - The Linux kernel comprises tens of millions of lines of C and assembly, coordinating millions of concurrent state transitions across heterogeneous memory topologies. As a kernel contributor, I know intimately that no single contributor, maintainer, or subsystem architect comprehends the totality of its execution paths. - Compilers such as LLVM perform dozens of layered optimization passes whose collective interaction is mathematically intractable to any individual human mind. The belief that the pre-AI engineer possessed complete cognitive mastery of their systems was always an illusion. It was a useful, comforting fiction sustained by the slow pacing of manual syntax construction. Manual coding did not grant total comprehension; it just provided **cognitive compression**. Writing a C loop, designing [[/writings/the-8-pixel-obsession-typus-mono/][font metrics]], or allocating a buffer by hand gave the practitioner the subjective sensation of control, even while executing on hardware and operating systems whose complexity had long since surpassed human cognitive bandwidth. #+begin_quote Generative AI did not destroy human mastery over computing. It dismantled the slow, ritualized pacing that allowed us to pretend that mastery was real. #+end_quote * Antiquarian Trap and the Final Aporia This realization forces the low-level craftsman into an uncomfortable self-interrogation. When I retreat into my custom Emacs configuration, or audit pointer arithmetic in C, am I genuinely defending human agency - or am I seeking refuge in an **antiquarian coping mechanism**? To claim that manual syntax construction possesses intrinsic moral superiority is indistinguishable from claiming that hand-carving wooden gears possesses intrinsic moral superiority over industrial metallurgy. It confuses an authentic personal aesthetic with a systemic virtue. It is the digital equivalent of spinning wool on a hand loom while industrial automated mills clothe civilization. If software systems can be generated, optimized, and patched by stochastic models at velocities and scales that human coordination cannot match, then the human programmer is no longer the indispensable cognitive linchpin of technical progress. We are approaching an inflection point where the insistence on individual human comprehension becomes an operational bottleneck. This is the ultimate aporia of contemporary software engineering: We are compelled to use these tools because the systemic scale of modern computing demands them. Yet the more we rely upon them, the more we accelerate the evacuation of human reason from the technical infrastructure of civilization. For me, the personal dividing line remains narrow but uncompromising. I will continue to use large language models. I will continue to prompt them for AST transforms, build pipeline optimizations, and boilerplate acceleration. But I refuse to confuse generative throughput with authentic creation. The true test of a tool is not whether it was prompted in fifteen seconds or hammered out over sleepless nights. The test is whether, long after the initial dopamine of the prompt has dissolved, there remains a human being who understands why the system exists, accepts direct accountability for its execution, and possesses the quiet fortitude to stand behind it when the server fails at two in the morning. As always: ~Signed-off-by: Szymon Wilczek ~ [fn:baudrillard] Jean Baudrillard, /Simulacra and Simulation/ (Paris: Éditions Galilée, 1981; translated from French by Sheila Faria Glaser, Ann Arbor: University of Michigan Press, 1994). [fn:wittgenstein] Ludwig Wittgenstein, /Philosophical Investigations/ (Oxford: Basil Blackwell, 1953; translated by G. E. M. Anscombe). [fn:brooks] Frederick P. Brooks Jr., "No Silver Bullet-Essence and Accidents of Software Engineering," /IEEE Computer/, Vol. 20, No. 4 (April 1987). [fn:cargill] Tom Cargill, "The Ninety-Ninety Rule," as quoted by Jon Bentley in "Programming Pearls: Bumper-Sticker Computer Science," /Communications of the ACM/, Vol. 28, No. 9 (September 1985). ================================================================================ ARTICLE: Architecture of Inevitable Hypocrisy URL: https://szymon-wilczek.me/writings/the-architecture-of-inevitable-hypocrisy/ DATE: 2026-09-01 CATEGORY: Philosophy TAGS: philosophy, privacy, sovereignty, open-source DESCRIPTION: On the illusion of ideological purity, the doomed romanticism of rebellion, the AI enclosure of the digital commons, and the inescapable hypocrisy of modern digital life. ================================================================================ * Purity Trap and the Fantasy Ideological purity is remarkably easy to preach when it costs you nothing. In the clean, abstract world of computing philosophy, the battle lines are drawn with theatrical clarity. Stallman refuses to touch non-free JavaScript or run machines with proprietary firmware blobs. Snowden reminds us with mathematical precision that a cellular smartphone is, by architectural definition, a tracking beacon broadcasting physical coordinates to proprietary baseband processors and cellular towers. There is a deeply romantic, radical instinct in many of us who care about digital freedom - \\ the fantasy of the uncompromising rebel wanting to burn the corporate monolithic towers to the ground (/you caught that reference, right?/). Part of me sympathizes entirely with that raw anger. Modern corporate software ecosystems are predatory, extractive, and parasitic by design. You want to see the whole edifice dismantled. Except it is a war doomed to fail before it even begins. Corporations are no longer external adversaries we can simply boycott or burn down; they are the water supply, the power grid, the telecommunications backbone, and the operating system of civil society. Nobody likes this arrangement, yet we all inhabit it. I am not writing this to advocate for paranoid survivalist cosplay. I am not going to tell anyone to route every git commit through disposable virtual machines, or to swap their smartphone for a vintage Nokia - especially when telecommunication giants are already decommissioning the 2G and 3G networks that kept those phones alive. I won't pretend that masking your git author address behind an =ID+username@users.noreply.github.com= alias preserves your anonymity, because data brokers and scraping engines will inevitably link your identity anyway. Total non-participation does not make you a sovereign digital rebel. It simply renders you incapable of living in the modern world. * Gas Station Paradox Consider a mundane, almost embarrassingly petty scenario that played out in my mind recently at a petrol station. I despise closed, proprietary ecosystems. I run Linux on bare metal, audit my dotfiles with obsessive care, avoid walled gardens, and strive to keep my digital footprint deliberate and minimal. Yet there I stood, pulling a smartphone out of my pocket - a closed glass slab running proprietary firmware - just to scan a loyalty barcode inside a proprietary app for a minor discount per liter of fuel. The internal monologue immediately rushed to construct a defense: /"I am outsmarting the system. I don't use this phone for anything else; I'm just wringing a little economic value out of a predatory corporation."/ It is a comforting lie. But hey, at least I know it. Who extracted value from whom? To save a few coins, I surrendered telemetry, validated my identity, confirmed my physical location, and - most insidiously - allowed an algorithm to subtly dictate my physical driving route through the city. I did not exploit the system; I complied with its incentive architecture. The illusion of agency was just the lubricant that made the concession painless. Of course, a familiar rationalization immediately follows: /"I am nobody special. I am just an ordinary, unremarkable person commuting between daily errands; why would any corporation care about my mundane telemetry?"/ I remember Linus Torvalds saying that his personal philosophy on privacy was simply to /[[https://youtu.be/mfv0V1SxbNA?si=7MDt8a-3wcHp6IDg&t=2980]["be so uninteresting that nobody cares"]]./ Perhaps for some, that defense works. But I find it difficult to accept the premise that the only way to survive surveillance is to preemptively dilute who you are - to make yourself deliberately gray, uniform, and uninteresting just to be left alone. Sure, they might not look at my data directly. I might just be an anonymous row in an automated database. But that misses the point entirely. This is not about whether some corporate analyst is actively inspecting my telemetry; it is about *my own internal peace of mind*. Nobody genuinely enjoys living with the persistent, low-grade awareness of being observed, quantified, and nudged. \\ Desiring unmonitored boundaries is not paranoia - it is a fundamental human instinct to want to move through the world without an uninvited corporate passenger sitting silently in the passenger seat of your life. * The Illusion of Open Protocols and the Subscription Enclosure We like to tell ourselves that open protocols are the antidote. We point to email, the decentralized pioneer of the early internet. Yet try running your own sovereign mail server today. Within hours, your meticulously configured Postfix instance will have its packets silently dropped into the spam abyss by the corporate duopoly of Google and Microsoft, who have effectively cartelized email delivery under the banner of reputation scoring. And what happens when you turn to privacy-respecting alternatives? When you sign up for an encrypted, independent provider like Proton, you land right back into the defining economic cage of the twenty-first century: *the indefinite monthly subscription*. Subscriptions are everywhere. You no longer buy tools; you rent temporary permission to use them. You cannot escape the recurring debit, because sovereignty itself has been repackaged as a premium service tier. We trade one form of corporate dependency for another, congratulating ourselves on choosing the "ethical" landlord. * AI Enclosure: The Great GPL Expropriation For decades, the free software movement operated under a noble, almost sacred premise: *the digital commons*. Generations of developers contributed millions of lines of code under the GPL, copyleft, and permissive licenses, believing they were constructing a shared, un-enclosable reservoir of human knowledge. The philosophical pact was simple: you take freely from the commons, and in return, you contribute back to the commons. Then came large language models. Without asking for consent, negotiating terms, or honoring license attribution clauses, tech monopolies scraped decades of open-source repositories to train commercial neural networks. Today, those same corporations package the synthesis of our own collective work into tools like GitHub Copilot and ChatGPT, selling it back to us behind recurring monthly paywalls. The irony is devastating: the open-source movement did not dismantle software monopolies. It ended up serving as free, uncompensated fuel for the most centralized and impenetrable corporate walled gardens in technological history. * Should Closed-Source Software Even Exist? If we strip away the marketing rhetoric, a fundamental, uncomfortable question remains: \\ *is there any legitimate ethical reason for closed-source software to exist at all?* Whenever this is debated, defenders of proprietary code offer the same predictable arguments: 1. /Developers need to eat; if the source code is public, competitors will copy it and destroy the business./ 2. /Proprietary algorithms are the intellectual property that gives a firm value./ 3. /If attackers can read the source code, they will discover zero-day exploits and compromise users./ Yet when examined through an engineering lens, these justifications crumble into rationalizations for artificial control. Security through obscurity has been proven a dangerous fallacy for decades. Closing the source does not eliminate vulnerabilities; it just sweeps them behind NDAs and legal threats. And the economic argument? It equates software not with mathematics, literature, or shared human engineering knowledge, but with artificial scarcity. Closed source has never been about making software better. Its entire purpose is to erect a legal fence around a digital commons so that rent can be extracted indefinitely. It transforms software from a tool of human agency into a mechanism of leverage, where the user never truly owns the machine, only licensed to operate within the vendor's designated parameters. If closed source is an inherently artificial, anti-user construct, then every time we compile a proprietary binary or accept a closed EULA, we are validating a system designed to disenfranchise us. And yet, we do it every single day. * Software-Defined Hardware The encroachment of closed code has long escaped the boundaries of the monitor; it has colonized the physical world. Consider the modern reality of the Right to Repair. You can purchase a [[https://www.npr.org/2025/01/15/nx-s1-5260895/john-deere-ftc-lawsuit-right-to-repair-tractors][John Deere]] tractor, drive a modern connected vehicle ([[https://evcarlatest.com/bmw-cancels-heated-seat-subscription-criticism/][where seat heating or acceleration curves are gated behind software toggles]]), or buy a flagship smartphone. Physically, the object sits in your garage or your pocket. Yet you do not own it. Through cryptographic parts serialization - where components like camera sensors, batteries, or display panels are digitally paired to the logic board at the factory - replacing a broken module with an identical, genuine replacement fails unless authorized by the manufacturer's remote validation server. Code has transformed physical atoms into licensed services (sometimes with wheels). If a manufacturer decides to sunset an activation API, disable a feature, or declare your hardware obsolete, your physical property is reduced to an expensive paperweight. You are no longer a buyer; you are a permanent licensee of matter. * Cashless Chokepoint and the Crypto Mirage True sovereignty does not merely concern source code or file formats; its ultimate frontier is economic. The steady, orchestrated elimination of physical cash in favor of digital payment rails (Visa, Mastercard, mobile contactless schemes) represents the structural death of transactional anonymity. Every coffee, every tank of fuel, and every server hosting invoice is routed through centralized payment processors that possess the unilateral power of financial deplatforming. When you cannot transact without an intermediary's cryptographic blessing, your right to participate in society is strictly provisional. For a brief moment, cryptocurrency was heralded as the mathematical salvation - a trustless, decentralized medium of exchange that would disintermediate the banks and restore monetary sovereignty. To dismiss the entire ecosystem as a simple joke or generic scam, however, misses the real architectural and economic mechanics at play. Proponents and traders argue that crypto markets represent the purest form of financial meritocracy - a ruthless game of skill, quantitative analysis, and risk management where the most disciplined participants extract legitimate alpha. Yet when scrutinized through the cold lens of market microstructure and systems engineering, the structural reality is unforgiving: 1. Unlike productive equities - which are backed by enterprises producing real-world goods, services, and cash flows - secondary token speculation is structurally a *negative-sum game*. Once you account for exchange trading fees, network gas, slippage, and liquidation penalties, capital is continuously drained from the system. In a closed loop without organic external revenue, every dollar of profit extracted by a skilled trader is mathematically paid for by the capital loss of another participant acting as exit liquidity. It is not an engine of shared economic value; it is an adversarial player-versus-player matchmaking arena. 2. On-chain, retail participants are systematically outmatched by *Maximal Extractable Value*. High-frequency searcher bots and block builders monitor the public mempool in real time, executing sandwich attacks, front-running, and arbitrage that extract rent directly from ordinary transactions before they are even confirmed in a block. 3. Forensic blockchain analytics and peer-reviewed economic research have documented that between [[https://www.forbes.com/sites/javierpaz/2022/08/26/more-than-half-of-all-bitcoin-trades-are-fake/][50%]] and [[https://www.nber.org/papers/w30783][70%]] of reported volume across unregulated exchanges consists of automated wash trading - market makers trading with themselves to fabricate artificial liquidity and create the illusion of genuine market depth. 4. The ultimate irony is architectural. The vast majority of the crypto economy does not run on sovereign, self-hosted nodes. It relies on centralized custodial exchanges, centralized RPC node infrastructure (Infura or Alchemy hosted on AWS), and centralized stablecoins (USDT and USDC). In these stablecoins, the issuers maintain administrative smart-contract functions enabling them to freeze, blacklist, and confiscate balances with a single multi-signature transaction. Crypto did not deliver a sovereign, censorship-resistant currency for daily commerce; extreme volatility and throughput constraints disqualified it as a stable unit of account. Instead, we traded regulated commercial banks for opaque offshore exchanges and automated front-running bots, proving once again how easily the dream of decentralization collapses into another layer of compromise. * Convenience Trap: Illusion of Proprietary Security Whenever the conversation turns to proprietary software, someone inevitably brings up mobile banking or digital identity. The standard defense is immediate: /"Well, critical financial and government software has to be closed and heavily restricted - otherwise, it wouldn't be secure."/ This is not a nostalgic plea for the days of standing in physical bank queues or carrying binders of paper documents; instant digital transactions and modern identity verification are genuine engineering achievements. But we must be intellectually honest about the architectural trade-off we accepted. We bought into the premise that digital progress requires total vendor control: proprietary hardware attestations, Play Integrity checks, closed binary blobs, and continuous background telemetry. We accepted the doctrine that opacity equals safety. Yet reality continually punctures that illusion. Consider centralized systems and digital ID ecosystems like Poland's [[https://www.gov.pl/web/mobywatel][mObywatel]] and state-integrated medical registries - championed as the pinnacle of mobile civic convenience. Despite all the closed-source security theater, when a massive third-party breach [[https://www.eska.pl/news/biznes/wyciekly-dane-medyczne-milionow-polakow-gawkowski-apeluje-o-zastrzeganie-numerow-pesel-aa-EzQ9-WF7j-zxjo.html][exposed sensitive medical records and PESEL numbers for millions of citizens]], the state’s primary advice was to scramble into yet another proprietary mobile menu to lock our IDs. The closed architecture did not make the system impervious; it just ensured that when the failure occurred, the users were entirely powerless. Why, then, do we continue to surrender our devices to closed ecosystems? The answer is rarely about superior security. It comes down to what Neil Postman diagnosed in /Technopoly/ [fn:postman] - the total surrender of human culture to the mandate of algorithmic efficiency. #+begin_quote Technopoly eliminates alternatives to itself in precisely the way Aldous Huxley outlined in Brave New World. It does not make them illegal. It does not make them immoral. It does not even make them unpopular. It makes them invisible and therefore irrelevant. And it does so by redefining what we mean by religion, by art, by family, by politics, by history, by truth, by privacy, by intelligence, so that our definitions fit its new requirements. Technopoly, in other words, is totalitarian technocracy. ~ Neil Postman #+end_quote Convenience is the universal solvent of engineering ethics. It dissolves ideological resistance far more effectively than state coercion or corporate mandate ever could. We didn't migrate our finances and state identities into closed mobile silos because we audited their cryptographic superiority; we did it because authenticating from our pocket felt like two clicks easier. * Militarization of Closed Code: The Pegasus Reality If ad trackers, loyalty algorithms, and subscription models represent the banal, everyday monetization of our compliance, there is a far darker frontier at the extreme end of the proprietary spectrum: *mercenary spyware*. Take Pegasus, developed by Israel's NSO Group - and the broader, shadow ecosystem of state-grade cyberweapons (Candiru, and their unnamed successors). Pegasus is not something you download by mistake. It operates on exploit chains: a silent, weaponized payload delivered through an invisible iMessage, an unanswered WhatsApp call, or a malformed font rasterization request. It requires zero interaction from the victim. Within seconds, it gains absolute, invisible root privileges over your device - extracting encrypted communications, harvesting credentials, activating cameras, recording ambient microphone audio, and streaming real-time GPS coordinates. The existence of such tools is an obscenity, yet it represents the logical, inevitable culmination of a world built on closed proprietary black boxes. Tech giants market these smartphones as impenetrable, luxury vaults of personal privacy. We pay premium prices to carry them. Yet because the entire stack - from the baseband processor firmware to the proprietary operating system kernel - is shrouded behind legal and technical walls, independent scrutiny is perpetually handicapped. Zero-day vulnerabilities are quietly hoarded and commodified by private cyber-arms dealers, auctioned off to intelligence agencies, authoritarian regimes, and sovereign wealth funds. It exposes the ultimate reality of the modern smartphone: *you are never the root user of your own hardware.* You are just a tenant occupying a glass slab, while private mercenaries and state actors hold the master keys. We reassure ourselves that our mundane, quiet lives make us uninteresting targets. But the fundamental architectural vulnerability remains: the physical device in our pocket is architecturally untrustworthy. * Price of Admission to "Society" To be intellectually honest, we must acknowledge an obvious counter-argument: *nobody is physically forcing you to surrender* (very obvious reference to /Brave New World/ by Huxley). You can choose absolute digital sovereignty today. You can flash a fully deblobbed Linux kernel onto an ancient ThinkPad, air-gap your workstation, sit in your room, and achieve immaculate software purity. Nobody is breaking down your door to force a proprietary binary onto your disk. The option of total isolation is real and achievable. The catch, of course, is the door itself. The moment you want to step outside your room and participate in the circle known as *Society*, the terms of engagement change completely. This dynamic was articulated with prophetic clarity by Jacques Ellul in /The Technological Society/ [fn:ellul]. Ellul demonstrated that /Technique/ is not just a collection of machines, but the autonomous, unstoppable pursuit of absolute efficiency and rationalization in every domain of human activity. When Technique becomes our primary environment, it subordinates ethics, politics, and culture, forcing the individual into constant adaptation under threat of total social exile. #+begin_quote No technique is possible when men are free. ... Technique requires predictability and, no less, exactness of prediction. It is necessary, then, that technique prevail over the human being. ... The individual must be fashioned by techniques ... in order to wipe out the blots his personal determination introduces into the perfect design of the organization. ~ Jacques Ellul #+end_quote Modern society does not enforce technical compliance through legal statutes; it enforces it through this exact mechanism of Technique - an unwritten web of wild, unspoken standards that humanity arbitrarily decided to call *norms*. Need to board a train or access an event? /"Just present the dynamic QR code in our proprietary app."/ \\ Need to communicate with your family or coordinate with colleagues? /"Why aren't you on WhatsApp? Everyone is there."/ \\ Need to rent an apartment, authenticate with a government portal, or split an expense? /"Just use the instant mobile transfer."/ If you refuse to use these closed platforms, you are not celebrated as a principled philosopher of software freedom. You are treated as an intolerable source of social friction - an eccentric nuisance who refuses to play by the arbitrary rules of the game. Society has effectively weaponized human connection against technical sovereignty. The real trade-off is never just about software; it is an ultimatum between ideological purity in total exile, or quiet compromise as the mandatory price of admission to human community. * Fourfold Litmus Test of the Impossible Outlaw To truly understand how deeply the corporate apparatus is intertwined with daily existence, consider a simple thought experiment. What would it actually look like if you refused every single technical compromise today? Apply the litmus test across four mundane dimensions of living: 1. Does your home internet run through the ISP-provided black-box router with un-auditable factory firmware and closed Wi-Fi binary blobs? Or did you source open hardware, compile a deblobbed OpenWrt image from source, and inspect every incoming packet? 2. When you finish work and want to relax, do you stream music on Spotify, watch a film on Netflix, or launch a game on PlayStation - passively accepting their DRM wrappers and telemetry algorithms? Or do you maintain an offline library of hand-ripped, DRM-free FLAC and MKV files on a local NAS? 3. When you open your sovereign Neovim or Emacs buffer, do you pipe keystrokes to cloud-hosted LLM assistants like Copilot, Claude, or ChatGPT? Do you download thousands of opaque, transient dependencies on the fly via =npm=, =cargo=, or =pip= from centralized corporate registries? 4. This one is mostly Poland-based: How do you collect a parcel or buy groceries? Do you tap InPost parcel lockers using a mobile app with Bluetooth and GPS permissions, paying instantly with contactless tokens and BLIK? Or do you walk to the post office with physical banknotes, waiting in line and refusing to register a phone number? Reading this list reveals the brutal truth: if you tried to achieve an uncompromised "yes" across all four categories, you would not be an enthusiast of software freedom. You would be *an outcast*. You would spend forty hours a week maintaining the friction of your own existence, alienating friends, family, and colleagues, and appearing to the surrounding world like a deranged technological eccentric. The modern infrastructure was deliberately engineered so that opting out requires superhuman stamina. * Anatomy of Modern Hypocrisy This brings us to the central wound of this essay: *what does hypocrisy actually look like for a software engineer today?* It is not just about scanning a barcode at a gas station or carrying a smartphone. The hypocrisy is woven directly into our livelihoods. In /The Myth of the Machine/ [fn:mumford], Lewis Mumford described the /Megamachine/ - a massive, institutionalized socio-technical apparatus where human beings are stripped of autonomous agency and repurposed as standardized, interchangeable components. #+begin_quote The one lasting contribution of the megamachine was the myth of the machine itself: the notion that this machine was, by its very nature, absolutely irresistible - and yet, provided one did not oppose it, ultimately beneficent. That magical spell still enthralls both the controllers and the mass victims of the megamachine today. ~ Lewis Mumford #+end_quote Consider how neatly the modern software industry fulfills Mumford's diagnosis: From nine to five, we write closed-source, proprietary code for companies whose business models rely on telemetry, tracking, vendor lock-in, and algorithmic engagement. We act as standard-issue cogs assembling the very digital walls we despise. We implement tracking SDKs, optimize conversion funnels, and sign contracts forbidding us from sharing our work. We collect paychecks funded directly by surveillance capitalism. Then, at five o'clock, we close our corporate laptops, switch to our personal Linux machines, fire up Emacs or Neovim, and write impassioned essays about software sovereignty, the beauty of open source, and the sanctity of user privacy. We maintain a hierarchy of comfortable justifications: - /"I need to pay rent and feed my family."/ - /"I'm just an engineer; I don't make product decisions."/ - /"I'm nudging the company toward better open-source practices from within."/ These rationalizations may be practically true. But they do not dissolve the moral contradiction. We are the willing architects of the digital enclosures we spend our evenings lamenting. Is this *active hypocrisy* - a cynical, bad-faith betrayal of our stated values? Or is it *structural hypocrisy* - the unavoidable condition of existing inside a megamachine where total ideological purity requires social and professional suicide? * On Dualism: The Schizophrenia of the Modern Practitioner What does it actually mean to be a /"dualist"/ in technology? In classical philosophy, dualism explored the tension between the immaterial mind and the physical body - two radically different realities forced to inhabit the same space. In modern computing, dualism is the psychological split between the *sovereign craftsman* and the *networked citizen*. As a craftsman, I obsess over control. I spent months configuring the sub-millisecond modal editing of Neovim, only to switch to the expansive, self-contained universe of GNU Emacs because both satisfy different, uncompromised ideals of my technical identity. I want local executables, deterministic builds, and clean abstractions that obey my will. As a citizen, however, I must interface with a world that operates on the exact opposite principles: closed binary blobs, opaque cloud backends, mandatory 2FA authenticators, and telemetry-laden platforms. To the dogmatic purist, this dualism looks like cowardice and hypocrisy. You preach open-source sovereignty at your desk, yet swipe a proprietary glass screen at the cash register. To the average consumer, the dualism looks like neurotic overthinking. Why spend hundreds of hours tailoring a text editor when X (where =X= is probably VS Code) works out of the box? Is the dualist a hypocrite? Or is dualism the only viable survival strategy for someone who refuses to succumb to either total apathy or total isolation? * Living in the Unresolved Tension I do not have a five-point manifesto to resolve this contradiction. I am not writing this from an off-grid cabin running on open-hardware RISC-V silicon. I am writing this on a machine entangled in global corporate supply chains, living in an economy that demands continuous digital compliance. Perhaps the goal of reflecting on hypocrisy is not to discover some miraculous escape hatch where we emerge morally immaculate. Perhaps the real value is simply refusing to let the hypocrisy become invisible. When we stop pretending that our pragmatic trade-offs are "smart hacks," when we admit that our convenience comes at the cost of our principles, we preserve a tiny ember of critical friction. Knowing that you are participating in a system you despise will not make you pure. But it might be the only thing that keeps you from mistaking your cage for a home. And yet, here is the ultimate, undeniable irony: I am publishing all of these thoughts on a public website, linked directly in my portfolio and pinned to my GitHub profile - complete with curated OpenGraph tags, semantic SEO, and structured GEO scaffolding designed specifically to be ingested and indexed by LLMs. And to put the cherry on top, I sign off every commit with a Gmail address - as you can see at the very bottom. Maybe I really am a hypocrite after all. Who knows. Apparently, that is not for me to judge. As always: ~Signed-off-by: Szymon Wilczek ~ [fn:ellul] Jacques Ellul, /The Technological Society/ (New York: Vintage Books, 1954; translated from French by John Wilkinson, 1964). [fn:postman] Neil Postman, /Technopoly: The Surrender of Culture to Technology/ (New York: Vintage Books, 1992). [fn:mumford] Lewis Mumford, /The Myth of the Machine: Technics and Human Development/ (New York: Harcourt, Brace & World, 1967). ================================================================================ ARTICLE: 8-Pixel Obsession: Crafting Typus Mono URL: https://szymon-wilczek.me/writings/the-8-pixel-obsession-typus-mono/ DATE: 2026-08-31 CATEGORY: Typography TAGS: typography, emacs, fonts, ghostty, linux DESCRIPTION: On the madness of condensing JetBrains Mono by 8%, and wrestling 10,000 Nerd Font glyphs into mathematical submission. ================================================================================ * Itch That Wouldn't Go Away Every obsessive engineering rabbit hole begins with an innocent, reasonable thought. \\ Mine was simply: *I just want my text in GNU Emacs to look identical to my terminal.* If you read my previous post on [[/writings/building-a-modular-sovereign-emacs][Building a Modular Sanctuary]], you know that I spend most of my working hours inside two environments: Ghostty and Emacs. In Ghostty, I had dialed in what I consider the sweet spot of monospace ergonomics: cell compression. By configuring ~adjust-cell-width = -1~ and ~adjust-cell-height = 1~ on JetBrains Mono at ~12pt~, the character grid tightened up into a dense, high-information layout. No wasted horizontal space, no visual drift. Just crisp and pure visuals. Then I would switch over to graphical GNU Emacs and the difference was jarring. In Emacs GUI, the exact same text felt... loose, as if the dense terminal grid had been casually stretched out. The root of the problem is architectural. Modern GPU-accelerated terminal emulators can compress character cells on the fly, shifting X-coordinates before rasterizing them through custom shaders. Graphical Emacs, by design, does not do that. It faithfully honors the TrueType metrics baked into the font tables, allocating every single pixel of advance width the type designer defined. No dynamic cell squishing, no shader tricks. If I wanted consistent, high-density typography across both environments, there was only one real solution: \\ *Bake the compression directly into the font files themselves.* * Seductive Lie of Font Hacking /"How hard could it really be?"/ Famous last words. Digital typography is a dark art where legacy specifications from the early nineties still wait to punish anyone who touches an OpenType table unprepared. The first prototype looked terrible. The glyphs were indeed 8% narrower, but they appeared frail and skeletal. GPU terminal renderers naturally produce slightly more visual "mass" through custom gamma curves and subpixel blending. Emacs GUI, relying on standard Linux FreeType rasterization, rendered the condensed outlines noticeably washed out. To compensate, I had to completely remap the weight hierarchy. In Typus Mono, *Regular* is actually generated from upstream *SemiBold*, *SemiBold* is forged from *Bold*, and *Bold* is extracted from *ExtraBold*. Only then did the characters carry the right physical weight on screen. While restructuring the tables, I also addressed programming ligatures. I understand why some developers enjoy watching =->= turn into an arrow or =!== collapse into a single glyph. Personally, I despise them. Code is code; a dash should remain a dash and an equals sign an equals sign. The build script stripped every ~calt~, ~liga~, and ~dlig~ lookup table from the OpenType ~GSUB~ registry. [[/assets/typus-fonts/preview.png]] The result above speaks for itself: clean numerals, distinct operators, zero ligatures, and a tight 530-pixel horizontal footprint for 64 columns of text. At that point, it felt like the hard part was done. And then I looked at the icons. * Nerd Fonts... If standard Latin typography is a disciplined grid, Nerd Fonts is an unconstrained carnival. It packs over 10,000 disparate glyphs - distribution logos, Git graph nodes, file tree icons, terminal arrows, and legacy powerline dividers - into the Private Use Area of Unicode. Applying a naive 8% horizontal scale across the entire patch set broke down immediately: 1. *Squished Logo Syndrome*: Wide logos compressed into narrow silhouettes, while already slender icons turned into unreadable vertical lines. 2. *Levitating Glyphs*: Standalone icons designed for full cell heights floated awkwardly 200 units above the text baseline, hovering near the ceiling while adjacent text sat on the floor. 3. *Fedora Hole Massacre*: TrueType outlines depend on Non-Zero Winding rules. If an outer contour runs clockwise, any inner cutout (like the transparent center of the Fedora logo or the loops of a =%= sign) must run counter-clockwise. An early winding algorithm I tested incorrectly treated every secondary contour as a cutout. The bottom loop of my percent signs and the middle of the Fedora icon collapsed into solid, pitch-black blobs. [[/assets/typus-fonts/grid_specimen.png]] Resolving this required formalizing a dedicated layout pipeline (*Approach A*): - *Baseline Anchoring*: Every standalone icon is mathematically anchored to the font baseline (=Y = 0=). - *The Cap-Height Ceiling*: Tall icons are proportionally clamped to a maximum height of =700 UPM= (matching the ascender line of capital letters). - *1:1 Proportional Geometry*: No artificial horizontal distortion. When an icon scales down in height, its width scales by the exact same ratio. - *Untouched Powerline Dividers*: Full-height powerline glyphs and box-drawing elements remain unscaled. * Monospace Sanctuary Polishing Typus Mono took dozens of automated build iterations, side-by-side rendering tests, FreeType hinting adjustments, and tuning the OpenType ~usWidthClass~ metadata so fontconfig would correctly group the family rather than splintering it. Was it worth spending nights writing a custom compiler for a monospace font? *Absolutely.* I'd gladly do that again and recommend it to anyone who - just like me - likes everything done *their own* way. There is a quiet satisfaction in opening an editor buffer where every character cell behaves predictably down to the pixel, where statusline icons align perfectly with the text, and where your terminal and your editor share the exact same visual weight. And I'm chasing that Zen zone every single day. If you share the same stubborn typographic preferences, the entire family (with 90%, 92%, and 95% width variants across 12 weights) is open source: [[https://github.com/szymonwilczek/typus-fonts][szymonwilczek/typus-fonts]]. As always: ~Signed-off-by: Szymon Wilczek ~ ================================================================================ ARTICLE: The Sins of Low-Level Bootstrapping URL: https://szymon-wilczek.me/writings/code-silence-and-boot-sectors/ DATE: 2026-08-30 CATEGORY: YouTube TAGS: assembly, linux, youtube DESCRIPTION: On starting a no-talking programming channel and building an 8-part Linux bootloader in complete silence. ================================================================================ * The Algorithmic Hysteria of Tech YouTube Like every proper article, this will also begin with my thesis: \\ *Technical YouTube has become genuinely exhausting to watch.* Almost everything pushed by the algorithm today feels either centered on artificial intelligence or noticeably written by it. It’s hard to shake the feeling that most content has devolved into recycled documentation and synthetic scripts, packaged into high-energy videos designed to chase engagement metrics rather than teach actual engineering. Take a look at most technical channels. They mostly just summarize /what is new in AI this week/. One creator will actually DO some research, the rest are just copycats, uploading and reuploading the same stuff over and over again, so I can see the same video multiple times - just from different accounts. I just couldn't see myself in that ecosystem. For me, programming has never been about frantic pacing or chasing whatever framework or LLM wrapper came out this morning. \\ Non-technical people believe the AI will come to replace us - /the programmers/, the ancient coders that write the code by their hand, watching us like people watch small dogs, thinking: /Awww... it's cute... Look! He's doing the trick!/ \\ The trick - my fellow readers - is being quiet when that person is speaking. Real software development - at least the kind that keeps me at the keyboard - is quiet, stubborn, and deeply, intimately personal. It's about sitting alone with a problem until the abstractions melt away and you're dealing directly with it yourself. \\ It is DEEP, and if anyone disagrees about that - well, we've got ourselves a viber! #+begin_quote This is essentially what a program was, a love letter from the programmer to the hardware, full of the intimate details known only to partners in an affair. ~ Michael Marcotty #+end_quote That quote captures why I fell in love with computing in the first place. Ellen Ullman put it equally well in [[https://www.themarginalian.org/2012/07/26/close-to-the-machine-ellen-ullman/][Close to the Machine]] - there’s something almost intimate about stripping away the noise and confronting the raw mechanics of the magical hardware. So when I decided to start sharing my work on YouTube, I chose a ~No Talking~ format. \\ No commentary, no camera pointed at my face, no sponsor plugs. Just a dark buffer, audio, and the code being written *by hand* (/aaand... scene!/). * The First Project: Building MiniBoot For my first project, I knew I didn't want to build something that I've already seen before (that would be kind of hypocritical, right?). I wanted something that forced me to touch bare metal and to show that I understand how a computer actually wakes up from dead silicon. That curiosity turned into MiniBoot: a two-stage x86 bootloader written in assembly, capable of loading a 64-bit Linux kernel into BusyBox userspace. The project grew into an eight-part series, where each episode tackled a specific hurdle of the PC architecture: 1. [[https://www.youtube.com/watch?v=BS-IOpHpvyU][Stage 1 (MBR)]]: Setting up segments, writing BIOS TTY print routines, and squeezing the boot signature into the unforgiving 512-byte limit. 2. [[https://youtu.be/7TT6he72WCI][Stage 2 Loader and BIOS Disk I/O]]: Loading subsequent sectors from the drive and executing a far jump to hand over control. 3. [[https://youtu.be/3C1JJJrkPZs][Text-Mode UI Engine]]: Querying the RTC timer to seed a pseudo-random generator, cycling status slogans directly in VGA text memory. 4. [[https://youtu.be/NmRHWWEs_1A][A20 Gate]]: Wrestling with ancient PC quirks to enable the A20 line and bypass the 1 MB real-mode memory wrap-around. 5. [[https://youtu.be/tTp4Xd5x2JY][Unreal Mode]]: Briefly entering Protected Mode to stretch the segment limits to 4 GB. 6. [[https://youtu.be/3PfisHAM4is][32-Bit EDD Disk Driver]]: Using EDD packets to stream multi-megabyte payloads off disk without being held back by CHS limits. 7. [[https://youtu.be/Gcfy00WT9Ho][Decoding the bzImage]]: Parsing kernel setup headers, validating the =HdrS= signature, configuring heap pointers, and passing command-line parameters. 8. [[https://youtu.be/pvLNE2GlRuk][The Leap to Linux]]: Relocating the 32-bit payload, positioning the initramfs, clearing the IDTR, and jumping straight into the kernel entry point. If you - just like me - like everything in one place, then you're in good hands. I've also made [[https://www.youtube.com/playlist?list=PLVuQCPKH0CEc][a playlist]]. Or maybe do you want *really* everything in one place? Sure, no problem, if also made a [[https://youtu.be/UAl9zcX3CGA][complete video]]. * Real-World Friction Recording in complete silence sounds peaceful in theory. In practice, it was a nightmare. \\ *Disclaimer:* writing the code in complete silence is delightful, but recording THE complete silence is what I'm talking about. When you don't have a voiceover or background music to hide behind, you quickly realize just how loud the world is. I never really thought about it. Recording in the summer meant battling crickets outside my window. I lost count of how many hours I spent staring at audio spectrograms, hunting down and notching out the exact high frequencies where crickets were chirping - all while trying not to ruin the natural, tactile sound of the keyboard switches. \\ To prove that I'm not an anti-AI guy (which I'm not), I actually gave it a shot. \\ The Antigravity CLI completely blew me away, practically forcing me to stand up and applaud. Really. It was that GOOD. Of course the prompt to clear something from an audio track WAS technologically deep, not just this: #+begin_quote Clear the crickets mister. Thanks! #+end_quote I have not tried that. I do not know what kind of output it will give me. I first jumped into Audacity, ran a quick spectrogram analysis, and learned that these f*ckin crickets were chatting with each other in a high-frequency range (9kHz - 11kHz), which meant I could obliterate them surgically - with the AI. Since AI did a fantastic job, I gladly used it to clear the same crickets from the rest of the videos. See? Tool. Tool to kill the crickets. And a good one! If you ever have a cricket problem like me, the same *tool* happily spat out an *allegedly* reusable command to fix every video. (That's satire, for anyone who couldn't tell): #+begin_src sh ffmpeg -i video1.mp4 \ -af "highpass=f=75:p=2,equalizer=f=8277.1:t=q:w=35:g=-30,equalizer=f=8436. 0:t=q:w=35:g=-30,equalizer=f=8518.8:t=q:w=35:g=-30,equalizer=f=8616.2:t=q:w=35:g=- 30,equalizer=f=8720.2:t=q:w=35:g=-30,equalizer=f=8778.1:t=q:w=35:g=-30, equalizer=f=8847.7:t=q:w=35:g=-30,equalizer=f=8871.8:t=q:w=35:g=-30, equalizer=f=9073.2:t=q:w=35:g=-30,equalizer=f=9116.5:t=q:w=35:g=-30, equalizer=f=9137.0:t=q:w=35:g=-30,equalizer=f=9195.6:t=q:w=35:g=-30, equalizer=f=9219.7:t=q:w=35:g=-30,equalizer=f=9255.6:t=q:w=35:g=-30, equalizer=f=9282.7:t=q:w=35:g=-30,equalizer=f=9325.2:t=q:w=35:g=-30, equalizer=f=9345.7:t=q:w=35:g=-30,equalizer=f=9483.4:t=q:w=35:g=-30, equalizer=f=9525.2:t=q:w=35:g=-30,equalizer=f=9619.6:t=q:w=35:g=-30, equalizer=f=9642.3:t=q:w=35:g=-30,equalizer=f=9683.4:t=q:w=35:g=-30, equalizer=f=9724.4:t=q:w=35:g=-30,equalizer=f=9769.0:t=q:w=35:g=-30, equalizer=f=9880.4:t=q:w=35:g=-30,equalizer=f=9895.8:t=q:w=35:g=-30, equalizer=f=9912.6:t=q:w=35:g=-30,equalizer=f=10031.3:t=q:w=35:g=-30, equalizer=f=10052.5:t=q:w=35:g=-30,equalizer=f=10073.7:t=q:w=35:g=-30, equalizer=f=10114.8:t=q:w=35:g=-30,equalizer=f=10130.9:t=q:w=35:g=-30, equalizer=f=10279.5:t=q:w=35:g=-30,equalizer=f=10302.3:t=q:w=35:g=-30, equalizer=f=10392.3:t=q:w=35:g=-30,equalizer=f=10407.7:t=q:w=35:g=-30, equalizer=f=10708.7:t=q:w=35:g=-30,equalizer=f=10741.0:t=q:w=35:g=-30, equalizer=f=10899.9:t=q:w=35:g=-30,loudnorm=I=-16:TP=-1.5:LRA=11:linear=true, aresample=48000" \ -c:v copy -c:a aac -b:a 320k video1_cleaned.mp4 #+end_src It gave me exactly this command with a description ~To run it again on other videos or to automate the process in FFmpeg, run this~. I'm sure that the equalizer settings will match every video's audio. Thanks. ** Not only the crickets Then there were the software bugs, as always. Building an initramfs on a modern Fedora host, for instance, turned out to have some nasty traps. If you let BusyBox run its default =--install= or accidentally generate absolute symlinks, those symlinks point back to your host's root directory, not the target environment. You get that magical moment where the kernel boots, mounts the filesystem, and immediately dies with =sh: ls: not found= because every single binary points into the void. Or terminal sessions. The first time you boot cleanly into =/bin/sh=, you're greeted with: #+begin_src sh sh: can't access tty; job control turned off #+end_src Fixing that required wrestling with process session management, pairing =setsid= with BusyBox’s =cttyhack= just to give =/bin/sh= a proper controlling terminal on =/dev/tty0=. * What Comes Next Some of you may ask if I'll ever do spoken architectural deep-dives or lecture-style videos on OS internals. Not planning it for now. Maybe eventually - there's plenty of fascinating theory I'd love to talk through. But for now, I really enjoy the honesty of silent implementation. There's no persona to maintain and no algorithm to pander to. Thank you for reading, and watch out for the crickets if you ever think about recording silent coding videos. The entire 8-part series and the complete full-course video are up on YouTube. As always: ~Signed-off-by: Szymon Wilczek ~ ================================================================================ ARTICLE: Building a Modular Sanctuary: An Engineer's Dualism URL: https://szymon-wilczek.me/writings/building-a-modular-sovereign-emacs/ DATE: 2026-08-27 CATEGORY: Emacs TAGS: emacs, neovim DESCRIPTION: On the eternal ping-pong between Neovim and Emacs and building a modular setup that stops pretending to be something it is not. ================================================================================ * The Confession of an Incurable Addict Let us get the uncomfortable truth out of the way first: I am, and almost certainly will remain until the heat death of the universe, a creature of the Vi lineage. Years of modal editing do not just change how you write code; they permanently rewire your nervous system. Hitting =Escape= is no longer a conscious command, but a spinal reflex. Traversing text with =hjkl=, swapping words with =ciw=, or deleting whole function bodies with =da{= are burned so deep into my muscle memory that putting me in front of a standard, modeless editor is a recipe for instant humiliation. And then, of course, there is Neovim. Neovim is an engineering masterpiece. It boots in under 15 milliseconds, runs an asynchronous C core that treats latency as a personal insult, and executes Lua with near-native efficiency. It follows the classic Unix philosophy to the letter: it edits text, it does it blisteringly fast, and it gets out of your way. So why on earth did I spend hundreds of hours configuring GNU Emacs? For a long time, I lived in a state of perpetual identity crisis. I bounced between both editors like an indecisive maniac. Ping...and pong...and ping...and pong. On Monday, I was a devout Unix minimalist: /"Look at this 12ms startup! Look at this memory footprint! Lua is the pinnacle of human reason!"/ On Tuesday, I would fire up Emacs because no Neovim plugin in existence comes within a lightyear of Org-mode, only to spend Wednesday cursing at single-threaded ELisp as a heavy JSON payload from an LSP server caused my cursor to freeze while the Garbage Collector took a leisurely stroll. Eventually, the penny dropped: *stop trying to turn Emacs into a faster Neovim*. You cannot out-C an editor written in C using an interpreter conceived during the Carter administration. If GNU Emacs ever reaches true sub-millisecond input parity with Neovim, I will pack my bags and move into Emacs permanently without blinking. But as of today, that is simply not reality. Single-threaded execution and legacy runtime baggage have hard, physical limits. When I need to rip through a Go codebase, debug C systems code, or patch a remote server over SSH, Neovim is my weapon of choice. Emacs, however, became something entirely different: my personal computing sanctuary. An unmatched environment for thinking, academic planning, technical writing, and LaTeX authoring. To make it livable without tearing my hair out, I had to strip away the pre-packaged things, stop caring about what Reddit thought, and rebuild it from raw metal. * The Distro Trap: Why Doom and Spacemacs Aren't the Answer Every Vim user who wanders into the Emacs territory makes the exact same rookie mistake: *„I'll just install Doom Emacs or Spacemacs! It has Evil mode, leader keys, and everything works out of the box!”* I did it too. For the first week, you feel like a wizard. And then, inevitably, you want to change one tiny behavior that the distribution maintainers did not anticipate. Suddenly you are not debugging Emacs. You are not learning Emacs Lisp. You are drowning in tens of thousands of lines of terrifying macro magic, nested hooks, and obscure domain-specific abstractions written by someone who had a completely different philosophy of computing than you. Maybe that is designed and suitable for someone, but that someone is not /me/. The hard engineering reality is simple: *the only Emacs configuration you will ever truly understand is the one you write yourself.* I threw out the frameworks and established a strict, modular layout. Every functional area gets its own sandbox split cleanly into two files: - =-mod.el= - packages, logic, and configuration. - =-keys.el= - exclusively keybindings wired through =general.el= and the Leader key. That is something I've done, and want to share it - maybe it will suitable for *you* as well? #+begin_src text ~/.config/emacs/ ├── early-init.el # Frame allocation, GC tuning, anti-flashbang ├── init.el # Module loader ├── .bg-cache # Cached frame background HEX color ├── .theme-cache # Active theme persistence └── modules/ ├── core.el # Runtime sanitation, I/O hygiene, performance ├── evil/ # Vim thinkerings ├── completion/ # Vertico, Orderless, Consult, Marginalia, Company ├── lsp/ # Eglot, Tree-sitter, format engine ├── git/ # Magit, Forge, Lazygit ports ├── ui/ # Themes, fonts ├── projectile/ # Workspace isolation ├── tabs/ # My bufferline takes ├── terminal/ # Ghostel (libghostty engine) ├── academic/ # Org-mode, LaTeX, citations and academic related things └── writing/ # Olivetti, Zen mode #+end_src * Wrestling the Engine: Milliseconds, Flashbangs, and Garbage Tuning Emacs feels a lot like wrenching on a 1990s Japanese sports car (believe me, I have one - and it's called /Mitsubishi Galant/): the mechanical soul is brilliant, but the factory defaults were chosen when floppy disks were considered high-capacity storage. ** Retinal Surgery Prevention If you use a dark theme on a tiling Wayland compositor (like I'm using Sway), you are painfully familiar with the Emacs flashbang: you spawn a client frame in a pitch-black room at 2 AM, and before Emacs even begins evaluating your theme file, the Wayland surface blinds you with a pure white rectangle. The fix is delightfully crude and 100% effective. In =early-init.el= (which executes long before any graphical window is drawn), you just have to read the background color from a tiny cache file and shove it directly into =default-frame-alist=: #+begin_src elisp ;; early-init.el -*- lexical-binding: t; -*- (defvar my-bg-cache-file (expand-file-name ".bg-cache" user-emacs-directory)) (let ((bg-color (if (file-exists-p my-bg-cache-file) (with-temp-buffer (insert-file-contents my-bg-cache-file) (string-trim (buffer-string))) "#121212"))) (when (and bg-color (string-prefix-p "#" bg-color)) (push `(background-color . ,bg-color) default-frame-alist))) #+end_src Whenever I switch themes, a hook writes the new HEX color to =.bg-cache=. On the next startup, the display server allocates the window with the correct dark background from frame zero. No flashing, no retinal burn. ** The 800 KB Garbage Joke By default, Emacs sets its garbage collection threshold to 800 kilobytes. In 2026, where my own workstation has 128 gigabytes of DDR5 RAM, Emacs defaults to a memory ceiling designed for a toaster. The result? The GC runs dozens of times a second just while scrolling a text file. #+begin_src elisp ;; Inhibit GC completely during boot (setq gc-cons-threshold most-positive-fixnum gc-cons-percentage 0.6) ;; Set a SANE working ceiling (add-hook 'emacs-startup-hook (lambda () (setq gc-cons-threshold (* 128 1024 1024) gc-cons-percentage 0.1))) ;; Only sweep when I'm staring blankly at the screen for 15 seconds (run-with-idle-timer 15.0 t #'garbage-collect) #+end_src ** Git Repository Pollution: Banishing .# Lockfiles Another vintage Emacs quirk: generating lockfiles (=.#file.c=) and tilde backups (=file.c~=) directly in your project root. If you work with modern file watchers, these ghost files trigger infinite rebuild loops and pollute your Git status. Kill them with fire: #+begin_src elisp (setq create-lockfiles nil make-backup-files nil auto-save-default nil auto-save-list-file-prefix nil) ;; If Emacs insists on auto-saving, isolate it to a dedicated sandbox (let ((auto-save-dir (expand-file-name "auto-save/" user-emacs-directory))) (make-directory auto-save-dir t) (setq auto-save-file-name-transforms `((".*" ,auto-save-dir t)))) #+end_src ** JSON Acceleration for LSP Adding a single environment variable in =early-init.el= instructs Emacs to parse JSON structures directly into property lists (/plists/) rather than hash tables: #+begin_src elisp (setenv "LSP_USE_PLISTS" "true") #+end_src Combined with native =libjansson= support in C, this delivers an instant **3x throughput boost** when deserializing language server messages inside Eglot. * The Modeline Trauma Many third-party statusline packages (looking at you, =doom-modeline=) suffer from a critical design flaw: they re-evaluate Git status, branch heads, LSP diagnostics, and buffer metrics **on every single keystroke**. A commit message from my dotfiles repository during the early days of this setup summarizes the experience accurately: #+begin_quote /„God it was laggy. God damn.”/ #+end_quote I threw the packages out and wrote =modeline.el= from scratch, inspired by Neovim's Lualine. The secret sauce is simple: *strict time throttling* on expensive operations. #+begin_src elisp ;;; modeline.el -*- lexical-binding: t; -*- (require 'timeout) (defvar-local my/modeline--cached-diagnostics "") (defun my/modeline-update-diagnostics () (setq my/modeline--cached-diagnostics (if (bound-and-true-p flymake-mode) (let* ((known-diags (flymake-diagnostics)) (errs 0) (warns 0)) (dolist (d known-diags) (pcase (flymake-diagnostic-type d) (:error (cl-incf errs)) (:warning (cl-incf warns)))) (concat " [" (propertize (format "%d" errs) 'face 'error) " " (propertize (format "%d" warns) 'face 'warning) "] ")) ""))) ;; Never query diagnostics more frequently than once every 250ms! (timeout-throttle #'my/modeline-update-diagnostics 0.25) #+end_src Inactive windows fold down automatically to a dim, understated filename. No spinners, no animated icons eating CPU cycles, and butter-smooth typing. * The Dashboard Cemetery For a brief period, I succumbed to the temptation of pretty splash screens. I configured the =dashboard= package with an ASCII banner, recent file lists, and quick-open bookmarks. It looked fantastic for Reddit screenshots on =r/unixporn=. (I still use it in Neovim.) In practice, it was infuriating. Whenever you spawn a quick frame via =emacsclient= to edit a file, the dashboard insists on hijacking the buffer. In commit =279fd28=, I nuked it from orbit with the commit message: #+begin_quote /„It was really a pain in the ass to maintain ANY new frame when dashboard kept popping up. Sometimes it should be okay to use a shotgun for a fly.”/ #+end_quote Emacs does not need splash screens. A clean =*scratch*= buffer get you to work in zero milliseconds. * Magit: The Reason We Forgive Emacs Everything If there is one piece of software on Earth that justifies having GNU Emacs installed on your system, it is **Magit**. No CLI alias, no graphical client, and no Neovim wrapper has ever come close to the precision of staging individual lines, crafting cherry-picks, and navigating interactive rebases. DO NOT get me wrong: I'm as well using Lazygit and when I'm not using Magit OR Lazygit, I still use CLI commands. Sometimes is just okay to accept patch line-by-line or in chunks. I like it, so I will keep doing that. Since I also appreciate the speed of /Lazygit/, I ported my favorite operations directly into ELisp: ** Enforcing GPG Signing and Signoffs I refuse to manually check signing boxes in transient menus. By inspecting Magit's internal transient structures, I inject signing flags directly into the commit prefix. Every single commit is cryptographically signed with my hardware key and stamped with a \\ =Signed-off-by= trailer automatically. ** Single-Key Co-Author Attribution Pairing with colleagues or AI agents (not you Claude, you will continue to add yourself as Co-author anyway) usually means typing out tedious =Co-authored-by: Name = trailers by hand. I bound =my/magit-add-co-author= to =W= in Magit log buffers: #+begin_src elisp (defun my/magit-add-co-author (author) "Add Co-authored-by trailer to commit at point or HEAD." (interactive (let* ((cmd "(git log --format='%aN <%aE>'; git log --all --format='%(trailers:key=Co-authored-by,valueonly=true)') | sed '/^$/d' | sort -u") (authors (split-string (shell-command-to-string cmd) "\n" t)) (chosen (completing-read "Pick Co-author: " authors nil nil))) (list chosen))) (let* ((commit (or (magit-commit-at-point) (magit-rev-parse "HEAD"))) (head (magit-rev-parse "HEAD")) (branch (magit-get-current-branch))) (if (magit-rev-equal commit head) (magit-call-git "commit" "--amend" "--no-edit" (format "--trailer=Co-authored-by: %s" author)) (if (and branch (magit-commit-p commit)) (progn (magit-call-git "checkout" commit) (magit-call-git "commit" "--amend" "--no-edit" (format "--trailer=Co-authored-by: %s" author)) (magit-call-git "rebase" "--onto" "HEAD" commit branch)) (user-error "Cannot rebase without an active branch"))) (magit-refresh))) #+end_src The function scrapes the repository's commit history for all past contributors, feeds them into Vertico fuzzy search, and amends the trailer directly into the commit. One keypress, select the name, hit Enter. Done. Cool? * Deterministic Formatting vs Plugin Circus Have you ever installed a 500-line formatting package only to watch your cursor jump to line 1 and your viewport glitch violently every time you save a buffer? Instead of bringing in heavy external dependencies, I wrote =my/format-buffer-with-command=. \\ It executes CLI formatters (Prettier, clang-format, gofmt) directly through =call-process-region=: 1. Caches exact =point= and =window-start= positions. 2. Streams buffer contents through the external binary. 3. On exit code 0, replaces buffer contents and restores view coordinates instantly. 4. On parse error, rolls back changes atomically and logs the diagnostic. #+begin_src elisp (defun my/format-buffer-with-command (cmd-args) (let* ((cmd (car cmd-args)) (args (mapcar (lambda (arg) (if (string-match-p "%f" arg) (replace-regexp-in-string "%f" (or (buffer-file-name) "temp.md") arg) arg)) (cdr cmd-args)))) (when (executable-find cmd) (let ((orig-point (point)) (orig-window-start (window-start)) (orig-content (buffer-string)) (err-file (make-temp-file "formatter-err-"))) (unwind-protect (let ((exit-code (apply #'call-process-region (point-min) (point-max) cmd t (list t err-file) nil args))) (if (= exit-code 0) (progn (goto-char (min orig-point (point-max))) (set-window-start nil orig-window-start) (message "Formatted buffer with %s" cmd) t) (erase-buffer) (insert orig-content) (goto-char orig-point) (message "Formatter returned non-zero exit status") nil)) (when (file-exists-p err-file) (delete-file err-file))))))) #+end_src Feel free to use it if you also stumbled upon the same problems as I did. * The Sanctuary: Where Emacs Actually Wins Once you stop treating Emacs as an underperforming IDE for heavy systems programming and treat it as a personal computing substrate, it becomes completely irreplaceable. ** 1. Academic Sanity: plan-polsl.el I study computer science at the Silesian University of Technology. Navigating university web portals in 2026 just to find out which lab room I need to run to is an exercise in psychological endurance. MAYBE if this website worked, was intuitive or something, then it would be okay. \\ In the meantime, I DARE *YOU* to try to navigate on [[https://plan.polsl.pl][it]]. I wrote [[https://github.com/szymonwilczek/plan-polsl.el][plan-polsl.el]], which hits the university schedule API directly, normalizes course data, and generates a structured =plan-polsl.org= file. Plugged into =org-agenda=, it renders my entire week on an 8:00-20:00 grid with Polish day names and a live time marker. ** 2. Org-Mode and Real-Time Vector LaTeX Markdown is fine for README files. For academic papers and technical prose, Org-mode is on another planet. Nothing more to add here from me. ** 3. Distraction-Free Zen Writing When I write essays - or articles, such as this one - I switch to Zen mode based on =olivetti=: text is constrained to 74 columns, line numbers vanish, and soft wrapping engages. * The Dualist Manifesto Software engineering culture loves religious wars. You are expected to pick a camp, buy the t-shirt, and vehemently argue on forums why your editor is objectively superior to everything else. People will tell you that you *have* to pick a side. I don't really believe that. I think those two editors (which their communities are at war since the beginning of time) CAN and SHOULD coexist, as they serve - in my opinion - different purpose. Therefore, I choose to be a dualist. When I need to write a Go service, patch configuration files over SSH, or perform rapid codebase surgery: **I open Neovim.** Because it is blazingly fast, predictable, and does exactly what I ask without arguing. When I sit down to write an essay, organize university schedules, or author LaTeX documents: **I open GNU Emacs.** Because as an environment for thinking, structuring ideas, and manipulating text, it has no equal. The engineering challenge was never about finding one magic tool that does everything poorly. It is about understanding the strengths and trade-offs of your tools, bending them to your will, and staying in complete sovereign control of your computing environment. Remember - tools are meant to serve you, not the opposite way. If you ever catch yourself as a slave of your tools, you probably have to change a thing or two in your life. The configuration backing this setup is public in my dotfiles repository. Pick what you like, discard what you do not, and build your own sanctuary. Tinkering is a funny hobby. As always: ~Signed-off-by: Szymon Wilczek ~