# HyperTwist VPS post-cutover operational invariants

Created on `2026-05-30`.

## Purpose

This note records the operational rules that are now true on the new VPS after
the DNS and TLS cutover. It exists so a later operator does not have to infer
these constraints from shell history or chat fragments.

## New VPS identity

- host IPv4: `212.227.13.220`
- DNS remains hosted at IONOS
- browser-facing TLS is VPS-side `certbot` / Let's Encrypt, not the IONOS
  certificate UI

## Root account invariant

The migration sequence preserved the original root login identity.

Confirmed invariant:

- the Linux superuser name remains `root`
- the existing root password was **not** rotated during this migration
- SSH key access was added to `root`
- `dev` and `deploy` were added as additive operational users only

Operational rule:

- do **not** change the `root` username
- do **not** rotate the root password inside this migration lane as an
  incidental cleanup step
- if credential rotation is ever wanted, treat it as a dedicated follow-up
  operation with explicit validation of SSH, Rider, Visual Studio, cron, and
  recovery procedures

Reason:

- earlier environment changes around root access created avoidable operator
  friction
- the current lane depends on preserving known-good recovery access while the
  new VPS stabilizes

## New additive users

Current additive users on the new VPS:

- `dev`
- `deploy`

Current role:

- `dev` is the default remote-development user
- `deploy` is an additive service-operations helper
- neither replaces `root` as the recovery anchor for this lane

Current privilege state:

- `dev` is in `sudo`
- `dev` is in `docker`
- `deploy` is in `sudo`
- `deploy` is in `docker`
- `dev` password login is locked
- `deploy` password login is locked
- both additive users currently authenticate by SSH key, not by a usable Unix
  password
- `dev` now has a narrow `NOPASSWD` sudoers rule for package-management
  commands:
  - `/usr/bin/apt`
  - `/usr/bin/apt-get`
  - `/usr/bin/apt-cache`
  - `/usr/bin/apt-mark`

Operational rule:

- IDE sessions, terminal development, and remote Git work should use `dev`
- `dev` may perform routine package-management operations with `sudo apt ...`
  and related read-only `apt-cache` / `apt-mark` commands without an
  interactive password prompt
- `root` remains the required lane for broader system administration, certbot,
  service repair, account recovery, and any privileged task outside the narrow
  package-management sudoers rule
- the current practical default remote-development lane is now `VS Code
  Remote-SSH` for agent-first work

## Current public HTTPS state

As of `2026-05-30`, these hostnames are live on the new VPS with working public
HTTPS:

- `scriptoriumai.io`
- `www.scriptoriumai.io`
- `app.scriptoriumai.io`
- `git.scriptoriumai.io`
- `ci.scriptoriumai.io`
- `verticaltension.com`
- `www.verticaltension.com`
- `app.verticaltension.com`
- `api.verticaltension.com`
- `hypertwist.app`
- `www.hypertwist.app`
- `vectorshell.com`
- `www.vectorshell.com`
- `git.verticaltension.com`
- `ci.verticaltension.com`

The current VPS certificate set is:

- `scriptoriumai.io` + `www.scriptoriumai.io`
- `app.scriptoriumai.io` + `api.scriptoriumai.io`
- `git.scriptoriumai.io` + `ci.scriptoriumai.io`
- `verticaltension.com` + `app.verticaltension.com` +
  `www.verticaltension.com`
- `api.verticaltension.com`
- `hypertwist.app` + `www.hypertwist.app`
- `vectorshell.com` + `www.vectorshell.com`
- `git.verticaltension.com` + `ci.verticaltension.com`

## Forgejo and Woodpecker auth state

The migrated control plane was preserved as an authenticated service surface.

Forgejo current state:

- `ROOT_URL = https://git.scriptoriumai.io/`
- `DOMAIN = git.scriptoriumai.io`
- `SSH_DOMAIN = git.scriptoriumai.io`
- `SSH_PORT = 2222`
- `DISABLE_REGISTRATION = true`
- `REQUIRE_SIGNIN_VIEW = true`
- existing accounts/data were copied; no passwordless public access was enabled

Woodpecker current state:

- `WOODPECKER_HOST = https://ci.scriptoriumai.io`
- `WOODPECKER_GITEA_URL = https://git.scriptoriumai.io`
- `WOODPECKER_ADMIN = scriptoriumadmin`
- `WOODPECKER_OPEN = true`

Operational implication:

- sign-in is required for Forgejo web viewing
- Forgejo still expects authenticated write access
- Git push auth is still the normal Forgejo model: SSH key or HTTPS credential
- Woodpecker open mode is inherited from the old stack and should be revisited
  later if tighter enrollment is desired

Authentication boundary that should stay explicit:

- "push without prompting every time" is fine when it is still backed by an SSH
  key or stored HTTPS credential
- anonymous unauthenticated internet write access should **not** be enabled on
  the public Forgejo surface

## Remote-development seed state

The current VPS remote-development corpus is seeded under:

- `/home/dev/src`

Current seeded top-level trees:

- `HyperTwist`
- `NyxOS`
- `ScriptoriumAI`
- `VectorShell`
- `VerticalTension`
- `Workspaces`
- `visual_studio_solutions/multi_project`

