🔮 Bold Little Oracle ▸ docs/overnight/blo-relaunch/README.md
updated 2026-07-15

BLO Relaunch — Stream B (overnight 2026-07-14, round 4)

Round 4 (2026-07-15 overnight) changes: (1) paywall conversion pass on iap-restore (src aaeac1c) — “{price} once” anchor, locked-value sassy tease at the lock moment, benefit bullets, quiet Restore in the modal, brand trust line; tsc clean. (2) de-DE App Store localization — full German metadata set + en-GB/en-AU free keyword slots, APP_STORE_LISTING.md §12 (paste in step C). (3) Creator list web-verified — 20 named DM-ready creators, 5 cut for cause (over band / DMs closed), AM residue down to ~12 min (CREATOR-OUTREACH.md). (4) Reddit two-tier plan — r/SideProject CONFIRMED link surface with post drafted; r/AppHookup killed by its own rules; 200-karma reality check; 10-min logged-in rule checklist (REDDIT-PLAN.md). (5) TT-02/03/04 scripted from the same §F recording + researched hashtag sets, posting Mon/Wed/Fri of approval week (LAUNCH-KIT §1). Channel math updated below.

Round 3 (final) changes: TT-01 + App Store preview got hard calendar slots (no more “fast-follow”); Play Store trigger is now a numeric Decision (5); email-capture promise softened to match the automation that exists (Decision 6); fonts self-hosted (GDPR); Art. 13 microcopy under the form; real Apple-logo SVG in the store badges; site images cropped (status bars) + optimized 7.6MB→~100KB; frame 2 caption made truthful; Impressum ships both entity variants; creator list de-placeholdered (16 verified-name + 4 hashtag slots, URL + recent-post columns, ?ref= promise cut); Apple VAT-ID hardcode removed. Details in STATUS.md.

Bold Little Oracle v1.1.0: lifetime unlock restored at €6.99, ASO rewrite shipped, landing site rebuilt, App Store frames + IG media rendered, launch kit re-anchored with Product Hunt pulled forward, creator outreach + launch emails drafted. Nothing was deployed, posted, or submitted — everything below is launch-ready assets plus the exact human steps.

Round 2 changes (every council must-fix applied; disagreements — there were none material — would be documented here): - Landing page + privacy + support + Impressum built in site/ (the live site still says “Coming soon — join the waitlist”; deploying is MORNING ACTIONS step 0). - Email capture wired above the fold; launch + PH-day emails drafted (EMAILS.md). - Product Hunt moved 2026-08-04 → 2026-07-28 with an explicit slip rule. - Decided: no PH-day discount (see Decisions below). - 5 App Store/PH frames rendered at the correct 1284×2778 with caption overlays, including the previously-missing trust/close frame (media/appstore-frames/out/). - 4 new IG squares rendered + 3 existing = 7 statics; kit honestly re-scoped to “Bluesky + Reddit + IG statics + PH” because the simulator recording Vega’s audit cited is a 0-byte file (videos = 10-min morning re-record, then fast-follow). - 20-creator TarotTok/IG affiliate list + DM/follow-up/PH-ping copy (CREATOR-OUTREACH.md), moved to week 1. - Code (src iap-restore, commit 5b6a072): user-cancel no longer shows “Purchase Failed” (discriminated 'purchased' | 'cancelled' result, both buy surfaces aligned); v1.0 founding users grandfathered — anyone with pre-1.1 draw history keeps unlimited draws + Sassy forever, with a one-time thank-you alert. - Honest revenue math below, with VAT-correct proceeds.

