# The Collected Writing of Tom Kirkpatrick > CTO. Systems Engineer. > Building agentic infrastructure for the sovereign future. This document contains the full text of all published articles for AI/LLM consumption. --- ## Case Study: Optimizing AI Image Generation Date: 2026-02-13 Tags: ai, gemini, engineering, automation URL: https://kirkdesigns.co.uk/writing/ai-image-generation-workflow > **Note:** This entire guide and workflow - from problem identification through implementation and documentation - was created through real-time voice conversation using Claude and Gemini over approximately 2 hours. Using [The Bitcoin Heuristic](/writing/bitcoin-ai-journey) article as narrative context, I used [Mac Whisper](https://goodsnooze.gumroad.com/l/macwhisper) for speech-to-text and [GitHub Copilot](https://github.com/features/copilot) to orchestrate agent skills for image generation (Nano Banana Pro), shell scripting, and iterative validation in a single session. ## Overview I was preparing a keynote presentation for the engineering team at [Strike](https://strike.me), talking about our AI evolution, the work I'd been doing, and our roadmap. Through this process, I noticed a pattern: the journey teams take with AI mirrors the Bitcoin adoption journey almost exactly. Same stages, same traps, same breakthrough moments. This felt like a critical insight worth highlighting in the presentation, so I needed compelling visuals. I generated an initial set of Wojak meme characters - one for each stage of both journeys - to bring the concept to life in the slides. The final set of 10 characters: 5 Bitcoin journey stages (top row) and 5 AI journey stages (bottom row) That weekend, I decided to write up the full thesis in detail. That became [The Bitcoin Heuristic](/writing/bitcoin-ai-journey) article. As I was publishing it, I realized the images needed work - style inconsistencies, background issues. The initial script I'd built for the presentation was basic (good enough for slides), but I wanted something more robust: proper validation, consistent style enforcement, observability for debugging. What started as "improve the generation script" turned into a case study in validation, iteration, and why semantic AI evaluation beats pixel heuristics. ## The Problem The [Bitcoin Heuristic](/writing/bitcoin-ai-journey) article told a story in stages - how people's understanding of Bitcoin evolved over time. To visualize it, I needed a character for each stage: an archetype showing what adoption looked like at different points. The Bitcoin journey had five stages: the skeptic (dismissive, angry at the idea), the tourist (excited but clueless), the speculator (manic energy, focused on gains), the student (starting to understand the fundamentals), and the maximalist (fully committed, stoic conviction). The AI journey mirrored this same arc: skeptic, casual explorer, prompt engineer (trying to figure the tool out), pragmatist (understanding real-world applications), and finally the native (thinking in AI capabilities as default). The requirements were strict: - Consistent classic Wojak meme aesthetic (that crude MS Paint style the internet recognizes) - Solid pitch-black backgrounds - no gradients, no transparency - Character fills the entire frame edge-to-edge - Each character visually distinct enough to show progression I also needed both high-resolution archival versions (4K) and web-optimized files (1024px) to use on the website. ### The Initial Approach The first iteration was simple: a bash script that looped through a list of prompts and called a Python wrapper for the Gemini API. The goal was to generate the full set of 10 characters—one for each stage of the Bitcoin and AI journeys—in a single automated pass. Here’s an example of the prompt used for the "Bitcoin Skeptic" character: ```text [CRITICAL REQUIREMENTS] 1) Background: SOLID PITCH BLACK (#000000) - never white, never gray, never gradient. 2) Composition: Character fills the entire frame edge-to-edge, NO padding or borders. 3) Style: MS Paint meme aesthetic. Hand drawn internet meme illustration of Pink Wojak (SOLID PINK skin fill, not outline), screaming in anger, veins popping, wearing a business suit (banker), with red falling financial chart candles and Bitcoin logos floating around him. Crude MS Paint style, rough black outlines. The pink skin must be SOLID FILL. Remember: BLACK background only, character fills frame. ``` I expected this to be a "set it and forget it" task. I was wrong. ### The First Attempts Three immediate problems surfaced: 1. **Style Drift**: Some images came out as pixelated 8-bit art, others as outline art instead of the consistent classic Wojak meme style. 2. **Background Violations**: Despite the strict prompt requirements, the model wouldn't consistently produce the solid pitch-black background needed for the keynote. 3. **Observability Gap**: Since the goal was a 'clean' final set of 10 images, the script didn't save any of the discarded intermediate attempts. Without a record of what went wrong, I had no data to use for iterating on the prompts. Failure: 8-bit pixel art instead of MS Paint style Failure: Outline only, no color fills Success: Classic MS Paint with solid fills ## Attempt 1: Fix It In Post First idea: use better prompts and then clean up the image afterward with [ImageMagick](https://imagemagick.org/). I added explicit style requirements ("MS Paint aesthetic", "crude black outlines") and used ImageMagick's flood-fill to darken any non-black background pixels. **The problem**: Flood-fill is naive. It destroyed the character details - pink faces became just black outlines, all the internal character work vanished. The algorithm couldn't tell the difference between "this should be black" and "this is part of the character." Bigger issue: I was treating a symptom, not the cause. The real problem was that the generator wasn't producing black backgrounds in the first place. **Lesson learned**: Don't fix generation problems with image processing. Fix them upstream. ## Attempt 2: Trust The Algorithm Next idea: stop post-processing and instead validate each image. Generate, check if the background is black, retry if not. I built a validator that sampled 100x100px crops from each corner of the image, averaged their brightness, and said "if it's darker than 15%, it's good." This actually worked... until I started saving the failed attempts to debug what was happening. ### The Discovery I looked at what the validator was rejecting and found something infuriating: **most of them actually had black backgrounds**. The validator was throwing away good images. The issue: corner sampling is too simple. When a character has a glowing orange aura, the corner crop catches the glow, not the background. When text appears near the edge ("UP! UP! UP!"), same problem. **By the numbers**: Of 17 images the validator rejected, 12 actually had black backgrounds when I checked them manually with Gemini. That's a **70% false positive rate**. The validator was actively making things worse. False Positive: Glowing aura near edges triggers rejection, but background is actually black False Positive: Text "UP! UP! UP!" near edges triggers rejection, but background is black ## Attempt 3: Semantic Validation The real insight: "Is this background black?" isn't a pixel problem. It's a semantic problem. You need something that understands what "background" means - i.e., that an orange glow isn't the background, that a white character face isn't a background problem, that text overlays are foreground. I built `eval_background.py` to use [Gemini's vision model](https://ai.google.dev/gemini-api/docs/vision) instead of pixel sampling. **The Prompt**: ``` Analyze this image and determine if it has a solid black or very dark background. IMPORTANT: Focus on the BACKGROUND areas (edges, negative space around the subject), NOT on the subject/character itself. Do NOT consider these as background issues: - A character with white/light colored skin - A character with a glowing aura or glow effects around them - Text or UI elements that are part of the foreground - Computer monitors or screens that are part of the scene Answer with ONLY one word: PASS or FAIL ``` **Why This Works**: - Gemini understands context. An orange glow isn't the background. - It knows a white Wojak face isn't a background problem. - It distinguishes between character details and actual background. - It's trained on real-world images and knows what backgrounds look like. **Implementation**: ```bash # The main validation function now calls Gemini eval_result=$(uv run "eval_background.py" "$image_file") eval_status=$(echo "$eval_result" | cut -d'|' -f1) if [[ "$eval_status" == "PASS" ]]; then # Accept and create web version else # Reject and retry fi ``` **Cost & Model Choice**: The implementation originally used [Gemini 2.0 Flash](https://ai.google.dev/gemini-api/docs/models/gemini#gemini-2.0-flash) for validation. However, Gemini 2.0 Flash is now deprecated (shuts down March 31, 2026). Future implementations should migrate to Gemini 2.5 Flash or Gemini 3.0 Flash Preview - though vision input costs on newer models run 3-5x higher than the deprecated 2.0 Flash. The cost increase is still cheaper than manual validation, but worth noting for budget planning. I chose Flash over Pro because binary classification doesn't require advanced reasoning capabilities. ## The Style Problem I also had to fix inconsistent style rendering. Some images came out as pixelated 8-bit art when I wanted smooth classic Wojak meme style. The fix was blunt: explicitly tell the model what NOT to do. **Original**: "GigaChad Wojak (strong jawline drawn crudely in MS Paint style)" **Fixed**: "GigaChad Wojak in classic Wojak meme style (NOT pixel art, NOT 8-bit). Smooth vector-like meme aesthetic, NOT retro pixel art." This is counterintuitive but it works. Models understand negatives pretty well when you pair them with context. It's specific enough to override the default "retro pixel art" interpretation of "meme." ## Final Architecture The final system works as follows: The complete system flow - from prompt definition through validation and integration ## Results & Metrics ### Before Optimization - **Success Rate**: ~70% - several images would fail on first attempt, requiring manual intervention - **False Positives**: 70% of rejected images actually had valid black backgrounds - **Debugging**: Impossible - failed attempts weren't saved - **Style Consistency**: Some images were pixel art, others classic meme style - inconsistent aesthetic - **Time**: Manual tweaking and verification as needed for failures ### After Optimization - **Success Rate**: 100% - all 10 images generated successfully - **Efficiency**: 1.2 attempts per final image (12 total generations for 10 assets) - **False Positives**: 0% - Gemini semantic evaluation eliminates guessing - **Debugging**: Complete - all failed attempts saved with timestamps and metadata - **Style Consistency**: All 10 images now use consistent classic Wojak meme aesthetic - **Total Cost**: < $1.00 (12 generations via Pro + 12 validations via Flash) - **Automation**: Can re-run any subset with `./generate_wojak_assets.sh btc ai-native` without manual intervention ## Key Techniques ### 1. **Use Semantic Evaluation, Not Heuristics** When evaluating AI outputs, prefer another AI system with semantic understanding (like Gemini vision) over pixel-level heuristics. Seems expensive and redundant at first, but accuracy gains and elimination of false positives make it worth the cost. ### 2. **Save Failed Attempts for Inspection** Never discard failures. They provide: - Evidence of what doesn't work - Input for better prompts next time - Leverage for manual review if needed ### 3. **Combine Positive and Negative Instructions** "Don't do pixel art" paired with "do classic meme style" beats either alone. The real power comes from anchoring with context on both sides - telling the model what you want AND what you don't want. The article's fix used both together: "GigaChad Wojak in classic Wojak meme style (NOT pixel art, NOT 8-bit). Smooth vector-like meme aesthetic, NOT retro pixel art." Negations without guidance can leave the model guessing; positives without exclusions can default to common misconceptions. ### 4. **Retry Logic Alone Won't Fix Bad Validation** Retrying with the same prompt usually just fails the same way. Better to fix the evaluator than add more attempts. ### 5. **Parallelize What You Can** 5 concurrent image generations beats sequential one-at-a-time. For batch tasks, parallelization is usually the biggest time win. ### 6. **Model Economics Change Over Time** The cost calculus shifts as models evolve. Gemini 2.0 Flash ($0.02/eval) was deprecated within months, replaced by 2.5 Flash ($0.06/eval) and 3.0 Flash Preview ($0.10/eval). Budget for API cost increases - what's cheap today may be 5x more expensive (or unavailable) next year. Factor model lifecycle into production planning. ## What I Learned This didn't feel like a lesson in image generation. It felt like a lesson in evaluation and iteration. Production AI image generation isn't just calling an API and hoping. It's about: - **Knowing what you need.** I needed images with specific styles and black backgrounds, not just "images." - **Catching failures early.** Without saving attempts, I never would have discovered the 70% false positive rate. - **Recognizing where intuition breaks.** Pixel sampling seemed sensible until I actually looked at what it was doing. - **Iterating on the right thing.** Better prompts help, but better validation helped more. The jump from 70% false positives to 0% didn't come from computing power or larger models. It came from asking a different question: "Should I scan pixels or ask an AI?" Once I asked that, the answer was obvious. But I had to fail first to see it. --- ## The Bitcoin Heuristic: A Mental Model for AI Date: 2026-01-25 Tags: ai, bitcoin, philosophy URL: https://kirkdesigns.co.uk/writing/bitcoin-ai-journey If you have been around Bitcoin for more than one cycle, you know the feeling. You remember the initial skepticism ("It's a Ponzi"). You remember the confusion ("How does mining work?"). And you remember the specific moment the switch flipped - when you stopped looking at the price and started looking at the protocol. You might think that journey was unique to hard money. It wasn't. **You are about to walk the exact same path with AI.** The journey from "AI Skeptic" to "AI Native" follows the exact same stages. The traps are identical. And the endpoint - finding signal in the noise - is identical. If you found your way to "tick tock next block," you already have the playbook to become AI native. **Does this path look familiar?** Skeptic Native Bitcoin Skeptic Tourist Speculator Student Maximalist AI Skeptic Toy User Prompt Eng Pragmatist Native "We all start with skepticism or hype. We all aim for Signal." ## 1. The Skeptic Hubris got the best of you, as it did most of us. - **The Bitcoin Skeptic:** You used "magic internet money" like a punchline. It was easier to mock the volatility than admit you didn't understand the protocol. - **The AI Skeptic:** You screenshot the hallucinations and post them for engagement. Mocking the "slop" makes you feel safe; it proves that *humanity* still has the edge. **The Trap:** You are using cynicism as a shield. Dismissing the tech feels like wisdom, but it's actually just fear of the rate of change. ## 2. The Tourist The "Toy Phase." You decide to engage, but you treat it like a game. - **The Bitcoin Tourist:** You didn't care about censorship resistance. You bought Doge because your friends did, and you wanted the dopamine hit of "number go up." - **The AI Tourist:** You don't care about reasoning capabilities. You treat the model like a party trick - trying to get it to make a video of your cat bench pressing or say something forbidden. **The Trap:** You are treating a tool like a toy. Most people get stuck here - they pull the lever, look for the magic, get bored, and leave before they ever find the utility. ## 3. The Speculator This is where you got hurt. You saw the potential, but you let your ego take the wheel. - **The Bitcoin Speculator:** You confused a bull market for brain power. You leveraged everything on an altcoin because you thought you were smarter than the market. You weren't. - **The AI Speculator (The Prompt Engineer):** You confused early access for a moat. You are building "wrappers" that are one update away from being obsolete, convinced you've found a shortcut to building software. **The Trap:** Greed. You want the leverage without the discipline. You are trying to skip the "Student" phase and go straight to the payout. ## 4. The Student The pivot point. The moment the noise stops. - **The Bitcoin Student:** You stop watching the price charts. You realize that "getting rich" was the distraction, and "censorship-resistant money" was the point. You start reading the whitepaper. - **The AI Pragmatist:** You stop looking for the "God Prompt." You realize the model isn't a magic 8-ball; it's a deterministic engine. You stop trying to *trick* it and start trying to *architect* it. **The Shift:** You stop trying to exploit the system and start trying to understand it. ## 5. The Native The endpoint. The tool disappears and becomes an extension of how you think. - **The Bitcoin Maximalist:** You don't "check the price" anymore. You measure your wealth in sats, not dollars. The volatility doesn't scare you because your time horizon is "forever." - **The AI Native:** You don't "chat" with the bot anymore. You view intelligence as a commodity you can pipe, route, and stack. You don't ask the AI to do a task; you build a system that *contains* the AI. The User types into a prompt box. You, the Native, build the box. You look at a problem and see a system that can be dismantled, reasoned through, and rebuilt. --- ## The First-Mover Advantage The world is splitting. Most of your peers are stuck in Stage 1 or 2. They are dismissing AI as "slop" or playing with it as a toy. They are waiting for it to be perfect before they take it seriously. **You don't have that luxury.** If you are a Bitcoiner, you have already trained your brain to: - Ignore the FUD. - Look past the volatile hype cycle. - Study first principles. - Optimize for leverage. You don't need to "believe" in AI. You just need to recognize the territory. You have walked this path before. What you learned watching money become software is what you're watching again as thinking becomes software. **"History doesn't repeat itself but it often rhymes" — Mark Twain** --- ## Further Reading - *[The Bullish Case for Bitcoin](https://vijayboyapati.medium.com/the-bullish-case-for-bitcoin-6ecc8bdecc1)* - The essential map for understanding the asset's trajectory. - *[The Bitter Lesson](http://www.incompleteideas.net/IncIdeas/BitterLesson.html)* - Rich Sutton's proof that in AI, leveraging computation always beats human cleverness. - *[Software 2.0](https://karpathy.medium.com/software-2-0-a64152b37c35)* - Andrej Karpathy on why AI is a fundamental shift in how we engineer systems. --- ## PeerSwaps: Rebalancing Channels Without the Chain Date: 2024-06-05 Tags: lightning, peerswap, liquidity URL: https://kirkdesigns.co.uk/writing/peerswaps ## The Context Running a Lightning node at scale means constantly fighting liquidity imbalances. Channels get depleted on one side. Traditional rebalancing means chain fees - expensive and slow. PeerSwaps offers an alternative: swap liquidity directly with peers using atomic swaps, no on-chain transaction required. ## Why This Matters This is infrastructure-level efficiency improvement. Less chain footprint means lower costs and faster operations. The post covers our integration approach, the trust assumptions involved, and the measurable impact on our channel management overhead. --- ## Migrating a Lightning Node: Zero-Downtime Surgery Date: 2024-05-15 Tags: lightning, infrastructure, systems URL: https://kirkdesigns.co.uk/writing/migrating-a-lightning-node ## The Context At Strike, we needed to migrate our primary Lightning node. This wasn't a dev environment. It was a production system handling real money with real uptime requirements. The challenge: move terabytes of channel state without losing a single satoshi or dropping a single payment. ## Why This Matters State management in distributed systems is the only problem that matters. This migration taught me more about operational resilience than any architecture diagram ever could. The post walks through our exact methodology - the tooling we built, the edge cases we discovered, and the one moment where everything almost went wrong. --- ## BOLT12 Playground: Learning by Building Date: 2024-04-10 Tags: lightning, bolt12, devtools URL: https://kirkdesigns.co.uk/writing/bolt12-playground ## The Context Documentation tells you what something does. A playground shows you what it *feels* like. When we shipped BOLT12 support, we realized the barrier to adoption wasn't technical capability - it was developer confidence. Engineers needed a safe space to experiment before touching production. ## Why This Matters Developer tooling is often treated as an afterthought. We treated it as the product. This post covers the architecture decisions behind the playground and why "learning by doing" is the fastest path to protocol adoption. --- ## BOLT12 Offers: A Technical Deep Dive Date: 2024-03-15 Tags: lightning, bolt12, engineering URL: https://kirkdesigns.co.uk/writing/bolt12-offers ## The Context BOLT12 Offers fix a problem that has plagued Lightning since day one: reusable payment endpoints. The old way - BOLT11 invoices - required generating a new invoice for every payment. Fine for one-off transactions. Terrible for subscriptions, donations, or any recurring payment flow. ## Why This Matters This isn't just a UX improvement. It's infrastructure-level capability unlocking. With Offers, Lightning can finally compete with card-on-file payment patterns. The technical implications for Strike's merchant products were significant - and this post walks through exactly how we approached the integration. --- ## Blended Bitcoin Fee Estimations Date: 2024-02-20 Tags: bitcoin, fees, engineering URL: https://kirkdesigns.co.uk/writing/blended-bitcoin-fee-estimations ## The Context Bitcoin fee estimation sounds simple: look at the mempool, pick a fee rate, broadcast. In practice, it's a prediction problem wrapped in a game theory problem. Get it wrong and your transaction sits in mempool purgatory. Get it *very* wrong and you overpay by 10x. ## Why This Matters At Strike's scale, fee efficiency directly impacts the bottom line. We couldn't rely on a single estimation source. We needed a system that weighted multiple signals intelligently. This post details our blended approach - the data sources, the weighting algorithm, and the real-world accuracy improvements we measured. --- ## Twelve Months Building the Zap Desktop Wallet Date: 2019-02-10 Tags: zap, lightning, product URL: https://kirkdesigns.co.uk/writing/twelve-months-zap-wallet ## The Context After the initial launch, Zap became a real project. Contributors showed up. Users showed up. Problems showed up. This post is a retrospective on that first full year - the architecture decisions that worked, the ones that didn't, and the surprising challenges of maintaining open source software with actual users. ## Why This Matters Building in public teaches you things private development never will. You learn to prioritize ruthlessly, communicate clearly, and ship constantly. These patterns - small iterations, tight feedback loops, relentless focus - are exactly what I apply to building agentic infrastructure today. --- ## A Journey into the World of Bitcoin Lightning Development Date: 2018-09-15 Tags: lightning, bitcoin, development URL: https://kirkdesigns.co.uk/writing/lightning-development-journey ## The Context This was 2018. Lightning was brand new. Documentation was sparse. I decided to learn by building. What started as a weekend project became Zap - one of the first user-friendly Lightning wallets. This post captures that early journey: the confusion, the breakthroughs, and the moment it finally clicked. ## Why This Matters Looking back, this piece captures a mindset I still use today: when the documentation doesn't exist, *become* the documentation. Build the thing you wish existed and write about what you learn. The parallels to the current AI moment are striking. The frontier is chaotic, the tooling is rough, and the opportunity belongs to those who ship first. ---