Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/scripts/docker-runtime-smoke-contract.test.mjs
T

734 lines
42 KiB
JavaScript

import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { ECDH } from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { describe, it } from "vitest";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootDir = path.resolve(__dirname, "..");
const smokeScripts = [
"scripts/docker-web-runtime-smoke.sh",
"scripts/docker-api-runtime-smoke.sh",
"scripts/docker-mcp-runtime-smoke.sh",
"scripts/docker-worker-runtime-smoke.sh",
"scripts/docker-hocuspocus-runtime-smoke.sh",
];
const allSmokeScripts = [...smokeScripts, "scripts/docker-portal-domain-controller-runtime-smoke.sh"];
describe("Docker runtime smoke contract", () => {
it.each([
["Dockerfile", "hivegrid-pnpm-store-v2", 3],
["apps/hocuspocus/Dockerfile", "hivegrid-hocuspocus-pnpm-store", 3],
])("locks each writable pnpm store: %s (%s)", (relativePath, cacheId, expectedMounts) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const storeMounts = source.match(new RegExp(`--mount=type=cache,id=${cacheId},[^\\s\\\\]+`, "g")) ?? [];
assert.equal(storeMounts.length, expectedMounts);
assert.equal(
storeMounts.every((mount) => mount.includes("sharing=locked")),
true
);
});
it("builds all production closures in one locked warm-store bundle", () => {
const source = fs.readFileSync(path.join(rootDir, "Dockerfile"), "utf8");
const normalized = source.replace(/\\\r?\n\s*/gu, " ");
const bundleBody = normalized.match(/^FROM build AS production-deps-bundle\s*$([\s\S]*?)(?=^FROM\s)/mu)?.[1] ?? "";
const bundleInstructions = bundleBody
.split("\n")
.map((line) => line.replace(/\s+/gu, " ").trim())
.filter((line) => line.length > 0 && !line.startsWith("#"));
assert.deepEqual(bundleInstructions, [
"RUN --mount=type=cache,id=hivegrid-pnpm-store-v2,target=/pnpm/store,sharing=locked bash scripts/ci/deploy-production-closures.sh",
]);
assert.doesNotMatch(source, /hivegrid-pnpm-store-v5-production|PNPM_STORE_CACHE_SCOPE|sharing=shared(?:,ro)?/u);
assert.equal((source.match(/FROM production-deps-bundle AS [a-z-]+-production-deps/gu) ?? []).length, 5);
assert.equal((source.match(/pnpm --offline[^\n]* deploy /gu) ?? []).length, 0);
});
it("deploys every production closure concurrently and collects every result in each wave", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/ci/deploy-production-closures.sh"), "utf8");
const normalized = source.replace(/\\\r?\n\s*/gu, " ").replace(/\s+/gu, " ");
const runWave = source.match(/^run_wave\(\)\s*\{\s*\n([\s\S]*?)^\}/mu)?.[1] ?? "";
for (const target of ["web", "api", "mcp", "worker", "portal-domain-controller"]) {
assert.match(source, new RegExp(`--filter @hivegrid/runtime-${target} deploy`, "u"));
}
assert.equal((source.match(/pnpm --offline/gu) ?? []).length, 5);
assert.match(runWave, /local -a pids=\(\)/u);
assert.match(runWave, /"\$task" &/u);
assert.match(runWave, /pids\+=\("\$!"\)/u);
assert.match(runWave, /for index in "\$\{!pids\[@\]\}"; do/u);
assert.match(runWave, /if wait "\$\{pids\[\$index\]\}"; then/u);
assert.match(runWave, /if \[\[ "\$status" -eq 0 \]\]; then\s+status="\$child_status"/u);
assert.match(runWave, /return "\$status"/u);
assert.equal((normalized.match(/\brun_wave (?:offline-first|after-fetch)\b/gu) ?? []).length, 2);
});
it("refreshes a missed warm store once, retries one complete wave, and fails closed", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/ci/deploy-production-closures.sh"), "utf8");
const normalized = source
.replace(/\\\r?\n\s*/gu, " ")
.replace(/\s+/gu, " ")
.trim();
const initialWaveIndex = normalized.indexOf("run_wave offline-first || initial_status=$?");
const cleanupIndex = normalized.indexOf('for target in "${targets[@]}"; do rm -rf -- "/prod/${target}" done');
const fetchIndex = normalized.indexOf("if pnpm fetch --frozen-lockfile; then");
const retryIndex = normalized.indexOf("run_wave after-fetch || retry_status=$?");
assert.match(source, /^tasks=\(deploy_web deploy_api deploy_mcp deploy_portal_controller deploy_worker\)$/mu);
assert.match(source, /^targets=\(web api mcp portal-domain-controller worker\)$/mu);
assert.equal((source.match(/\brm -rf\b/gu) ?? []).length, 1);
assert.equal((source.match(/\bpnpm fetch --frozen-lockfile\b/gu) ?? []).length, 1);
assert.ok(initialWaveIndex >= 0 && cleanupIndex > initialWaveIndex && fetchIndex > cleanupIndex && retryIndex > fetchIndex);
assert.match(
normalized,
/if \[\[ "\$initial_status" -eq 0 \]\]; then .* exit 0 fi .* if pnpm fetch --frozen-lockfile; then .* else fetch_status=\$\? .* exit "\$fetch_status" fi/u
);
assert.match(
normalized,
/retry_status=0 run_wave after-fetch \|\| retry_status=\$\? if \[\[ "\$retry_status" -ne 0 \]\]; then .* exit "\$retry_status" fi/u
);
assert.doesNotMatch(source, /sentinel|sha256sum|lockfile[_-]?hash/iu);
assert.doesNotMatch(source, /\brm\s+-rf\s+(?:--\s+)?["']?\/prod["']?(?:\s|;|$)/u);
assert.doesNotMatch(source, /\brm\s+-rf\s+(?:--\s+)?["']?\/prod\/\*/u);
assert.doesNotMatch(source, /\|\|\s*(?:true|:|exit\s+0)\b/u);
});
it("rehydrates the hocuspocus production store in the deploy layer", () => {
const source = fs.readFileSync(path.join(rootDir, "apps/hocuspocus/Dockerfile"), "utf8");
const normalized = source.replace(/\\\r?\n\s*/gu, " ");
const deploys = normalized
.split("\n")
.filter(
(line) =>
line.includes("RUN --mount=type=cache,id=hivegrid-hocuspocus-pnpm-store,target=/pnpm/store,sharing=locked") &&
line.includes("pnpm fetch --frozen-lockfile") &&
line.includes("&& pnpm --offline") &&
line.includes(" deploy ")
);
assert.equal(deploys.length, 1);
});
it.each(allSmokeScripts)("isolates Docker resources by run and installs bounded cleanup traps: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const cleanupBlock = source.match(/cleanup\(\) \{([\s\S]*?)\n\}/u)?.[1] ?? "";
assert.match(source, /source "\$\(dirname "\$\{BASH_SOURCE\[0\]\}"\)\/lib\/docker-runtime-smoke\.sh"/);
assert.match(source, /DOCKER_SMOKE_RUN_ID="\$\{DOCKER_SMOKE_RUN_ID:-\$\$\}"/);
assert.match(source, /\^\[A-Za-z0-9_\.\-\]\+\$/);
assert.match(source, /docker_smoke_install_cleanup_traps cleanup/);
assert.match(cleanupBlock, /docker_smoke_cleanup_(?:container|network|volume)/);
assert.doesNotMatch(cleanupBlock, /\bdocker\s+(?:rm|network\s+rm|volume\s+rm)\b/);
assert.doesNotMatch(source, /trap cleanup EXIT/);
assert.ok((cleanupBlock.match(/docker_smoke_cleanup_(?:container|network|volume)/gu) ?? []).length <= 3);
execFileSync("bash", ["-n", path.join(rootDir, relativePath)]);
});
it.each(allSmokeScripts)("names every Docker one-shot with the run-scoped cleanup contract: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const oneShots = source.split("\n").filter((line) => line.includes("docker run --rm"));
assert.ok(oneShots.length > 0);
assert.equal(
oneShots.every((line) => line.includes("--name")),
true
);
});
it("bounds Postgres readiness by an absolute shared deadline", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/lib/docker-runtime-smoke.sh"), "utf8");
const helper = source.match(/docker_smoke_wait_for_postgres\(\) \{([\s\S]*?)\n\}/u)?.[1] ?? "";
assert.match(helper, /deadline_seconds=\$\(\(SECONDS \+ DOCKER_SMOKE_DATABASE_READY_TIMEOUT_SECONDS\)\)/u);
assert.match(helper, /while \[\[ "\$SECONDS" -lt "\$deadline_seconds" \]\]; do/u);
assert.match(helper, /docker_smoke_probe "\$stage" docker exec "\$container_name"/u);
assert.match(helper, /pg_isready -h 127\.0\.0\.1 -U "\$database_user" -d "\$database_name"/u);
assert.doesNotMatch(helper, /seq|attempt/u);
});
it.each(smokeScripts)("uses the shared bounded Postgres readiness helper: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const readinessBlock = source.match(/if ! docker_smoke_wait_for_postgres ([\s\S]*?)\nfi/u)?.[1] ?? "";
assert.match(readinessBlock, /"\$DB_CONTAINER_NAME" "\$DB_USER" "\$DB_NAME"/u);
assert.match(readinessBlock, /DOCKER_SMOKE_DATABASE_READY_TIMEOUT_SECONDS/u);
assert.match(readinessBlock, /docker_smoke_logs|emit_runtime_logs/u);
assert.match(readinessBlock, /exit 1/u);
assert.doesNotMatch(source, /for attempt in \$\(seq 1 "\$DOCKER_SMOKE_DATABASE_READY_TIMEOUT_SECONDS"\)/u);
});
it.each([
["scripts/docker-web-runtime-smoke.sh", "web:migrate:initial"],
["scripts/docker-api-runtime-smoke.sh", "api:migrate"],
["scripts/docker-mcp-runtime-smoke.sh", "mcp:migrate"],
["scripts/docker-worker-runtime-smoke.sh", "worker:migrate"],
["scripts/docker-hocuspocus-runtime-smoke.sh", "hocuspocus:migrate"],
])("streams migration failures through a named timeout stage: %s", (relativePath, stage) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
if (relativePath.endsWith("docker-web-runtime-smoke.sh")) {
assert.match(source, new RegExp(`run_migrator MIGRATOR_LOGS "${stage}"`));
assert.match(source, /docker_smoke_capture "\$output_variable" "\$stage" "\$DOCKER_SMOKE_MIGRATION_TIMEOUT_SECONDS"/);
} else {
assert.match(source, new RegExp(`docker_smoke_run "${stage}" "\\$DOCKER_SMOKE_MIGRATION_TIMEOUT_SECONDS"`));
}
assert.doesNotMatch(source, /migrate\s*>\/dev\/null/);
});
it.each([
["scripts/docker-web-runtime-smoke.sh", "web:provision-rls-roles"],
["scripts/docker-api-runtime-smoke.sh", "api:provision-rls-roles"],
["scripts/docker-mcp-runtime-smoke.sh", "mcp:provision-rls-roles"],
["scripts/docker-worker-runtime-smoke.sh", "worker:provision-rls-roles"],
["scripts/docker-hocuspocus-runtime-smoke.sh", "hocuspocus:provision-rls-roles"],
])("runs RLS role provisioning through a named command timeout: %s", (relativePath, stage) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const roleFixture = fs.readFileSync(path.join(rootDir, "scripts/lib/docker-rls-role-fixture.sh"), "utf8");
assert.match(source, new RegExp(`provision_docker_smoke_rls_roles \\\\\\n "${stage}"`));
assert.match(roleFixture, /docker_smoke_run "\$stage" "\$DOCKER_SMOKE_ROLE_PROVISION_TIMEOUT_SECONDS"/);
});
it.each([
["scripts/docker-worker-runtime-smoke.sh", "worker:reject-spoofed-revision"],
["scripts/docker-worker-runtime-smoke.sh", "worker:reject-wrong-group"],
["scripts/docker-worker-runtime-smoke.sh", "worker:reject-disabled"],
["scripts/docker-mcp-runtime-smoke.sh", "mcp:reject-spoofed-revision"],
["scripts/docker-mcp-runtime-smoke.sh", "mcp:reject-redis-outage"],
["scripts/docker-mcp-runtime-smoke.sh", "mcp:reject-db-outage"],
["scripts/docker-portal-domain-controller-runtime-smoke.sh", "portal-controller:reject-foreign-revision"],
])("distinguishes an expected product rejection from infrastructure failure: %s", (relativePath, stage) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
assert.match(source, new RegExp(`docker_smoke_expect_docker_exec_rejection "${stage}" "\\$DOCKER_SMOKE_PROBE_TIMEOUT_SECONDS" "\\$CONTAINER_NAME"`));
assert.doesNotMatch(source, new RegExp(`docker_smoke_probe "${stage}"`));
});
it("fails closed when portal-controller environment inspection cannot run", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-portal-domain-controller-runtime-smoke.sh"), "utf8");
assert.match(source, /docker_smoke_capture RUNTIME_ENV_KEYS "portal-controller:inspect-runtime-env"/);
assert.ok(source.includes("| sed '\\''s/=.*//'\\'''"));
assert.match(source, /grep -qx "\$forbidden" <<<"\$RUNTIME_ENV_KEYS"/);
assert.doesNotMatch(source, /docker_smoke_run "portal-controller:inspect-runtime-env"[\s\S]{0,180}\| grep/);
});
it("diagnoses portal-controller status mismatches with expected values and bounded logs", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-portal-domain-controller-runtime-smoke.sh"), "utf8");
assert.match(source, /expect_status\(\)/);
assert.match(source, /returned \$\{actual:-<empty>\}, expected \$\{expected\}/);
assert.match(source, /docker_smoke_logs "portal-controller:logs-status"/);
assert.match(source, /expect_status \/healthz 200/);
assert.match(source, /expect_status \/readyz 200/);
assert.match(source, /expect_status \/metrics 401/);
assert.match(source, /expect_status \/metrics 200 "\$METRICS_TOKEN"/);
assert.doesNotMatch(source, /^\[\[ "\$\(http_status \/(?:healthz|readyz|metrics)[^\n]*\]\]$/mu);
});
it("does not reuse a global worker temp file and derives one-shot names from the run ID", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
assert.doesNotMatch(source, /\/tmp\/hivegrid-worker-runtime-smoke/);
assert.match(source, /DISABLED_HEALTH_CONTAINER_NAME=.*\$\{DOCKER_SMOKE_RUN_ID\}/);
assert.match(source, /ENABLED_HEALTH_CONTAINER_NAME=.*\$\{DOCKER_SMOKE_RUN_ID\}/);
assert.match(source, /MAIL_HEALTH_CONTAINER_NAME=.*\$\{DOCKER_SMOKE_RUN_ID\}/);
});
it("derives the portal-controller revision from the exact image instead of a fake SHA", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-portal-domain-controller-runtime-smoke.sh"), "utf8");
assert.doesNotMatch(source, /0123456789abcdef0123456789abcdef01234567/);
assert.match(source, /org\.opencontainers\.image\.revision/);
assert.match(source, /EXPECTED_REVISION="\$IMAGE_REVISION"/);
});
it.each(smokeScripts)("reads the expected revision from the built image label: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
assert.match(source, /docker image inspect -f '\{\{ index \.Config\.Labels "org\.opencontainers\.image\.revision" \}\}' "\$IMAGE"/);
assert.match(source, /SMOKE_REVISION="\$\(resolve_smoke_revision\)"/);
});
it.each(smokeScripts)("rejects Dockerfile's default unknown revision: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
assert.match(source, /\$SMOKE_REVISION" == "unknown"/);
assert.match(source, /does not expose a concrete org\.opencontainers\.image\.revision/);
});
it.each(smokeScripts)("does not override APP_REVISION when launching the runtime: %s", (relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const sourceWithoutNegativeSpoofChecks = source
.split("\n")
.filter((line) => !line.includes('docker exec -e APP_REVISION="$MISMATCHED_REVISION"'))
.join("\n");
assert.doesNotMatch(sourceWithoutNegativeSpoofChecks, /-e APP_REVISION=/);
});
it.each(["scripts/docker-mcp-runtime-smoke.sh", "scripts/docker-worker-runtime-smoke.sh"])(
"proves that runtime APP_REVISION spoofing fails closed: %s",
(relativePath) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
assert.match(source, /env APP_REVISION="\$MISMATCHED_REVISION"/);
assert.match(source, /docker_smoke_expect_docker_exec_rejection "(?:mcp|worker):reject-spoofed-revision"/);
}
);
it("validates the API runtime OpenAPI JSON contract", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-api-runtime-smoke.sh"), "utf8");
assert.match(source, /expect_openapi_json/);
assert.match(source, /\/v1\/openapi\.json/);
assert.match(source, /payload\.paths\["\/v1\/session\/current-user"\]/);
assert.doesNotMatch(source, /payload\.paths\["\/v1\/workflows\/run\/\{id\}"\]/);
});
it("keeps the separately deployed API surface out of the web runtime", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.doesNotMatch(source, /expect_openapi_json/);
assert.match(source, /expect_status api\.localhost \/v1\/docs 404/);
assert.match(source, /expect_status api\.localhost \/v1\/openapi\.json 404/);
assert.match(source, /expect_status api\.localhost \/v1\/health 404/);
});
it("requires the built web runtime to expose a fetch-capable service-worker CSP", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /expect_status app\.localhost \/sw\.js 200/);
assert.match(source, /expect_service_worker_csp app\.localhost/);
assert.match(source, /connect-src 'self'/);
assert.match(source, /connect-src 'none'/);
});
it("requires the built login document to recover already-controlled tabs before stylesheet discovery", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /expect_service_worker_recovery_bootstrap app\.localhost/);
assert.match(source, /service-worker-csp-recovery:v3/);
assert.match(source, /stylesheetIndex <= markerIndex/);
assert.match(source, /nonce=/);
});
it("boots the web runtime with a valid public VAPID fixture", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
const publicKey = source.match(/SMOKE_WEB_PUSH_VAPID_PUBLIC_KEY='([^']+)'/)?.[1];
assert.ok(publicKey);
assert.doesNotThrow(() => ECDH.convertKey(publicKey, "prime256v1", "base64url", "hex", "uncompressed"));
assert.match(source, /-e WEB_PUSH_VAPID_PUBLIC_KEY="\$SMOKE_WEB_PUSH_VAPID_PUBLIC_KEY"/);
});
it("boots all three web surfaces with the same encrypted GDPR export storage fixture", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
const coreLaunch = source.indexOf('docker run -d --name "$CONTAINER_NAME"');
const adminLaunch = source.indexOf('docker run -d --name "$ADMIN_CONTAINER_NAME"');
const portalLaunch = source.indexOf('docker run -d --name "$PORTAL_CONTAINER_NAME"');
const coreRuntime = source.slice(coreLaunch, adminLaunch);
const adminRuntime = source.slice(adminLaunch, portalLaunch);
const portalRuntime = source.slice(portalLaunch);
const fixtureKey = source.match(/SMOKE_GDPR_EXPORT_SSE_C_KEY_BASE64='([^']+)'/)?.[1];
const requiredStorageEnv = [
"STORAGE_ENDPOINT='https://storage.example.test'",
"STORAGE_REGION='eu-central-1'",
"STORAGE_BUCKET='docker-smoke-private-exports'",
"STORAGE_ACCESS_KEY_ID='docker-smoke-storage-access-key'",
"STORAGE_SECRET_ACCESS_KEY='docker-smoke-storage-secret-key'",
"STORAGE_SESSION_TOKEN='docker-smoke-storage-session-token'",
"STORAGE_FORCE_PATH_STYLE=false",
'GDPR_EXPORT_SSE_C_KEY_BASE64="$SMOKE_GDPR_EXPORT_SSE_C_KEY_BASE64"',
];
assert.ok(coreLaunch >= 0 && adminLaunch > coreLaunch && portalLaunch > adminLaunch);
assert.ok(fixtureKey);
assert.equal(Buffer.from(fixtureKey, "base64").byteLength, 32);
for (const env of requiredStorageEnv) {
assert.equal(coreRuntime.includes(`-e ${env}`), true);
assert.equal(adminRuntime.includes(`-e ${env}`), true);
assert.equal(portalRuntime.includes(`-e ${env}`), true);
}
});
it("proves password login and server-session persistence in the exact web image under required RLS", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /SMOKE_LOGIN_EMAIL="[^"]+@mitarbeiter\.example\.test"/);
assert.match(source, /docker run --rm --name "\$PASSWORD_HASH_CONTAINER_NAME" --entrypoint node "\$IMAGE" -e/);
assert.match(source, /import\("argon2"\)/);
assert.match(source, /type: argon2\.argon2id/);
assert.match(source, /INSERT INTO "User"/);
assert.match(source, /INSERT INTO "TenantUser"/);
assert.match(source, /"active"\)\s*\nVALUES \([^\n]+true\);/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(source, /-e WEB_RUNTIME_SURFACE=core/);
assert.match(source, /-e PORTAL_APP_HOST=portal\.localhost/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.match(source, /-e SENTRY_ENVIRONMENT=staging/);
assert.match(source, /-e STAGING_DEMO_LOGIN_ENABLED=true/);
assert.match(source, /expect_password_login_session/);
assert.match(source, /name=\["\\x27\]csrf-token/);
assert.match(source, /loginPage\.headers\["set-cookie"\]/);
assert.match(source, /Cookie: cookieHeader/);
assert.match(source, /Origin: "http:\/\/app\.localhost"/);
assert.match(source, /Referer: "http:\/\/app\.localhost\/login"/);
assert.match(source, /__Host-hivegrid_app_session=/);
assert.match(source, /FROM "UserSession"/);
assert.match(source, /"revokedAt" IS NULL/);
assert.match(source, /"expiresAt" > now\(\)/);
assert.match(source, /active_session_count" != "1"/);
assert.doesNotMatch(source, /(?:echo|printf)[^\n]*SMOKE_LOGIN_PASSWORD(?:_HASH)?/);
});
it("runs migration in a DIRECT_URL-only one-shot web container before the app runtime", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /provision_docker_smoke_rls_roles/);
assert.match(source, /-e DIRECT_URL="\$MIGRATOR_DATABASE_URL"/);
assert.match(source, /"\$IMAGE" migrate/);
assert.match(source, /One-shot migrator logs are missing the migration banner/);
assert.match(source, /permission-catalog-sync-complete/);
assert.match(source, /run_migrator SECOND_MIGRATOR_LOGS "web:migrate:idempotency"/);
assert.match(source, /run_migrator THIRD_MIGRATOR_LOGS "web:migrate:drift-repair"/);
assert.match(source, /docker_smoke_capture "\$output_variable" "\$stage" "\$DOCKER_SMOKE_MIGRATION_TIMEOUT_SECONDS"/);
assert.match(source, /--name "\$MIGRATION_CONTAINER_NAME"/);
assert.match(source, /docker_smoke_run "web:db-push" "\$DOCKER_SMOKE_MIGRATION_TIMEOUT_SECONDS"/);
assert.match(source, /--name "\$DB_PUSH_CONTAINER_NAME"/);
assert.doesNotMatch(source, /db push[\s\S]{0,160}>\/dev\/null/);
assert.match(source, /seed_permission_catalog_sentinel/);
assert.match(source, /inject_permission_catalog_drift/);
assert.match(source, /Idempotent permission catalog sync changed canonical catalog state/);
assert.match(source, /Permission catalog drift repair mutated a tenant-owned template role/);
assert.match(source, /Permission catalog drift repair did not restore canonical values and grants/);
assert.match(source, /relation\.relforcerowsecurity AS force_rls/);
assert.match(source, /NOT has_table_dml AND NOT has_column_dml/);
assert.match(source, /-e DATABASE_URL="\$APP_DATABASE_URL"/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.doesNotMatch(source, /-e MIGRATE_ON_BOOT=/);
assert.doesNotMatch(source, /-e SEED_ON_BOOT=/);
assert.doesNotMatch(source, /RLS_RUNTIME_MODE=off/);
});
it("boots the exact web image as the isolated portal surface against the disposable migrated database", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
const roleFixture = fs.readFileSync(path.join(rootDir, "scripts/lib/docker-rls-role-fixture.sh"), "utf8");
const migration = source.indexOf('"$IMAGE" migrate');
const coreReadiness = source.indexOf("expect_status app.localhost /readyz 200");
const legacyRecut = source.indexOf('apply_image_sql_artifact "/myapp/prisma/rls/portal-legacy-commerce-recut-pre-db-push.sql"');
const schemaSync = source.indexOf("/myapp/node_modules/prisma/build/index.js db push");
const tenantPolicies = source.indexOf('apply_image_sql_artifact "/myapp/prisma/rls/tenant-policy-contract-isolation.sql"');
const portalPolicies = source.indexOf('apply_image_sql_artifact "/myapp/prisma/rls/portal-policy-contract-isolation.sql"');
const domainCapabilities = source.indexOf('apply_image_sql_artifact "/myapp/prisma/rls/portal-domain-capabilities.sql"');
const portalLaunch = source.indexOf('docker run -d --name "$PORTAL_CONTAINER_NAME"');
const portalAssertions = source.slice(portalLaunch);
assert.ok(migration >= 0);
assert.ok(legacyRecut > migration);
assert.ok(schemaSync > legacyRecut);
assert.ok(tenantPolicies > schemaSync);
assert.ok(portalPolicies > tenantPolicies);
assert.ok(domainCapabilities > portalPolicies);
assert.ok(coreReadiness > domainCapabilities);
assert.ok(portalLaunch > coreReadiness);
assert.match(roleFixture, /DOCKER_SMOKE_PORTAL_DB_PASSWORD="\$\{DOCKER_SMOKE_PORTAL_DB_PASSWORD:-portal_smoke_[^}]+\}"/);
assert.match(roleFixture, /local portal_password="\$DOCKER_SMOKE_PORTAL_DB_PASSWORD"/);
assert.match(source, /PORTAL_DATABASE_URL="postgresql:\/\/hivegrid_portal:\$\{DOCKER_SMOKE_PORTAL_DB_PASSWORD\}@db:5432/);
assert.match(portalAssertions, /-e PORTAL_APP_HOST=portal\.localhost/);
assert.match(portalAssertions, /-e WEB_RUNTIME_SURFACE=portal/);
assert.match(portalAssertions, /-e DATABASE_URL="\$PORTAL_DATABASE_URL"/);
assert.match(portalAssertions, /-e DATABASE_RUNTIME_ROLE=hivegrid_portal/);
assert.match(portalAssertions, /-e RLS_RUNTIME_MODE=required/);
assert.match(portalAssertions, /-e PORTAL_SESSION_SECRET=/);
assert.match(portalAssertions, /-e CAPTCHA_PROVIDER=mcaptcha/);
assert.match(portalAssertions, /-e MCAPTCHA_INSTANCE_URL=/);
assert.match(portalAssertions, /-e MCAPTCHA_SITEKEY_LOGIN=/);
assert.match(portalAssertions, /-e MCAPTCHA_ACCOUNT_SECRET=/);
assert.match(portalAssertions, /-e REDIS_URL='redis:\/\/redis:6379\/0'/);
assert.match(portalAssertions, /-e BULLMQ_REDIS_URL='redis:\/\/redis:6379\/0'/);
assert.doesNotMatch(portalAssertions, /-e SESSION_SECRET=/);
assert.doesNotMatch(portalAssertions, /-e DIRECT_URL=/);
assert.match(portalAssertions, /expect_status portal\.localhost \/healthz 200/);
assert.match(portalAssertions, /expect_runtime_payload portal\.localhost \/healthz ok hivegrid-portal portal/);
assert.match(portalAssertions, /expect_status portal\.localhost \/readyz 200/);
assert.match(portalAssertions, /expect_runtime_payload portal\.localhost \/readyz ready hivegrid-portal portal/);
});
it("boots the exact web image as a fail-closed admin-only surface", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
const adminLaunch = source.indexOf('docker run -d --name "$ADMIN_CONTAINER_NAME"');
const portalLaunch = source.indexOf('docker run -d --name "$PORTAL_CONTAINER_NAME"');
const coreAssertions = source.slice(0, adminLaunch);
const adminAssertions = source.slice(adminLaunch, portalLaunch);
assert.ok(adminLaunch >= 0 && portalLaunch > adminLaunch);
assert.match(coreAssertions, /expect_status admin\.localhost \/settings 404/);
assert.match(adminAssertions, /-e WEB_RUNTIME_SURFACE=admin/);
assert.match(adminAssertions, /-e DATABASE_URL="\$APP_DATABASE_URL"/);
assert.match(adminAssertions, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(adminAssertions, /-e RLS_RUNTIME_MODE=required/);
assert.match(adminAssertions, /-e SESSION_SECRET='deploy-smoke-admin-session-secret-minimum-32'/);
assert.match(adminAssertions, /-e ADMIN_FALLBACK_LOGIN_ENABLED=false/);
assert.match(adminAssertions, /-e AUTHENTIK_ISSUER_URL=/);
assert.match(adminAssertions, /-e AUTHENTIK_ADMIN_CLIENT_ID=/);
assert.match(adminAssertions, /-e AUTHENTIK_ADMIN_CLIENT_SECRET=/);
assert.match(adminAssertions, /-e AUTHENTIK_ADMIN_REDIRECT_URI='https:\/\/admin\.localhost\/auth\/admin\/callback'/);
assert.match(adminAssertions, /-e AUTHENTIK_ADMIN_JIT_DATABASE_URL="postgresql:\/\/hivegrid_authentik_jit:/);
assert.doesNotMatch(adminAssertions, /-e PORTAL_SESSION_SECRET=/);
assert.doesNotMatch(adminAssertions, /-e DIRECT_URL=/);
assert.match(adminAssertions, /expect_runtime_payload admin\.localhost \/healthz ok hivegrid-admin admin/);
assert.match(adminAssertions, /expect_runtime_payload admin\.localhost \/readyz ready hivegrid-admin admin/);
assert.match(adminAssertions, /expect_status app\.localhost \/healthz 404/);
assert.match(adminAssertions, /expect_status portal\.localhost \/healthz 404/);
assert.match(adminAssertions, /expect_status admin\.localhost \/settings 302/);
});
it("requires the web smoke to observe Docker health as well as HTTP health", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /\.State\.Health/);
assert.match(source, /CONTAINER_HEALTH/);
assert.match(source, /"\$HTTP_STATUS" == "200" && "\$CONTAINER_HEALTH" == "healthy"/);
assert.match(source, /Docker HEALTHCHECK became unhealthy with HTTP status/);
});
it("boots the web runtime with its required production Redis dependency", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-web-runtime-smoke.sh"), "utf8");
assert.match(source, /--network-alias redis redis:7-alpine/);
assert.match(source, /redis-cli ping/);
assert.match(source, /-e REDIS_URL='redis:\/\/redis:6379\/0'/);
assert.match(source, /-e AUDIT_CHAIN_SECRET='deploy-smoke-audit-chain-secret-minimum-32'/);
assert.match(source, /-e ADMIN_CONNECTION_MASTER_KEY='deploy-smoke-admin-connection-key-minimum-32'/);
assert.match(source, /\\\[DEP0169\\\]/);
assert.match(source, /deprecated url\.parse\(\) runtime path/);
});
it("rejects deprecated Redis URL parsing in the worker runtime", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
assert.match(source, /-e AUDIT_CHAIN_SECRET=deploy-smoke-audit-chain-secret-minimum-32/);
assert.match(source, /-e ADMIN_CONNECTION_MASTER_KEY=deploy-smoke-admin-connection-key-minimum-32/);
assert.match(source, /WORKER_LOGS="\$\(docker_smoke_logs "worker:logs-deprecation"/);
assert.match(source, /\\\[DEP0169\\\]/);
assert.match(source, /deprecated url\.parse\(\) runtime path/);
});
it("migrates the API smoke database with the matching web image and keeps the migrator out of the API image", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-api-runtime-smoke.sh"), "utf8");
assert.match(source, /MIGRATOR_IMAGE="\$\{DOCKER_SMOKE_MIGRATOR_IMAGE:-hivegrid-web:smoke\}"/);
assert.match(source, /migrator_revision" != "\$SMOKE_REVISION/);
assert.match(source, /provision_docker_smoke_rls_roles/);
assert.match(source, /-e DIRECT_URL="\$MIGRATOR_DATABASE_URL"/);
assert.match(source, /"\$MIGRATOR_IMAGE" migrate/);
assert.match(source, /-e DATABASE_URL="\$APP_DATABASE_URL"/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.match(source, /require\.resolve\("prisma"\)/);
assert.doesNotMatch(source, /\bpnpm\s+(?:exec|run|install)\b/);
assert.doesNotMatch(source, /127\.0\.0\.1::5432/);
});
it("boots the API smoke with the required production Redis dependency", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-api-runtime-smoke.sh"), "utf8");
assert.match(source, /--network-alias redis redis:7-alpine/);
assert.match(source, /redis-cli ping/);
assert.match(source, /-e REDIS_URL='redis:\/\/redis:6379\/0'/);
assert.match(source, /-e AUDIT_CHAIN_SECRET='deploy-smoke-audit-chain-secret-minimum-32'/);
assert.match(source, /-e ADMIN_CONNECTION_MASTER_KEY='deploy-smoke-admin-connection-key-minimum-32'/);
});
it("fails the API health poll immediately with container exit diagnostics", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-api-runtime-smoke.sh"), "utf8");
assert.match(source, /DOCKER_API_SMOKE_HEALTH_ATTEMPTS:-120/);
assert.match(source, /assert_api_container_running/);
assert.match(source, /docker inspect -f '\{\{\.State\.Running\}\}'/);
assert.match(source, /exit=\{\{\.State\.ExitCode\}\} oom=\{\{\.State\.OOMKilled\}\}/);
assert.match(source, /docker_smoke_logs "api:logs-exit" "\$CONTAINER_NAME"/);
assert.match(source, /\n'\n}\n\nassert_api_container_running\(\)/);
assert.match(source, /for attempt in \$\(seq 1 "\$HEALTH_ATTEMPTS"\); do\n assert_api_container_running/);
});
it("migrates the worker smoke database with the matching web image and keeps build toolchains out of the worker image", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
assert.match(source, /MIGRATOR_IMAGE="\$\{DOCKER_SMOKE_MIGRATOR_IMAGE:-hivegrid-web:smoke\}"/);
assert.match(source, /migrator_revision" != "\$SMOKE_REVISION/);
assert.match(source, /provision_docker_smoke_rls_roles/);
assert.match(source, /-e DIRECT_URL="\$MIGRATOR_DATABASE_URL"/);
assert.match(source, /"\$MIGRATOR_IMAGE" migrate/);
assert.match(source, /-e DATABASE_URL="\$WORKER_DATABASE_URL"/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_worker/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.match(source, /\^prisma@/);
assert.match(source, /\^typescript@/);
assert.match(source, /\^@prisma\\\+engines@/);
assert.doesNotMatch(source, /\bpnpm\s+(?:exec|run|install)\b/);
assert.doesNotMatch(source, /127\.0\.0\.1::5432/);
});
it("proves worker queue-group routing for general and mail workers", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
const mailHealthBlock = source.match(/mail_health_output=""[\s\S]*?expect_worker_health "\$mail_health_output"[^\n]*/)?.[0];
const mailCryptoFixture = /-e CRYPTO_SECRET=deploy-smoke-shared-tenant-envelope-secret-minimum-32/;
assert.match(source, /-e WORKER_QUEUE_GROUP=general/);
assert.match(source, /-e WORKER_QUEUE_GROUP=mail/);
assert.ok(mailHealthBlock, "worker smoke must keep a dedicated mail-health block");
assert.match(mailHealthBlock, mailCryptoFixture);
assert.equal(source.match(new RegExp(mailCryptoFixture.source, "g"))?.length, 1, "CRYPTO_SECRET smoke fixture must remain mail-only");
assert.match(source, /expect_worker_health "\$enabled_health_output" ready true general hivegrid\.notifications/);
assert.match(source, /expect_worker_health "\$mail_health_output" ready true mail hivegrid\.email/);
assert.match(source, /report\.workerGroup !== expectedGroup/);
assert.match(source, /report\.queues\.includes\(expectedQueue\)/);
assert.match(source, /product_acquisition_env=\(/);
assert.match(source, /-e LAGO_API_URL=/);
assert.match(source, /-e LAGO_API_KEY=/);
assert.match(source, /-e LAGO_TIMEOUT_MS=/);
assert.match(source, /-e MOLLIE_API_KEY=/);
assert.match(source, /-e MOLLIE_PROFILE_ID=/);
assert.match(source, /-e MOLLIE_TIMEOUT_MS=/);
assert.match(source, /"\$\{product_acquisition_env\[@\]\}"/);
});
it("boots the general worker with delete-only retention and hard-delete fixtures", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
const hardDeleteBlock = source.match(/general_hard_delete_env=\([\s\S]*?\n\)/)?.[0];
const requiredFixtures = [
"EXPORT_RETENTION_QUEUE_ENABLED=true",
"STORAGE_ENDPOINT=https://storage.example.test",
"STORAGE_REGION=eu-central-1",
"STORAGE_BUCKET=docker-smoke-private-exports",
"STORAGE_ACCESS_KEY_ID=docker-smoke-retention-access-key",
"STORAGE_SECRET_ACCESS_KEY=docker-smoke-retention-secret-key",
"STORAGE_FORCE_PATH_STYLE=false",
"MEILI_URL=http://meili:7700",
"MEILI_API_KEY=docker-smoke-tenant-delete-meili-master-key",
];
assert.ok(hardDeleteBlock, "worker smoke must keep a dedicated general hard-delete fixture");
for (const fixture of requiredFixtures) {
assert.equal(hardDeleteBlock.includes(`-e ${fixture}`), true);
}
assert.doesNotMatch(hardDeleteBlock, /GDPR_EXPORT_SSE_C_KEY_BASE64/);
assert.equal(
source.match(/"\$\{general_hard_delete_env\[@\]\}"/g)?.length,
2,
"hard-delete fixtures must cover both the health probe and the running general worker"
);
assert.match(source, /--network-alias meili/);
assert.match(source, /MEILI_IMAGE="\$\{DOCKER_WORKER_SMOKE_MEILI_IMAGE:-getmeili\/meilisearch:v1\.8\}"/);
assert.match(source, /worker:pull-meili/);
assert.match(source, /docker run -d --pull=never/);
assert.match(source, /worker:probe-meili/);
});
it("checks the running worker revision without starting a second Node runtime", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-worker-runtime-smoke.sh"), "utf8");
const revisionBlock = source.match(
/docker_smoke_run "worker:assert-revision-file"[\s\S]*?' _ "\$SMOKE_REVISION"/
)?.[0];
assert.ok(revisionBlock, "worker smoke must prove the immutable revision file");
assert.match(revisionBlock, /docker exec "\$CONTAINER_NAME" sh -eu -c/);
assert.match(revisionBlock, /stat -c "%u"/);
assert.match(revisionBlock, /0\$mode & 022/);
assert.doesNotMatch(revisionBlock, /\bnode\s+-e\b/);
});
it("boots the MCP image with its required production secrets and Redis dependency", () => {
// The MCP runtime refuses to boot in production without a token hash secret
// (security audit #7). The smoke runs NODE_ENV=production, so it must supply
// one or the container exits before the health check.
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-mcp-runtime-smoke.sh"), "utf8");
assert.match(source, /-e NODE_ENV=production/);
assert.match(source, /-e MCP_OAUTH_TOKEN_HASH_SECRET=/);
assert.match(source, /-e AUDIT_CHAIN_SECRET='deploy-smoke-audit-chain-secret-minimum-32'/);
assert.match(source, /--network-alias redis redis:7-alpine/);
assert.match(source, /redis-cli ping/);
assert.match(source, /-e REDIS_URL='redis:\/\/redis:6379\/0'/);
assert.match(source, /--network-alias db/);
assert.match(source, /pg_isready/);
assert.match(source, /provision_docker_smoke_rls_roles/);
assert.match(source, /-e DIRECT_URL="\$MIGRATOR_DATABASE_URL"/);
assert.match(source, /MIGRATOR_IMAGE="\$\{DOCKER_SMOKE_MIGRATOR_IMAGE:-hivegrid-web:smoke\}"/);
assert.match(source, /migrator_revision" != "\$SMOKE_REVISION/);
assert.match(source, /"\$MIGRATOR_IMAGE" migrate/);
assert.match(source, /-e DATABASE_URL="\$APP_DATABASE_URL"/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.match(source, /\["prisma", "typescript", "@prisma\/engines"\]/);
assert.match(source, /MCP runtime retained build-only package/);
assert.match(source, /wait_for_status \/readyz 200 "initial dependency readiness"/);
assert.match(source, /docker stop "\$REDIS_CONTAINER_NAME"/);
assert.match(source, /wait_for_status \/readyz 503 "Redis outage readiness"/);
assert.match(source, /wait_for_status \/readyz 200 "Redis recovery readiness"/);
assert.match(source, /docker stop "\$DB_CONTAINER_NAME"/);
assert.match(source, /wait_for_status \/readyz 503 "Postgres outage readiness"/);
assert.match(source, /expect_status \/healthz 200/);
});
it("boots the Hocuspocus image as non-root and validates its pruned target-specific runtime inventory", () => {
const source = fs.readFileSync(path.join(rootDir, "scripts/docker-hocuspocus-runtime-smoke.sh"), "utf8");
assert.match(source, /docker_smoke_capture IMAGE_USER "hocuspocus:inspect-user"/);
assert.match(source, /process\.getuid\?\.\(\) !== 1000/);
assert.match(source, /Runtime retained package-manager executables/);
assert.match(source, /entry\.name\.endsWith\("\.map"\)/);
assert.match(source, /entry\.name\.endsWith\("\.d\.ts"\)/);
assert.match(source, /sbom\.schema !== "hivegrid\.sbom-pnpm\/v2"/);
assert.match(source, /sbom\.target !== "hocuspocus"/);
assert.match(source, /installed pruned pnpm runtime tree/);
assert.match(source, /packageNames\.has\("@hocuspocus\/server"\)/);
assert.match(source, /query_compiler_fast_bg\.postgresql\.mjs/);
assert.match(source, /query_compiler_fast_bg\.postgresql\.wasm-base64\.mjs/);
assert.match(source, /Runtime retained unexpected Prisma compiler payloads/);
assert.match(source, /Runtime retained the build-only Prisma client generator/);
assert.match(source, /expectedPrismaCompilers\.map\(\(specifier\) => import\(specifier\)\)/);
assert.match(source, /--network-alias db/);
assert.match(source, /pg_isready/);
assert.match(source, /MIGRATOR_IMAGE="\$\{DOCKER_SMOKE_MIGRATOR_IMAGE:-hivegrid-web:smoke\}"/);
assert.match(source, /migrator_revision" != "\$SMOKE_REVISION/);
assert.match(source, /provision_docker_smoke_rls_roles/);
assert.match(source, /-e DIRECT_URL="\$MIGRATOR_DATABASE_URL"/);
assert.match(source, /"\$MIGRATOR_IMAGE" migrate/);
assert.match(source, /-e DATABASE_URL="\$APP_DATABASE_URL"/);
assert.match(source, /-e DATABASE_RUNTIME_ROLE=hivegrid_app/);
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
assert.match(source, /-e HOCUSPOCUS_AUTH_SECRET=/);
assert.match(source, /require\("node:net"\)\.connect\(1234, "127\.0\.0\.1"\)/);
assert.match(source, /docker_smoke_capture RUNTIME_REVISION "hocuspocus:runtime-revision"/);
});
it.each([
["scripts/docker-web-runtime-smoke.sh", "hivegrid_app"],
["scripts/docker-api-runtime-smoke.sh", "hivegrid_app"],
["scripts/docker-mcp-runtime-smoke.sh", "hivegrid_app"],
["scripts/docker-worker-runtime-smoke.sh", "hivegrid_worker"],
["scripts/docker-hocuspocus-runtime-smoke.sh", "hivegrid_app"],
])("keeps privileged database credentials out of the long-lived runtime: %s", (relativePath, role) => {
const source = fs.readFileSync(path.join(rootDir, relativePath), "utf8");
const runtimeLaunch = source.slice(source.indexOf('docker run -d --name "$CONTAINER_NAME"'));
assert.match(source, new RegExp(`-e DATABASE_RUNTIME_ROLE=${role}`));
assert.match(source, /-e RLS_RUNTIME_MODE=required/);
if (role === "hivegrid_worker") assert.match(runtimeLaunch, /"\$\{worker_env\[@\]\}"/);
assert.doesNotMatch(runtimeLaunch, /-e DIRECT_URL=/);
assert.doesNotMatch(runtimeLaunch, /-e (?:MIGRATE_ON_BOOT|SEED_ON_BOOT|SEED_ONCE)=/);
assert.doesNotMatch(runtimeLaunch, /RLS_RUNTIME_MODE=off/);
});
});