Upgrading
Upgrade a generated product through reviewed source changes and explicit evidence.
Upgrading a generated product
The buyer owns a product repository; the foundation does not update it at runtime. An update is a reviewed source merge with application, migration, provider, and deployment verification.
Pre-release truth
There is no supported previous commercial release yet. The mutable default branch and the current uncommitted development checkout are not releases. Until the first commercial tag and release bundle exist, a “previous-to-current upgrade” would be an engineering rehearsal, not a buyer update.
The first commercial tag establishes the baseline. Do not invent compatibility with planning documents, historical branches, or the pre-release custom-auth schema that Better Auth replaced.
Version and compatibility policy
Product release tags, not private workspace package versions, define the delivered foundation:
- patch: compatible defect, security, documentation, or provider fix;
- minor: backward-compatible capability or supported-path improvement;
- major: a change requiring buyer action to preserve an existing supported contract.
The first commercial release will establish v1.0.0. Before that tag, version numbers inside
private package manifests are implementation metadata and must not be presented as product releases.
Every tagged update must identify:
- supported toolchain and provider versions;
- changed product/architecture contracts;
- required environment additions, removals, or rotations;
- database migrations and whether rollback is safe;
- generated artifacts that must be refreshed;
- breaking or manual merge actions;
- exact verification and known limitations.
See the commercial update policy in docs/commercial/updates.md. The current tagged release is the
supported source baseline; the default branch is not an entitlement or stability promise.
Responsibilities
The foundation maintainer must provide a tag, changelog, upgrade notes, migration impact, verification commands, and a reproducible unmodified-reference comparison.
The buyer must:
- preserve a recoverable application and database backup;
- compare the exact release they started from with the exact target tag;
- disclose and review material local architecture departures;
- resolve application-specific conflicts;
- test migrations against disposable or staged data;
- verify provider dashboards, origins, cookies, webhooks, and environment;
- deploy with a rollback point and observe health/readiness.
An update entitlement does not include merging a customized application on the buyer's behalf.
Prepare
Record a clean product state before merging:
git status --short
git rev-parse HEAD
git tag --points-at HEAD
node --version
bun --version
pnpm --version
vp --version
vp install --frozen-lockfile
vp check
vp run -r test
vp run -r buildCommit or deliberately set aside product work before upgrading. Never hide a dirty starting state in an upgrade report.
Download the old and target foundation releases into separate read-only sibling directories. Run
create-app from each with the same app name, workspace namespace, and brand into two disposable
reference directories. The resulting reference diff removes seller-only files and normalizes
scope/brand changes before comparison.
Do not:
- rerun
create-appinto the non-empty product repository; - copy the target release over the product;
- accept an unbounded search/replace;
- merge from the mutable default branch;
- apply migrations to production first.
Review in dependency order
Classify the release diff before porting it:
- toolchain pins, install policy, package manifests, and lockfile;
- shared compiler/configuration policy;
- migrations and persistence;
- shared wire contracts;
- server repositories, services, routes, auth, and provider adapters;
- web services, modules, routing, PWA, and styles;
- email source followed by regenerated HTML;
- deployment, environment, CI, tests, and documentation.
Keep a short merge ledger: accepted release change, local conflict, resolution, command, and remaining risk. A second agent should be able to explain every non-trivial resolution without the author transcript.
Migration and provider safety
- Never edit, rename, reorder, or delete a migration already applied by the product.
- Apply new migrations to a disposable database, prove
up → down → upwhen the down path is safe, and run domain integration tests. - Treat destructive or irreversible data changes as explicit deployment decisions with backups and forward-recovery steps.
- Preserve webhook idempotency and ordering while provider adapters change.
- Add new environment values atomically; remove stale values from validators, examples, deployment, CI, and secrets management.
- Regenerate email HTML through the source command; do not resolve conflicts in generated templates by hand.
Toolchain escape hatches
Run:
pnpm verify:toolchainThis exercises Bun server tests/build, package-native TypeScript checks, package-native web tests, and an exact official Vite build without Vite+ orchestration. It is diagnostic, not a second supported stack:
- if package-native commands pass while Vite+ fails, restore the last green Vite+ pin and diagnose the orchestrator;
- if TypeScript fails after an update, restore the release lockfile/pins and isolate the compiler or type change; do not disable type-aware checks;
- if Bun tests/build fail, restore the pinned Bun version; a Node API runtime is not a supported fallback;
- the official Vite diagnostic is online and exact-version pinned; it must not modify the lockfile.
Changing Bun, TypeScript, Vite, Vite+, Node, or pnpm is release engineering and requires a fresh buyer, CI, PWA, Sentry, compiled-server, and deployment proof.
Verify and deploy
After conflicts are resolved:
vp install --frozen-lockfile
vp check
vp run -r typecheck
vp run -r test
vp run -r build
pnpm verify:toolchain
pnpm audit --audit-level high
git diff --checkRun DB-enabled integration tests and provider-specific tests for every affected boundary. Deploy to
a disposable or staging environment, then verify /health, /ready, authentication, paid access,
email, upload, PWA/offline behavior, and the application-specific critical path.
Failure and rollback
Stop when a migration, ownership check, auth flow, billing state, or provider contract is uncertain. Do not weaken a test to complete the merge.
Application rollback means redeploying the last verified release-compatible build. Database rollback is separate: use a reviewed down migration only when data effects are safe; otherwise forward-fix from a backup-informed plan. Provider configuration and already-delivered webhooks may not roll back with code.
Capture the old commit/tag, target tag, reference diff, conflict ledger, database proof, test output, deployment identifier, and rollback point. Follow Troubleshooting and use the support request contract when an unmodified reference also fails.