Current remote-development host profile:

- `12` vCPU
- `23 GiB` RAM
- `16 GiB` swap
- verified toolchains under `dev`:
  - native/C++: `cmake`, `ninja`, `g++`, `clang`, `clangd`, `clang-format`,
    `clang-tidy`, `gdb`, `lldb`, `ccache`
  - JavaScript/TypeScript: `node 22`, `npm 10`, `pnpm`, `yarn`, `bun`
  - Python: `python3`, `pipx`, `uv`
  - Rust: `rust`, `cargo`, `rust-analyzer`, `clippy`, `rustfmt`
  - Go: `go 1.22`
  - .NET: SDK `8.0` and `10.0`
  - supporting CLI: `git-lfs`, `Java 21`, `PowerShell 7`, `jq`, `ripgrep`,
    `fd`, `tmux`, `htop`

Current remote Git auth posture for server-side worktrees:

- `/home/dev/src` main repos now use Forgejo SSH remotes under the `dev` user
- the previous VPS-side HTTPS credential-prompt posture was replaced with SSH
  key-based Git auth for the server worktrees
- if later retreating to local-first development, revert workflow authority to
  the laptop first and only then unwind the VPS-side SSH convenience wiring

Current local SSH stability posture:

- prepared host entries:
  - `scriptoriumai`
  - `scriptoriumai-new`
  - `scriptoriumai-new-dev`
  - direct host entry for `212.227.13.220`
- keepalive settings:
  - `ServerAliveInterval 30`
  - `ServerAliveCountMax 6`
  - `TCPKeepAlive yes`

Operational reading:

- prefer `scriptoriumai-new-dev` for remote development
- short reconnects after transient network blips are acceptable during
  stabilization

## Reverse-sync lane

The local reverse-sync scaffolding now exists here:

- `C:\ScriptoriumAI\ops\ssh\run-vps-remote-dev-reverse-sync.ps1`
- `C:\ScriptoriumAI\ops\ssh\install-vps-remote-dev-reverse-sync-task.ps1`
- scheduled task: `VPS-Remote-Dev-Reverse-Sync`

Current design:

- nightly at `03:30`
- changed-file reverse sync from `/home/dev/src`
- conservative excludes for obviously rebuildable artifacts
- `mirrors` are excluded from the retained reverse-sync payload
- no second full local mirror root by default; it syncs back into the existing
  local project paths when enabled
- the same script can also be pointed at an external-drive destination root for
  an extra offline backup lane when the operator asks for it

Measured retained payload with rebuildable junk and `mirrors` omitted:

- about `18.6 GiB`

Measured omitted `mirrors` payload:

- about `107.9 GiB`

Current safety rule:

- the task refuses to overwrite a dirty local Git worktree by default
- that safeguard currently matters because several local repos are dirty
- the scheduled task is currently enabled again after the `mirrors` exclusion
  reduced the retained payload into the acceptable local storage envelope
- future instances should periodically remind the operator to run or schedule an
  additional reverse sync to external drives for offline backup redundancy

## VerticalTension git/ci alias stance

Canonical Git/CI hostnames remain:

- `git.scriptoriumai.io`
- `ci.scriptoriumai.io`

Safe incorporation path for:

- `git.verticaltension.com`
- `ci.verticaltension.com`

is to treat them as branded aliases that redirect to the canonical ScriptoriumAI
control-plane hosts, not as a second canonical Forgejo/Woodpecker identity.

Why:

- Forgejo `ROOT_URL` and Woodpecker `HOST` are already anchored to the
  ScriptoriumAI hostnames
- dual-canonical hostnames create link, callback, and webhook ambiguity without
  adding real capability

Current prep state:

- the new VPS has HTTPS redirect coverage live for both alias hosts:
  - `git.verticaltension.com`
  - `ci.verticaltension.com`
- both now redirect to the canonical ScriptoriumAI control-plane hosts

## IONOS SSL posture

The current deployment does not depend on paid IONOS SSL products.

Operational rule:

- do not use the IONOS SSL UI to manage the public certificates for these VPS
  hostnames
- the live browser certificate is the one NGINX presents from the VPS
- the current setup is already using Certbot successfully for the public HTTPS
  surface

## Follow-up packaging

Once the cross-project remote-development and backup lane is settled, the VPS
runbook should be copied into the other project documentation surfaces where it
is actually relevant.

For the concrete JetBrains Gateway and Visual Studio registration sequence, see:

- `C:\HyperTwist\docs\ops\HYPERTWIST_REMOTE_DEVELOPMENT_REGISTRATION_PLAN_JETBRAINS_GATEWAY_2026_1_2_AND_VISUAL_STUDIO_2022_2026-05-30.md`

See also:

- `C:\HyperTwist\docs\ops\HYPERTWIST_PLATFORM_TAXONOMY_ALIAS_AND_RENAME_PLAN_2026-05-30.md`
- `C:\HyperTwist\docs\ops\HYPERTWIST_VPS_TLS_CERTIFICATE_AND_IONOS_SEPARATION_GUIDE_2026-05-30.md`
