Skip to content

Trial engine — lifecycle + nudges

PROD-03 introduced a shared trial engine at packages/trial-engine/. Every commercial product reuses it.

  • Provisions a trial tenant on /trial?product=<slug> with the manifest’s default_tier, seed_dataset, and first_action_route.
  • Schedules an 8-stage lifecycle of emails offset from trial_started: welcome, day-1 nudge, day-3 spotlight, day-7 check-in, day-11 trial-ends-soon, day-13 final reminder, day-14 trial-ended, day-21 survey.
  • Detects failure-to-launch via an hourly job — fires trial_help_needed Pulse + a help-offer email when the user is stuck (no first-action after 4 hours, no login after 24 hours).
  • Honors consent — every send is gated through consent.ts. CAN-SPAM unsubscribe + GDPR consent reset.

Per-product config (in packages/naming/manifest.json)

Section titled “Per-product config (in packages/naming/manifest.json)”
"onboarding": {
"first_action_route": "/scan/new",
"first_action_event": "scan_started",
"first_action_prompt": "Run your first AEGIS scan",
"seed_dataset": "aegis-demo-tenant",
"default_tier": "pro"
}

trial_started, trial_first_action_started, trial_first_action_completed, trial_help_needed, trial_converted, trial_downgraded_to_free, trial_expired_no_action. Documented in Pulse.

  • Don’t fork the lifecycle per product — extend the shared schedule and stamp per-product copy at render.
  • Don’t bypass consent.ts in templates — every send routes through it.
  • Don’t manipulate trial_started_at to re-trigger emails — the scheduler is idempotent on (tenant_id, stage).

See packages/trial-engine/README.md for the API + test fixtures.