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
viascripts/seed-dreampro-coaching.ts--personas N— enrolls AI personas asis_seedcoached 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 / thecoach_briefcron), not by the seed (keeps it $0-LLM). Workout-Window check-in backfill was skipped (checkins require a non-nullchain_idFK — 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 byPOST /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 vianote_analyses, which is exactly the Throughline trend input).- Workout Window AI users (
migration 026,ai-profile-generator.ts) — already modelcheck_in_probabilityper persona; the same probability drives coaching check-in simulation. - The seed pattern — service-role script,
is_seedflag,--generate/--wipe/--stats(seed-dreampro-coaching.tsis 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:
- Enroll as a client — a
coaching_membershipsrow (is_seed = true) under a seed coach (an AI coach persona) → that coach's channel partner.referral_codepoints at a seed code so attribution analytics have shape. - 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). - Set up a Workout Window — activity type + window + (fuzzed) location, so the persona joins chains/squads.
- Seat them — a
coaching_seatsrow held by the AI coach persona, with asupervisor_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_REGISTRYtoggle per RECURRING_TASKS.md,is_seedrows 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.brieffeature_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 —
--wiperemoves every seeded coaching row (memberships, seats, check-ins, clones, competition entries) byis_seed+ the coaching pattern slug.
6. Build checklist
- Extend
withscripts/seed-dreampro-coaching.ts--personas N [--weeks W]: enroll N personas asis_seedcoached 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_REGISTRYtoggle),is_seedonly - Seed-vs-real toggle respected on coach dashboard + leaderboard
-
--wiperemoves all of it
7. Open decisions
- Cohort size — how many persona clients (demo wants ~20–40 for a lively leaderboard; dogfooding the brief queue wants ~10 with briefs).
- Backfill window — 4 vs 8 weeks (longer = better-looking trends, more rows).
- Trends depth — backfill persona journals for real trend panels, or scope the first demo to check-in/streak/leaderboard surfaces?
- 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.