Codebase
Getting updates
Verify, merge, migrate, test, deploy, and roll back a signed V03 release.
An update is a signed source release plus manifest, SBOM, AIBOM, migration set, and release notes. Do not deploy from an uncommitted working tree or an unverified archive.
Two update channels exist. Every buyer has the archive channel: new releases appear in your Polar library automatically, and re-claiming your purchase always downloads the current release. The git channel is optional — send us your GitHub username and we add you to the private template repository, so updates become a fetch and merge.
Update from a release archive (default)
Download the new archive from your Polar library and verify it exactly as
described in the README (shasum -a 256 -c plus minisign -Vm against the
minisign.pub you already trust). Then treat the archive as a new immutable
release:
mkdir /opt/aiworkflowcenter/releases/<new-version>
tar -xzf aiworkflowcenter-<new-version>.tar.gz \
-C /opt/aiworkflowcenter/releases/<new-version>
cd /opt/aiworkflowcenter/releases/<new-version>
pnpm install --frozen-lockfile
Diff the new tree against your running release before building — pay
attention to the Prisma schema, migrations, the environment contract
(.env.example), Caddy routing, and task definitions. Re-apply your local
customizations onto the new tree (keeping them in version control or as
patches makes this repeatable), then continue at the "Release gate" step
below. Deployment, health checks, and rollback are identical for both
channels because both end in an immutable release directory.
Update from the private repository (optional)
With repository access configured as a template remote:
git status --short
git fetch template
git log --oneline HEAD..template/main
if [[ -f .gitmodules ]]; then git submodule status; fi
Commit or safely preserve local changes before merging. Review changes to the Prisma schema, migrations, environment contract, Caddy routing, task definitions, policy packages, and the agent-core submodule pointer.
Merge and regenerate
git merge template/main
if [[ -f .gitmodules ]]; then git submodule update --init --recursive; fi
pnpm install --frozen-lockfile
pnpm --filter @repo/database analyze
Never resolve a submodule conflict by discarding an unseen commit. Inspect its graph and merge required security and contract commits on a named branch.
Release gate
pnpm verify
Run migration and backfill tests against both an empty database and a production-shaped clone. Confirm row counts, canonical hashes, orphan checks, RLS, idempotent replay, and rollback-window compatibility.
Deploy
Assemble and sign a new buyer artifact, update the immutable release descriptor, take PostgreSQL and R2 backups, run the checked-in migration/bootstrap jobs, then switch PM2 to the new immutable release directory:
source "${AWP_RUNTIME_ENV:?set AWP_RUNTIME_ENV to the root-owned runtime env file}"
export NEXT_PUBLIC_SITE_URL NEXT_PUBLIC_SITE_NAME SITE_SLUG
export COMMERCE_DEMO_HOST EDUCATION_DEMO_HOST HEALTH_DEMO_HOST
DATABASE_URL="$MIGRATION_DATABASE_URL" APP_DATABASE_ROLE=aiwc_app \
bash scripts/ops/migrate-and-grant.sh
DATABASE_URL="$MIGRATION_DATABASE_URL" V03_DATA_MODE=upgrade \
bash scripts/ops/bootstrap-v03-data.sh
AWP_RELEASE_DIR="$PWD" pm2 startOrReload ecosystem.config.cjs --update-env
pnpm ops:health
Verify health, public contracts, admin login, all Demo domains, worker/scheduler health, checkout webhook rejection/acceptance, and a bounded download.
Rollback
Keep the preceding signed release directory and descriptor available. Switch
AWP_RELEASE_DIR back, reload PM2, and verify all five probes without attempting
a destructive schema reversal. If a migration changed read shape, the
expand/contract window must keep the prior application compatible until the
rollback window closes.