# HWLAB DEV Gate Preflight This preflight is the read-only gate before a real DEV deploy or DEV smoke on D601. It decides whether the current `origin/main` can enter the real `hwlab-dev` runtime path, or whether it is blocked by missing contract, artifact, cluster, registry, edge, or safety evidence. It does not authorize PROD, restart runtime services, read secrets or tokens, substitute UniDesk services for HWLAB runtime, or run heavyweight/browser e2e. ## Command Run from the repository root: ```sh node --check scripts/dev-gate-preflight.mjs node --check scripts/src/dev-gate-preflight.mjs node --check scripts/src/registry-capabilities.mjs node --check scripts/deploy-desired-state-plan.mjs node --check scripts/src/deploy-desired-state-plan.mjs node --check scripts/refresh-artifact-catalog.mjs node scripts/deploy-desired-state-plan.mjs --check node scripts/dev-gate-preflight.mjs ``` The command writes `reports/dev-gate/dev-preflight-report.json` and prints a short JSON summary. A `blocked` conclusion means the preflight ran correctly but found blockers; the command exits zero by default so the report can be committed as evidence. Use `--fail-on-blocked` only in CI jobs that should fail on an open gate. Useful options: ```sh node scripts/dev-gate-preflight.mjs --target-ref origin/main node scripts/dev-gate-preflight.mjs --report reports/dev-gate/dev-preflight-report.json node scripts/dev-gate-preflight.mjs --timeout-ms 5000 node scripts/dev-gate-preflight.mjs --no-write ``` ## Read-Only Scope The preflight checks: - `deploy/deploy.json` and `deploy/artifact-catalog.dev.json` are internally consistent and DEV-only. - `scripts/deploy-desired-state-plan.mjs --check` can be run as a read-only source support check for deploy commit/image/tag/workload/env mirror convergence. It does not contact a registry or prove DEV runtime state. - The deploy manifest, artifact catalog, catalog service commits, and image tags are covered by the selected `origin/main` target. If `origin/main` is a report-only evidence commit whose changes do not touch artifact build inputs, the preflight may accept the artifact source recorded in `reports/dev-gate/dev-artifacts.json`. - The artifact catalog clearly separates source commit, artifact commit, `ciPublished`, `registryVerified`, and per-service digest state. - The artifact catalog has real publish and registry digest evidence, or stays blocked with `not_published` digests. - `reports/dev-gate/dev-artifacts.json`, when present, proves all frozen DEV service artifacts were published for the selected target or for an artifact source commit that still covers the target. - Registry capability evidence is split into `process-http-access`, `docker-daemon-push-access`, and `k3s-pull-access` instead of one ambiguous "registry reachable" result. - `deploy/k8s/base` and `deploy/k8s/dev` parse and remain scoped to `hwlab-dev`. - `hwlab-cloud-api` declares the DEV DB env contract: `HWLAB_CLOUD_DB_URL` from Secret reference `hwlab-cloud-api-dev-db/database-url` and `HWLAB_CLOUD_DB_SSL_MODE=require`. - The local cloud-api health payload reports DB env presence/missing status with redacted values only. This is a readiness gate, not live DB evidence. - `deploy/frp` and `deploy/master-edge` describe the D601-to-master DEV route on public frontend `:16666` and API/edge/live `:16667`. Legacy public `:6666/:6667` observations are historical/deprecated only and must not be used as current green evidence or current active blockers. - The runner can perform read-only `kubectl` probes against `hwlab-dev`. - `reports/dev-gate/dev-edge-health.json`, when present, records read-only public edge, frps, tunnel-health, and k3s observability evidence. - `http://74.48.78.17:16667/health/live` responds. - Catalog image manifests are visible without reading credentials. A failed manifest read is tracked as a #66 registry reachability dimension and must not be conflated with missing publish digests. - Deploy images do not point at UniDesk, provider-gateway, or microservice-proxy substitutes. ## Registry Capability Dimensions `registryCapabilities` appears in both the preflight report and the artifact publish report. The dimensions are: - `process-http-access`: runner-process HTTP access to `/v2/`. A failed `127.0.0.1` request can happen while Docker daemon push access still works, so this dimension is diagnostic and may be `degraded` without blocking publish. - `docker-daemon-push-access`: read-only Docker daemon evidence for the local/internal registry target. This is the publish-path capability. - `k3s-pull-access`: read-only `kubectl` evidence for whether the DEV cluster can inspect image pull state. This is the deploy-path capability. ## Verdict Rules `ready` requires all checks to pass and no open blocker. `degraded` means a non-publish-path capability is observable but incomplete, such as runner-process loopback HTTP refusing `127.0.0.1:5000/v2/` while Docker daemon registry visibility is still present. `blocked` is expected until the real DEV runtime path can be proven. Each blocker includes a `type`, `scope`, `summary`, and `nextTask` so the next task is the smallest repair needed before rerunning the preflight. The DB gate has two common blocked scopes: - `cloud-api-db-env-contract`: manifest/Kubernetes placeholders are incomplete. - `cloud-api-db-health-gate`: runtime env presence is missing. The next task is to configure the DEV Secret/env names, not to print or commit any secret value. For catalog commit mismatch, the preflight emits an `artifactIdentity.refreshCommands.blocked` command. Use it when the source commit changed but publish is still blocked: ```sh node scripts/deploy-desired-state-plan.mjs --target-ref origin/main --pretty node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked ``` Only use the published refresh path after `reports/dev-gate/dev-artifacts.json` proves every frozen service has a registry digest for that same source commit: ```sh node scripts/deploy-desired-state-plan.mjs --target-ref origin/main --pretty node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json ``` Committed DEV artifact reports can prove required service digests only for the source commit they name. If the selected `origin/main` target drifts onto files that change artifact build inputs, the preflight can still reopen `artifact-source-commit` or `dev-artifact-publish` even though the base-image blocker stays closed. Remaining registry manifest-read failures are #66 reachability evidence, not a reason to reopen the base-image blocker. This is M3 virtual hardware trusted-loop support only. It does not claim M3 DEV-LIVE unless a real `DO1 -> patch-panel -> DI1` chain is observed through the current DEV endpoint.