Closed-runtime cutover

The architectural rewrite changes persisted execution state. Treat it as a coordinated release, not a rolling web-server update. A successful offline conversion is not authorization to deploy.

Before merge

  1. Verify the exact release commit with the full verification gate and all deployed frontend profiles. Review dependency advisories and use hosted CI or the approved manual release gate. Review actual build/start commands and Node version.
  2. Control activation from main: either hold automatic deployment or reserve the merge until the coordinated cutover prerequisites are complete. Keep the worker held through web acceptance. Staging and production deploy independently; neither automatically gates the other.
  3. Rehearse on a separate local or staging Mongo instance. Never point a test at production or share a dataset between old and new writers. The importer uses database process-platform and the new canonical collections, leaving legacy collections alone.
  4. Verify the actual Auth0 origins/callbacks and operator permissions. Reconcile worker provider capabilities, rather than assuming the web service's credentials are present on the worker.
  5. Provision durable, distinct PROCESS_EFFECT_ENCRYPTION_KEY and PROCESS_EFFECT_DERIVATION_KEY on hosts that need persistent protected effects. Hosts sharing protected handles need the same keyring and derivation key. Keep these values outside source control and logs.
  6. Inventory and back up every attachment volume, not just Mongo. PROCESS_FILES_ROOT defaults to filesystem storage; the absence of GridFS files does not establish absence of attachments.

Offline preparation

Use an authorized JSON export {processes: [...], templates: [...]} with API-shaped process IDs and template keys. Keep original database/export evidence separately, including its checksum. Use explicit public target bindings; do not infer capability availability from a laptop's secrets.

npm run migrate:language -- \
  --input /private/export.json \
  --bindings /private/public-bindings.json \
  --ownership /private/ownership-by-template.json \
  --output /private/new-plan-directory

The command writes private plan.json evidence and reports both process and latest-template results. Every rejected or held record blocks application. It reports invalid latest templates individually, rather than allowing one invalid template to hide the other diagnostics. Large arrays are written incrementally. Existing plan directories/files are never overwritten.

Known historical scripts and display expressions are expanded only after exact source-hash attestation. They become ordinary closed syntax. Unknown source remains rejected; the converter never evaluates JavaScript, calls providers or replays completed work. Obsolete allowedRoles metadata is ignored as it was by the deployed v1 runtime; explicit permissions are preserved, and missing legacy permission arrays normalize to their old empty-array defaults. Original source remains in evidence. Values that cannot be admitted are identified by source index and retained in the original export rather than embedded in canonical records.

Explicit import

The default is always dry-run, even if MONGO_URL exists in the environment. For a reviewed Mongo import, supply a dedicated target-URL environment variable from secure operator configuration:

npm run migrate:language -- \
  --input /private/export.json \
  --bindings /private/public-bindings.json \
  --ownership /private/ownership-by-template.json \
  --output /private/new-import-plan-directory \
  --apply-mongo-url-env PROCESS_MIGRATION_TARGET_URL \
  --confirm-mongo-database process-platform

Do not put a connection string on the command line. The CLI refuses ambient MONGO_URL as the target variable, requires database confirmation, and refuses simultaneous file/Mongo destinations. --apply-to /private/new-file-store remains available for an explicitly selected file store.

Import is create-only and idempotent for identical data. Conflicting records/latest pointers stop it; there is no overwrite, reconciliation-by-guessing, or rollback of earlier successful inserts. An interruption can leave a partial import. Keep writers stopped, investigate, then retry the identical approved input against the same target. Mongo driver diagnostics are not printed because they can contain credentials. Read back all aggregates and latest registrations and compare canonical hashes. Preserve historical registrations without promoting them into latest-template pointers.

Activation order

  1. Stop old worker and web writers. Prevent new services from receiving traffic.
  2. Take the final consistent data export and attachment backup; the development rehearsal export is not this final backup. Record source counts and hashes.
  3. Convert, import, and reconcile all records, latest templates and attachment references/bytes.
  4. Only then activate the new web services. Their first readiness await seeds absent built-in registrations; starting them before import can create conflicting latest pointers.
  5. Perform controlled login/read/write/attachment checks with approved synthetic acceptance data.
  6. Enable exactly the intended worker, with no overlapping old worker, and verify progression using a controlled workflow before allowing operational external actions.

Rollback

Keep a known-good old deployment, old dataset and attachment backup. Before enabling new writes or external effects, a rollback can restore the old service/data combination. After activation, record and reconcile new writes and external outcomes before deciding how to recover. Reverting code does not revert database state or undo an on-chain transaction, message, document or other external action.

Required ownership and membership policy

The deployment access policy is required on every web host and worker. The CLI requires --ownership /private/ownership-by-template.json. It maps each template key to {deploymentId, ownerOrganizationId, applicationId}. Missing/conflicting assignments block import. The plan records the mapping and hash. This is operator-reviewed ownership, not creator identity or Auth0 affiliation. No unowned compatibility import is offered by the CLI.

Approve the policy and mapping together, provision the same policy on each service, and verify owned store readback before activation. Review duplicate email unions, unverified identities and retained operator privileges explicitly. Do not silently tighten or broaden access from inferred company roles. Owner claims prevent different deployments sharing the same backing resource; review the claim before any recovery, never delete a marker simply to bypass a mismatch.

Inventory attachment ownership as well as bytes: old sidecars may lack activity/uploader metadata. Backfill only from unambiguous evidence with operator approval. Retain ambiguous/orphaned files and deny deletion until resolved. A metadata export is not an attachment backup.