# Historical discovery — rollout now complete

This is the predeployment discovery record, not current runtime status. See [verified rollout](../../astra-integration/index.html) for the deployed merge and live checks.

# Production discovery and deployment handoff

No deployment command was run in this phase. All host inspection was read-only.

## Verified current topology

- SSH profile: `multi-server` (`37.27.12.140`, user `webuser`).
- Public app: `https://agentartifact.ai`; sandbox frame host:
  `https://usercontent.agentartifact.ai`.
- Nginx site: `/etc/nginx/sites-enabled/zz-agentartifact.ai`; both hosts proxy allowed routes to
  port 4700.
- PM2 app: `agentartifact-prod` (id 77 during inspection), running
  `/opt/projects/agentartifact-prod/dist/index.js` from `/opt/projects/agentartifact-prod`.
- Production checkout: clean `main` at
  `9268ae3920771c3ac9b90293e733e45924ed040d`; its cached `origin/main` was the same commit.
- The public production process PID was 3231578 and the built `dist/index.js` modification time was
  2026-09-06 06:09:46 UTC when inspected. These process facts are evidence, not stable identifiers.
- Current GitHub `main` is `2f7fc731239d1083c85cc35251420896deec2180`. Its only difference
  from the running production commit is `docs/production.md`; all product/template/public/package
  paths are identical.
- The five live public frame prefixes matched the canonical files at the feature branch point.
- SQLite is at `/opt/projects/agentartifact-prod/data/agent-artifacts.db` and must be backed up with
  the SQLite backup API, not `cp`, because WAL mode can leave current data outside the main file.
- Canonical deploy entry point: `/opt/projects/agentartifact-prod/deploy.sh`, SHA-256
  `fd9d2001323ae6e7d3bf917dca1f7c3d66b612c0b8dba5c95d663c369352d38e`. It pulls clean
  `main` with rebase, installs the frozen lockfile, builds, calls PM2 `startOrReload` with the existing
  environment, and gates on local `/healthz` for up to 30 seconds.

## Safe next deployment steps (after parent review and merge)

1. Record the approved merge commit and the current production SHA. Re-fetch `origin/main`, and stop
   if the production worktree is not clean or `main` is not a fast-forward to the reviewed commit.
2. Create a consistent timestamped SQLite backup with `sqlite3.Connection.backup()` while the live
   database is opened read-only. Store it outside the repository and verify it opens and contains the
   expected schema before changing code.
3. Reconfirm `deploy.sh` has the recorded SHA above and the PM2 app is `agentartifact-prod`. Run the
   repository's existing `/opt/projects/agentartifact-prod/deploy.sh`; do not replace it with an
   improvised process command.
4. Verify local and external health, `/templates`, all five selected detail/frame routes, all five
   new thumbnail bytes, the 19 HTML + 1 markdown gallery inventory, sandbox allow-list behavior and
   Nginx neighbor health. Confirm the five frame prefixes match the reviewed canonical source hashes.
5. Record the running checkout SHA, PM2 restart count/status and browser screenshots only after the
   external checks pass.

## Rollback plan

This change has no migration, schema, dependency, CSP, billing or runtime change. The built-in seeder
will restore the prior five source documents when a prior commit is started, so code rollback is
schema-compatible. Keep `9268ae3920771c3ac9b90293e733e45924ed040d` as the currently verified known
good product commit and keep the pre-deploy SQLite backup.

Preferred rollback is an auditable revert of the reviewed merge on `main`, followed by the same
`deploy.sh` and health/frame/thumbnail checks. If an emergency host-only checkout of the saved commit
is explicitly authorized, build that exact saved SHA and reload with the existing
`ecosystem.prod.config.cjs`, then restore the `main` checkout via the revert workflow. A database
restore should not be needed for this content-only change; use the verified pre-deploy backup only if
startup evidence shows unrelated data damage.

## Non-blocking operational observation

Port 4700 currently listens on `0.0.0.0` even though Nginx is the intended public entry point. That
predates this work and is not changed here. It should be handled as a separate infrastructure review,
not bundled into a template deployment.
