Ship log · iter #29

Iteration 29 ship log

2026-05-10 · continued autonomous /loop

On this pageWhat shipped Files changed inventory Why this matters Status snapshot What still needs work Next 5 recommended autonomous tasks Cumulative iter 1-29

Date: 2026-05-10 (continued autonomous /loop)

What shipped

This iteration found and fixed a real conversion-killer bug, then ensured the fix survives future regenerations.

Bug caught + fixed: hardcoded ICP on every unlock page

Discovered: All 188 unlock pages were showing the same hardcoded "Director of Revenue Operations at a B2B SaaS in the $5M-$50M ARR band..." teaser regardless of which product was being unlocked. A buyer comparing /unlock/bookkeeper-ai/ vs /unlock/discovery-call-ai/ saw identical "Locked: full schema" content. That's a credibility-destroying signal: it screams template-not-real.

Fixed: Added _extract_dossier_preview(slug) helper to regen-unlock-pages.py. Reads the private full.md for that product, pulls section 3 (named ICP) and section 5 (what it does) first paragraphs, em-dash-strips, html-escapes, falls back to friendly text if missing. Patched the locked teaser to render real per-product content.

Verified across 4 products:

A buyer comparing 3 ideas now sees 3 distinct, credible teasers, not template-cookie-cutter content.

Wired post-regen injector hook

Discovered that the unlock regen wipes the iter 27 objection handler block (which is injected after generation, not part of the generator). Future cron-driven regenerations would have left a 60-min gap with no objection handler.

Fixed: Added a post-regen subprocess hook to regen-unlock-pages.py that calls objection-handler-injector.py immediately after writing pages. Tested: regen now writes pages → injects objections automatically. No race condition with cron.

Em-dash discipline

The preview extractor proactively strips em/en dashes from upstream dossier content during extraction. Verified 0 em-dashes on all 192 unlock pages.

Files changed inventory

Modified

All .bak backups preserved.

Why this matters

This was the single highest-impact bug in the buyer-path funnel. The unlock page is where someone decides whether to spend $5. Showing them an obviously-fake template ICP on every product was actively harmful.

Now the unlock page reads as: "Here's the named buyer this dossier is about, here's what the product does in their words, here's a blur veil over the rest. Pay $5 to read it." That's the credible version.

Combined with iter 27's objection handler and iter 28's trust-signal block on builds pages, the funnel is now:

  1. Builds page: trust signals (Adoptability, Fermi math, named axes)
  2. Unlock page top: per-product preview with real ICP + what-it-does + blur veil
  3. Unlock page mid: objection handler with product-specific concerns
  4. Unlock page CTA: clear $5 unlock vs $99 adopt vs operator partnership

Status snapshot

What still needs work

Same Wes-side as before:

  1. Stripe wiring (30 min)
  2. Email-send for auto-fulfill
  3. First real traffic push
  1. Same-bug-class audit - check other generator-injector pairs for the same regen-wipes-injection issue (trust-signal, utility-bar, hero-insight, pricing-band, etc.). If any are wiped by regenerators, wire post-regen hooks like iter 29.
  2. Hero-polish second pass - Claude CLI on the bottom-50 Adoptability landing pages.
  3. Per-product /how-it-works/ page - surface implementation_plan + tech_stack as a public sub-page.
  4. More audience pages - "AI ideas under 30 days to launch", "AI ideas under $5k to launch".
  5. Newsletter signup confirmation - when someone subscribes via /fresh/, route to a thank-you page that recommends 3 ideas.

Cumulative iter 1-29

The Wishdeal Factory buyer path is now genuinely tight. From "curious" → "$5 decision" the buyer:

What's unique vs typical AI-idea catalogs: the honest disclosures, the per-product preview content, the dossier methodology page, the changelog showing real iteration. Together these read as a real operator's product, not template slop.

← PreviousIter #28 Next →Iter #30