<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>The zxn.uk blog</title><description>What we built, what broke and what we learned at zxn.uk.</description><link>https://zxn.uk/blog/</link><language>en-gb</language><item><title>Eleven pieces of psychology we design with, and where to see them</title><link>https://zxn.uk/blog/design-psychology-field-guide/</link><guid isPermaLink="true">https://zxn.uk/blog/design-psychology-field-guide/</guid><description>A field guide to the design psychology behind our apps and sites: the published source for each idea, the screen where we used it, and the dark-pattern version of it we will not ship.</description><pubDate>Sat, 07 Nov 2026 00:00:00 GMT</pubDate><category>Product</category><category>design</category><category>mobile</category><category>web</category><category>accessibility</category></item><item><title>Six months in, by the numbers</title><link>https://zxn.uk/blog/six-months-by-the-numbers/</link><guid isPermaLink="true">https://zxn.uk/blog/six-months-by-the-numbers/</guid><description>Mediant Partners Ltd was incorporated on 11 May 2026. Six months on: 195 repos, 5,795 animal logs in ZooLog, 4,710 commits in the five repos we work in most, and a November repo count that needs an asterisk.</description><pubDate>Sat, 07 Nov 2026 00:00:00 GMT</pubDate><category>Studio</category><category>business</category><category>data</category><category>process</category></item><item><title>What Cloudflare can still do to us</title><link>https://zxn.uk/blog/what-cloudflare-can-still-do-to-us/</link><guid isPermaLink="true">https://zxn.uk/blog/what-cloudflare-can-still-do-to-us/</guid><description>We moved TipBop and TyreStack to Cloudflare in a day and made it the default for everything. This is the case against that, from our own standard: five ways it fails, the limits we accepted, and four conditions that would send us back.</description><pubDate>Sat, 07 Nov 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>cloudflare</category><category>gcp</category><category>reliability</category><category>cost</category><category>migration</category></item><item><title>The entitlement arrived. The feature still is not live.</title><link>https://zxn.uk/blog/tap-to-pay-and-app-review/</link><guid isPermaLink="true">https://zxn.uk/blog/tap-to-pay-and-app-review/</guid><description>On 6 November Apple granted the Tap to Pay entitlement we had asked for since September. Workers still cannot use it, because the build sitting in Apple&apos;s separate App Store review would lose its place in the queue if we swapped it now.</description><pubDate>Fri, 06 Nov 2026 00:00:00 GMT</pubDate><category>Product</category><category>payments</category><category>mobile</category><category>process</category><category>business</category></item><item><title>The checklist before a client site goes live</title><link>https://zxn.uk/blog/the-launch-checklist/</link><guid isPermaLink="true">https://zxn.uk/blog/the-launch-checklist/</guid><description>Every line on our launch checklist traces to an incident, a decision or a question nobody could answer by looking. Here is where each one came from, what we automated so the list stays short, and what no checklist can prove.</description><pubDate>Thu, 05 Nov 2026 00:00:00 GMT</pubDate><category>Studio</category><category>process</category><category>web</category><category>testing</category><category>seo</category><category>email</category></item><item><title>The ten pound rule</title><link>https://zxn.uk/blog/the-ten-pound-rule/</link><guid isPermaLink="true">https://zxn.uk/blog/the-ten-pound-rule/</guid><description>In October our GitHub Actions use ran to nearly five times the minutes our plan includes, and a spending cap we kept raising turned two dozen alerts red. On 5 November we set one rule for every metered vendor: free tier or £10 a month.</description><pubDate>Thu, 05 Nov 2026 00:00:00 GMT</pubDate><category>Studio</category><category>cost</category><category>ci</category><category>business</category></item><item><title>Every guard on our agents started as an incident</title><link>https://zxn.uk/blog/guard-hooks-born-from-incidents/</link><guid isPermaLink="true">https://zxn.uk/blog/guard-hooks-born-from-incidents/</guid><description>Our AI coding agents run behind five small scripts that can refuse a shell command before it runs. None of them was designed up front. Each one is the scar from something that went wrong, and each says so in its first lines.</description><pubDate>Wed, 04 Nov 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>ai-agents</category><category>security</category><category>tooling</category></item><item><title>Load average 14, and the CPU was mostly idle</title><link>https://zxn.uk/blog/load-average-thirty/</link><guid isPermaLink="true">https://zxn.uk/blog/load-average-thirty/</guid><description>One of our Macs crawled, with load readings up to 30 and eight agent sessions open. We blamed the cores. Measured at a load of 8 to 14, they were 68 to 80% idle. The memory had run out, and our first fix watched the wrong number.</description><pubDate>Wed, 04 Nov 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>ci</category><category>hardware</category><category>performance</category></item><item><title>We designed for wet gloves and never tested a glove</title><link>https://zxn.uk/blog/designing-for-wet-gloves/</link><guid isPermaLink="true">https://zxn.uk/blog/designing-for-wet-gloves/</guid><description>Five design choices in ZooLog+ for keepers working outdoors, the published research behind each, and the glove test we have not run.</description><pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate><category>Product</category><category>design</category><category>mobile</category><category>accessibility</category></item><item><title>We moved every ticket into a Markdown file</title><link>https://zxn.uk/blog/tickets-as-files/</link><guid isPermaLink="true">https://zxn.uk/blog/tickets-as-files/</guid><description>On 12 October we retired our ticket tracker and put every open task in a Markdown file in each business&apos;s own git repo. It worked for just over two weeks. Then many agents writing at once pulled six of those repos apart.</description><pubDate>Sat, 31 Oct 2026 00:00:00 GMT</pubDate><category>Studio</category><category>process</category><category>tooling</category></item><item><title>Who watches the alerts?</title><link>https://zxn.uk/blog/who-watches-the-alerts/</link><guid isPermaLink="true">https://zxn.uk/blog/who-watches-the-alerts/</guid><description>On 18 October we found our Slack bot tokens had died and every alert since had gone nowhere. We rebuilt the path so it is much harder to fail quietly, then spent a week learning that an alert path can also fail loudly, by paging for things nobody could fix.</description><pubDate>Fri, 30 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>monitoring</category><category>reliability</category><category>email</category></item><item><title>Rewriting ZooLog in Swift and Kotlin in a week</title><link>https://zxn.uk/blog/rewriting-zoolog-native-in-a-week/</link><guid isPermaLink="true">https://zxn.uk/blog/rewriting-zoolog-native-in-a-week/</guid><description>On 19 October the ZooLog mobile app was 134,442 lines of Dart. On 26 October it was Swift and Kotlin, opening the old app&apos;s database and settings where they lay. What it took, and why we have no better reason than a director&apos;s call.</description><pubDate>Tue, 27 Oct 2026 00:00:00 GMT</pubDate><category>Product</category><category>mobile</category><category>testing</category><category>migration</category></item><item><title>An undo button that tells the truth</title><link>https://zxn.uk/blog/an-undo-button-that-tells-the-truth/</link><guid isPermaLink="true">https://zxn.uk/blog/an-undo-button-that-tells-the-truth/</guid><description>A TyreStack fitter now gets 30 seconds to take back a Done tap, but only while undoing it would not falsify the stock or money records. The same audit found our board plotting jobs at invented places.</description><pubDate>Mon, 26 Oct 2026 00:00:00 GMT</pubDate><category>Product</category><category>design</category><category>mobile</category><category>data</category></item><item><title>Postgres to D1, with the rollback timed first</title><link>https://zxn.uk/blog/postgres-to-d1-with-money-in-flight/</link><guid isPermaLink="true">https://zxn.uk/blog/postgres-to-d1-with-money-in-flight/</guid><description>D1 has no interactive transactions, and TipBop&apos;s payouts relied on them. How we moved a tipping app in beta off Postgres in a day: a lease row for the locks, one schema for 37 migrations, and a rollback we timed before we needed it.</description><pubDate>Thu, 22 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>cloudflare</category><category>gcp</category><category>data</category><category>payments</category><category>migration</category></item><item><title>Ten thousand worlds before the first real fitter</title><link>https://zxn.uk/blog/ten-thousand-simulated-worlds/</link><guid isPermaLink="true">https://zxn.uk/blog/ten-thousand-simulated-worlds/</guid><description>TyreStack&apos;s scheduler had no customers yet, so before launch we built an audited oracle and threw ten thousand generated worlds of bookings, holds and late vans at it, comparing the old engine and the new one call for call.</description><pubDate>Wed, 21 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>testing</category><category>reliability</category><category>booking</category><category>data</category></item><item><title>The outage that moved us to Cloudflare</title><link>https://zxn.uk/blog/the-outage-that-moved-us-to-cloudflare/</link><guid isPermaLink="true">https://zxn.uk/blog/the-outage-that-moved-us-to-cloudflare/</guid><description>At 06:02 a Google Cloud zone stopped answering and took two products, both still in beta, with it. Our own review said stay and pay for high availability. By 15:45 we had left anyway. Here is the reasoning, and the objections to it.</description><pubDate>Wed, 21 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>cloudflare</category><category>gcp</category><category>reliability</category><category>cost</category><category>migration</category></item><item><title>24 files we are not allowed to edit</title><link>https://zxn.uk/blog/24-files-byte-for-byte/</link><guid isPermaLink="true">https://zxn.uk/blog/24-files-byte-for-byte/</guid><description>Ed proved his scheduling engine against ten thousand simulated worlds. TyreStack imports it unchanged, locks 24 files to his exact bytes with a hash, and the gate fails the moment one of them differs.</description><pubDate>Sun, 18 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>testing</category><category>ci</category><category>tooling</category><category>process</category></item><item><title>Sign-in without passwords, SMS or an auth vendor</title><link>https://zxn.uk/blog/sign-in-without-passwords/</link><guid isPermaLink="true">https://zxn.uk/blog/sign-in-without-passwords/</guid><description>On 16 October we wrote one sign-in standard for every app we run: an emailed code plus Apple, Google and Microsoft, our own revocable sessions, and no passwords, SMS codes or auth vendors. Here is why, and the linking rule that matters most.</description><pubDate>Sat, 17 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>security</category><category>privacy</category><category>tooling</category></item><item><title>A thousand synthetic finger drags</title><link>https://zxn.uk/blog/a-thousand-synthetic-finger-drags/</link><guid isPermaLink="true">https://zxn.uk/blog/a-thousand-synthetic-finger-drags/</guid><description>A bot playing our iOS puzzle game through real touch events caught SwiftUI dropping finger positions whenever a frame ran late, turning a +672 chain into +80. It also caught a Release build that no longer compiled.</description><pubDate>Wed, 14 Oct 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>mobile</category><category>testing</category><category>performance</category></item><item><title>Three things ZooLog refuses to do, with the numbers</title><link>https://zxn.uk/blog/three-things-zoolog-will-never-do/</link><guid isPermaLink="true">https://zxn.uk/blog/three-things-zoolog-will-never-do/</guid><description>We built photo recognition and left it switched off. Voice can write a keeper&apos;s note but never a drug dose. And there is no keeper leaderboard. Three refusals in a welfare app, and the numbers behind each one.</description><pubDate>Tue, 06 Oct 2026 00:00:00 GMT</pubDate><category>Product</category><category>privacy</category><category>design</category><category>data</category></item><item><title>20.5 hours of agent time spent watching CI</title><link>https://zxn.uk/blog/sixty-nine-hours-waiting/</link><guid isPermaLink="true">https://zxn.uk/blog/sixty-nine-hours-waiting/</guid><description>We read two weeks of our AI coding-agent sessions by hand: 129 sessions, 496 prompts. The agents were rarely slow at the work. They were slow at finishing it: they kept stopping to ask, and 20.5 hours went on watching CI.</description><pubDate>Sat, 26 Sep 2026 00:00:00 GMT</pubDate><category>Studio</category><category>ai-agents</category><category>process</category><category>ci</category></item><item><title>A green health check and an empty database</title><link>https://zxn.uk/blog/green-dashboard-empty-database/</link><guid isPermaLink="true">https://zxn.uk/blog/green-dashboard-empty-database/</guid><description>TipBop moved to Cloud Run on 17 September with a test-mode Stripe key, placeholder secrets, no data and no photos. The health check said ok the whole time. What it was checking, what it should have checked, and the two guards we added.</description><pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate><category>Engineering</category><category>reliability</category><category>payments</category><category>testing</category></item><item><title>The customer pays the fee, so the worker gets every penny</title><link>https://zxn.uk/blog/the-customer-pays-the-fee/</link><guid isPermaLink="true">https://zxn.uk/blog/the-customer-pays-the-fee/</guid><description>On a £5 tip the customer pays £5.60 and the worker gets exactly £5.00. Taking a cut out of the tip instead loses money on small tips and breaks the one promise TipBop makes. Here is the arithmetic.</description><pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate><category>Product</category><category>payments</category><category>business</category><category>cost</category></item><item><title>Tappy was taken, so we became TipBop</title><link>https://zxn.uk/blog/tappy-was-taken/</link><guid isPermaLink="true">https://zxn.uk/blog/tappy-was-taken/</guid><description>We built our tipping app as Tappy on 21 August 2026. Fifty-eight hours later it was TipBop, because the old name belonged to somebody else. How we screened more than 60 names, and why the code still says tappy.</description><pubDate>Mon, 24 Aug 2026 00:00:00 GMT</pubDate><category>Product</category><category>business</category><category>design</category><category>mobile</category></item><item><title>ZooLog is on Cloudflare from the first commit</title><link>https://zxn.uk/blog/zoolog-cloudflare-from-day-one/</link><guid isPermaLink="true">https://zxn.uk/blog/zoolog-cloudflare-from-day-one/</guid><description>Two days in, the keeper app runs on Workers, D1, Queues and R2, with no other backend behind it. That was the easy decision. The hard one is what happens when a keeper logs a feed where the phone has no signal.</description><pubDate>Fri, 05 Jun 2026 00:00:00 GMT</pubDate><category>Product</category><category>cloudflare</category><category>data</category><category>mobile</category></item></channel></rss>