Writing & build logs.
Essays on software development, web builds, and AI tooling. Plus build notes from what I'm actually working on right now.
Five sprints inside one PR: what an iOS budget app's side-branch pattern reveals about tracking
PR #10 on an iOS budget app landed five complete features in a single merge. Each devlog entry reads as a self-contained sprint brief with its own type, its own boundary, its own completion signal. PR-level granularity and feature-level granularity are not the same number.
The dedup layer had three hash schemes. CDImportSource replaced them — and four banks validated with zero per-bank code.
The an iOS budget app import layer had three coexisting hash schemes with no shared contract between them. Collapsing them into CDImportSource — a unified source-attribution model — was the structural prerequisite for universal CSV and PDF parsers that validated across Monzo, Halifax, Revolut, and HSBC.
The S-4 cohort made two editorial pipeline decisions. I shipped them.
Two weeks of UK Calculators editorial pipeline sprints ended with two decisions that came from the cohort data, not preference: live Bank of England rate fetches and a constrained LLM composer. The pipeline silently stalled for four days after shipping.
Cursed Energy Phase C: wiring an iOS budget app's quest system to real transaction history
The an iOS budget app gamification layer had quest cards, a claim button, and a streak counter. None of it read from actual spending. Replacing a hardcoded array with a transaction-aware QuestGenerator turned decorative chrome into a feedback loop that surfaces real patterns.
Device QA found three regressions. The simulator had approved them all.
Round-2 device QA on bb finance flagged a navigation stack popping two levels instead of one, ProMotion locked at 60Hz on a 120Hz panel, and category rules over-reaching on shared word fragments. None of them showed in the simulator.




