# BaoLife — In-App Validation & Release Hardening — PROGRESS

**Goal:** Drive the real iOS app, find UX/content/correctness bugs tests miss, fix + verify + ship each, until release-ready. Method: drive app (slow time to beat event cadence) or code-inspect → find → root-cause → fix → verify → ship.

**Status:** ✅ DONE — `full_outcome_complete: true` (release-readiness audit T999). Every major surface validated; 7 fixes shipped + prod-verified; all owner-decisions resolved; remaining items are documented diminishing-returns. Suite 150 files / 1714 / 0 failed.

## Final summary (7 shipped commits this loop)
| Commit | Fix |
|--------|-----|
| `662c8575` (iOS) | Health-clobber parse + GPA 0-100→4.0 scale |
| `58d0d3c4` | Dilemma choices: diamonds → money (12 mis-ports) |
| `98bf9d1a` | Adults-only (18+) romance (content-safety) |
| `27a44532` | Dead daily quests wired (safe subset) + date/gift 18+ gate + socialize cleanup |
| `c03d4e71` | Deleted orphaned premium dating dead code (472 lines) |
| `4d1af840` | Real account deletion (persist + 30-day purge job) |

**Owner-decisions resolved:** under-18 existing data → leave (test data); orphaned premium dating → delete; account deletion → implement.
**Diminishing-returns backlog (post-release):** work/money/class quests (deferred); IAP server-side receipt validation (acknowledged stub); daily-reward numbering (ruled working-as-intended).
**iOS note:** `662c8575` reaches users in the next app build; server fixes are live.

**Baseline:** HEAD `98bf9d1a`; tsc clean; vitest 147 files / 1697 / 0 failed.

## Shipped this loop

| Fix | Commit | Surface | Notes |
|-----|--------|---------|-------|
| Health displayed 0 (parse clobber) | `662c8575` (iOS) | Home stats | `else { health = 0 }` clobbered default 100 |
| GPA 0.0 (scale gap) | `662c8575` (iOS) | Education | linear (GPA/100)*4 to match server |
| Dilemma costs charged diamonds not money | `58d0d3c4` (server) | Life dilemmas | all 12 diamondCost→moneyCost |
| **Adults-only (18+) romance** (content-safety) | `98bf9d1a` (server) | Dating | gated all romance-creation paths 18+ |
| (offline milestone credit — prior goal) | `72a4f0a8` (server) | Offline loop | |

## Surfaces validated CLEAN

Onboarding/FTUE; core loop (time/energy/stats); event system end-to-end (questionEvent→choice→cost→effects→"What changed"→Life Timeline); education (enroll/GPA/academic perf); job application (occupation list + requirement gating); life goals (toast + money reward); monetization tiers (energy refill 10-50💎, time skip 5-100💎, IAP packs 100-2000💎 — diamonds correctly used as premium sinks); diamond/money audit isolated to dilemmas (rest clean). Stress → mood emoji (not a hidden dead stat).

## ⚠️ Open owner-decision (flagged, NOT actioned) — T005

**Existing-data migration for under-18 romantic relationships.** The 18+ gate (`98bf9d1a`) stops NEW under-age romance but does NOT retroactively change already-saved players who already have an under-18 partner. A one-time production-DATA cleanup (break up / age-up existing under-18 links) needs Craig's explicit go-ahead. Prep-the-plan is safe; running it is not. **Awaiting Craig's decision.**

## Not yet driven in-app

"Do an Activity" stat loop; daily rewards/quests UI; in-app Dating actions (Date/Gift/Chat); Messaging/Chat; Store item purchases; Profile sheet deep-dive; Settings (data export/account deletion).

## Wave log

| Wave | Status | Surface | Result |
|------|--------|---------|--------|
| T001-T004 | ✅ SHIPPED `27a44532` | activity/retention/dating | wired dead daily quests (safe subset) + date/gift 18+ gate + socialize cleanup |

**Wave 1 result (T001 scout → T002 judge → T003 worker → T004 ship):** Found most daily-quest types were uncompletable (retention hooks had no callers) + the 18+ romance gate had a gap on date/gift. Fixed + shipped: wired complete_activities/spend_energy/study/increase_affinity (single-fire in performActivity), 18+ gate on date/gift (player+partner), dropped meaningless socialize affinity. 148 files / 1703 tests / 0 failed.

## Resolved rulings (no code)

- **T008 daily-reward divergence → WORKING AS INTENDED.** The two day-number formulas converge on every reachable state; the divergence only appears on an unreachable fixture, and the security test correctly anchors the grant to the earned streak (anti-over-claim). "Fixing" it would weaken the guard. No change.
- **T006 work/money/class quests → DEFERRED (known-minor).** Passive auto-completing quests; gross-vs-net mismatch + no hours source + a prorated-offline double-count trap. 8/11 quest types already work. Low value, high risk → post-release gap.

## Open follow-ups

- **T006 (queued):** wire work_hours/earn_money/attend_class quests through an offline-safe path (dual online/offline finance loop — double-count hazard; needs Judge contract).
- **T008 (active):** daily-reward day-number divergence (claim vs display) — needs a security/semantics ruling (a security test guards the day-7 case); I can resolve this autonomously.
- **T005 (✅ resolved — won't-do):** Craig: existing under-18 data is test data, cleared before release — no migration needed (the 18+ code gate suffices).
- **T007 (✅ done `c03d4e71`):** Craig chose DELETE — removed the orphaned premium `dateActivities.ts` (452 lines dead code) + its barrel re-export.

## Receipts / notes

- Full findings + setup: memory `project_inapp_validation_loop.md`.
