Safety model
Guardrails that prevent accidental source writes, double billing, and stale schedule plans.
The product is designed for conservative Stripe Billing migrations.
Dry-run by default
Every write-capable command has a plan mode. Apply mode requires both:
- an
applycommand, and - a matching confirmation environment variable set to
yes.
Examples:
CREATE_DESTINATION_CATALOG=yes pnpm stripe-migrate catalog apply
EXECUTE_SUBSCRIPTION_SCHEDULES=yes pnpm stripe-migrate subscriptions schedule apply
CANCEL_SOURCE_SUBSCRIPTIONS=yes pnpm stripe-migrate source cancel applyBuffer-time protection
The migration plan uses a minimum start buffer before a subscription can stay in the automatic path. The default is 48h.
This protects against a common failure mode: starting customer copy or destination schedule creation too close to renewal, then having the source account renew before the destination schedule is verified.
Source account safety
Source inventory prefers restricted/read-only keys. Source writes are limited to the final cancel-at-period-end step.
Before source cancellation, the runner verifies:
- destination schedules have zero verification issues
- source key belongs to the expected account
- source subscription customer matches the schedule map
- source current period end matches the destination schedule start
- source subscription is still active
Destination verification gates
Destination writes are not trusted just because Stripe accepted an API request. The runner retrieves and verifies destination objects before moving forward.
Important gates:
- copied customer verification
- payment default/card count checks
- invoice/tax previews
- subscription schedule verification
Artifact trail
Every phase writes artifacts for operators and future reviewers:
- JSON for machine-readable state
- CSV for Stripe Dashboard workflows and spreadsheet review
- Markdown for human-readable summaries
The final packet collects migration evidence into one reviewable document.
Explicit scope boundary
The runner does not change customer application databases, webhooks, entitlements, or usage-event code. Keeping that boundary narrow makes the Stripe migration safer and easier to reason about.