Files
DevRunbook-Public/docs/43-milestone-zero-host-validation.md
DevRunbook release export cfd2804e27
Managed validation / full (push) Successful in 3m18s
Publish DevRunbook source
2026-09-03 04:09:17 +02:00

6.8 KiB

43 — Milestone 0 host validation

Outcome

Milestone 0 passed its host-dependent acceptance gate on 2026-07-27. The authoritative target was an Unraid 7.2 server (Tower) with Docker 27.5.1, Compose 2.40.3, the pinned Node.js 24.18.0 image, and the pinned PostgreSQL 17.9 image. The workstation's unsupported Node.js 23 runtime was not used as release evidence.

This report closes only Milestone 0. Later product acceptance items remain assigned to their milestones in IMPLEMENTATION_PLAN.md.

Specification and clean install

The validation checkout was created from Git without copying node_modules or build output. A frozen pnpm 10.33.0 install under Node.js 24.18.0 succeeded. The following checks passed:

  • python3 scripts/validate_pack.py: 28 P0 packages, six normative examples, 72 catalog entries, nine schemas, 28 golden prompts, and 68 release-evidence requirements;
  • python3 scripts/reference_compose.py --check: all 28 prompts matched;
  • pnpm verify: formatting, lint, strict typecheck, unit tests, both specification checks, and all 13 production builds;
  • pnpm test:security: 11 tests passed;
  • PostgreSQL-backed integration gates: six files and 15 database tests passed, including idempotent jobs, workspace isolation, guarded leases, stale lease recovery, generated-run persistence, and artifact integrity.

The CI image needed the packages in scripts/requirements-validate.txt; the canonical workflow now installs those exact dependencies before invoking the Python validators.

Production Compose evidence

All targets built from the clean checkout. The production stack started with an empty PostgreSQL volume. The migration service exited successfully, web and worker ran as the unprivileged node user with a read-only root filesystem, and PostgreSQL was not published to the host. Web, worker, and PostgreSQL reached healthy state without a restart loop.

The first worker image exposed an ESM/Pino bundle defect. The standalone bundle was repaired with an ESM-safe createRequire shim and a regression assertion. The rebuilt worker then stayed healthy and processed both a safe system.health-probe job and an unsupported job. The first succeeded; the second reached a terminal job_type_unsupported state without executing job content. A controlled worker restart did not duplicate either job.

/health/live returned 200 while PostgreSQL was deliberately stopped. /health/ready returned 503 with the explicit database-unavailable reason. After PostgreSQL restarted, readiness returned to 200 and both long-running services reconnected.

Running the migration against the initialized database exited zero and left the two recorded migrations unchanged. A migration run against a deliberately unreachable, non-secret test URL exited non-zero with an explicit connection failure; it did not silently continue.

Identity, authorization, catalog, and persistence

Fresh first-run setup returned 201; a repeated setup attempt returned 409. The built-in API returned 28 persisted records. Wrong credentials returned 401, correct local credentials returned 200, and the session survived a service restart. Logout revoked the session. Password reset, expiry, replay, session revocation, and legacy-hash upgrade were exercised against PostgreSQL without exposing reset tokens in logs.

The live workspace matrix proved viewer read, editor write, owner control, cross-workspace denial, disabled-user denial, and no instance-administrator bypass.

pnpm validate:m0-persistence uses the production composer and the real authorization, PostgreSQL, and local-artifact adapters. It rendered the root-cause fixture byte-identically, persisted the immutable run and a 6,806 byte Markdown artifact, and read the artifact back with SHA-256 8389b948158cc35fa1716e170c9893bd3939dc3aaad9311971b6c267f835ae1b. After a full Compose restart, the same command returned the original run and artifact IDs with both created flags false and the same digest.

Browser evidence

The in-app Chromium browser verified the live Unraid deployment at its LAN address:

  • home and package detail rendered persisted catalog data without Gitea;
  • the setup page reported Instance ready and did not reopen first-run;
  • an invalid local sign-in returned the same generic failure and cleared the password field;
  • the root-cause-bugfix detail showed its persisted version and digest;
  • a 390 by 844 viewport had no horizontal overflow;
  • semantic headings, links, inputs, status, alert, and button roles were present;
  • no browser console warnings or errors were recorded.

The canonical Playwright gate separately covers keyboard focus, reduced motion, security headers, recovery, login, and responsive behavior.

Backup and restore drill

A PostgreSQL custom-format logical dump and a compressed artifact-volume archive were created under the restricted validation directory. Their backup digests were recorded on the host. They were restored into a new PostgreSQL 17 volume and a new artifact volume on an isolated Docker network. The validation command found the original run and artifact without creating replacements and verified the 6,806 bytes and SHA-256 shown above. The temporary restore container, network, and volumes were removed after verification; the backup files were retained as operator evidence.

Encryption and session keys are not part of these ordinary backup archives. They remain separate operator secrets and are required independently for a real instance restore.

Security and logging

The configured secret values, authorization headers, and bearer-token markers were absent from production Compose logs. PostgreSQL recorded two deliberate operator validation query errors; neither contained a configured secret. The application services emitted structured, redacted records and no application stack trace after the worker repair.

No default credential, Docker socket, host PID namespace, privileged mode, or arbitrary command-execution path was introduced.

Reproduction commands

From a fresh checkout with the documented environment values set:

corepack pnpm install --frozen-lockfile
python3 -m pip install --requirement scripts/requirements-validate.txt
pnpm verify
pnpm test:security
docker compose build
docker compose up -d
docker compose ps

The persistence validator is intentionally explicit and requires both targets:

DATABASE_URL='postgresql://…' \
ARTIFACT_ROOT='/absolute/artifact/path' \
pnpm validate:m0-persistence

It is a validation client, not an HTTP route or worker job, and never executes repository or imported content.

Milestone boundary

The authenticated composer UI/API, full Library Explorer, repository-profile management, export formats, Gitea adapter, and final release evidence belong to later milestones. They are not claimed by this report. Milestone 1 may begin because the repository contract and first vertical slice now have live proof.