# HyperTwist Website VPS Precutover Host State

Created on `2026-06-22`.

## Purpose

This note records the actual shared-VPS state observed immediately before the
HyperTwist same-origin website/auth-server cutover.

It exists so future deployment work starts from current host truth rather than
from the idealized checkout layout used by the new deployment templates.

## Current inspected host facts

Read-only inspection on `212.227.13.220` confirmed:

- the intended checkout path `/srv/hypertwist/current` does not exist yet
- the tracked repo checkout currently present for the `dev` user is
  `/home/dev/src/HyperTwist`
- there is no `hypertwist-website-auth-server.service` unit currently installed
- the live `hypertwist.app` NGINX vhost is still
  `/etc/nginx/sites-available/hypertwist-app.conf`
- that live vhost still serves a static root:
  - `/var/www/hypertwist`
- the live static root currently contains:
  - `/var/www/hypertwist/index.html`
- the live public site is therefore still the older placeholder rollout page

## Current shared-port reality

The same inspection also confirmed that port `3001` is already occupied on the
shared VPS:

- listener:
  - `*:3001`
- owning process:
  - `/usr/bin/node --require /home/dev/src/FamiliarOS/website/server/node_modules/tsx/dist/preflight.cjs --import file:///home/dev/src/FamiliarOS/website/server/node_modules/tsx/dist/loader.mjs src/index.ts`
- related env posture:
  - `/home/dev/src/FamiliarOS/website/server/.env` contains `PORT=3001`

Operational consequence:

- HyperTwist same-origin deployment on this shared VPS must not reuse `3001`
  as its default upstream port
- the current first-party HyperTwist deployment templates and bundle renderer
  therefore now use `3011` as the shared-host default instead

## Current live-route evidence

At inspection time:

- `https://hypertwist.app/` still resolved to the placeholder rollout page
- local `curl http://127.0.0.1:3001/api/auth/health` returned Express
  `Cannot GET /api/auth/health`
- local `curl http://127.0.0.1:3001/api/releases/manifest` returned Express
  `Cannot GET /api/releases/manifest`

This confirms that the current process on `3001` is not the HyperTwist
same-origin website/auth-server lane.

## Practical next cutover implications

Before the real cutover can happen, the host still needs:

- a chosen live checkout path for HyperTwist website deployment
- rendered `.env` files copied into that checkout
- a real long-lived HyperTwist website/auth-server process bound to a free port
  such as `3011`
- the NGINX vhost for `hypertwist.app` rewritten from static-root serving to
  reverse-proxy the HyperTwist website/auth-server process
- root-owned service enablement and NGINX reload

## Addendum - isolated VPS-local staging proof on `2026-06-22`

A follow-up isolated-host proof was then executed from a temporary checkout on
the same VPS:

- staged path:
  - `/tmp/hypertwist-website-staging-24e780e`
- source shape:
  - current committed `website/` tree from `24e780e`
- rendered env posture:
  - manifest-driven same-origin bundle
  - `publicOrigin=https://hypertwist.app`
  - `PORT=3011`
- build/start flow:
  - `npm ci` in `website/`
  - `npm --prefix server ci`
  - `npm run build`
  - `npm --prefix server start`

Observed proof results:

- `GET http://127.0.0.1:3011/health`
  - returned `{\"ok\":true,\"service\":\"hypertwist-auth-server\"}`
- `GET http://127.0.0.1:3011/api/auth/health`
  - returned `ok: true`
  - `supertokens.reachable: true`
  - `supertokens.ready: true`
  - `runtime.public_origin_ready: true`
  - `runtime.mode: mixed`
  - only runtime warning:
    `SUPERTOKENS_CORE_URI still targets a loopback/local-development host.`
- `GET http://127.0.0.1:3011/api/releases/manifest`
  - returned the expected anonymous release-manifest JSON
  - Windows metadata was populated
  - raw download URL remained hidden from the anonymous viewer
- `GET http://127.0.0.1:3011/`
  - included the first-party shell marker
    `hypertwist-site-shell`
  - included the expected `#root` mount

Cleanup result:

- the temporary `3011` listener was removed after the proof
- the temporary `/tmp/hypertwist-website-staging-24e780e` tree was deleted

Operational reading:

- the repo-side same-origin website/auth-server lane is now proved on the real
  shared VPS behind the new host-safe `3011` port
- the repo now also ships
  `website/scripts/run-vps-same-origin-staging-proof.mjs` so that same
  isolated-host proof can be rerun from the local HyperTwist repo without
  hand-assembling the SSH/archive/build/boot sequence again
- the remaining gap is the root-owned live cutover from static
  `/var/www/hypertwist` NGINX serving into the long-lived HyperTwist
  website/auth-server process plus real production values, not another missing
  repository-side deployment behavior

Follow-up proof on `2026-06-22`:

- the new scripted staging-proof helper reproduced that same `3011` host proof
  successfully against the live VPS
- on success it removed the temporary staging checkout again
- on the final cleanup check, no `3011` listener remained and the temp checkout
  path was absent

Additional preview-tier proof on `2026-06-22`:

- the scripted helper was rerun in `--archive-source worktree` mode so the
  exact in-progress local packet, not just committed `HEAD`, was staged to the
  VPS
- the rendered manifest used `deploymentTier=preview` with honest empty
  operator checkout, Windows download, release-manifest
  version/build/checksum/published-at, and `PADDLE_WEBHOOK_SECRET` values
- `/api/auth/health` still returned `ok: true`,
  `runtime.public_origin_ready: true`, and `runtime.mode: mixed`
- the only runtime warning remained the loopback SuperTokens-core notice
- billing health truthfully reported `webhookSecretConfigured: false`
- `/api/releases/manifest` returned `ok: true` with all platform entries still
  `configured: false` and `download_available: false`
- cleanup again removed the temporary `3011` listener and the temp checkout

Operational reading from that second proof:

- HyperTwist now has a first-party preview-tier rehearsal path for the real
  shared host, not only a launch-like proof lane
- the bundle/readiness helpers now align with the live website behavior that
  already truthfully distinguishes preview posture from launch-ready posture

Final live cutover on `2026-06-22`:

- the committed HyperTwist `website/` tree is now installed at
  `/srv/hypertwist/current`
- service user `hypertwist` and
  `hypertwist-website-auth-server.service` are now live on the host
- `/etc/nginx/sites-available/hypertwist-app.conf` now proxies the public
  origin to `127.0.0.1:3011` instead of serving `root /var/www/hypertwist`
- `https://hypertwist.app/health` returns
  `{"ok":true,"service":"hypertwist-auth-server"}`
- `https://hypertwist.app/api/auth/health` returns `ok: true`,
  `runtime.mode: mixed`, `public_origin_ready: true`, and the expected
  preview-tier billing/runtime warnings
- `https://hypertwist.app/api/releases/manifest` returns the first-party public
  preview manifest with anonymous download URLs withheld

Updated operational reading:

- the earlier host-state blocker has been cleared; the live origin no longer
  serves the placeholder rollout page
- the remaining live work is launch-tier release, checkout, and webhook
  completion rather than same-origin host cutover itself

## Related authorities

- `docs/ops/HYPERTWIST_WEBSITE_SAME_ORIGIN_DEPLOYMENT_HANDOFF_2026-06-22.md`
- `docs/ops/HYPERTWIST_WEBSITE_RUNTIME_CONFIGURATION_GUIDE_2026-06-22.md`
- `docs/ops/HYPERTWIST_PUBLIC_WEBSITE_AUTH_BILLING_AND_DISTRIBUTION_PACKET_2026-06-22.md`
