KB-340D

08 — Safe Deploy / Operator Packet

4 min read Revision 1
architecturerpoperator-packetdeployrollback2026-06-06

— 08 SAFE DEPLOY / OPERATOR PACKET

Why deploy is operator-gated: the web source repo is not reachable from this session (absent on the workstation and outside the VPS read allowlist), and applying any fix requires restarting incomex-nuxt, an all-users SSR action. Per the macro, production restart/rebuild executes only on a clean operator path; here it is staged with rollback rather than executed.

Topology the operator needs:

  • Compose: /opt/incomex/docker/docker-compose.yml, service "nuxt", image nuxt-ssr-local:s174, mem_limit 512m.
  • Served bundle is the host bind-mount /opt/incomex/deploys/nuxt-output -> /app/.output. Live handler files: /opt/incomex/deploys/nuxt-output/server/chunks/routes/api/registry/{matrix,pivot-query}.get.mjs (confirmed present, dated 2026-05-31).
  • nginx proxies /api/registry/, /api/registries/, /api/registries-pivot/ and / to nuxt:3000.

PATH 1 — EXPRESS HOTFIX (no rebuild; fixes the 2 existing-route 500s):

  • Script: rp-apply-hotfix.sh (staged on VPS, bash -n clean). Run it ON the VPS host.
  • It backs up the two live handler files to a timestamped backup dir, copies patches/matrix.get.mjs and patches/pivot-query.get.mjs over them, restarts incomex-nuxt, waits for health, runs the smoke harness, and AUTO-ROLLS-BACK (restore + restart) if matrix or pivot-query do not return 200.
  • After this path: matrix 200, pivot-query 200. registries/index remains 404 (a new route needs a rebuild).
  • CAVEAT: this edits build artifacts on the bind-mount; the next legitimate npm build + redeploy of nuxt-output OVERWRITES it. It is a stopgap. Apply the source patches for durability.

PATH 2 — DURABLE FIX (rebuild; fixes all 3):

  • In the web repo apply the three source changes captured by the staged patches: (1) pivot-query handler — drop the jsonb group_spec _neq filter, filter cross in JS; (2) matrix handler — replace the entity_labels REST pull with rpQuery over v_rp_entity_label_facet_counts (facetsCovered from facet_count); (3) add server/api/registries/index.get.ts (candidate staged) OR repoint the /knowledge/registries fetch to /api/registry/composition.
  • Rebuild the Nitro output, deploy it to /opt/incomex/deploys/nuxt-output, restart incomex-nuxt, run the smoke harness; expect PASS (exit 0).

DB prerequisite (already applied, birth-neutral, reversible): the views in 01_apply.sql — including v_rp_entity_label_facet_counts that the matrix fix depends on — are live. Rollback via 99_rollback.sql. Do NOT roll back the substrate view while the matrix patch is deployed.

Git divergence: not assessed against a reachable repo (none present). The durable path must run in the operator's own web repo where divergence/creds are visible; do not force-push over divergence. The express path needs no git at all.

No-go conditions for either path: if post-restart the page (/) does not return 200 within the health window, the hotfix auto-rolls back; for the rebuild path, if smoke shows any new FAIL beyond the expected, redeploy the prior nuxt-output. Never deploy if the smoke harness cannot run.

Back to Knowledge Hub knowledge/dev/reports/architecture/rp-production-api-operator-fix-ui-truth-smoke-2026-06-06/08-safe-deploy-operator-packet.md