> ## Documentation Index
> Fetch the complete documentation index at: https://getoverlay.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Worktree Staging QA

> Test a staging release candidate and promote the verified revision to production.

This guide covers hosted QA and release promotion only. Follow [Agentic Development](/docs/develop/agentic-development) for feature branches, worktree creation, pull requests, commit history, and integration ownership.

## Deployment lanes

Overlay has two backend lanes that must stay paired with their matching web deployment:

| Lane           | Git branch | Web URL                 | Convex deployment |
| -------------- | ---------- | ----------------------- | ----------------- |
| Production     | `main`     | `www.getoverlay.io`     | production        |
| Shared staging | `staging`  | `staging.getoverlay.io` | development       |

A feature worktree must never change production Convex. The `main` app and production Convex are a single release unit: deploy them only from an up-to-date, clean `main` worktree.

The development Convex deployment is shared by local development and `staging.getoverlay.io`. A Convex change from one branch changes that backend for every user of this lane. Do not run concurrent staging QA sessions that make incompatible changes under `convex/`.

## Prepare the staging release candidate

Use one dedicated, long-lived worktree for the shared `staging` branch. Reuse it for every sequential Builder pull request; the Integration agent does not create a new worktree per PR or check out each feature branch into this worktree. This prevents a feature worktree from accidentally becoming the staging or production deployment source while avoiding duplicate checkouts.

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing
git fetch origin
git worktree add ../overlay-landing-staging staging
cd ../overlay-landing-staging
git pull --ff-only origin staging
```

The Builder normally opens its pull request against `staging` and stops at submission. The Integration agent reviews the diff and required checks, then merges the Builder PR into `staging` through GitHub. If `DevelopedByDev` explicitly authorizes the owner-only direct-push fast path, the Integration agent instead performs the documented local review and checks, integrates in this dedicated staging worktree, confirms a fast-forward update, and pushes without force. A direct `staging` push normally starts the staging Vercel build.

Review feature branches through GitHub and the pull request diff. After each merge, update this same staging worktree to the exact remote `staging` revision before testing. Create a short-lived additional worktree only when an unusual conflict or side-by-side investigation cannot be performed safely in the dedicated staging worktree; remove it after the investigation.

After that merge, update the dedicated staging worktree to the exact remote revision:

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing-staging
git fetch origin
git pull --ff-only origin staging
git rev-parse HEAD
git rev-parse origin/staging
```

Both SHAs must match. Record the staging SHA before testing. Do not force-push `staging`; if a candidate must be removed, create a revert commit so staging history stays auditable.

Prefer one release candidate at a time. If the Integration agent intentionally batches several Builder PRs, record every included PR and test the combined staging revision.

The staging Vercel project is branch-gated to `staging` to keep build costs predictable:

* Its Git production branch is `staging`.
* `DEPLOY_BRANCH=staging` is configured for both the Preview and Production environments.
* `bash scripts/vercel-ignore-build.sh` is the project's Ignored Build Step. With the staging target, it runs only when `VERCEL_GIT_COMMIT_REF` exactly matches `DEPLOY_BRANCH`; missing variables, missing branch refs, pull-request branches, manual deployments, and deploy hooks are skipped (Vercel exit `0`). If the shared script is ever reused for another explicit target, its no-ref manual-release behavior remains available for that target.
* Preview deployment sources remain disabled. The project therefore has one hosted QA lane: the `staging` branch's deployment.

When changing this policy, verify the project settings and run the guard locally with both matching and non-matching branch refs before merging. Do not rely on an account-level deployment-source policy alone; the repository guard is the defense that travels with the project configuration.

## Push Convex for staging QA

If and only if the staged change includes `convex/` changes, deploy the exact staging revision to the shared development deployment before testing the staging website:

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing-staging
npm run convex:push:dev
```

Then wait for the `staging` Vercel build to finish and open `https://staging.getoverlay.io`.

For every staging QA run, verify the changed flow plus these basics where applicable:

* Authentication/session loading succeeds.
* The affected API route or UI flow returns the expected result.
* A chat change streams, completes, and persists after a refresh.
* A billing or entitlement change creates and finalizes its expected usage state.
* Browser console and staging runtime logs have no new errors.

