<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Christian Riesen — Posts</title><description>Notes on engineering, applied AI, leadership and the occasional detour into writing fiction.</description><link>https://christianriesen.com/</link><language>en</language><item><title>Spec-driven agentic development in practice</title><link>https://christianriesen.com/posts/spec-driven-agentic-development/</link><guid isPermaLink="true">https://christianriesen.com/posts/spec-driven-agentic-development/</guid><description>The one trick almost nobody uses: tell the LLM to ask you the questions. A working method for turning a braindump into a spec precise enough that an agent can build from it — and keeping the spec as the source of truth afterwards.</description><pubDate>Wed, 12 Nov 2025 00:00:00 GMT</pubDate><category>AI</category><category>AI</category><category>Specs</category><category>Agentic development</category><category>Claude Code</category></item><item><title>Configure default datetime format of Symfony Serializer DateTimeNormalizer</title><link>https://christianriesen.com/posts/configure-default-datetime-format-of-symfony/</link><guid isPermaLink="true">https://christianriesen.com/posts/configure-default-datetime-format-of-symfony/</guid><description>The Symfony Serializer happily normalizes DateTimes — until you need milliseconds. How to change the DateTimeNormalizer default format once, globally.</description><pubDate>Thu, 12 Dec 2019 00:00:00 GMT</pubDate><category>Engineering</category></item><item><title>Add disks to a setup with a LUKS container on a LVM volume without losing data</title><link>https://christianriesen.com/posts/add-disks-to-a-setup-with-a-luks-container-on-a/</link><guid isPermaLink="true">https://christianriesen.com/posts/add-disks-to-a-setup-with-a-luks-container-on-a/</guid><description>Growing an encrypted LUKS-on-LVM data partition onto freshly bought disks without losing a byte — the exact command sequence, plus the obligatory backup sermon.</description><pubDate>Fri, 30 Mar 2018 00:00:00 GMT</pubDate><category>Engineering</category></item><item><title>Auto deploy a Sculpin website for free</title><link>https://christianriesen.com/posts/auto-deploy-a-sculpin-website-for-free/</link><guid isPermaLink="true">https://christianriesen.com/posts/auto-deploy-a-sculpin-website-for-free/</guid><description>Public repo on GitHub, merge to master, site live on S3 — a zero-cost Travis auto-deploy for a Sculpin static site, as used for rokka.io.</description><pubDate>Fri, 25 Nov 2016 00:00:00 GMT</pubDate><category>Engineering</category><category>sculpin</category><category>AWS</category><category>deployment</category></item><item><title>How to NaNoWriMo</title><link>https://christianriesen.com/posts/how-to-nanowrimo/</link><guid isPermaLink="true">https://christianriesen.com/posts/how-to-nanowrimo/</guid><description>The system that carried me through NaNoWriMo wins: plain text files, automatic backups, no backspace key, and a merciless focus on reaching the end of the story.</description><pubDate>Mon, 31 Oct 2016 00:00:00 GMT</pubDate><category>Writing</category><category>nanowrimo</category></item><item><title>Symfony 2.5 using a new structure</title><link>https://christianriesen.com/posts/symfony-25-using-a-new-structure/</link><guid isPermaLink="true">https://christianriesen.com/posts/symfony-25-using-a-new-structure/</guid><description>Saying yes to the new 3.0 directory structure in a fresh Symfony 2.5 project: what moves where, and why var and bin make daily life easier.</description><pubDate>Sun, 08 Jun 2014 00:00:00 GMT</pubDate><category>Engineering</category><category>symfony2</category></item><item><title>Alternative location of the symfony2 documentation</title><link>https://christianriesen.com/posts/alternative-location-of-the-symfony2-documentation/</link><guid isPermaLink="true">https://christianriesen.com/posts/alternative-location-of-the-symfony2-documentation/</guid><description>When symfony.com goes down mid-task, the entire documentation is still sitting in a GitHub repo — less pretty to navigate, but all there.</description><pubDate>Wed, 13 Feb 2013 00:00:00 GMT</pubDate><category>Engineering</category><category>documentation</category><category>symfony2</category></item><item><title>One Time Passwords in PHP and Google Authenticator</title><link>https://christianriesen.com/posts/one-time-passwords-in-php-and-google-authenticator/</link><guid isPermaLink="true">https://christianriesen.com/posts/one-time-passwords-in-php-and-google-authenticator/</guid><description>Two-factor auth for your own app with Google Authenticator: how the one-time-password RFCs work, and the PHP library I published to handle the tricky bits.</description><pubDate>Sun, 17 Jun 2012 00:00:00 GMT</pubDate><category>Engineering</category><category>OTP</category><category>One Time Password</category><category>Google Authenticator</category><category>PHP</category></item><item><title>Zend Certified Engineer PHP 5.3</title><link>https://christianriesen.com/posts/zend-certified-engineer-php-53/</link><guid isPermaLink="true">https://christianriesen.com/posts/zend-certified-engineer-php-53/</guid><description>After years of owning the study guide, I finally sat the ZCE PHP 5.3 exam — number 95 in Switzerland, with honest notes on the test&apos;s fuzzier questions.</description><pubDate>Sat, 16 Jun 2012 00:00:00 GMT</pubDate><category>Engineering</category></item><item><title>Extension &apos;/path/script.php&apos; not present</title><link>https://christianriesen.com/posts/extension-pathscriptphp-not-present/</link><guid isPermaLink="true">https://christianriesen.com/posts/extension-pathscriptphp-not-present/</guid><description>A PHP script that ran fine by hand but failed in cron with a nonsense error — the culprit was DOS line endings, and dos2unix ended it.</description><pubDate>Fri, 24 Feb 2012 00:00:00 GMT</pubDate><category>Engineering</category></item><item><title>Writing is the smallest part in writing</title><link>https://christianriesen.com/posts/writing-is-the-smallest-part-in-writing/</link><guid isPermaLink="true">https://christianriesen.com/posts/writing-is-the-smallest-part-in-writing/</guid><description>Sanderson-scale word counts make the point: typing the words is the smallest part of writing a novel — the process around them is the real job.</description><pubDate>Mon, 02 Jan 2012 00:00:00 GMT</pubDate><category>Writing</category><category>Writing</category></item><item><title>The QuPiD principle</title><link>https://christianriesen.com/posts/the-qupid-principle/</link><guid isPermaLink="true">https://christianriesen.com/posts/the-qupid-principle/</guid><description>Quality, Performance, Design — pronounced like cupid — a three-question filter for choosing frying pans, software and pretty much everything else.</description><pubDate>Fri, 30 Dec 2011 00:00:00 GMT</pubDate><category>Engineering</category></item><item><title>Testing USB Drive Capacity</title><link>https://christianriesen.com/posts/testing-usb-drive-capacity/</link><guid isPermaLink="true">https://christianriesen.com/posts/testing-usb-drive-capacity/</guid><description>Cheap USB sticks that report 16 GB and silently eat your files — how the controller lie works, and how to test a drive before trusting it.</description><pubDate>Mon, 10 Jan 2011 00:00:00 GMT</pubDate><category>Engineering</category><category>USB Drives</category></item><item><title>Disappointing endings in Video Games</title><link>https://christianriesen.com/posts/disappointing-endings-in-video-games/</link><guid isPermaLink="true">https://christianriesen.com/posts/disappointing-endings-in-video-games/</guid><description>Finishing Arcania: Gothic 4 left me cold, and it is not alone — a long, spoiler-heavy look at why games keep fumbling the one part you remember: the ending.</description><pubDate>Mon, 18 Oct 2010 00:00:00 GMT</pubDate><category>Writing</category><category>Games</category><category>Writing</category><category>Endings</category></item><item><title>Flattr Statistics of September 2010</title><link>https://christianriesen.com/posts/flattr-statistics-of-september-2010/</link><guid isPermaLink="true">https://christianriesen.com/posts/flattr-statistics-of-september-2010/</guid><description>Four more months of Flattr numbers, from three-dollar summers to a single click worth 30 cents — small data on whether micro-donations add up.</description><pubDate>Fri, 01 Oct 2010 00:00:00 GMT</pubDate><category>Engineering</category><category>Flattr</category><category>statistics</category></item><item><title>MS SQL Blob truncated</title><link>https://christianriesen.com/posts/ms-sql-blob-truncated/</link><guid isPermaLink="true">https://christianriesen.com/posts/ms-sql-blob-truncated/</guid><description>JPEGs stored as blobs in MS SQL came back truncated at exactly 64&apos;512 bytes — the triple-facepalm hunt that ended in a FreeTDS config default.</description><pubDate>Mon, 12 Jul 2010 00:00:00 GMT</pubDate><category>Engineering</category><category>MSSQL</category><category>FreeTDS</category></item><item><title>Flattr Statistics of May 2010</title><link>https://christianriesen.com/posts/flattr-statistics-of-may-2010/</link><guid isPermaLink="true">https://christianriesen.com/posts/flattr-statistics-of-may-2010/</guid><description>Full transparency on a month of micro-donations: 24 things, 66 clicks, 11.34 euros — and why more clicks did not mean more money.</description><pubDate>Tue, 08 Jun 2010 00:00:00 GMT</pubDate><category>Engineering</category><category>Flattr</category><category>Statistics</category></item><item><title>Debian Killall Command</title><link>https://christianriesen.com/posts/debian-killall-command/</link><guid isPermaLink="true">https://christianriesen.com/posts/debian-killall-command/</guid><description>The package name I keep forgetting: where killall actually lives on Debian, written down so I never have to look it up again.</description><pubDate>Thu, 08 Apr 2010 00:00:00 GMT</pubDate><category>Engineering</category><category>Debian</category><category>Linux</category><category>Killall</category></item><item><title>Language reversal, from German to English and back to German</title><link>https://christianriesen.com/posts/language-reversal-from-german-to-english-and-back/</link><guid isPermaLink="true">https://christianriesen.com/posts/language-reversal-from-german-to-english-and-back/</guid><description>One harmless German sentence about a bed, and everything that quietly breaks when you try to carry it into English and back again.</description><pubDate>Fri, 02 Apr 2010 00:00:00 GMT</pubDate><category>Writing</category><category>Language</category><category>Translation</category><category>Writing</category></item><item><title>Writing as the main job?</title><link>https://christianriesen.com/posts/writing-as-the-main-job/</link><guid isPermaLink="true">https://christianriesen.com/posts/writing-as-the-main-job/</guid><description>Would you quit tomorrow and write full time if the money stayed the same? Reading how full-time authors actually live made me answer carefully.</description><pubDate>Wed, 24 Feb 2010 00:00:00 GMT</pubDate><category>Writing</category><category>writing</category></item><item><title>Comics and closed lips</title><link>https://christianriesen.com/posts/comics-and-closed-lips/</link><guid isPermaLink="true">https://christianriesen.com/posts/comics-and-closed-lips/</guid><description>A pet peeve turned craft note: if a comic character is speaking, draw the mouth open — and how much a pair of lips can say about how someone talks.</description><pubDate>Thu, 18 Feb 2010 00:00:00 GMT</pubDate><category>Writing</category><category>writing</category><category>comics</category></item><item><title>How characters look, Comics versus Books</title><link>https://christianriesen.com/posts/how-characters-look-comics-versus-books/</link><guid isPermaLink="true">https://christianriesen.com/posts/how-characters-look-comics-versus-books/</guid><description>Comics show you a face; novels hand you a description and let your head do the drawing — on the two ways a reader gets to meet a character.</description><pubDate>Wed, 17 Feb 2010 00:00:00 GMT</pubDate><category>Writing</category><category>writing</category><category>comics</category><category>imagination</category></item><item><title>Testing missing translations in Zend Framework</title><link>https://christianriesen.com/posts/testing-missing-translations-in-zend-framework/</link><guid isPermaLink="true">https://christianriesen.com/posts/testing-missing-translations-in-zend-framework/</guid><description>Finding untranslated strings in Zend_Translate by swapping in an adapter that answers everything with the same marker — an instant visual map of what you missed.</description><pubDate>Thu, 10 Dec 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category><category>Zend Framework</category></item><item><title>GoDaddy SSL Certificate and Apache</title><link>https://christianriesen.com/posts/godaddy-ssl-certificate-and-apache/</link><guid isPermaLink="true">https://christianriesen.com/posts/godaddy-ssl-certificate-and-apache/</guid><description>Support swore the certificate was installed correctly, yet fresh browsers rejected it — a broken intermediate chain, exposed by a free online tester.</description><pubDate>Wed, 02 Dec 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>SSL</category><category>Apache</category><category>GoDaddy</category></item><item><title>Simple wget written in PHP</title><link>https://christianriesen.com/posts/simple-wget-written-in-php/</link><guid isPermaLink="true">https://christianriesen.com/posts/simple-wget-written-in-php/</guid><description>No wget, no install rights, but a working PHP — a tiny stand-in script that fetches a file from a URL when that is all you need.</description><pubDate>Sun, 25 Oct 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category><category>Wget</category><category>Tool</category></item><item><title>(128)Network is unreachable: connect to listener on [::]:80</title><link>https://christianriesen.com/posts/128network-is-unreachable-connect-to-listener/</link><guid isPermaLink="true">https://christianriesen.com/posts/128network-is-unreachable-connect-to-listener/</guid><description>A cryptic Apache error filling the logs on Solaris 10, and the one-line Listen directive change that silences it for good.</description><pubDate>Thu, 15 Oct 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>Apache</category></item><item><title>Ant and Zend Studio</title><link>https://christianriesen.com/posts/ant-and-zend-studio/</link><guid isPermaLink="true">https://christianriesen.com/posts/ant-and-zend-studio/</guid><description>Ant mysteriously disabled in Zend Studio, and the trick with a throwaway project wizard that switches it back on.</description><pubDate>Wed, 23 Sep 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>Zend Studio</category><category>Ant</category><category>PHP</category></item><item><title>Making lists easier and more beautiful</title><link>https://christianriesen.com/posts/making-lists-easier-and-more-beautiful/</link><guid isPermaLink="true">https://christianriesen.com/posts/making-lists-easier-and-more-beautiful/</guid><description>Building &apos;a, b, c&apos; lists without dangling commas or foreach gymnastics — implode was right there all along, and it composes further than you would think.</description><pubDate>Thu, 27 Aug 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category></item><item><title>The coders approach to writing</title><link>https://christianriesen.com/posts/the-coders-approach-to-writing/</link><guid isPermaLink="true">https://christianriesen.com/posts/the-coders-approach-to-writing/</guid><description>What years of wrangling structured data teach about novel writing — and why the tidy expand-from-one-sentence method rarely survives contact with a real idea.</description><pubDate>Sun, 02 Aug 2009 00:00:00 GMT</pubDate><category>Writing</category><category>Writing</category></item><item><title>How novels work</title><link>https://christianriesen.com/posts/how-novels-work/</link><guid isPermaLink="true">https://christianriesen.com/posts/how-novels-work/</guid><description>At 500 words a day, a 100&apos;000-word novel is 200 working days before editing even starts — sobering arithmetic on what a book actually costs.</description><pubDate>Sun, 26 Jul 2009 00:00:00 GMT</pubDate><category>Writing</category><category>Writing</category><category>Novels</category></item><item><title>Creating a MySQL dump in CSV format</title><link>https://christianriesen.com/posts/creating-a-mysql-dump-in-csv-format/</link><guid isPermaLink="true">https://christianriesen.com/posts/creating-a-mysql-dump-in-csv-format/</guid><description>mysqldump has no --csv switch, but with the right -T incantation you get clean CSV files that Excel and Calc open without complaint.</description><pubDate>Fri, 26 Jun 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>MySQL</category></item><item><title>Cycling between strings</title><link>https://christianriesen.com/posts/cycling-between-strings/</link><guid isPermaLink="true">https://christianriesen.com/posts/cycling-between-strings/</guid><description>Cycling through a fixed set of values without counters, resets or static-variable hacks — a small class that keeps its own state does it better.</description><pubDate>Mon, 15 Jun 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category></item><item><title>Mini caching in classes</title><link>https://christianriesen.com/posts/mini-caching-in-classes/</link><guid isPermaLink="true">https://christianriesen.com/posts/mini-caching-in-classes/</guid><description>A method called repeatedly, a result too expensive to recompute, and the five-line private-array cache that beats passing state around.</description><pubDate>Fri, 12 Jun 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category><category>Cache</category></item><item><title>2009 has 53 weeks</title><link>https://christianriesen.com/posts/2009-has-53-weeks/</link><guid isPermaLink="true">https://christianriesen.com/posts/2009-has-53-weeks/</guid><description>The cronjob was fine, the import was fine — my firm belief that a year has 52 weeks was not. A calendar surprise, and the one-line PHP fix.</description><pubDate>Wed, 10 Jun 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category></item><item><title>Large MySQL Inserts with PHP</title><link>https://christianriesen.com/posts/large-mysql-inserts-with-php/</link><guid isPermaLink="true">https://christianriesen.com/posts/large-mysql-inserts-with-php/</guid><description>A million rows from PHP without trashing the disk or timing out: combine the inserts and the whole job finishes in under thirty seconds.</description><pubDate>Wed, 10 Jun 2009 00:00:00 GMT</pubDate><category>Engineering</category><category>PHP</category><category>MySQL</category><category>Database</category></item></channel></rss>