# Wishdeal Factory buyer-path - iteration 40 ship log

**Date:** 2026-05-11 (continued autonomous /loop)

## What shipped

5 items. Key insight: switching em-dash discipline from "patch each generator" (whack-a-mole) to "universal safety net" (15-min sweep cron).

### NEW: universal em-dash sweep cron

After 15 iterations of patching individual generators with `_no_dash` wraps, em-dashes kept reappearing when new generators were discovered. The whack-a-mole pattern was working but never definitively closed.

**Shipped a structurally different solution**: `em-dash-sweep.py` that walks the entire `/srv/sites/factory/` HTML tree every 15 minutes and strips any em/en dashes it finds. Idempotent. 0.2s execution time across 2600+ files.

Cron: `*/15 * * * *`

This means: **worst-case em-dash exposure for any buyer is now 15 minutes.** A buyer browsing the catalog will essentially never see one.

Combined with the existing 15 source-level patches, this creates a defense-in-depth:
- **Layer 1**: 15 generators+scripts strip dashes at write time
- **Layer 2**: 3 injectors strip dashes on output
- **Layer 3**: Universal sweep cron catches anything that slips through within 15 minutes

The trade-off: we lose the ability to catch the bug at the source. But for em-dashes specifically (zero semantic value, never legitimate), this is fine.

### Initial sweep

41 em-dashes had re-accumulated in 13 files since iter 39 (admin pages, top-level index files, log/index.html). Single sweep cleared all of them. Factory-wide count: 0.

### SESSION-MASTER v6

Replaced v5 (covered iters 1-36) with v6 covering iters 1-40 (~32 hours of autonomous work). New section: "Em-dash invariant defense in depth" documenting all 3 layers.

## Files changed inventory

### New
- `/home/ubuntu/factory/director/em-dash-sweep.py` (universal sweep, 30 lines)

### Modified
- `/srv/sites/factory/log/SESSION-MASTER.md` (v5 -> v6)

### Re-rendered / cleaned
- 13 HTML files (41 em-dashes stripped)

### New cron
- `*/15 * * * *` em-dash-sweep.py

## Why this matters

15 iterations of source-level patches taught us: every generator that touches upstream content is a potential em-dash leak. The autonomous studio will keep adding generators. Each new one is a potential regression vector.

The universal sweep is the right shape: instead of fighting every leak, accept that leaks happen and clean them quickly. 15-minute cadence is fast enough that no realistic buyer session encounters an em-dash.

This pattern is generalizable: any "must never be in output" rule could be enforced via a similar sweep. Future iterations could add similar sweeps for:
- Stale dates
- Empty alt-text on visible images
- Missing JSON-LD on product pages
- Etc.

## Status snapshot

- 200+ products in catalog (Director still ticking)
- 62 buyer-facing pages
- 59/59 health endpoints passing
- Sitemap: 1379 URLs
- 0 em-dashes across 2600+ HTML files (verified)
- Em-dash defense in depth: 15 source patches + 3 injectors + universal 15-min sweep
- 11 broken links (admin/log only)

## What still needs work

Same Wes-side as always:
1. Stripe wiring (30 min)
2. Email-send for auto-fulfill
3. First real traffic push

## Next 5 recommended autonomous tasks

1. **Hero-polish second pass** - Claude CLI on bottom-50 Adoptability products.
2. **Per-product /how-it-works/ sub-page** - lightweight new content surface from implementation_plan + tech_stack.
3. **Catalog card hover preview** - hover shows first line of dossier teaser.
4. **Run promote-artifacts.py** to fill more /about/ pages on new products.
5. **Audit /factory/today/, /factory/hotlist/, /factory/founders/** for stale content.

## Cumulative iter 1-40

The factory is genuinely production-ready as far as autonomous polish can take it:

**Surface quality:**
- 200+ products, 62 buyer-facing pages, 10 audience landings
- Per-product objection handlers + trust signals + previews + per-product preview teasers
- Money-back guarantee at every CTA
- Honest disclosure + graduated proof page + adoptability methodology
- 0 em-dashes across all 2600+ HTML files

**Durability:**
- 15 generator+script source patches
- 3 injectors enforcing on output
- Universal 15-min sweep cron as safety net
- Weekly .bak cleanup cron
- 59 health endpoints, all passing
- 11 broken links (admin-only)

**Monitoring:**
- Director + watchdog alive
- ~104 cron entries
- Real-time intent capture + Telegram alerts (with internal-test filter)
- Admin morning briefing + inbox + captures + health + link audit dashboards

The product is structurally ready to charge $5. Remaining work is exclusively Wes-side: Stripe + traffic push.
