#!/usr/bin/env node // scripts/verify-phase-5.mjs // [doc->REQ-DEP-04] // Source: Phase 5 DEP-01..DEP-08 composite verify gate. // // Sequential orchestrator running every Phase 5 lint + test + carry-over. // First non-zero exit fails. Mirrors scripts/verify-phase-4.mjs structure. // // Usage: node scripts/verify-phase-5.mjs OR: pnpm verify:phase-5 // Exit: 0 success, 1 first-failed-step. import { spawnSync } from 'node:child_process'; const isWindows = process.platform === 'win32'; // WR-14 fix: cheap lints (regex against committed source) run BEFORE // the full workspace test suite so a developer who accidentally commits // a deploy-stack drift / ADR structure violation surfaces the failure // in seconds rather than after a 2-minute test run. Order rationale: // 1. Phase 4 carry-over — a Phase 4 regression invalidates everything // 2. Workspace typecheck — fastest type-level safety net // 3. Cheap regex lints — Phase 5 forcing functions (lint:deploy-stack, ADR lints) // 4. Workspace test — slowest step; ordering it last means the cheap // stuff fails-first and saves CI time // 5. Traceable-reqs check — anchored last per CLAUDE.md hard rule // // NOTE: Soak (Plan 11) is OUT-OF-BAND — NOT in this gate. // `pnpm soak:staging` runs via workflow_dispatch + nightly cron (Plan 11). // RESTORE.md drill (Plan 13) is manual UAT — not in this gate either. // SKIP_TRACE_CHECK=1 — `traceable-reqs` is operator-installed (CLAUDE.md // links to BigscreenVR/traceable-reqs) and not yet packaged for Linux // runners; CLAUDE.md defers the CI hard-gate. Local runs unaffected. // SKIP_PHASE_4_CARRYOVER=1 — staging-debug escape hatch. Use only when // Phase 4 has already been covered by a prior gate or local focused checks; // normal release/merge verification must keep the carry-over enabled. const SKIP_PHASE_4 = process.env.SKIP_PHASE_4_CARRYOVER === '1'; const SKIP_TRACE = process.env.SKIP_TRACE_CHECK === '1'; const steps = [ ...(SKIP_PHASE_4 ? [] : [['Phase 4 carry-over: verify-phase-4', 'pnpm', ['verify:phase-4']]]), ['Workspace: typecheck', 'pnpm', ['-r', 'typecheck']], ['Lint: deploy-stack', 'pnpm', ['lint:deploy-stack']], ['Lint: deploy-stack test', 'pnpm', ['lint:deploy-stack:test']], ['ADR 0005 lint', 'pnpm', ['lint:adr:0005']], ['ADR 0006 lint', 'pnpm', ['lint:adr:0006']], ['Workspace: test', 'pnpm', ['-r', 'test']], ...(SKIP_TRACE ? [] : [['Traceable-reqs: check', 'pnpm', ['trace:check']]]), ]; let failed = null; for (const [label, cmd, args] of steps) { process.stdout.write(`\n=== ${label} ===\n>>> ${cmd} ${args.join(' ')}\n`); const r = spawnSync(cmd, args, { encoding: 'utf-8', shell: isWindows, stdio: 'inherit' }); if (r.status !== 0) { failed = { label, cmd, args, status: r.status }; break; } } if (failed) { process.stderr.write( `\nverify-phase-5 FAILED at step '${failed.label}': ${failed.cmd} ${failed.args.join(' ')} (exit ${failed.status})\n` ); process.stderr.write(`Fix the failing step and re-run \`pnpm verify:phase-5\`.\n`); process.exit(1); } process.stdout.write(`\nverify-phase-5: OK (${steps.length} steps green)\n`); process.exit(0);