Decisions (made now, not on launch morning)

  1. No PH-day discount. €6.99 everywhere. Three assets already bake in €6.99, and a “€2 off €6.99” claim is legally unsound in Germany days after the €4.99→€6.99 raise (§ 11 PAngV requires the reference price to be the 30-day low — it isn’t). Price flips also burn early buyers. The lever we keep: ASC promo codes (100/month) for creators — free product, zero pricing-law surface. “One price, forever, no games” is now a PH maker-comment talking point.
  2. Founding users are grandfathered, in code. v1.1 would otherwise remove things v1.0 users have today (unlimited draws, Sassy). Install base is tiny, so the revenue cost is ~zero and the goodwill/review upside is real. Review-response template, in case anyone still complains:

    “You were using BLO before v1.1, so nothing was taken away from you — the app detects earlier installs and keeps everything unlocked, free, forever. If you’re seeing a lock anyway the detection missed you: email support@unicorn.land and we’ll fix it same-day.”

  3. PH on the first Tuesday ≥5 days after approval (planned 2026-07-28, slip 2026-08-04). The 30-day window can’t afford its biggest spike on day ~20.
  4. Impressum entity = whichever entity holds the Apple Developer account — one decision, three places (Impressum, ASC trader status, tax routing). Both variants are now IN site/impressum.html (UG active, Einzelunternehmer commented out) — morning is delete-one-block, fill-the-other, whatever the entity call is.
  5. Play Store trigger is numeric, decided now (was Open Question 3): if by day 10 post-approval iOS shows ≥200 installs AND ≥2% install→unlock, ship the Play build that same week (staged in code; listing drafted in docs/google-play-listing.md; est. +10-30 unlocks in the window). If below either number, hold to week 4 and apply REVENUE-MOVES kill-switch logic unchanged. No morning deliberation — read the two numbers off ASC on day 10 and execute.
  6. Email capture promise = welcome week, not a daily forever (round 3). The only automation staged is the 7-day welcome sequence, so the site/POST-15/PH copy now says exactly that (“a card a day for your first week, then launch news”). Optional upgrade (NOT required for launch): batch-build a recurring daily-card queue in Beehiiv from the 144 hand-written readings (~1 hr templating) and restore the “daily” promise once ≥30 sends are queued.

The honest math (VAT-correct)

Proceeds per unlock is NOT €6.99 × 0.85. In the EU Apple deducts VAT first, then takes its 15% (small-dev tier):

Storefront Customer pays Net of VAT Developer proceeds
Germany (19%) €6.99 €5.87 ≈ €4.99
US (sales tax added on top in most states) $6.99 $6.99 ≈ $5.94

Blended (EU-heavy for a German-based launch) ≈ €5.20/unlock. The earlier “€5.94 net” figure was ~18% too optimistic.

$1000 (≈ €920) in month one therefore needs ~175-180 unlocks, not ~150. The stream’s own day-30 product gate (500 installs × 2%) is ~10 unlocks ≈ €50 — a signal gate, 17x short of the money gate. Nobody should discover that on day 30.

Path to ~175 unlocks — named channels, honest per-channel estimates (month 1)

Channel Action staged Realistic unlocks (round 3 → round 4)
Creator affiliates (20 verified DMs, week 1) CREATOR-OUTREACH.md 5-25 (unchanged range, but list is now verified — probability of actually sending 20 DMs went way up)
Product Hunt (Tue 07-28) LAUNCH-KIT §2 5-20
ASO — EN rewrite + de-DE localization + en-GB/en-AU keyword slots APP_STORE_LISTING.md §1-6, §12 10-30 → 13-38 (DE is the home storefront at €4.99 proceeds and previously matched ~nothing in German)
TikTok/IG videos — 4 posts (TT-01 Fri 07-17; TT-02/03/04 Mon/Wed/Fri approval week, same source recording) LAUNCH-KIT §1 5-25 → 8-32 (four lottery tickets, zero extra recording time)
Beehiiv list — launch + PH emails + welcome seq EMAILS.md 3-10
Reddit — Tier A (r/SideProject confirmed + 2 conditional) + Tier B rule-checked REDDIT-PLAN.md 3-10 → 4-14
IG statics (7 rendered) media/ig-out/ 2-8
Bluesky (new account, 11 posts) LAUNCH-KIT §1 0-4
Subtotal (before conversion uplift) 40-151
Paywall conversion pass (src aaeac1c) — price anchor, locked-value tease, benefits, quiet restore multiplies install→unlock on EVERY row above if it moves 2% → 2.5-3%, subtotal becomes ~50-190
Total, honest planning range ~45-175 (mid-case ~90)