If staging is broken after a Convex schema or function change, first restore the shared development deployment by checking out the last known-good `staging` commit in the dedicated staging worktree and running `npm run convex:push:dev`. Never use a feature worktree or production deployment as the rollback source.

## Remote Postgres contract QA

`overlay-web-postgres.vercel.app` is the dedicated Vercel/Neon lane for Postgres checks. When local disk or Docker is unavailable, do not start Postgres or Redis locally. Deploy the reviewed revision with `npm run smoke:remote-postgres` running in the Vercel build environment; the script applies app-data migrations and executes the Postgres repository contract suite using the linked production project environment.

Record the migration schema version, the complete contract count, and the Vercel build result before claiming Postgres parity. This lane currently has no remote Redis resource; Redis checks remain unverified until a remote Redis environment is explicitly configured.

## Promote a verified release

After staging passes, confirm that the tested staging SHA is still current and that the latest `main` is included in the candidate:

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing-staging
git fetch origin
git rev-parse HEAD
git rev-parse origin/staging
git merge-base --is-ancestor origin/main origin/staging
```

If either staging SHA differs from the recorded QA revision, or if the ancestry check fails, update `staging` and repeat the affected QA before promotion.

The Integration agent normally opens or updates a release pull request from `staging` to `main`, waits for the main-branch checks, and merges it with a merge commit. The release PR must identify every included Builder PR and the exact tested staging SHA. If `DevelopedByDev` explicitly authorizes a direct push to `main`, the Integration agent may instead fast-forward `main` to the exact tested staging revision after completing the owner fast-path checks in [Agentic Development](/docs/develop/agentic-development). The direct path must not change the tested tree or rewrite either branch.

Before merging a release PR, confirm root `vercel.json` sets `git.deploymentEnabled.main` to `false`. Vercel evaluates this source-controlled rule for Git events, so `staging` continues to deploy for hosted QA while a release PR merge updates `main` without creating a production deployment. Do not rely on an account-level deployment-source policy alone. After the merge, verify both the exact `origin/main` SHA and that Vercel created no production deployment for it, then align `staging` with the accepted merge commit so the next Builder PR has a clean comparison:

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing-staging
git fetch origin
git merge --ff-only origin/main
git push origin staging
```

This is a non-rewriting fast-forward: the release merge commit has the tested staging revision as a parent. If it cannot fast-forward, stop and inspect the unexpected branch movement instead of force-pushing. If Vercel unexpectedly creates a production deployment, cancel it before aliases are assigned and treat the deployment gate as failed until the trigger configuration is corrected. After alignment and the no-deployment check, report the accepted SHA as **merged but not deployed**, then stop unless the user explicitly authorizes production deployment.

Before any production Convex deploy, use the canonical `main` worktree and verify it is clean and matches `origin/main`:

```bash theme={null}
cd ~/Downloads/overlay-mono/overlay-landing
git fetch origin
git status --short
git log --oneline -1 HEAD
git log --oneline -1 origin/main
```

After explicit user authorization, create a production build without immediately assigning the production domain:

```bash theme={null}
npx --yes vercel@59.5.0 deploy --prod --skip-domain --yes
```

Inspect the returned deployment and verify it was built from the accepted `origin/main` SHA. Promote that verified deployment explicitly:

```bash theme={null}
npx --yes vercel@59.5.0 promote <deployment-url> --yes
```

After `main` is deployed to Vercel, and only when that main revision contains `convex/` changes, sync production Convex from this `main` checkout:

```bash theme={null}
npm run convex:push:prod
```

Then run an authenticated smoke test on `https://www.getoverlay.io`. For chat, send a message, confirm the streamed answer completes, refresh the page, and confirm the message remains in the conversation.

## Integration agent checklist

Before the Integration agent runs a Convex command, it must state:

1. its current branch and worktree path;
2. whether it is targeting the shared development or production deployment;
3. why that deployment is the correct lane for the revision being tested.

The Integration agent may run `npm run convex:push:dev` only from the dedicated `staging` worktree for a staging release candidate. It may run `npm run convex:push:prod` only after explicit production-deployment authorization, from the clean canonical `main` worktree, and after main's web deployment is live. `convex:push:all` is not part of the worktree workflow. The Builder never deploys Convex.
