# Controlled Update Runbook — Commercial Pilot

Procedure for applying a signed release to an existing single-tenant installation.

## Preconditions

- [ ] Staging clone restored from latest production backup (DB + evidence).
- [ ] Release verified: `scripts/verify_release.sh` + manifest signature.
- [ ] Change control / validation record approved (customer QA if applicable).
- [ ] Maintenance window communicated; users logged out.

## Backup (mandatory)

```bash
export DB_NAME=your_production_db
export OUT_DIR=/secure/backups
bash scripts/backup_full.sh
```

Retain at least one DB dump and one evidence tarball off-server.

## Update steps

1. **Enable maintenance** — reverse proxy maintenance page or `app.env=staging` on a clone first.
2. **Deploy files** — rsync/scp new release over existing tree; preserve `app/config.php` and `storage/private/`.
3. **Run migrations** — `php scripts/run_migrations.php` (or installer migration pass on fresh schema only).
4. **Verify schema floor** — `schema_migrations_applied` max key ≥ 287; `installations.schema_floor` updated if release notes require.
5. **Smoke test** — login, System Health, one evidence upload, one GRN read-only view.
6. **Record release** — insert row in `release_records` (installation_id, product_version, manifest_fingerprint).
7. **Disable maintenance** — confirm `/system-health` pass; notify users.

## Rollback

If migration fails fatally (InstallController / run_migrations fail-fast):

1. Do **not** mark release as applied.
2. Restore previous code tree from tagged backup.
3. Restore database from pre-update dump.
4. Restore `storage/private/` from pre-update evidence tarball if files changed.
5. Document incident; re-test on staging before retry.

## Idempotent migrations

Duplicate column/table/key errors (MySQL 1060, 1061, 1050, 1062) are tolerated on re-run. Any other SQL error is **fatal** — treat as failed update.

## Sign-off

| Role | Action |
|------|--------|
| Engineering | Migration log, manifest hash, git tag |
| Customer admin | UAT on staging, production approval |
| RP (optional) | Change control linkage for GxP sites |