Conclusion, stated plainly (round 4): the staged range now brackets the ~175-180 unlock target at its top end instead of falling short of it — but the top end still requires videos posted on schedule, ≥3 creators active, AND the paywall pass actually moving conversion (unmeasurable directly — no analytics; the only readout is day-10/day-30 ASC unlocks-per-install). Mid-case is still ~€470 net, roughly half the $1000 goal. The two levers that most change the curve are unchanged: (a) the four TikTok posts actually going out, (b) 3+ active creator affiliates. Play Store (Decision 5, numeric day-10 trigger) is the month-two volume lever. If day-60 still shows <500 installs or <2% conversion, REVENUE-MOVES’ kill-switch logic applies unchanged.

What was built (round 1 recap, still true)

What’s in this directory

README.md              ← you are here
LAUNCH-KIT.md          ← posts (re-anchored), PH listing, media backlog
EMAILS.md              ← Beehiiv launch + PH-day emails, final copy
CREATOR-OUTREACH.md    ← 20 web-verified creators, DM/follow-up/PH-ping copy, tracking table
REDDIT-PLAN.md         ← two-tier Reddit plan: verified link surfaces + rule-check checklist
site/                  ← DEPLOY-READY landing page (index/privacy/support/impressum + images/)
media/appstore-frames/ ← 5 HTML templates + render.sh + out/*.png (1284×2778, final)
media/ig-templates/    ← 4 new IG square templates + render.sh
media/ig-out/          ← 7 IG-ready 1080×1080 PNGs

The site is self-contained static HTML on the Unicorn.Land design system (--ul-* tokens, Outfit) with BLO’s dark/gold brand as the accent layer. The email form posts to the existing /api/subscribe Pages Function (same-origin, Beehiiv-backed) — see step 0 contingency below.


MORNING ACTIONS (Joshua only — exact click-paths)

Est. ~90 min active + build wait. Order matters.

0. Deploy the landing site (~15 min) — DO THIS FIRST

Everything (App Store marketing URL, all 15 posts, PH listing, Reddit profile) points at https://boldlittleoracle.unicorn.land, which currently says “Coming soon”. 1. Decide the operating entity (Decision 4). site/impressum.html now contains BOTH variants — UG (active) and Einzelunternehmer (commented out): keep one, delete the other, fill the [PLACEHOLDER]s (address, phone; UG only: Registergericht/HRB, USt-IdNr). 2. Deploy overnight/blo-relaunch/site/ to the existing Cloudflare Pages project that serves boldlittleoracle.unicorn.land. Preferred: npx wrangler pages deploy site/ --project-name=<the BLO pages project>. Note: the live waitlist site’s source was NOT found on this Mac — if the project has a functions/ dir for /api/subscribe, deploy from a copy that includes it. 3. Verify before submitting the app: these must return 200 with real content — /, /privacy, /support, /impressum — and the email form must actually subscribe (test with a +tag address). Contingency: if /api/subscribe 404s after deploy (direct-upload deploys can drop Pages Functions), grab the Beehiiv embed code (Beehiiv → Grow → Subscribe forms) and swap it into the .capture block in index.html — 5 minutes.

A. Create the IAP product in App Store Connect (~10 min)

  1. appstoreconnect.apple.com → AppsBold Little Oracle.
  2. Monetization → In-App Purchases+ → Type Non-Consumable. Reference Name Lifetime Unlock, Product ID com.unicornland.boldlittleoracle.unlock (must match exactly — hardcoded in the app).
  3. Availability: all countries. Price Schedule: base Germany → €6.99 tier.
  4. App Store Localization (English U.S.): Lifetime Unlock / Unlimited draws + Sassy mode, forever.
  5. Review Information: screenshot of the paywall (any ≥640×920 PNG; grab one in simulator) + note: “One-time non-consumable unlock. Trigger: draw twice in one day, or tap the Sassy toggle.”
  6. Leave “Ready to Submit” — a first IAP ships with the app version (step C).

B. Build + submit build 10 (~5 min active)

cd /Users/joshua/Projects/Unicorn.Land/bold-little-oracle/src
git checkout iap-restore   # now includes aaeac1c (paywall conversion pass; also 5b6a072 cancel-silence + grandfathering)
pnpm install
npx tsc --noEmit
eas build --platform ios --profile production
eas submit --platform ios --latest

If expo-iap pod install fails in the first minutes of the EAS log, stop and ping the overnight branch — it autolinked clean in dependency resolution.

C. New app version in App Store Connect (~20 min)

  1. App page → + → iOS App1.1.0.
  2. Paste from APP_STORE_LISTING.md: Name §1, Subtitle §2, Promo §3, Description §4, Keywords §5, What’s New §6. Review notes §11. 2b. German localization (~5 min, same submission): version page → language selector (top right) → add German → paste every field from APP_STORE_LISTING.md §12 (name/subtitle/promo/keywords/description/What’s New + the German IAP localization §12.7). Then add English (U.K.) and English (Australia) reusing the en-US copy but with the §12.8 keyword fields — two free extra keyword slots. EN screenshots are fine on all of them (§12.9); do not delay the submission for localized frames.
  3. Screenshots (6.5”/6.7”): upload the five rendered frames from overnight/blo-relaunch/media/appstore-frames/out/ in order 1→5. Frame 2’s caption now reads “Every card. Two voices.” so the render is truthful as-is (re-capturing the same card in both voices is optional polish, no longer required). App Preview video: upload the 30s take from §F in the same screenshot section (slot 1). If it isn’t ready or ASC rejects the format, submit WITHOUT it — do not delay the submission — and attach it in the first metadata update.
  4. Select build 10 once processed; add Lifetime Unlock in the version’s In-App Purchases section; pricing stays Free; Submit for Review.

D. Sandbox-test before/while in review (~15 min, on device)

  1. ASC → Users and Access → Sandbox Testers → create one if none.
  2. TestFlight build 10; iPhone Settings → App Store → Sandbox Account.
  3. Draw → draw again → sheet shows €6.99 localized (no “€€6.99”). Buy → premium badge, unlimited, Sassy on.
  4. Cancel test (new behavior): start a purchase, dismiss the Apple sheet → app must return silently, no “Purchase Failed” alert.
  5. Delete → reinstall → Settings → Restore Purchases → premium returns.
  6. Airplane mode → paywall shows fallback price, purchase fails gracefully.
  7. Grandfather test: install v1.0 (build 9) from TestFlight, draw once, update to build 10 → “You were here first” alert + everything unlocked.

E. Distribution prep (today, ~35 min)

  1. Account inventory (know what exists before creating anything): - Instagram: @boldlittleoracle EXISTS (prior Meta Graph API setup — bold-little-oracle/docs/instagram-api-setup.md). Confirm you can log in; all IG-A..E posts + Reels publish from it. - TikTok: does NOT exist. Create @boldlittleoracle today (5 min — TT-01 fires Fri 07-17). Bio: 72 oracle cards, two voices each — gentle or sassy. your call. Link: boldlittleoracle.unicorn.land. - Bluesky: does NOT exist → step 1.
  2. Create @boldlittleoracle on Bluesky (3 min — POST-06 fires Thu noon). Same bio + link as TikTok.
  3. Start u/obadiah_finch karma warm-up today: 3-5 genuine comments/day in r/tarot + r/oracle + r/oraclecards. Revised target: 200 comment karma by Wed 07-22 (the old “~50” was low per 2026 enforcement bands — REDDIT-PLAN.md finding 3; slip dates in LAUNCH-KIT unchanged). 2b. Reddit rule check (~10 min, logged in): run the per-sub checklist in REDDIT-PLAN.md — it go/no-goes the two conditional link subs (r/indieapps, r/iosapps) and de-risks POST-03/05/08/12. r/SideProject is already verified (post drafted); r/AppHookup is verified DEAD (rules exclude freemium — don’t).
  4. Beehiiv (~10 min): step 0: Settings → confirm double opt-in is ON (the site promises confirmation-first, and DE list hygiene expects it). Then activate the 7-day welcome sequence (docs/email-welcome-sequence.md) for new subscribers; schedule Email 1 (EMAILS.md) to the existing list for approval day; leave Email 2 drafted.
  5. Draft the PH listing (PH → My products → New product) from LAUNCH-KIT §2; set launch Tue 2026-07-28 00:01 PT.

F. Record the two missing video sources (~15 min, TODAY Wed 07-15)

docs/screenshots/simulator/card-draw-recording.mp4 is a 0-byte file — there is no usable recording despite the audit’s claim. In simulator (xcrun simctl io booted recordVideo blo-draw.mov): record open → shuffle → flip → sassy reveal (~20s), and one 30s take for the App Store preview. These are no longer “fast-follow” — both have hard slots: the 30s preview uploads with the 1.1.0 submission (step C.3), and the 20s take becomes TT-01, posting Fri 2026-07-17 12:00 (copy + slip rule in LAUNCH-KIT §1). Unscheduled = never recorded; that loop is now closed.

G. Compliance + money plumbing (~15 min, before submitting is ideal)

  1. EU DSA trader status: ASC → Business (or App Information → Digital Services Act). Verify/complete trader status for the developer account — mandatory for paid/IAP apps in the EU; name, address, email, phone become public on the EU product page. (Same address as the Impressum — one decision, step 0.)
  2. Entity + VAT routing: confirm which entity signed the Paid Apps agreement (ASC → Business → Agreements, Tax, and Banking) and that its USt-IdNr is on file with Apple. Apple proceeds are reverse-charge B2B services to Apple Distribution International Ltd (Ireland): no German USt on the invoice, but they go into Zusammenfassende Meldung + § 18b UStG quarterly — this applies even under § 19 Kleinunternehmer treatment of domestic turnover. If the account is personal (Einzelunternehmer) and no USt-IdNr exists, apply at the BZSt this week (bzst.de → USt-IdNr-Vergabe, free, online) — you cannot file a ZM/§ 18b without one, regardless of § 19 status.
  3. Add a line to the MIA/CHUG filing tracker: “BLO Apple proceeds → ZM + § 18b quarterly, reverse-charge, Apple Distribution International Ltd (Ireland) — take Apple’s VAT ID from the actual monthly Apple financial report/invoice; do not trust any constant written in a planning doc.”
  4. Creator payouts (outbound 30%): each PayPal/Wise payout needs an invoice from the creator, or at minimum a written payout confirmation (name, country, amount, period) kept on file. Payouts to non-DE creators are inbound cross-border services → § 13b reverse-charge accounting, tracked alongside the Apple line in the MIA/CHUG filing tracker.

Week 1 (Wed-Fri)


Must verify on-device (cannot be verified headlessly)

Open questions for Joshua

  1. LockedCard “dismiss” behavior (free user can hide the upsell after daily draw): kept as-was. Make the paywall stickier only if day-30 conversion is <1%.
  2. Which entity for Impressum/DSA/Apple agreement (Decision 4 — needs your call; MIA UG is the obvious candidate if it holds the developer account).
  3. ~~Android/Play release timing~~ DECIDED — see Decision 5 (numeric day-10 trigger: ≥200 installs AND ≥2% install→unlock → ship Play that week; else week 4).