KI-Produktivität
Ein Beitrag mit einem Datum in der Zukunft existiert noch nicht
Eine schöne Veröffentlichungs-Pipeline ohne etwas, das zu sagen sich lohnt, ist ein sehr teurer Weg, ignoriert zu werden.
Wir veröffentlichen dreimal pro Woche auf zwei Seiten, und wir betreiben kein Content-Management-System. Es gibt kein Admin-Login, keine Datenbank und kein Plugin, das auf einen Patch wartet. Das ist, was wir stattdessen gebaut haben, und die Hälfte davon passiert, bevor jemand eine Tastatur anfasst.
Es beginnt nicht mit dem Tippen
Fast jeder Artikel über das Veröffentlichen beginnt an der Tastatur, und genau deshalb ist fast jeder Artikel über das Veröffentlichen nutzlos. Die Tastatur ist der letzte Teil.
Hier beginnt es laut. Etwas durchdenken, das während der Woche passiert ist, diktiert statt getippt, meist nicht am Schreibtisch, oft im Liegen, häufig zu einer Stunde, die niemand als Arbeitszeit bezeichnen würde. Keine Struktur, keine Überschriften, kein Versuch, klug zu klingen. Nur ein ganzer Gedanke, einmal ausgesprochen, einschließlich der Teile, die sich als falsch herausstellen.
Dann kommt es als geschriebener Text zurück, und die eigentliche Arbeit beginnt, nämlich ihn zu lesen. Wo ist das Argument dünn. Was wird behauptet, das nicht belegt werden kann. Welcher Satz tut nichts. Welcher Absatz ist wahr, aber der Satz einer anderen Person und nicht meiner.
Dann geht es noch einmal von vorn. Und noch einmal. Ein Beitrag dieser Länge wird drei- oder viermal richtig gelesen, und die Korrekturen betreffen selten die Grammatik. Sie betreffen eine falsche Prämisse, einen fehlenden Punkt, eine Pointe, die es schon einmal gab.
Erst wenn das Material in der menschlichen Ebene fertig ist, gibt es überhaupt etwas zu veröffentlichen. Alles unterhalb dieser Linie ist Installation. Sie ist wichtig, sie ist ehrlich gute Technik, und sie bleibt Installation, und diese Reihenfolge ist keine Dekoration.
Die Maschine macht Entwürfe schnell. Zu entscheiden, ob ein Entwurf wahr ist, lässt sich nicht beschleunigen, und das ist die ganze Arbeit.
Und dann muss es an einem Mittwoch erscheinen
Geschrieben wird in einem Zug. Die Beiträge müssen montags, mittwochs und freitags erscheinen, ob nun jemand an diesen Tagen am Rechner sitzt oder nicht.
Das ist ein gelöstes Problem. Jedes Content-Management-System der Welt hat ein Feld für das Veröffentlichungsdatum. Die Frage war, ob wir ein Content-Management-System haben wollten, nur um dieses Feld zu bekommen.
Wir betreiben kein CMS. Wir haben den Blog selbst gebaut.
Bei diesem Punkt will ich deutlich sein, denn es ist das gesamte Argument dieses Unternehmens, angewendet auf die eigene Website.
Hier gibt es kein WordPress. Keinen Admin-Bereich, keine Benutzerkonten, keine Datenbank, kein Theme, keine Plugins. Der Blog besteht aus wenigen Dateien, die wir geschrieben haben und die ein Mensch an einem Nachmittag lesen kann. Eine Datei enthält die Beiträge. Ein Skript macht daraus Seiten. Ein Skript prüft das Ergebnis und verweigert die Veröffentlichung, wenn ihm etwas nicht passt.
Es ist prüfbar. Jede Regel darüber, was auf dieser Seite erscheint, steht in Code, den wir geschrieben haben, in Dateien, die wir öffnen können. Es gibt nichts, dessen Verhalten wir erraten müssen, keine Einstellung vier Menüs tief, die jemand letztes Jahr geändert hat, kein Plugin, dessen Autor die Wartung 2019 eingestellt hat.
Es gibt keine Notfall-Updates. Das wird am meisten unterschätzt. Ein Content-System zu betreiben bedeutet eine dauerhafte Pflicht, es dringend zu patchen, nach dem Zeitplan anderer, weil eine Schwachstelle veröffentlicht wurde und nun öffentlich bekannt ist, dass Ihre Seite sie hat. Diese Pflicht endet nie, und sie kommt nie zu einer passenden Stunde. Wir haben sie nicht, weil wir die Software nicht betreiben, die sie erzeugt.
Wartung heißt lesen, nicht löschen. Hier aktualisiert sich nichts über Nacht von selbst und zerlegt das Layout.
Ein System, das man lesen kann, ist billiger als ein System, dem man vertrauen muss.
Und die Infrastruktur darunter
Die gebaute Seite besteht aus statischen Dateien, ausgeliefert über CloudFront. Es gibt keinen Anwendungsserver, der Anfragen beantwortet, also gibt es nichts, wo man sich einloggen könnte, und nichts, das eine Sitzung hält. Der Speicher dahinter ist nicht öffentlich beschreibbar.
Die Dinge, über die die Website eines kleinen Unternehmens üblicherweise übernommen wird, ein gestohlenes Admin-Passwort, ein ungepatchtes Plugin, ein eingeschleustes Skript in einem Theme, werden hier nicht bloß abgewehrt. Sie sind nicht vorhanden, um angegriffen zu werden.
Ich werde nicht den Satz schreiben, der sagt, dass uns das unangreifbar macht, denn diesen Satz schreibt immer jemand, der kurz davor ist, angegriffen zu werden. Wahr ist etwas Engeres und Besseres: die Oberfläche ist klein, wir wissen genau, was darauf liegt, und wir können alles davon lesen.
Und der Ort ist eine Entscheidung, keine Voreinstellung. Wo das läuft und wo alles liegt, was wir speichern, ist bewusst gewählt, in Europa, denn für die anderen Dinge, die dieses Unternehmen baut, ist das keine Vorliebe, sondern Gesetz.
Das ganze Feature, in einer einzigen Funktion
Ein Beitrag hat ein Datum. Ein Beitrag existiert, wenn sein Datum nicht in der Zukunft liegt. Das ist alles.
export function publishedPosts(today = todayInVienna()) {
return blogPosts.filter((post) => post.date <= today);
}
Daten werden als 2026-10-12 geschrieben, als Zeichenketten, und mit einem Kleiner-als-Zeichen verglichen. Das sieht faul aus und ist Absicht. In diesem Format, und nur in diesem Format, sind alphabetische und chronologische Reihenfolge dieselbe Reihenfolge, also ist der Vergleich, den ein Computer ohnehin gratis macht, bereits der Vergleich, den wir wollen. Keine Datumsbibliothek, nichts zu parsen, nichts, das sich mit sich selbst darüber streiten kann, welcher Tag heute ist.
Wien ist nicht UTC, und genau daran scheitert es
Der Build läuft auf einer Maschine in einem Rechenzentrum, und diese Maschine denkt in UTC. Wir sind in Wien, je nach Jahreszeit ein oder zwei Stunden voraus.
In den ersten ein bis zwei Stunden jedes Tages würde ein Server auf die Frage, welcher Tag heute ist, also gestern antworten. Ein auf Montag datierter Beitrag wäre am Montag um ein Uhr früh in Wien noch unsichtbar, und das ist genau die Art von Fehler, die aussieht, als sei alles in Ordnung.
export function todayInVienna() {
return new Intl.DateTimeFormat('en-CA', {
timeZone: 'Europe/Vienna',
year: 'numeric', month: '2-digit', day: '2-digit',
}).format(new Date());
}
Das en-CA ist kein Scherz und hat nichts mit Kanada zu tun. Dieses Gebietsschema formatiert Daten als Jahr, Monat, Tag, mit Bindestrichen, also genau in der Form, die der Vergleich oben braucht. Es steckt bereits im Browser und in Node, es weiß, wann Österreich die Uhren umstellt, und es kostet nichts zu laden.
Eine Funktion, von fünf Stellen gelesen
Das ist der Teil, den ich behalten würde, selbst wenn man alles andere hier wegwirft.
Fünf Stellen auf diesen Seiten haben eine Meinung dazu, welche Beiträge existieren. Die Blog-Übersicht. Die Artikelseite, die eine ordentliche 404 liefern muss statt einer Seite für einen Beitrag, der noch nicht erschienen ist. Das Prerendering, das pro Seite eine HTML-Datei schreibt. Die Sitemap, die Suchmaschinen sagt, wohin sie schauen sollen. Und der Endpunkt hinter dem kleinen Herz, der eine Stimme nur für einen veröffentlichten Beitrag annimmt.
Alle fünf rufen dieselbe Funktion auf. Nicht fünf ähnliche Prüfungen, die in Übereinstimmung gehalten werden müssen. Eine, fünfmal importiert.
Ein Beitrag, der in der Übersicht fehlt und in der Sitemap steht, ist keine kleine Unstimmigkeit. Es ist eine Seite, die Google abrufen wird und für die es eine 404 bekommt, auf einer Seite, deren ganzes Argument lautet, dass sie sorgfältig gebaut wurde.
Fünf Kopien derselben Regel sind fünf Gelegenheiten, vier davon zu reparieren.
Am Tag selbst muss etwas passieren
Hier ist der Teil, den man leicht übersieht. Die Seite ist eine Menge Dateien, die irgendwann in der Vergangenheit gebaut wurden. Nichts bewertet irgendetwas neu. Wenn der Montag kommt und niemand baut neu, erscheint der Montagsbeitrag nicht, weil keine Maschine irgendwo bemerkt hat, dass sich das Datum geändert hat.
Also baut sich die Seite jeden Morgen selbst neu.
on:
push:
branches: [main]
schedule:
- cron: '0 5 * * *' # 07:00 Wien im Sommer, 06:00 im Winter
Beachten Sie, was das nicht ist. Es ist kein zweiter Workflow, der Beiträge veröffentlicht. Es ist ein zweiter Grund, den auszuführen, den es schon gibt, damit eine geplante Veröffentlichung durch genau denselben Build, dieselben Prüfungen und dieselbe Weigerung läuft, bei einem Fehler auszuliefern. Ein getrennter Veröffentlichungsweg wäre ein Weg, den an gewöhnlichen Tagen niemand testet.
Und eine Sache, die in keinem Tutorial steht: GitHub schaltet einen geplanten Workflow nach sechzig Tagen ohne Aktivität im Repository ab. Ohne Warnung. Wer regelmäßig schreibt, wird es nie sehen. Wer zwei Monate still ist, bei dem fällt als Erstes das aus, was während der Stille funktionieren sollte. Einmal Run workflow drücken schaltet es wieder ein.
Die Einschränkung, direkt unter das Feature geschrieben
Jetzt der Teil, den die meisten Beschreibungen weglassen würden.
Alle Beiträge liegen in einer einzigen JavaScript-Datei, und diese Datei wird als Ganzes in das Bundle der Seite kompiliert. Der Text eines auf nächsten Freitag datierten Beitrags steckt also schon heute in dem JavaScript, das Ihr Browser herunterlädt.
Genau zu sein, was das bedeutet und was nicht. Es gibt keine Seite. Kein Link irgendwo zeigt darauf. Er steht nicht in der Sitemap, also erfährt keine Suchmaschine davon. Die Artikelroute verweigert ihn und liefert eine 404. Das Herz nimmt keine Stimme dafür an. Auf jedem gewöhnlichen Weg, über die Seite oder über Google, existiert er nicht.
Und wer die Entwicklerwerkzeuge öffnet und ein minifiziertes Bundle liest, findet ihn.
Wir haben das bewusst so gelassen, und der Grund steht als Kommentar neben dem Code, damit die nächste Person die Entscheidung erbt, statt sie neu zu entdecken. Nichts, was wir planen, ist vertraulich. Es ist ein Blogbeitrag, der am Freitag erscheint. Die Alternative wäre, die Datendatei aufzuteilen, sodass jeder Beitrag einzeln geladen wird, und das ist echte Arbeit, echte Komplexität und ein dauerhafter Wartungsaufwand, gekauft, um einen Blogbeitrag davor zu schützen, drei Tage zu früh von jemandem gelesen zu werden, der ihn am Freitag ohnehin lesen darf.
Wenn Sie eine Bilanzmitteilung planen, einen Produktstart unter Sperrfrist oder irgendetwas, wofür ein Wettbewerber zahlen würde, machen Sie es nicht so. Dieser Satz ist der nützliche Teil dieses ganzen Abschnitts, und es gibt ihn nur, weil wir die Einschränkung aufgeschrieben haben, statt das Feature zu bewundern.
Eine Einschränkung, die man veröffentlicht, ist eine Entscheidung. Eine Einschränkung, die man weglässt, ist eine Überraschung mit einem Datum darauf.
Was das gekostet hat, und was die Maschine nicht konnte
Einen Nachmittag. Die Funktion hat vier Zeilen, der Datumshelfer sechs, die Änderung am Workflow zwei, und der größte Teil des Nachmittags ging für die fünf Stellen drauf, die sie aufrufen, und dafür, die Sache in beide Richtungen zu beweisen.
Ich habe es mit einem KI-Assistenten gebaut, und ich will genau sein, welche Hälfte welche war, denn darüber wird derzeit viel Unsinn geschrieben.
Worin er wirklich gut war. Die Funktion schreiben. Alle fünf Aufrufstellen finden und keine übersehen. Wissen, dass en-CA genau das benötigte Format erzeugt, und das ist die Art Fakt, die einen Menschen zwanzig Minuten kostet. Danach die Kommentare und das Runbook schreiben, ordentlich, also genau die Arbeit, die alle auslassen und die in sechs Monaten zählt.
Was er nicht getan hat. Er hat mir nicht gesagt, dass die Datendatei als Ganzes gebündelt wird, bis ich gefragt habe, was mit dem Text eines geplanten Beitrags passiert. Als die Frage einmal da war, hat er sofort und ehrlich geantwortet. Aber die Frage musste existieren, und nichts an der Aufgabe, das Feature zu bauen, erzeugt sie.
Das ist die tatsächliche Form der Sache. Er baut, worum Sie bitten, und baut es gut. Er sagt Ihnen nicht, worum Sie nicht hätten bitten sollen. Das Prüfen ist nicht verschwunden, es ist umgezogen. Statt vierzig Zeilen zu schreiben, habe ich den Nachmittag damit verbracht zu entscheiden, ob es die richtigen vierzig sind, und das ist ein besserer Einsatz einer Ingenieurin als Tippen, und es ist dieselbe Fähigkeit wie einen Entwurf zu lesen und zu wissen, welcher Absatz eine Lüge ist.
Ein konkretes Beispiel, weil die allgemeine Fassung zu bequem ist
Vor ein paar Tagen wollte ich wissen, ob Google diese Seiten tatsächlich indexiert hat. Die Search Console war noch leer und ich wollte eine zweite Meinung.
Also habe ich gefragt, und die Antwort kam mit einer Suche zurück. Die Suche lieferte Ergebnisse, die nichts mit meiner Seite zu tun hatten, und die daraus gezogene Schlussfolgerung klang vernünftig. Ich habe sie nicht akzeptiert. Ich habe nachgesetzt, weil ich weiß, wofür diese Console da ist, und weil ich wusste, dass die Antwort, die ich bekommen hatte, aus nichts Echtem stammen konnte.
Die Korrektur war, als sie kam, die richtige Antwort und zugleich ein Eingeständnis: Dieses Werkzeug kann diese Frage überhaupt nicht beantworten. Nicht schlecht, nicht ungefähr. Eine allgemeine Websuche kann Ihnen nicht sagen, was eine bestimmte Suchmaschine für Ihre Domain indexiert hat. Das einzige Instrument, das das beantwortet, ist die URL-Prüfung in der Search Console, die Google direkt fragt und Googles eigenen Datensatz zurückbekommt.
Das ist der Fehlermodus, den man kennen sollte, und es ist nicht der, vor dem gewarnt wird. Die Gefahr ist selten eine Antwort, die offensichtlich Unsinn ist. Es ist eine plausible Antwort, erzeugt von einem Werkzeug, das die Frage nie beantworten konnte, geliefert im exakt gleichen Ton wie eine richtige. Nichts an der Ausgabe markiert den Unterschied.
Was die Lücke geschlossen hat, war keine Cleverness. Es waren achtundzwanzig Jahre Wissen darüber, wofür ein Werkzeug da ist. Ich wusste, was die Search Console misst, also wusste ich, dass die Antwort unmöglich war, also habe ich nachgesetzt. Jemand ohne diesen Hintergrund hätte die Antwort notiert und wäre weitergegangen, und hätte sich wochenlang geirrt, ohne es je zu merken.
Das ist es, was ich jedem sagen würde, dem verkauft wird, dass die Fachkenntnis jetzt optional sei. Die Fachkenntnis ist das, was Ihnen sagt, wann Sie der Ausgabe nicht mehr glauben sollen. Sie wurde nicht automatisiert. Sie wurde befördert.
Es war kein falscher Fakt. Es war das falsche Instrument, selbstsicher benutzt, und die Selbstsicherheit ist der Teil, der den Schaden anrichtet.
Wenn Sie das auf Ihrer eigenen Seite wollen
Vier Schritte, und keiner davon braucht ein Content-Management-System.
Erstens. Geben Sie jedem Beitrag ein Datum als schlichte YYYY-MM-DD-Zeichenkette.
Zweitens. Schreiben Sie eine Funktion, die danach filtert, in Ihrer eigenen Zeitzone, nicht in der des Servers.
Drittens. Finden Sie jede Stelle in Ihrem Code, die Beiträge auflistet oder nachschlägt, und lassen Sie alle diese eine Funktion aufrufen. Dieser Schritt kostet die Zeit und dieser Schritt macht es richtig.
Viertens. Fügen Sie dem Deployment, das Sie bereits haben, einen täglichen Zeitplan hinzu. Kein neues.
Testen Sie dann in beide Richtungen, denn das ist der Schritt, den alle auslassen: einmal mit einem Datum in der Vergangenheit bauen und bestätigen, dass der Beitrag da ist, und einmal mit einem Datum in der Zukunft und bestätigen, dass er in der Übersicht, auf der Artikelseite, in der Sitemap und beim Herz fehlt.
Warum wir das aufschreiben
Dies ist ein Unternehmen, das andere dazu berät, wie ihre Systeme gebaut sind, also ist es die ehrliche Variante, zu veröffentlichen, wie unsere gebaut sind, einschließlich der Teile, die wir bewusst nicht gelöst haben.
Ein Feature aus vierzig Zeilen mit einer dokumentierten Einschränkung ist ein nützlicheres Objekt als ein perfektes Feature, das vage beschrieben wird. Sie können dieses hier lesen, dem Abwägen widersprechen und auf Ihrer eigenen Seite anders entscheiden, und das ist die einzige Art technischen Schreibens, die je irgendjemandes Zeit wert war.
Planen ist einfach. Zu entscheiden, was das Geplante sein darf, ist die Ingenieursarbeit, und dieser Teil passiert weiterhin laut gedacht, bevor jemand eine Tastatur anfasst.
MK!
Maria Catalina Kovacs
Auf dieser Seite gibt es kein Tracking. Keine Analyse, keine Cookies, nichts, das aufzeichnet, wo Sie waren oder wie lange Sie geblieben sind.
Aber ich würde gerne wissen, ob hier etwas Ihre Zeit wert war. Wenn ja, drücken Sie das Herz. Es verrät mir nichts über Sie. Es ist eine Zahl, die steigt, und sie ist der Grund, warum ich weiterschreibe.
Wenn Sie mehr davon möchten, finden Sie mich auf X. @Queendemetriak