Port Completion Gate
Date: 2026-05-05
Objective
Turn the Hetzner port completion audit into a repeatable command.
The goal is simple: the project should not be called complete because many helper scripts exist. It should be called complete only when a gate can point to concrete source files, rebuilt artifacts, full local rebuild evidence, server runtime config, Hetzner milestone evidence, end-to-end product-flow evidence, and backup/restore evidence.
What Was Added
scripts/port-completion-gate.mjsRead-only completion gate for the full Picasso, Zweistein, and Studio API port.package.jsonscripts:port:completion:planport:completion:statusport:completion:check
Safety Rules
- The gate is read-only.
- It does not start servers.
- It does not build Docker images.
- It does not run migrations.
- It does not run
rsync. - It does not read or print runtime env values.
- It intentionally fails until real Hetzner evidence exists.
Commands
Print the completion criteria:
npm run port:completion:plan
Print the current status without failing the shell:
npm run port:completion:status
Fail until every completion criterion has evidence:
npm run port:completion:check
What It Checks
The gate checks:
- project root is
LegacyBlinkin-2-Hetzner; - legacy source files exist for Picasso FE, Zweistein, and Studio API;
- no real
.envfiles are copied insidelegacy-src/; - no obvious secret token patterns are present in scanned project files;
- local non-Python rebuild artifacts exist;
- full local rebuild evidence exists for all services, including Python Query Engine, Ingestion Worker, and Agent/AI runtime behavior;
- Hetzner Compose package, templates, and helper scripts exist;
- real Hetzner runtime config files exist on the server;
- source sync dry-run and push evidence exists;
- complete Linux x64 runbook evidence exists for
readiness,python,build,database,stack, andproxy, including the expected command manifest for each milestone; - Linux x64 staging status evidence exists;
- end-to-end Studio Editor to Houston App to Zweistein Agent/AI evidence exists with a verified
Published App URL:, verifier, password check result, andAgent/AI response observed: yes; - backup and restore rehearsal evidence exists from a recovery target.
Evidence Contracts
The gate intentionally does not accept loose prose as completion evidence.
Local full-stack evidence must live in a file named like:
docs/evidence/<timestamp>-local-full-stack.md
It must include:
# Local Full-Stack Runtime Verification
Status: complete
Target: local
Verifier:
Studio API HTTP 200: yes
Zweistein Server HTTP 200: yes
Zweistein Admin HTTP 200: yes
Zweistein Embedding Widget HTTP 200: yes
Picasso Houston HTTP 200: yes
Picasso Editor HTTP 200: yes
Picasso Widget HTTP 200: yes
Query Engine HTTP 200: yes
Ingestion Worker observed: yes
Agent/AI response observed: yes
Runtime status command: npm run legacy:runtime:status
Evidence collector command: npm run local:full-stack:collect
Live probe source: scripts/local-full-stack-evidence.mjs
End-to-end evidence must live in a file named like:
docs/evidence/<timestamp>-platform-e2e.md
It must include:
# End-to-End Platform Verification
Status: complete
Target: Hetzner staging
Published App URL:
Verifier:
Password protection checked:
Studio Editor
Houston
Zweistein
Agent/AI response observed: yes
Backup/restore evidence must live in a file named like:
docs/evidence/<timestamp>-backup-restore-rehearsal.md
It must include:
# Backup And Restore Rehearsal
Status: complete
Target: recovery
Backup command exit code: 0
Restore command exit code: 0
Health check exit code: 0
Runbook and staging evidence must show Platform: linux x64.
Runbook milestone evidence must also include:
Expected command count:
Milestone complete:
The gate checks that every expected milestone command appears in the ## Expected Commands manifest and in the numbered command output sections. This prevents a shallow completion note from satisfying the port gate.
Current Local Verification Evidence
node --check scripts/port-completion-gate.mjspassed.npm run port:completion:planprints the completion criteria.npm run port:completion:statusreports current pass/fail status without failing.npm run port:completion:checkfails locally as expected while local full-stack evidence, server evidence, and runtime config are missing.- Local full-stack evidence now has to come from the live probe collector path, not only from a copied template.
- Runbook evidence checks now require the expected command manifest for each milestone.
Current Boundary
This gate does not replace the Hetzner runbook. It is the final audit layer above it.
Use the runbook to generate the missing evidence:
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:readiness
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:python
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:build
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:database
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:stack
HETZNER_RUNBOOK_CONFIRM=1 npm run hetzner:runbook:proxy
Then rerun:
npm run port:completion:check
The source sync evidence is generated before the server run:
npm run hetzner:sync:dry-run
HETZNER_SYNC_CONFIRM=1 npm run hetzner:sync:push