The Great Trial-Promise Rollback
- Projects
- 28
- Commits
- 91
- Lines
- +383k / −3.9k
- Files
- 2871
- Claude time
- 23h
- Tokens
- 17.8M
Commits by day
Where the work went
LuckyCoin32%
Park'd25%
PoultryPal18%
Arby16%
Lucky RNG9%
Most weeks the work is scattered across the portfolio by accident. This week it was scattered on purpose: the same bug had quietly taken root in nearly every app we ship, and we spent a day yanking it out everywhere at once.
The paywall was writing checks StoreKit wouldn't cash
Across the catalog, our paywalls said some version of "start your free trial" — in hero copy, in FAQ answers, in the little caption under a locked Finances screen. The problem is that a free trial is a one-time thing. If you've already used it, StoreKit knows, and it will happily charge you on day one while the screen still promises seven free days. Not a great look, and not accurate.
So we went down the list and gated that copy on real eligibility: CoinIdentifier, ComicBooks, LuckyCoin, LuckyGame, LuckyNote, LuckySale, LuckySap, LuckyVinyl, LuckyFind, NationalParks, PoultryPal, and PriceGuide on iOS, plus the Android builds of LuckyCoin, Parkd, and PriceGuide. Now a trial-ineligible user sees copy that matches what will actually happen when they tap the button. Several of these came in through support tickets (the commit hashes are right there in the messages), which is usually how you find out a bit of boilerplate has been lying to people in a dozen places. While we were in LuckyFind's FAQ, we also translated the newly conditional answer for es-rMX, since that string lives locally and doesn't ride along with the rest.
It's not glamorous work, but it's the kind of thing that only a solo shop with a shared paywall lineage can fix in an afternoon — and only a solo shop would let the same bug propagate to a dozen apps in the first place.
LuckyCoin: getting people their collections back
The more serious thread this week was account data. LuckyCoin had a device-transfer bug where guest collections could get orphaned — you move to a new phone, sign in, and the coins you'd been tracking aren't attached to the account you land on. We fixed the fragmentation, verified that migrated sessions actually honor the iCloud Keychain sync contract, and added end-to-end tests plus DEBUG diagnostics so we can see the migration working instead of hoping it does. The Android side got the matching repair: guest data loss now handled through Google sign-in linking with a recovery prompt, so a guest who signs in gets a path back to their stuff rather than a fresh empty ledger.
There was also a smaller but annoying accuracy bug: add or remove coins and the count would update while the denomination and country totals stayed stale. The value was cached with a guard that assumed zero coins, and that guard went stale the moment coins existed — so we recompute the row value whenever there's anything to recompute.
Unrelated to the app itself, LuckyCoin's newsletter machinery got a productive few days: a Node 20-to-22 runtime bump (which promptly broke because firebase.json was pinning the old runtime over package.json, since fixed), recovery of five production functions whose source had gone missing — reconstructed from GCS build archives, which is a sentence no one wants to write — plus editorial guardrails against markdown leaking into sends and future events described in past tense, a Thursday scorecard email per edition, a Wednesday nudge for unapproved proofs, and an optional send cap for a cautious warm-up.
Parkd on Android, still chasing the iPhone
Parkd's Android build spent the week closing the gap with its iOS sibling. Park photos were vanishing when the National Park Service CDN threw intermittent 404s, so both the content-detail images and the loader now recover gracefully instead of leaving blank gaps. We ported the iOS image caching for trip-photo thumbnails and launch prefetch, matched the paywall hero gradient, map markers, nav titles, and tab bar, and fixed the visited-toggle so it behaves like iOS — a blank trip and a confirmation when you unmark, and "not gone here yet" that actually reflects the park you're looking at. Favorited parks get their red heart on the summary card. We also ported the hidden dev cheats (long-press for demo data, triple-tap for a premium override), documented them, wrote tests for the demo-data invariants, and drafted the Play Store listing copy. Steady catch-up work, one screen at a time.
PoultryPal's website grew feathers
The PoultryPal marketing companion got the most visible facelift: a Bricolage Grotesque display face with tabular figures, an on-brand hen illustration in the hero, baby chicks that scroll-reveal from alternating margins, and illustrated cover art across collections, breeds, and guides. On the substance side, we added 17 data-driven "best chickens for X" collection pages, per-breed OpenGraph cards, breed comparisons and deeper content, and swapped in real (Wikimedia-verified) breed photos on both the breed pages and the card thumbnails. Production now points at getpoultrypal.com with Vercel auto-deploy confirmed.
Rounding out the week, RandomBay and RandomNum both traded their emoji favicons for real app icons across the usual 16/32/ico/apple-touch set — most of RandomBay's enormous line count is generated icon and asset churn, not hand-written code — and RandomBay's weekly refresh got moved to a launcher under ~/.local/share after macOS's privacy layer kept killing it with a permissions error.
A fleet-wide honesty fix on the paywalls and a real repair to how LuckyCoin holds onto people's collections: two very different bugs, both the kind that erode trust quietly if you leave them alone. Good week to have cleared them.





