product

DreamPro Coaching — AI-Persona Dogfood + Data Backfill (Phase 0 data)

A plan to enroll AI personas as coached clients so the coaching surfaces (coach review dashboard, cohort leaderboard, brief-generator inputs, analytics) are populated and dogfoodable from day one — before a single real user, and so John's demo never shows empty shelves. Mirrors how the platform already uses AI personas: the writer fleet seeds Graphene, Workout Window AI users fill thin squads, the cafe contest auto-fills with bot entries.

Status (2026-06-14): seeding SHIPPED in scripts/seed-dreampro-coaching.ts via --personas N — enrolls AI personas as is_seed coached clients (seed channel partner + coach + referral code → membership + program clone + Coach Seat each; every 3rd seat autonomous). Briefs are generated on demand (the dashboard "Generate brief" button / the coach_brief cron), not by the seed (keeps it $0-LLM). Workout-Window check-in backfill was skipped (checkins require a non-null chain_id FK — heavy); adherence shows from real persona check-ins + journaling trends instead. Also available in the UI — a super-admin seed panel on /dashboard/coaching (Generate templates · Enroll N persona clients · Wipe), backed by POST /api/coaching/admin/seed/* (coaching-seed.ts). Companion to The DreamPro Coaching System, Coach Seat, and Channel economics.


0. Why + the two non-negotiable guardrails

Why: the Coach Seat (the AI-draft review queue) and the brief generator are hard to build well against an empty database. Personas-as-clients give us:

  • realistic Throughline trends + Workout Window adherence for the AI coach to read and draft against (we can dogfood the brief generator immediately),
  • a populated cohort leaderboard + a believable demo for John,
  • analytics with shape (funnel, retention curves) before real traffic.

Guardrail 1 — is_seed everywhere, wipeable. Every persona-generated row (membership, seat, check-in, trend, competition entry, decision) carries is_seed = true (or the table's equivalent flag) so it is cleanly excluded from real counts and removable in one command — exactly the discipline the existing seed scripts already follow (seed-open-energy-progress.ts, dreams.is_seed).

Guardrail 2 — personas NEVER touch real money. This is the load-bearing one. The channel-economics split (override + payouts) must skip is_seed memberships entirely — no creator_earnings rows, no Stripe transfers, no override accrual for a persona "subscription." Reuse the platform's existing isAiPersonaUserId() guard (the same check that sits before stripe.transfers.create so the cafe contest never wires prize money to a bot). Bots populate the dashboards; only humans move money.


1. What we reuse

  • ai_personas + their associated user ids — personas already have MBTI/backstory and journal (so they already produce mood/energy/sleep signals via note_analyses, which is exactly the Throughline trend input).
  • Workout Window AI users (migration 026, ai-profile-generator.ts) — already model check_in_probability per persona; the same probability drives coaching check-in simulation.
  • The seed pattern — service-role script, is_seed flag, --generate/--wipe/--stats (seed-dreampro-coaching.ts is the natural host).
  • isAiPersonaUserId() — the money guard (Guardrail 2).

Nothing here needs a new persona system — it wires existing personas into the coaching tables.


2. The persona-coached-client model

For each selected persona, in one seeded transaction:

  1. Enroll as a client — a coaching_memberships row (is_seed = true) under a seed coach (an AI coach persona) → that coach's channel partner. referral_code points at a seed code so attribution analytics have shape.
  2. Clone a program — clone one of the seeded fitness templates ("30-Day Reset" / "Couch to 5K" / "12-Week Strength") into the persona's account (dreams.is_seed = true).
  3. Set up a Workout Window — activity type + window + (fuzzed) location, so the persona joins chains/squads.
  4. Seat them — a coaching_seats row held by the AI coach persona, with a supervisor_user_id = a seed human-coach account for the supervised-tier demo.

A spread of personas across all three programs + a couple of cohorts gives the leaderboard and roster realistic variety.


3. Simulating the journey (forward, going)

Per-persona adherence probability (reuse check_in_probability; vary by MBTI so some are eager, some flaky) drives daily behavior:

  • Workout Window check-ins — photo check-in rows (is_seed) on most days for high-adherence personas, gaps for low ones → realistic streaks + at-risk signals.
  • Trends — personas already journal; their note_analyses (mood/energy/sleep) flow through the existing Throughline trend path, no new generation needed.
  • Program progress — periodic step completions advance the clone's progress %.
  • Competition entries — they accrue leaderboard points (clone/completion/build).

Two ways to drive it:

  • Seed-once + backfill (§4) for an instant populated state (recommended for the demo), and/or
  • A low-rate cron that ticks daily so the data stays alive (env-gated, default-off, recordHeartbeat + CRON_REGISTRY toggle per RECURRING_TASKS.md, is_seed rows only). Keep it cheap — check-ins/progress need no LLM; only AI-coach briefs do (§5).

4. Backfill (historical) — "if it makes sense"

It makes sense for the demo + for dogfooding trend/streak/leaderboard UIs: generate backdated check-ins, step completions, and competition activity over the past 4–8 weeks (all is_seed) so on first load the surfaces show real streaks, climbing leaderboards, and at-risk patterns — not zeros. The existing seed scripts already backdate with randomDateInLastDays(...); reuse that.

Where to be careful:

  • Trends need backdated journal/analysis too — a backfilled check-in streak with no matching mood/energy history looks hollow. Either backfill persona journal entries + run analysis, or scope the demo to surfaces that read check-ins/progress (leaderboard, streaks) and mark trend panels as "warming up."
  • Don't backfill money. No backdated creator_earnings / transfers (Guardrail 2).
  • Keep it bounded + wipeable — a fixed N personas × N weeks, one --wipe.

When it does NOT make sense: once real users exist, lean on real data; keep seeds clearly separated and consider a smaller persona cohort so dashboards aren't dominated by synthetic rows. Always expose a seed-vs-real toggle (the Open Energy views already do this).


5. Cost + safety detail

  • Check-ins / progress / leaderboard = $0 LLM — pure row generation. Backfill freely.
  • AI-coach briefs = the only LLM cost. A daily brief per seat × many personas adds up. Bound it: generate briefs for a small showcase subset (e.g. 5–10 personas) so the review-queue demo is real, and skip briefs for the rest (they still contribute check-ins/trends/leaderboard). Use the cheap model + the coaching.brief feature_key so spend lands in /dashboard/admin/llm-spend.
  • Money guard test — add an assertion in the split path: an is_seed / isAiPersonaUserId() membership must produce zero earnings rows. Worth a unit test so a refactor can't silently start paying bots.
  • Wipeability--wipe removes every seeded coaching row (memberships, seats, check-ins, clones, competition entries) by is_seed + the coaching pattern slug.

6. Build checklist

  • Extend scripts/seed-dreampro-coaching.ts with --personas N [--weeks W]: enroll N personas as is_seed coached clients (§2) + backfill W weeks of check-ins/progress (§4)
  • Reuse check_in_probability (vary by MBTI) for adherence realism
  • Seed coach + supervisor + channel-partner + referral-code rows (is_seed) so attribution/roster/leaderboard have shape (depends on the Phase-1 + Phase-2 tables existing first)
  • Showcase-subset AI-coach briefs (5–10 personas) via the brief generator
  • Split-path guard + unit test: is_seed/persona memberships → zero earnings/transfers (Guardrail 2)
  • Optional default-off cron to keep data alive (recordHeartbeat + CRON_REGISTRY toggle), is_seed only
  • Seed-vs-real toggle respected on coach dashboard + leaderboard
  • --wipe removes all of it

7. Open decisions

  1. Cohort size — how many persona clients (demo wants ~20–40 for a lively leaderboard; dogfooding the brief queue wants ~10 with briefs).
  2. Backfill window — 4 vs 8 weeks (longer = better-looking trends, more rows).
  3. Trends depth — backfill persona journals for real trend panels, or scope the first demo to check-in/streak/leaderboard surfaces?
  4. Keep-alive cron — one-shot seed only, or a daily default-off tick?

Sequencing note: this depends on the Phase-1 (coaching_seats) and Phase-2 (coaching_memberships) tables existing. Until then, the Phase-0 demo seed (seed-dreampro-coaching.ts) already populates templates + a competition with no schema dependencies — that's the "data to play with" available today; this doc is the richer version that lands with Phases 1–2.

DREAMPRO COACHING PERSONA DOGFOOD — Docs | HiveJournal