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:-\}, 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/); }); });