guides
Brownfield upgrade
Migrating an existing system without breaking it. Pipemason's brownfield-upgrade mode adds two pre-flight phases on top of the standard program machine: audit and migration_plan.
When this mode fits
- Auth swaps (Auth0 → Clerk, Cognito → Auth0, etc).
- Framework upgrades that cross multiple PRs (React 18 → 19, Next 14 → 15).
- Schema redesigns with data migrations.
- Monolith decomposition / extracting a service.
- Anything where the order of PRs matters for safety.
For smaller adds that don't need ordered migrations (e.g. add SSO to existing auth), use brownfield-extension instead.
The two extra phases
audit
The audit phase reads the current system and freezes AUDIT.md: a snapshot of architecture, dependencies, tests, CI, deploy surface, and known issues. Every downstream phase reads AUDIT.md as the source of truth for "what we have today".
Note
migration_plan
The migration plan phase writes MIGRATIONS.md — an ordered list of migration steps with rollback procedures. Each step becomes one or more stories that the iterate phase dispatches in order. A migration step usually has:
- A title + scope.
- A forward procedure (what the PR does).
- A rollback procedure (how to undo it without losing data).
- A gate the verify phase checks before allowing the next step (often: "both old and new paths work in parallel for N runs").
Walkthrough: auth swap
pipemason program start "migrate auth from Auth0 to Clerk, preserve sessions, deprecate Auth0 after 30 days" \ --mode brownfield-upgrade --dry-run
Review AUDIT.md + MIGRATIONS.md. A typical auth-swap migration plan looks like:
migrations:
- id: M-001
title: "Add Clerk alongside Auth0 (dual-write)"
forward: "Provision Clerk app; install SDK; wrap every protected route in <SignedIn> matching the Auth0 guard."
rollback: "Remove Clerk SDK + provider; routes fall back to Auth0-only."
gate: "Both auth surfaces accept tokens for 7 calendar days"
- id: M-002
title: "Migrate users (bulk Auth0 → Clerk import)"
forward: "Run import script in Clerk dashboard with backfilled metadata."
rollback: "Delete imported users; Auth0 remains authoritative."
gate: "100% of active Auth0 users have a Clerk shadow account"
- id: M-003
title: "Switch primary auth to Clerk"
forward: "Flip feature flag; new sessions issued by Clerk; old Auth0 sessions still accepted."
rollback: "Flip flag back; Auth0 resumes issuance."
gate: "0 errors on /api/me for 24 hours under Clerk-primary"
- id: M-004
title: "Decommission Auth0"
forward: "Remove Auth0 SDK + provider + env vars. Cancel Auth0 plan."
rollback: "Hard — restore from backup tag; reprovision Auth0 SaaS."
gate: "30 days under Clerk-primary; no rollback fired"Iterate
When you remove --dry-run the iterate phase dispatches one migration step at a time. Each step is a story / PR. The verify gate holds the next step until the previous step's gate passes.