#!/usr/bin/env bun import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { DEV_DB_ENV_CONTRACT } from "../internal/cloud/db-contract.ts"; import { DEV_ENDPOINT, ENVIRONMENT_DEV, SERVICE_IDS } from "../internal/protocol/index.mjs"; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); const serviceIdLabel = "hwlab.pikastech.local/service-id"; const namespace = "hwlab-dev"; const forbiddenRuntimeSubstitutes = Object.freeze([ "unidesk-backend", "provider-gateway", "microservice-proxy" ]); async function readText(relativePath) { return readFile(path.join(repoRoot, relativePath), "utf8"); } async function readJSON(relativePath) { const raw = await readText(relativePath); return JSON.parse(raw); } function assertObject(value, label) { assert.ok(value && typeof value === "object" && !Array.isArray(value), `${label} must be an object`); } function assertArray(value, label) { assert.ok(Array.isArray(value), `${label} must be an array`); } function assertUnique(values, label) { assert.equal(new Set(values).size, values.length, `${label} must be unique`); } function assertSameMembers(actual, expected, label) { assert.deepEqual([...actual].sort(), [...expected].sort(), `${label} must match expected members`); } function assertServiceId(serviceId, label) { assert.ok(SERVICE_IDS.includes(serviceId), `${label} uses unknown serviceId ${JSON.stringify(serviceId)}`); assert.match(serviceId, /^hwlab-/, `${label} must be an HWLAB service id`); assertNoForbiddenSubstitute(serviceId, label); } function assertDevOnlyEnvironment(value, label) { assert.equal(value, ENVIRONMENT_DEV, `${label} must be dev`); } function assertDevNamespace(value, label) { assert.equal(value, namespace, `${label} must be ${namespace}`); } function assertForbiddenList(actual, label) { assertArray(actual, label); assertSameMembers(actual, forbiddenRuntimeSubstitutes, label); } function splitCsv(value) { assert.equal(typeof value, "string", "CSV value must be a string"); return value .split(",") .map((item) => item.trim()) .filter(Boolean); } function assertNoForbiddenSubstitute(value, label) { if (typeof value !== "string") { return; } const lower = value.toLowerCase(); for (const forbidden of forbiddenRuntimeSubstitutes) { assert.equal( lower.includes(forbidden), false, `${label} must not use forbidden runtime substitute ${forbidden}` ); } } function assertNoForbiddenSubstitutesDeep(value, label) { if ( label.endsWith(".HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN") || label.endsWith(".forbiddenRuntimeSubstitutes") ) { return; } if (typeof value === "string") { assertNoForbiddenSubstitute(value, label); return; } if (Array.isArray(value)) { value.forEach((item, index) => assertNoForbiddenSubstitutesDeep(item, `${label}[${index}]`)); return; } if (value && typeof value === "object") { if (value.name === "HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN") { return; } for (const [key, item] of Object.entries(value)) { assertNoForbiddenSubstitutesDeep(item, `${label}.${key}`); } } } function containerList(workload, label) { const template = workload.kind === "Job" ? workload.spec?.template : workload.spec?.template; const containers = template?.spec?.containers; assertArray(containers, `${label}.containers`); return containers; } function labelsFor(resource, label) { const labels = resource.metadata?.labels; assertObject(labels, `${label}.metadata.labels`); return labels; } function assertMetadataServiceId(resource, expectedServiceId, label) { if (!resource.metadata?.labels?.["hwlab.pikastech.local/instance-id"]) { assert.equal(resource.metadata?.name, expectedServiceId, `${label}.metadata.name must match service id`); } else { assert.ok(resource.metadata?.name.startsWith(`${expectedServiceId}-`), `${label}.metadata.name must include service id prefix`); } assertDevNamespace(resource.metadata?.namespace, `${label}.metadata.namespace`); const labels = labelsFor(resource, label); assert.equal(labels[serviceIdLabel], expectedServiceId, `${label} service-id label`); assert.equal(labels["app.kubernetes.io/name"], expectedServiceId, `${label} app name label`); } function assertTemplateServiceId(workload, expectedServiceId, label) { const templateLabels = workload.spec?.template?.metadata?.labels; assertObject(templateLabels, `${label}.spec.template.metadata.labels`); assert.equal(templateLabels[serviceIdLabel], expectedServiceId, `${label} template service-id label`); assert.equal(templateLabels["app.kubernetes.io/name"], expectedServiceId, `${label} template app name label`); } function assertHwlabImage(image, serviceId, label) { assert.equal( typeof image, "string", `${label}.image must be a string` ); assert.match( image, new RegExp(`^(ghcr\\.io/pikastech|127\\.0\\.0\\.1:5000/hwlab|localhost:5000/hwlab)/${serviceId}:[a-f0-9]{7,40}$`), `${label}.image must be the HWLAB image for ${serviceId}` ); } function assertHealthProbe(container, serviceId, label) { for (const probeName of ["readinessProbe", "livenessProbe"]) { assert.equal( container[probeName]?.httpGet?.path, "/health/live", `${label}.${probeName} must use /health/live` ); } } function assertNoExternalNameSubstitute(service, label) { assert.notEqual(service.spec?.type, "ExternalName", `${label} must not be an ExternalName substitute`); assert.equal(service.spec?.type, "ClusterIP", `${label} must be a ClusterIP skeleton service`); } function assertKustomizationDevOnly(kustomization, label) { assert.equal(kustomization.kind, "Kustomization", `${label}.kind`); assertDevNamespace(kustomization.namespace, `${label}.namespace`); assert.equal(kustomization.commonLabels?.["hwlab.pikastech.local/profile"], "dev", `${label} profile label`); assert.ok(kustomization.resources?.includes("../base"), `${label} must include ../base`); } function assertRuntimePolicyText(value, label) { assert.equal(typeof value, "string", `${label} must be a string`); assert.ok(value.includes("HWLAB runtime"), `${label} must name HWLAB runtime`); assert.ok(value.includes("UniDesk backend"), `${label} must name UniDesk backend`); assert.ok(value.includes("provider-gateway"), `${label} must name provider-gateway`); assert.ok(value.includes("microservice proxy"), `${label} must name microservice proxy`); } function assertIncludes(value, expected, label) { assert.equal(typeof value, "string", `${label} must be a string`); assert.ok(value.includes(expected), `${label} must include ${JSON.stringify(expected)}`); } function assertDurableRuntimeRunbook(value) { const label = "docs/reference/dev-runtime-boundary.md durable runtime runbook"; for (const expected of [ "DB live readiness and durable runtime readiness are separate gates", "runtime_durable_adapter_query_blocked", "DEV DB Provisioning Automation", "Source migration contract", "Live provisioning apply", "Static runtime boundary contract", "Public health observation", "Live DB read verification", "Live migration/repair apply", "Durable runtime postflight", "Do not run `kubectl get secret`", "secretValuesPrinted=false", "Before any authorized live migration or repair", "After an authorized migration/repair", "Cleared:", "Moved:", "Still blocked:", "No full M3, M4, or M5 acceptance is allowed while runtime durability is blocked", "bun cmd/hwlab-cloud-api/provision.ts --check", "bun cmd/hwlab-cloud-api/provision.ts --dry-run --allow-live-db-read --confirm-dev --report /tmp/hwlab-dev-gate/dev-runtime-provisioning-report.json", "bun cmd/hwlab-cloud-api/provision.ts --apply --confirm-dev --confirmed-non-production --report /tmp/hwlab-dev-gate/dev-runtime-provisioning-report.json", "bun cmd/hwlab-cloud-api/migrate.ts --check", "bun cmd/hwlab-cloud-api/migrate.ts --dry-run --report /tmp/hwlab-dev-gate/dev-runtime-migration-report.json", "bun cmd/hwlab-cloud-api/migrate.ts --apply --confirm-dev --confirmed-non-production --report /tmp/hwlab-dev-gate/dev-runtime-migration-report.json", "DEV CD runtime migration Job uses", "node scripts/dev-runtime-provisioning.mjs --check", "node scripts/dev-runtime-provisioning.mjs --dry-run --allow-live-db-read --confirm-dev --report /tmp/hwlab-dev-gate/dev-runtime-provisioning-report.json", "node scripts/dev-runtime-provisioning.mjs --apply --confirm-dev --confirmed-non-production --report /tmp/hwlab-dev-gate/dev-runtime-provisioning-report.json", "node scripts/dev-runtime-migration.mjs --check", "node scripts/dev-runtime-migration.mjs --dry-run --report /tmp/hwlab-dev-gate/dev-runtime-migration-report.json", "node scripts/dev-runtime-migration.mjs --dry-run --allow-live-db-read --confirm-dev --report /tmp/hwlab-dev-gate/dev-runtime-migration-report.json", "node scripts/dev-runtime-migration.mjs --apply --confirm-dev --confirmed-non-production --report /tmp/hwlab-dev-gate/dev-runtime-migration-report.json", "node scripts/dev-runtime-postflight.mjs --check", "node scripts/dev-runtime-postflight.mjs --live --confirm-dev --confirmed-non-production --target api --report /tmp/hwlab-dev-gate/dev-runtime-postflight-report.json" ]) { assertIncludes(value, expected, label); } } function assertCloudApiImageRuntimeEntrypoints({ packageJson, artifactPublisher, gitopsRenderSource }) { const label = "cloud-api image runtime maintenance entrypoints"; for (const expected of [ "COPY internal ./internal", "COPY cmd ./cmd", "COPY scripts ./scripts", "COPY package.json ./package.json" ]) { assertIncludes(artifactPublisher, expected, `${label} artifact publisher`); } for (const expected of [ "cmd/hwlab-cloud-api/provision.ts", "cmd/hwlab-cloud-api/migrate.ts" ]) { assertIncludes(packageJson.scripts?.check, `bun build ${expected} --target=bun --packages=external`, `${label} package check`); assertIncludes(packageJson.scripts?.check, `bun ${expected} --check`, `${label} package runtime check`); } for (const expected of ["scripts/artifact-publish.mjs", "runtime-dev", "runtime-prod"]) { assertIncludes(gitopsRenderSource, expected, `${label} node GitOps render source`); } for (const expected of ["name: \"prepare-source\"", "name: \"repo-reports-guard\"", "name: \"node-contract-check\"", "name: \"codex-api-forwarder-check\""]) { assertIncludes(gitopsRenderSource, expected, `${label} Tekton primitive CI task`); } } function assertGuardFixture(guard) { assert.equal(guard.guard, "hwlab-runtime-boundary"); assert.equal(guard.schemaVersion, "v1"); assertDevOnlyEnvironment(guard.environment, "guard.environment"); assert.equal(guard.endpoint, DEV_ENDPOINT, "guard.endpoint"); assertDevNamespace(guard.namespace, "guard.namespace"); assert.equal(guard.policy?.runtimeSubstitution, "forbidden", "guard runtime substitution policy"); assert.equal(guard.policy?.prodDeployment, "forbidden", "guard prod policy"); assertForbiddenList(guard.policy?.forbiddenRuntimeSubstitutes, "guard forbidden substitutes"); assertSameMembers(guard.requiredManifest?.requiredServiceIds, SERVICE_IDS, "guard manifest service ids"); assertSameMembers(guard.requiredK3sSkeleton?.requiredWorkloadServiceIds, SERVICE_IDS, "guard workload service ids"); assert.ok( guard.validation?.commands?.includes("node scripts/validate-runtime-boundary.mjs"), "guard must record executable validation command" ); } function assertDeployManifest(manifest, guard) { assert.equal(manifest.manifestVersion, "v1"); assertDevOnlyEnvironment(manifest.environment, "deploy manifest environment"); assertDevNamespace(manifest.namespace, "deploy manifest namespace"); assert.equal(manifest.endpoint, DEV_ENDPOINT, "deploy manifest endpoint"); assert.ok(manifest.profiles?.dev?.enabled, "deploy manifest dev profile must be enabled"); assertDevNamespace(manifest.profiles.dev.namespace, "deploy manifest dev profile namespace"); assert.equal(manifest.profiles.dev.endpoint, DEV_ENDPOINT, "deploy manifest dev profile endpoint"); assert.equal(manifest.profiles?.prod?.enabled, false, "deploy manifest prod profile must stay disabled"); assertArray(manifest.services, "deploy manifest services"); const serviceIds = manifest.services.map((service) => service.serviceId); assertUnique(serviceIds, "deploy manifest service ids"); assertSameMembers(serviceIds, guard.requiredManifest.requiredServiceIds, "deploy manifest service ids"); assertSameMembers(serviceIds, SERVICE_IDS, "deploy manifest service ids"); for (const service of manifest.services) { assertServiceId(service.serviceId, `deploy service ${service.serviceId}`); assertHwlabImage(service.image, service.serviceId, `deploy service ${service.serviceId}`); assertDevNamespace(service.namespace, `${service.serviceId}.namespace`); assert.equal(service.profile, "dev", `${service.serviceId}.profile must be dev`); assert.match(service.healthPath, /^\//, `${service.serviceId}.healthPath must be absolute`); assertNoForbiddenSubstitutesDeep(service.env ?? {}, `${service.serviceId}.env`); } const cloudApi = manifest.services.find((service) => service.serviceId === "hwlab-cloud-api"); assertForbiddenList( splitCsv(cloudApi?.env?.HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN), "hwlab-cloud-api HWLAB_RUNTIME_SUBSTITUTE_FORBIDDEN" ); } function assertMasterHealthContract(contract, guard) { assertDevOnlyEnvironment(contract.environment, "master health contract environment"); assert.equal(contract.endpoint, DEV_ENDPOINT, "master health contract endpoint"); assert.equal(contract.prodAcceptance, false, "master health contract prodAcceptance"); assert.equal(contract.reverseLink?.mode, guard.requiredHealthContract.reverseLink.mode, "reverse link mode"); assert.equal( contract.reverseLink?.direction, guard.requiredHealthContract.reverseLink.direction, "reverse link direction" ); assert.equal(contract.reverseLink?.client, "hwlab-tunnel-client", "reverse link client"); assert.equal(contract.reverseLink?.publicPort, 16667, "reverse link public port"); assertForbiddenList(contract.forbiddenRuntimeSubstitutes, "master forbidden substitutes"); assertArray(contract.contracts, "master health contracts"); const serviceIds = contract.contracts.map((item) => item.serviceId); assertUnique(serviceIds, "master health contract service ids"); assertSameMembers( serviceIds, guard.requiredHealthContract.requiredContractServiceIds, "master health contract service ids" ); for (const item of contract.contracts) { assertServiceId(item.serviceId, `master health contract ${item.serviceId}`); } } function assertWorkloads(workloads, guard) { assert.equal(workloads.kind, "List", "workloads kind"); assertArray(workloads.items, "workloads items"); const serviceIds = workloads.items.map((item) => item.metadata?.labels?.[serviceIdLabel]); assertUnique(serviceIds, "workload service ids"); assertSameMembers(serviceIds, guard.requiredK3sSkeleton.requiredWorkloadServiceIds, "workload service ids"); for (const workload of workloads.items) { const serviceId = workload.metadata?.labels?.[serviceIdLabel]; assertServiceId(serviceId, `workload ${workload.metadata?.name}`); const expectedName = workload.kind === "Job" ? `${serviceId}-template` : serviceId; assert.equal(workload.metadata?.name, expectedName, `${serviceId} workload name`); assertDevNamespace(workload.metadata?.namespace, `${serviceId} workload namespace`); assert.equal(labelsFor(workload, serviceId)["app.kubernetes.io/name"], serviceId, `${serviceId} workload app label`); assertTemplateServiceId(workload, serviceId, `workload ${serviceId}`); const containers = containerList(workload, `workload ${serviceId}`); assert.ok(containers.length >= 1, `${serviceId} workload must define at least one container`); assertUnique( containers.map((container) => container.name), `${serviceId} container names` ); const primaryContainer = containers.find((container) => container.name === serviceId); assert.ok(primaryContainer, `${serviceId} workload must include primary container ${serviceId}`); for (const container of containers) { assertHwlabImage(container.image, serviceId, `${serviceId} container ${container.name}`); assertNoForbiddenSubstitutesDeep(container.env ?? [], `${serviceId} container ${container.name} env`); } assertHealthProbe(primaryContainer, serviceId, `${serviceId} container ${serviceId}`); } } function assertServices(services, guard) { assert.equal(services.kind, "List", "services kind"); assertArray(services.items, "services items"); const runtimeServices = services.items; const serviceNames = runtimeServices.map((item) => item.metadata?.name); const serviceIds = [...new Set(runtimeServices.map((item) => item.metadata?.labels?.[serviceIdLabel]))]; assertUnique(serviceNames, "k8s service names"); assertSameMembers(serviceIds, guard.requiredK3sSkeleton.requiredServiceServiceIds, "k8s service ids"); assert.equal( services.items.some((item) => item.metadata?.name === DEV_DB_ENV_CONTRACT.dns.serviceName), false, "cloud-api-db is an optional future alias and is not required in the current runtime boundary" ); assert.equal(DEV_DB_ENV_CONTRACT.endpointAuthority.source, "secret-url-host", "DB readiness authority must be the Secret URL host"); assert.equal(DEV_DB_ENV_CONTRACT.dns.requiredForReadiness, false, "DB DNS alias must not be a readiness hard requirement"); assert.equal(DEV_DB_ENV_CONTRACT.dns.usedForProbe, false, "DB DNS alias must not be the runtime probe target"); for (const service of runtimeServices) { const serviceId = service.metadata?.labels?.[serviceIdLabel]; assertServiceId(serviceId, `k8s service ${service.metadata?.name}`); assertMetadataServiceId(service, serviceId, `k8s service ${serviceId}`); assertNoExternalNameSubstitute(service, `k8s service ${serviceId}`); if (service.metadata?.labels?.["hwlab.pikastech.local/instance-id"]) { assert.match( service.spec?.selector?.["statefulset.kubernetes.io/pod-name"], new RegExp(`^${escapeRegExp(serviceId)}-\\d+$`), `${serviceId} indexed selector` ); } else { assert.equal(service.spec?.selector?.["app.kubernetes.io/name"], serviceId, `${serviceId} selector`); } } } function escapeRegExp(value) { return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function assertDevHealthConfig(configMap) { assert.equal(configMap.kind, "ConfigMap", "dev health contract kind"); assertDevNamespace(configMap.metadata?.namespace, "dev health contract namespace"); assert.equal(configMap.data?.endpoint, DEV_ENDPOINT, "dev health contract endpoint"); assertRuntimePolicyText(configMap.data?.["runtime-substitute-policy"], "dev runtime substitute policy"); } function assertProdDisabled(prodKustomization, prodDisabled) { assert.equal(prodKustomization.kind, "Kustomization", "prod kustomization kind"); assert.deepEqual(prodKustomization.resources, ["prod-disabled.yaml"], "prod kustomization resources"); assert.equal(prodDisabled.kind, "ConfigMap", "prod disabled kind"); assert.equal(prodDisabled.metadata?.labels?.["hwlab.pikastech.local/profile"], "prod", "prod disabled profile"); assert.equal( prodDisabled.metadata?.labels?.["hwlab.pikastech.local/acceptance"], "disabled", "prod disabled acceptance" ); assert.equal(prodDisabled.data?.status, "disabled", "prod disabled status"); } const guard = await readJSON("protocol/examples/runtime-boundary/guard.dev.json"); assertGuardFixture(guard); assertDeployManifest(await readJSON(guard.requiredManifest.path), guard); assertMasterHealthContract(await readJSON(guard.requiredHealthContract.path), guard); assertWorkloads(await readJSON(guard.requiredK3sSkeleton.workloadsPath), guard); assertServices(await readJSON(guard.requiredK3sSkeleton.servicesPath), guard); assertKustomizationDevOnly(await readJSON(guard.requiredK3sSkeleton.devKustomizationPath), "dev kustomization"); assertDevHealthConfig(await readJSON(guard.requiredK3sSkeleton.devHealthContractPath)); assertProdDisabled( await readJSON(guard.requiredK3sSkeleton.prodKustomizationPath), await readJSON(guard.requiredK3sSkeleton.prodDisabledPath) ); assertDurableRuntimeRunbook(await readText("docs/reference/dev-runtime-boundary.md")); assertCloudApiImageRuntimeEntrypoints({ packageJson: await readJSON("package.json"), artifactPublisher: await readText("scripts/artifact-publish.mjs"), gitopsRenderSource: await readText("scripts/gitops-render.mjs") }); console.log( `validated HWLAB runtime boundary guard for ${SERVICE_IDS.length} services; forbidden substitutes: ${forbiddenRuntimeSubstitutes.join(", ")}` );